pax_global_header00006660000000000000000000000064143747125460014527gustar00rootroot0000000000000052 comment=8c7c94a038aae72dc89c994551c9d2c690895607 ocaml-cstruct-6.2.0/000077500000000000000000000000001437471254600143145ustar00rootroot00000000000000ocaml-cstruct-6.2.0/.drone.yml000066400000000000000000000010111437471254600162150ustar00rootroot00000000000000kind: pipeline name: amd platform: os: linux arch: amd64 steps: - name: build image: ocaml/opam:debian-ocaml-4.12-afl commands: - sudo chown -R opam . - git -C /home/opam/opam-repository pull origin 1ce065bc0cbef7bc06effcd3865af0d430c6273b && opam update - opam pin add -n . - opam depext -u cstruct-async cstruct-lwt cstruct-unix cstruct ppx_cstruct - opam install -y . - opam install -y dune crowbar fmt 'bun>=0.3.4' - opam exec -- dune build @fuzz --no-buffer ocaml-cstruct-6.2.0/.gitattributes000066400000000000000000000001771437471254600172140ustar00rootroot00000000000000# Default behaviour, for if core.autocrlf isn't set * text=auto .azure-pipelines.sh text eol=lf ppx_test/errors/* text eol=lf ocaml-cstruct-6.2.0/.github/000077500000000000000000000000001437471254600156545ustar00rootroot00000000000000ocaml-cstruct-6.2.0/.github/workflows/000077500000000000000000000000001437471254600177115ustar00rootroot00000000000000ocaml-cstruct-6.2.0/.github/workflows/test.yml000066400000000000000000000032461437471254600214200ustar00rootroot00000000000000name: Cstruct on: [push, pull_request] jobs: latest: name: Latest runs-on: ${{ matrix.operating-system }} strategy: fail-fast: false matrix: ocaml-version: [ '4.13.1', '4.10.0', '4.08.1' ] operating-system: [macos-latest, ubuntu-latest, windows-latest] steps: - uses: actions/checkout@v2 - uses: avsm/setup-ocaml@v1 with: ocaml-version: ${{ matrix.ocaml-version }} - run: opam pin add -n . - name: Packages run: opam depext -yt cstruct cstruct-sexp cstruct-unix cstruct-lwt - name: Build run: opam install -t cstruct cstruct-sexp cstruct-unix cstruct-lwt ppx: name: PPX runs-on: ${{ matrix.operating-system }} strategy: fail-fast: false matrix: ocaml-version: [ '4.13.1', '4.10.0', '4.08.1' ] operating-system: [macos-latest, ubuntu-latest, windows-latest] steps: - uses: actions/checkout@v2 - uses: avsm/setup-ocaml@v1 with: ocaml-version: ${{ matrix.ocaml-version }} - run: opam pin add -n . - name: Packages run: opam depext -yt ppx_cstruct - name: Build run: opam install -t ppx_cstruct async: name: Async runs-on: ${{ matrix.operating-system }} strategy: fail-fast: false matrix: ocaml-version: [ '4.13.1', '4.10.0', '4.08.1' ] operating-system: [macos-latest, ubuntu-latest] steps: - uses: actions/checkout@v2 - uses: avsm/setup-ocaml@v1 with: ocaml-version: ${{ matrix.ocaml-version }} - run: opam pin add -n . - name: Packages run: opam depext -yt cstruct-async - name: Dependencies run: opam install -t cstruct-async ocaml-cstruct-6.2.0/.gitignore000066400000000000000000000000471437471254600163050ustar00rootroot00000000000000_build/ .merlin *.install .*.swp _opam ocaml-cstruct-6.2.0/.ocamlformat000066400000000000000000000000341437471254600166160ustar00rootroot00000000000000version=0.20.1 disable=true ocaml-cstruct-6.2.0/CHANGES.md000066400000000000000000000515121437471254600157120ustar00rootroot00000000000000v6.2.0 2023-02-20 ----------------- - Add `sub_copy` function (@c-cube, #305) - Fix documentation (@MisterDA, #304) - Add `to_hex_string` function (@c-cube, #306) - Fix documentation and use `Cstruct.length` instead of `Cstruct.len` (@reynir, #307) - Deprecate `copy` function (alias of `to_string`) (will be removed at the next minor release) (@reynir, #308) v6.1.1 2022-07-24 ----------------- - ppx_cstruct: remove superfluous stdlib-shims dependency (@hannesm #300) v6.1.0 2022-03-29 ----------------- **breaking changes** - The deprecated functions `Cstruct.len`, `Cstruct.add_len`, `Cstruct.set_len`, and `Cstruct.blit_to_string` have been removed (@hannesm #291) - Implement host_endian (@haesbaert #292, fixes #72) - Compatibility with OCaml 5.0.0 (@dinosaure #294) - Drop support of OCaml < 4.08.0, remove bigarray-compat dependency (@hannesm #298) - Fix year in changes of 6.0.1 (@reynir #297) v6.0.1 2021-06-25 ----------------- **breaking changes** - `Cstruct.len` is deprecated, it will be deleted at the next release. You should use `Cstruct.length` instead. (@dinosaure, @hannesm, #284) - Remove color from ppx's binary to replicate diff of errors in any contexts (@dinosaure, @sternenseemann, #285) - Add `shiftv` (@talex5, @avsm, @dinosaure, #287) - Use `Bytes_val` if available (@hannesm, @avsm, @dinosaure, #286) v6.0.0 2020-09-10 ----------------- **breaking changes** - Add the function `Cstruct.length`, `Cstruct.len` will be deprecated to next release (@dinosaure, @hannesm, @avsm, #279) - `Cstruct.to_string` requires 2 optional arguments `?off` and `?len` (@hannesm, @cfcs, @talex5, @dinosaure, #262) - Use `ppxlib` instead `ppx_tools_versioned` (@pveber, @avsm, @dinosaure, #280) - Delete the support of old version of OCaml (< 4.07.0) for `ppx_cstruct` (@avsm, @dinosaure, #280) - Add useful functions to be able to parse some contents with `Cstruct.t` like the `astring` library (#227, @dinosaure, @avsm, @samoht, @hannesm). - Improve the interface of `Cstruct.t` with capabilities (@hannesm, @cfcs, @talex5, @dinosaure, #262) v5.2.0 2020-06-10 ----------------- Upgrade the `ppx_cstruct` library to use the OCaml 4.11 AST rather than than OCaml 4.04, which in turn should make it easier to port to ppxlib in the future and improve interoperability with other PPXs (@bikallem #275). Also upgrades build files to use dune 2.0 (@bikallem #275) and fixes the GitHub Actions versions (@smorimoto #273) and also test OCaml 4.10.0 (@avsm). v5.1.1 2019-11-23 ----------------- This is a point release to fix a regression in 5.1.0 on compilers earlier than 4.07. The release also fixes the test suite and CI on compilers greater than 4.07. v5.1.0 2019-11-23 ----------------- - Do not issue deprecation warnings when using OCaml 4.08.0 and cstruct-ppx with enums due to `Pervasives` (#269 @cypheon @hannesm) - Tighten parsing of the `[@len]` attribute to ensure it is a valid, positive integer (#265 @emillon) - Update JavaScript bindings to latest `Js_of_ocaml` 3.5.0 interfaces (@hhugo #268) v5.0.0 2019-04-19 ----------------- **Security**: This release tightens bounds checks to ensure that data outside a given view (but still inside the underlying buffer) cannot be accessed. - `sub` does more checks (#244 #245 @hannesm @talex5 review by @dinosaure) - `add_len` and `set_len` are now deprecated and will be removed in a future release. (#251 @hannesm) - do not add user-provided data for bounds checks (#253 @hannesm, report and review by @talex5) - improve CI to add fuzzing (#255 #252 @avsm @yomimono @talex5) **Remove Unix dependency**: cstruct now uses the new `bigarray-compat` library instead of Bigarray directly, to avoid a dependency on Unix when using OCaml compilers less than 4.06.0. This will break downstream libraries that do not have a direct dependency on `Bigarray`. Simply fix it in your library by adding a `bigarray` dependency in your dune file. (#247 @TheLortex) **Capability module**: To improve the safety of future code with stronger type checking, this release introduces a new `Cstruct_cap` module which makes the underlying Cstruct an abstract type instead of a record. In return for this extra abstraction, the module can enforce read-only, write only, and read/write buffers by tracking them as phantom type variables. Although this library shares an implementation internally with classic `Cstruct`, it is a significant revision and so we will be gradually migrating to it. Feedback on it is welcome! (#237 @dinosaure and many excited reviewers) **Ppx compare functions**: A new `compare_X` function is generated for `cenum` declarations. This respects custom ids supplied in the cenum declaration and so is more robust than polymorphic compare (#248 @emillon) The CI has also been switched over to both Azure Pipelines and Drone in addition to Travis, and as a result the tests all run on Windows, macOS, various Linux distributions, on x86 and arm64 machines, and runs AFL fuzz tests on the Drone cloud (#255 @avsm). v4.0.0 2019-03-25 ----------------- - Sexplib is now an optional library for the base `Cstruct` module. A new `Cstruct_sexp` module has been introduced with the serialiser functions, contained within the `cstruct-sexp` opam package. To convert old code, simply use `Cstruct_sexp.t` instead of `Cstruct.t` in a record type for which you are using `[@@deriving sexp]`. This is a type alias to `Cstruct.t` but also has the right sexp-conversion functions in scope. There is an example of this in the `ppx_test/with-sexp` directory in the source repo. When you have converted and released your library, add an opam constraint of `cstruct {>="4.0.0"}` to your own opam packages to ensure that they pick up this version of the library. (fixes #222, @avsm) - JavaScript stubs are now installed using the jsoo mechanism rather than a manual specification (#241 @jonludlam) - Use computed versions in opam files to ensure that dependent opam packages such as cstruct-async get the same base version of cstruct to avoid mismatches. (@avsm) - Add a ppx test suite to checks that all error paths in ppx handling are reachable and have meaningful location info (#238 @emillon) v3.7.0 2019-03-10 ----------------- - Improve performance by not doing redundant bounds checks in both the Bigarray and Cstruct level (#236 @Reperator @chambart) - Ignore fields starting wih `_` by skipping code generation but still respecting the space usage of that field. This was a convention before but is now enforced by the code generator to save space in the output (#233 @emillon) - More warnings suppression for sizeof and enums (#231 @emillon) v3.6.0 2019-03-01 ----------------- - A `[%%cstruct type ...]` declaration generates many values that are potentially unused. The code generator in `ppx_cstruct` now guarantees that there will be no more "unused value" (warning 32) statements from use of the ppx form. (#228 @emillon) - Actually run the ppx tests instead of just building them. (#227 @emillon to fix #226 from @XVilka) v3.5.0 2019-02-26 ----------------- - Remove trailing spaces in hexdump output (#219 @emillon) - Add `Cstruct.rev` to allocate a reversed cstruct (#221 @emillon) - `Cstruct_unix` now uses the post-OCaml 4.06 `Unix.map_file` instead of the deprecated Bigarray `map_file` that was removed in OCaml 4.08 (@avsm, see ocaml/ocaml#2263) - Remove unnecessary `(wrapped false)` in the build system (@avsm) - Correct ocamldoc to the right `cstruct-ppx` package pointer (@avsm) v3.4.0 2019-02-02 ----------------- - Remove old compatibility packages for `cstruct.lwt`, `cstruct.async`, `cstruct.ppx` and `cstruct.unix`. These were deprecated in cstruct.3.0.0 in favour of counter part libraries with a dash in the name (`cstruct-lwt`, `cstruct-async`, `cstruct.unix`) or `ppx_cstruct` for the PPX extension. (@avsm) v3.3.0 2019-01-22 ----------------- - Support for bi-endian cstructs that generate both sets of accessor functions (#212 by @XVilka). This generates both `BE` and `LE` modules to use as needed. - Modify `of_string` and `of_bytes` to have an option `?off` offset argument into the source bytes. (#208 by @XVilka) - Improve tests to work on 32-bit architectures and handle Gc better (@samoht) - Do not depend explicitly on deprecated `ppx_driver`. This was primarily there for older compilers, and new uses should be based around `ppxlib`. (#201 by @edwintorok). - Upgrade opam metadata to 2.0 format. (#217 by @XVilka @avsm) - Upgrade to dune from jbuilder and support dune-release instead of topkg (@avsm) v3.2.1 2017-12-13 ----------------- - improve performance by using primitives instead of C stubs. the performance regression was introduced in #177 in 3.2.0 (#195 by @pqwy) v3.2.0 2017-11-17 ----------------- - wrap `hexdump_pp` output in a box (#175 by @cfcs) - remove dependency on `ocplib-endian` (#177 by @hannesm) - add `of_hex: string -> t` (#179 by @hannesm and @pqwy) - add `to_bytes: t -> Bytes.t` (#183 by @hannesm) - add `empty: t` (#184 by @hannesm) - sub: check the bounds more carefully for overflow (#185 by @hannesm) - cstruct-unix: fix the build on OCaml 4.06.0 (#187 by @djs55) - travis: test OCaml 4.04.2 and 4.06.0 (#186 by @hannesm) v3.1.1 2017-07-13 ----------------- - `check_alignment` now treats a large alignment as an unsigned value and so doesnt raise a signal (#171 by @yallop) - Improve Windows support by avoiding `void *` pointer arithmetic and have more portable headers in the C stubs (#170 by @fdopen) v3.1.0 2017-07-12 ----------------- - Fix arithmetic overflow in `Cstruct.lenv` and `copyv` (#159 by @yallop) - Reject negative destination offsets in `blit` (#160 by @yallop) - Add AFL fuzz tests using Crowbar, which independently discovered #160 and also an overflow in `of_bigarray` and `sub`, now bith fixed (#164 by @talex5) - Improve performance of several allocation functions by eliminating an unnecessary buffer zero step (#158 by @hannesm) - Compile the source tree with stricter flags, including dead variable detection and deprecation warnings (#157 by @samoht) - Bump the required minimum OCaml version up to 4.03.0 (due to #157). v3.0.2 2017-06-14 ----------------- - fix the `cstruct-async` package build, and depend on the latest Async packages (>="v0.9.0") as part of this. (#152 @jnfoster) v3.0.1 2017-06-09 ----------------- - ppx: remove an errant standalone initialiser that was messing up the composition of cstruct with other `ppx_driver` based ppx converters (most notably `ppx_sexp_conv`. If you are having trouble with using `ppx_cstruct` with other drivers, put a constraint on `ppx_cstruct>=3.0.1`. (#151 #150 #149 #148 via @djs55 @g2p @avsm @diml). - ppx: also add a test case for `cstruct` and `lwt` working together, but this will not work until a `lwt>3.0` release happens. - Update opam rules to use `jbuilder subst` for version information in the distribution. - Fix tests so that `check_alignment` expects a negative result. - Add opam test target for core library. v3.0.0 2017-05-11 ----------------- - Split up OPAM packages into multiple independent ones. We now have a standalone `cstruct`, and then separate `cstruct-lwt`, `cstruct-async`, `cstruct-unix` packages, and a `ppx_cstruct` package for the syntax extension. Transitional findlib packages with the old scheme are available, but now packages should migrate to using `cstruct-async` instead of `cstruct.async` for example. This has the added benefit of the OPAM package names now matching the findlib names. (#138 by @avsm @rgrinberg). - Port build to [jbuilder](https://github.com/janestreet/jbuilder). See the README for local development instructions. - Ensure that `check_alignment` only takes a non-zero argument for alignment (#143 #145 by @cfcs @avsm). v2.4.1 2017-05-03 ----------------- - fix missing `ppx_tools_versioned` dependency (#136, @let-def) v2.4.0 2017-03-30 ----------------- Distribute the PPX extension so that it is compatible with Jbuilder. `ppx_cstruct` is now distributed as both a library and a binary. Findlib predicates are used to distinguish usage: - the binary is used for toplevel and simple -ppx building - the library is used for linking custom rewriters - `-package cstruct.ppx` alone uses the binary for rewriting. - `-package cstruct.ppx` -predicates custom_ppx,ppx_driver" is used to link the rewriter. To use the PPX extension in jbuilder, just add: ``` (libraries (cstruct)) (preprocess (pps (cstruct.ppx))) ``` to your `jbuild` file. This may be renamed to `ppx_cstruct` in a future release so that the PPX dependency is decoupled from the main library, so this `cstruct.ppx` is intended to be transitional as it is what was originally used. v2.3.3 2017-03-28 ----------------- * Port ppx extension to use `ocaml-migrate-parsetree` so it should also compile on future revisions of OCaml (#127 via @let-def). v2.3.2 2017-03-03 ----------------- * Add support for OCaml 4.05 for the PPX extension. * Docs: correct to description of shift function (#121 via @orbifx). v2.3.1 2016-12-10 ----------------- * Fix a memory leak in the exception printing code (#130 via @djs55) * Appveyor CI fixes (#130 via @avsm) * Fix typo in docstring (#117 via @yomimono) * Fix opam base-unix dependency (#115 via @avsm) v2.3.0 2016-08-16 ----------------- * Add `Cstruct.of_bytes/to_bytes`. In common with the existing implementation, this relies on the representation of bytes and string being the same, which is true as of OCaml 4.04 and lower (#105 via @yallop). * Support OCaml 4.04 (#111 via @gasche). v2.2.0 2016-06-30 ----------------- * Make `create` zero out the new buffer. The new `create_unsafe` function can be used if you want to trade safety for speed. v2.1.0 2016-05-04 ----------------- * Add `hexdump_pp` that uses the Format module. This works better with the Logs library than using `hexdump_to_buffer`, and also makes it easy to indent the hexdump (#100 via @talex5). v2.0.0 2016-04-26 ----------------- * Remove camlp4 extension as it is no longer maintained (#95). * Add support for OCaml 4.03 in the PPX extension (#96). * Minimum supported OCaml version for the library is now 4.02.3. * Fix parsing of high int32 `@@enum` values. * Move `Cstruct.check_alignment` into the stubs. Before this patch we returned the buffer address from C and then calculated using OCaml's boxed `Int64.t`. This patch reduces minor allocations by performing the calculation in the C stubs. This makes the function suitable for use in an assert in a performance sensitive path. v1.9.0 2016-02-19 ----------------- * Add support for a ppx-based extension that uses the extension point support in OCaml 4.02 and higher to generate Cstruct and Cenum function definitions. The new syntax is documented in the README file. v1.8.0 2016-01-05 ----------------- * Add support for `-safe-string` in OCaml 4.02 upwards. The main change is to rename `blit_to_string` to `blit_to_bytes` and change its type so that it writes to bytes rather than string (#74 by @yallop). * Remove strong build-time dependency on `camlp4` in the base library. The `sexplib` functions were only used in the interface, so replace them with manually written ones. This also enables compatibility with latest Core that has switched to ppx. * Add multi-distro testing via Travis/Docker containers. v1.7.1 2015-12-15 ----------------- * Correct error output for `LE.get_uint16` on invalid bounds (#75) * Fix `fillv`. If the source didn't fit in the buffer then we skipped the amount we wanted to copy, not the amount actually copied (#77). v1.7.0 2015-07-11 ----------------- * Add `Cstruct.concat` and `Cstruct.append` (#57, @pqwy) * Add `js_of_ocaml` stubs (#63, #64, @djs55) v1.6.0 2015-03-28 ----------------- * Add `memset` to set all the bytes of a cstruct value efficiently (#49) * More useful `Invalid_argument` parameters (#48). * Fix `to_sexp` to expose only the current view (#44 from David Kaloper). * Add `compare` and `equal` (#23, #24 and #45 from David Kaloper). * Add `fillv` to copy over a list of buffers (from Thomas Leonard). * Shift to centralised Travis scripts. v1.5.0 2014-11-24 ----------------- * Make `camlp4` an optional build-time dependency (#35). * Remove `ounit` as a dependency in the `opam` file. * Improve `opam` description file for OPAM 1.2 workflow (#36). * Refresh Merlin IDE description (#37). v1.4.0 2014-08-10 ----------------- Comprehensive addition of bounds checking to all cstruct operations (from @pqwy in #33). The major changes are: * Disallow negative indexing with all cstruct accessors. * Disallow negative `sub` and `shift` operations. * Make sure `of_bigarray` cannot create invalid `cstruct` values. v1.3.1 2014-07-10 ----------------- * Also bounds test single-byte operations on views (#31 via @pqwy). v1.3.0 2014-07-04 ----------------- * Add bounds checks for `Cstruct.BE/LE` functions that violate a view. Previously, only bounds errors on the underlying buffers would raise. Bug #25, reported by Mindy Preston in mirage/mirage-tcpip#56. * Add 'Lwt_cstruct.complete' to ensure that `read`/`write` operatiosn run to completion. * Add `Sexplib` conversion functions to `Cstruct.t` values (#27 #22). v1.2.0 2014-06-06 ----------------- Add a `sexp` optional decorator to `cenum` to output the values as s-expressions. This is compatible with the `sexplib` convention. The syntax is; ``` cenum foo64 { ONE64; TWO64; THREE64 } as uint64_t(sexp) ``` And `sexp_of_foo64` and `foo64_of_sexp` functions will also be available. The representation of the Sexp is the string representation of the enum. v1.1.0 2014-02-19 ----------------- * Improve bounds checks on sub, shift, set_len, add_len. * Add `to_bigarray` to convert back into a Bigarray slice. v1.0.1 2013-12-09 ----------------- * Fix Cstruct.shift function v1.0.0 2013-12-05 ----------------- * Remove IPv4/IPv6 types (now moved to `ocaml-ipaddr`). * Improved ocamldoc for the interface. * More conservative bounds checking in the length manipulation functions. * Build C stubs with `-Wall`. v0.8.1 2013-11-06 ----------------- * Trailing semicolons are allowed in cstruct field definitions. * Buffer elements can be any primitive integer, not just `uint8`. v0.8.0 2013-10-13 ----------------- * Improved ocamldoc for BE/LE modules. * Add Travis-CI test scripts and fix `test.sh` script compilation. * Support int32/int64 constant values in cenum like `VAL = 0xffffffffl`, useful for 32-bit hosts. * Check and raise error in case of negative offsets for blits (#4). * Correctly preserve the sequence after a constant constructor is set during a `cenum` definition. * Do not repeat the `sizeof_` binding for every get/set field (should be no externally observable change). * Add `Cstruct.hexdump_to_buffer` to make spooling hexdump output easier. * Generate `hexdump_foo` and `hexdump_foo_to_buffer` prettyprinting functions for a `cstruct foo`. v0.7.1 2013-03-06 ----------------- * Add `Async_cstruct.Pipe` to map pipes of `Cstruct` buffers to strings or `Bigsubstring`. v0.7.0 2013-02-25 ----------------- * Add zero-copy conversion functions to/from the Core `Bigsubstring`. * Add an `of_string` function to simplify the construction from OCaml values. * Add Async interface to interoperate with Jane Street Core code. v0.6.2 2013-02-08 ----------------- * Add experimental `cstruct.obuild` for the `obuild` build tool. * Use bounds checked version of all functions in the external interface. * Expose the `Cstruct.debug` to dump internal state of a buffer to a string. * Add `set_len` and `add_len` to manipulate the total-length field directly. v0.6.1 2012-12-20 ----------------- * Add `sendto`, `read` and `recvfrom` functions to the Lwt subpackage. v0.6.0 2012-12-20 ----------------- * Add fast bigarray<->string functions to replace byte-by-byte copies. * Add an Lwt sub-package to expose a write call. * Depend on ocplib-endian for fast low-level parsing of integers. * Make `Cstruct.t` a record type that doesn't use Bigarray slicing to provide views onto buffers. This lets views be allocated directly on the minor heap rather than forcing a major heap allocation. It does alter the external API, so previous users of cstruct wont work. v0.5.3 2012-12-16 ----------------- * No functional changes, just OASIS packaging fix to right version. v0.5.2 2012-12-11 ----------------- * Remove the separate `xen` and `unix` subdirectories, as the portable `Bigarray` is now provided by the `xenbigarray` package. v0.5.1 2012-09-28 ----------------- * Add `string_to_` function to match the `_to_string`, primarily to help with command-line parsing of enum arguments. v0.5.0 2012-09-20 ----------------- * Add a signature generator for cstruct and cenum to permit their use in `.mli` files. * Use the more reliable revised syntax camlp4 quotation expander, to avoid broken AST output from antiquotations. * Switch the `xen/` version over to using OASIS also. v0.4.0 2012-09-02 ----------------- * Fix META file for use with Xen v0.3 2012-08-25 -------------- * Initial public release ocaml-cstruct-6.2.0/LICENSE.md000066400000000000000000000026611437471254600157250ustar00rootroot00000000000000Copyright (c) 2012 Anil Madhavapeddy Copyright (c) 2012 Pierre Chambart Copyright (c) Christiano F. Haesbaert Copyright (c) Citrix Inc Copyright (c) David Sheets Copyright (c) Drup Copyright (c) Hannes Mehnert Copyright (c) Jeremy Yallop Copyright (c) Mindy Preston Copyright (c) Nicolas Ojeda Bar Copyright (c) Richard Mortier Copyright (c) Rudi Grinberg Copyright (c) Thomas Gazagnaire Copyright (c) Thomas Leonard Copyright (c) Vincent Bernardoff Copyright (c) pqwy Permission to use, copy, modify, and distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ocaml-cstruct-6.2.0/Makefile000066400000000000000000000004411437471254600157530ustar00rootroot00000000000000.PHONY: all clean fuzz build-fuzz all: dune build clean: dune clean test: dune runtest doc: dune build @doc build-fuzz: dune build fuzz/fuzz.exe fuzz: build-fuzz mkdir -p _build/in echo > _build/in/empty afl-fuzz -i _build/in -o _build/out -- _build/default/fuzz/fuzz.exe @@ ocaml-cstruct-6.2.0/README.md000066400000000000000000000157371437471254600156100ustar00rootroot00000000000000Cstruct - access C-like structures directly from OCaml ------------------------------------------------------ Cstruct is a library and syntax extension to make it easier to access C-like structures directly from OCaml. It supports both reading and writing to these structures, and they are accessed via the `Bigarray` module. ## Installation This repository provides several packages that can be installed via the [opam](https://opam.ocaml.org) package manager: - `cstruct`: the core Cstruct library - `cstruct-sexp`: serialisers into s-expression format of Cstructs - `cstruct-unix`: provide Unix variations of the read/write functions using file descriptors - `cstruct-async`: provide [Async](https://github.com/janestreet/async) Pipe and Bigstring support - `cstruct-lwt`: provide [Lwt](https://ocsigen.org/lwt) variants of read/write functions - `ppx_cstruct`: a [PPX](https://caml.inria.fr/pub/docs/manual-ocaml/extn.html#sec248) syntax extension (see below) The libraries depend on OCaml version 4.08.0 and later, since it provides a [ppx](http://whitequark.org/blog/2014/04/16/a-guide-to-extension-points-in-ocaml/) extension point. The old [camlp4](http://caml.inria.fr/pub/docs/manual-camlp4/manual002.html) syntax extension is nolonger available; the last cstruct release which contained it was v1.9.0. ### Local development You can build the library via [dune](https://github.com/ocaml/dune), using `make` or `dune build` directly. Since everything is built via dune, you can also place this repository within a wider dune workspace in order to make local modifications across repositories. ### Documentation A documentation of the last version of `cstruct` is available [here](https://mirage.github.io/ocaml-cstruct). ## Usage ### PPX The PPX processor is used by passing the OCaml source code through the `ppx_cstruct` binary. An example pcap description is: ``` [%%cstruct type pcap_header = { magic_number: uint32_t; (* magic number *) version_major: uint16_t; (* major version number *) version_minor: uint16_t; (* minor version number *) thiszone: uint32_t; (* GMT to local correction *) sigfigs: uint32_t; (* accuracy of timestamps *) snaplen: uint32_t; (* max length of captured packets, in octets *) network: uint32_t; (* data link type *) } [@@little_endian]] [%%cstruct type pcap_packet = { ts_sec: uint32_t; (* timestamp seconds *) ts_usec: uint32_t; (* timestamp microseconds *) incl_len: uint32_t; (* number of octets of packet saved in file *) orig_len: uint32_t; (* actual length of packet *) } [@@little_endian]] [%%cstruct type ethernet = { dst: uint8_t [@len 6]; src: uint8_t [@len 6]; ethertype: uint16_t; } [@@big_endian]] [%%cstruct type ipv4 = { hlen_version: uint8_t; tos: uint8_t; len: uint16_t; id: uint16_t; off: uint16_t; ttl: uint8_t; proto: uint8_t; csum: uint16_t; src: uint8_t [@len 4]; dst: uint8_t [@len 4]; } [@@big_endian]] ``` This auto-generates generates functions of the form below in the `ml` file: ``` let sizeof_pcap_packet = 16 let get_pcap_packet_ts_sec v = Cstruct.LE.get_uint32 v 0 let set_pcap_packet_ts_sec v x = Cstruct.LE.set_uint32 v 0 x let get_pcap_packet_ts_usec v = Cstruct.LE.get_uint32 v 4 let set_pcap_packet_ts_usec v x = Cstruct.LE.set_uint32 v 4 x let get_pcap_packet_incl_len v = Cstruct.LE.get_uint32 v 8 let set_pcap_packet_incl_len v x = Cstruct.LE.set_uint32 v 8 x let get_pcap_packet_orig_len v = Cstruct.LE.get_uint32 v 12 let set_pcap_packet_orig_len v x = Cstruct.LE.set_uint32 v 12 x let sizeof_ethernet = 14 let get_ethernet_dst src = Cstruct.sub src 0 6 let copy_ethernet_dst src = Cstruct.copy src 0 6 let set_ethernet_dst src srcoff dst = Cstruct.blit_from_string src srcoff dst 0 6 let blit_ethernet_dst src srcoff dst = Cstruct.blit src srcoff dst 0 6 let get_ethernet_src src = Cstruct.sub src 6 6 let copy_ethernet_src src = Cstruct.copy src 6 6 let set_ethernet_src src srcoff dst = Cstruct.blit_from_string src srcoff dst 6 6 let blit_ethernet_src src srcoff dst = Cstruct.blit src srcoff dst 6 6 let get_ethernet_ethertype v = Cstruct.BE.get_uint16 v 12 let set_ethernet_ethertype v x = Cstruct.BE.set_uint16 v 12 x ``` The `mli` file will have signatures of this form: ``` val sizeof_pcap_packet : int val get_pcap_packet_ts_sec : Cstruct.t -> Cstruct.uint32 val set_pcap_packet_ts_sec : Cstruct.t -> Cstruct.uint32 -> unit val get_pcap_packet_ts_usec : Cstruct.t -> Cstruct.uint32 val set_pcap_packet_ts_usec : Cstruct.t -> Cstruct.uint32 -> unit val get_pcap_packet_incl_len : Cstruct.t -> Cstruct.uint32 val set_pcap_packet_incl_len : Cstruct.t -> Cstruct.uint32 -> unit val get_pcap_packet_orig_len : Cstruct.t -> Cstruct.uint32 val set_pcap_packet_orig_len : Cstruct.t -> Cstruct.uint32 -> unit val hexdump_pcap_packet_to_buffer : Buffer.t -> pcap_packet -> unit val hexdump_pcap_packet : Cstruct.t -> unit val sizeof_ethernet : int val get_ethernet_dst : Cstruct.t -> Cstruct.t val copy_ethernet_dst : Cstruct.t -> string val set_ethernet_dst : string -> int -> Cstruct.t -> unit val blit_ethernet_dst : Cstruct.t -> int -> Cstruct.t -> unit val get_ethernet_src : Cstruct.t -> Cstruct.t val copy_ethernet_src : Cstruct.t -> string val set_ethernet_src : string -> int -> Cstruct.t -> unit val blit_ethernet_src : Cstruct.t -> int -> Cstruct.t -> unit val get_ethernet_ethertype : Cstruct.t -> Cstruct.uint16 val set_ethernet_ethertype : Cstruct.t -> Cstruct.uint16 -> unit val hexdump_ethernet_to_buffer : Buffer.t -> Cstruct.t -> unit val hexdump_ethernet : Cstruct.t -> unit ``` The `hexdump` functions above are convenient pretty-printing functions to help you debug, and aren't intended to be high performance. You can also declare C-like enums: ``` [%%cenum type foo32 = | ONE32 | TWO32 [@id 0xfffffffel] | THREE32 [@@uint32_t] ] [%%cenum type bar16 = | ONE [@id 1] | TWO | FOUR [@id 4] | FIVE [@@uint16_t] ] ``` This generates signatures of the form: ``` type foo32 = | ONE32 | TWO32 | THREE32 val int_to_foo32 : int32 -> foo32 option val foo32_to_int : foo32 -> int32 val foo32_to_string : foo32 -> string val string_to_foo32 : string -> foo32 option val compare_foo32 : foo32 -> foo32 -> int type bar16 = | ONE | TWO | FOUR | FIVE val int_to_bar16 : int -> bar16 option val bar16_to_int : bar16 -> int val bar16_to_string : bar16 -> string val string_to_bar16 : string -> bar16 option val compare_bar16 : bar16 -> bar16 -> int ``` Comparisons will be done relatively to the constructor ids. You can also add a `(sexp)` decorator to output s-expression convertors for use with the `sexplib` library. ``` [%%cenum type foo64 = | ONE64 | TWO64 | THREE64 [@@uint64_t] [@@sexp] ] ``` And `sexp_of_foo64` and `foo64_of_sexp` functions will also be available. The representation of the Sexp is the string representation of the enum. If you do use the sexp decorator, then you will also need to add `sexplib` to the dependency list for your package (both in the `dune` file and the `opam` file). Please see the `ppx_test/` directory for more in-depth examples. ocaml-cstruct-6.2.0/async/000077500000000000000000000000001437471254600154315ustar00rootroot00000000000000ocaml-cstruct-6.2.0/async/async_cstruct.ml000066400000000000000000000031531437471254600206510ustar00rootroot00000000000000(* * Copyright (c) 2013 Anil Madhavapeddy * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) open Core open Async let to_bigsubstring t = Bigsubstring.create ~pos:t.Cstruct.off ~len:t.Cstruct.len t.Cstruct.buffer let of_bigsubstring t = Cstruct.of_bigarray ~off:(Bigsubstring.pos t) ~len:(Bigsubstring.length t) (Bigsubstring.base t) let read rd t = Reader.read_bigsubstring rd (to_bigsubstring t) let schedule_write wr t = let open Cstruct in Writer.schedule_bigstring ~pos:t.off ~len:t.len wr t.buffer module Pipe = struct let map_string rd wr = let rd = Pipe.map rd ~f:Cstruct.to_string in let rd',wr' = Pipe.create () in don't_wait_for (Pipe.transfer rd' wr ~f:Cstruct.of_string); rd,wr' let map_bigsubstring rd wr = let rd = Pipe.map rd ~f:to_bigsubstring in let rd',wr' = Pipe.create () in don't_wait_for (Pipe.transfer rd' wr ~f:of_bigsubstring); rd,wr' end ocaml-cstruct-6.2.0/async/async_cstruct.mli000066400000000000000000000025031437471254600210200ustar00rootroot00000000000000(* * Copyright (c) 2013 Anil Madhavapeddy * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) open Core open Async val to_bigsubstring : Cstruct.t -> Bigsubstring.t val of_bigsubstring : Bigsubstring.t -> Cstruct.t val read: Reader.t -> Cstruct.t -> int Reader.Read_result.t Deferred.t val schedule_write: Writer.t -> Cstruct.t -> unit module Pipe : sig val map_string : Cstruct.t Pipe.Reader.t -> Cstruct.t Pipe.Writer.t -> (string Pipe.Reader.t * string Pipe.Writer.t) val map_bigsubstring : Cstruct.t Pipe.Reader.t -> Cstruct.t Pipe.Writer.t -> (Bigsubstring.t Pipe.Reader.t * Bigsubstring.t Pipe.Writer.t) end ocaml-cstruct-6.2.0/async/dune000066400000000000000000000001711437471254600163060ustar00rootroot00000000000000(library (name async_cstruct) (wrapped false) (public_name cstruct-async) (libraries core cstruct async async_unix)) ocaml-cstruct-6.2.0/cstruct-async.opam000066400000000000000000000020731437471254600177760ustar00rootroot00000000000000opam-version: "2.0" maintainer: "anil@recoil.org" authors: ["Anil Madhavapeddy" "Richard Mortier" "Thomas Gazagnaire" "Pierre Chambart" "David Kaloper" "Jeremy Yallop" "David Scott" "Mindy Preston" "Thomas Leonard" "Etienne Millon" ] homepage: "https://github.com/mirage/ocaml-cstruct" license: "ISC" dev-repo: "git+https://github.com/mirage/ocaml-cstruct.git" bug-reports: "https://github.com/mirage/ocaml-cstruct/issues" tags: [ "org:mirage" "org:ocamllabs" ] doc: "https://mirage.github.io/ocaml-cstruct/" build: [ ["dune" "subst"] {dev} ["dune" "build" "-p" name "-j" jobs] ] depends: [ "ocaml" {>= "4.08.0"} "dune" {>= "2.0.0"} "async" {>= "v0.9.0"} "async_unix" {>= "v0.9.0"} "core" {>= "v0.9.0"} "cstruct" {=version} ] synopsis: "Access C-like structures directly from OCaml" description: """ Cstruct is a library and syntax extension to make it easier to access C-like structures directly from OCaml. It supports both reading and writing to these structures, and they are accessed via the `Bigarray` module.""" ocaml-cstruct-6.2.0/cstruct-lwt.opam000066400000000000000000000021061437471254600174640ustar00rootroot00000000000000opam-version: "2.0" maintainer: "anil@recoil.org" authors: ["Anil Madhavapeddy" "Richard Mortier" "Thomas Gazagnaire" "Pierre Chambart" "David Kaloper" "Jeremy Yallop" "David Scott" "Mindy Preston" "Thomas Leonard" "Etienne Millon" ] homepage: "https://github.com/mirage/ocaml-cstruct" license: "ISC" dev-repo: "git+https://github.com/mirage/ocaml-cstruct.git" bug-reports: "https://github.com/mirage/ocaml-cstruct/issues" doc: "https://mirage.github.io/ocaml-cstruct/" tags: [ "org:mirage" "org:ocamllabs" ] build: [ ["dune" "subst"] {dev} ["dune" "build" "-p" name "-j" jobs] ] depends: [ "ocaml" {>= "4.08.0"} "base-unix" "dune" {>= "2.0.0"} "lwt" "cstruct" {=version} ] synopsis: "Access C-like structures directly from OCaml" description: """ Cstruct is a library and syntax extension to make it easier to access C-like structures directly from OCaml. It supports both reading and writing to these structures, and they are accessed via the `Bigarray` module.""" url { src: "git+https://github.com/mirage/ocaml-cstruct.git" } ocaml-cstruct-6.2.0/cstruct-sexp.opam000066400000000000000000000022411437471254600176350ustar00rootroot00000000000000opam-version: "2.0" maintainer: "anil@recoil.org" authors: ["Anil Madhavapeddy" "Richard Mortier" "Thomas Gazagnaire" "Pierre Chambart" "David Kaloper" "Jeremy Yallop" "David Scott" "Mindy Preston" "Thomas Leonard" "Anton Kochkov" "Etienne Millon" ] homepage: "https://github.com/mirage/ocaml-cstruct" license: "ISC" dev-repo: "git+https://github.com/mirage/ocaml-cstruct.git" bug-reports: "https://github.com/mirage/ocaml-cstruct/issues" doc: "https://mirage.github.io/ocaml-cstruct/" tags: [ "org:mirage" "org:ocamllabs" ] build: [ ["dune" "subst"] {dev} ["dune" "build" "-p" name "-j" jobs] ["dune" "runtest" "-p" name "-j" jobs] {with-test} ] depends: [ "ocaml" {>= "4.08.0"} "dune" {>= "2.0.0"} "sexplib" "cstruct" {=version} "alcotest" {with-test} ] synopsis: "S-expression serialisers for C-like structures" description: """ Cstruct is a library and syntax extension to make it easier to access C-like structures directly from OCaml. It supports both reading and writing to these structures, and they are accessed via the `Bigarray` module. This library provides Sexplib serialisers for the Cstruct.t values.""" ocaml-cstruct-6.2.0/cstruct-unix.opam000066400000000000000000000017771437471254600176560ustar00rootroot00000000000000opam-version: "2.0" maintainer: "anil@recoil.org" authors: ["Anil Madhavapeddy" "Richard Mortier" "Thomas Gazagnaire" "Pierre Chambart" "David Kaloper" "Jeremy Yallop" "David Scott" "Mindy Preston" "Thomas Leonard" "Etienne Millon" ] homepage: "https://github.com/mirage/ocaml-cstruct" license: "ISC" dev-repo: "git+https://github.com/mirage/ocaml-cstruct.git" bug-reports: "https://github.com/mirage/ocaml-cstruct/issues" doc: "https://mirage.github.io/ocaml-cstruct/" tags: [ "org:mirage" "org:ocamllabs" ] build: [ ["dune" "subst"] {dev} ["dune" "build" "-p" name "-j" jobs] ] depends: [ "ocaml" {>= "4.06.0"} "dune" {>= "2.0.0"} "base-unix" "cstruct" {=version} ] synopsis: "Access C-like structures directly from OCaml" description: """ Cstruct is a library and syntax extension to make it easier to access C-like structures directly from OCaml. It supports both reading and writing to these structures, and they are accessed via the `Bigarray` module. """ ocaml-cstruct-6.2.0/cstruct.opam000066400000000000000000000022141437471254600166600ustar00rootroot00000000000000opam-version: "2.0" maintainer: "anil@recoil.org" authors: ["Anil Madhavapeddy" "Richard Mortier" "Thomas Gazagnaire" "Pierre Chambart" "David Kaloper" "Jeremy Yallop" "David Scott" "Mindy Preston" "Thomas Leonard" "Anton Kochkov" "Etienne Millon" ] homepage: "https://github.com/mirage/ocaml-cstruct" license: "ISC" dev-repo: "git+https://github.com/mirage/ocaml-cstruct.git" bug-reports: "https://github.com/mirage/ocaml-cstruct/issues" doc: "https://mirage.github.io/ocaml-cstruct/" tags: [ "org:mirage" "org:ocamllabs" ] build: [ ["dune" "subst"] {dev} ["dune" "build" "-p" name "-j" jobs] ["dune" "runtest" "-p" name "-j" jobs] {with-test} ] depends: [ "ocaml" {>= "4.08.0"} "dune" {>= "2.0.0"} "alcotest" {with-test} "fmt" {>= "0.8.9"} "crowbar" {with-test} ] conflicts: [ "js_of_ocaml" {<"3.5.0"} ] synopsis: "Access C-like structures directly from OCaml" description: """ Cstruct is a library and syntax extension to make it easier to access C-like structures directly from OCaml. It supports both reading and writing to these structures, and they are accessed via the `Bigarray` module.""" ocaml-cstruct-6.2.0/dune-project000066400000000000000000000000741437471254600166370ustar00rootroot00000000000000(lang dune 2.0) (allow_approximate_merlin) (name cstruct) ocaml-cstruct-6.2.0/fuzz/000077500000000000000000000000001437471254600153125ustar00rootroot00000000000000ocaml-cstruct-6.2.0/fuzz/dune000066400000000000000000000003671437471254600161760ustar00rootroot00000000000000(executable (name fuzz) (libraries cstruct bigarray cstruct-sexp crowbar fmt)) (rule (alias fuzz) (deps fuzz.exe (source_tree input)) (action (run timeout --preserve-status 30m bun -v --input=input --output=output -- ./fuzz.exe))) ocaml-cstruct-6.2.0/fuzz/fuzz.ml000066400000000000000000000164061437471254600166510ustar00rootroot00000000000000open Crowbar [@@@warning "-3"] let create x = match Cstruct.create x with | c -> assert (x >= 0); c | exception Invalid_argument _ -> assert (x <= 0); bad_test () let create_sub x start len = try let c = Cstruct.create_unsafe x in for i = 0 to len - 1 do Cstruct.set_uint8 c i i done; Cstruct.sub c start len with Invalid_argument _ -> bad_test () let cstruct = choose [ map [int8] create; map [range 0x10000; int; int] create_sub; ] let bytes = map [bytes] Bytes.unsafe_of_string let buffer = map [uint8] Bigarray.(Array1.create Char c_layout) let pp_cstruct f c = Format.pp_print_string f (Cstruct.debug c) let check_within ~base x = check Cstruct.(base.off <= x.off); check Cstruct.(base.off + base.len >= x.off + x.len); check Cstruct.(x.len >= 0 && x.len <= base.len) let () = (* assert (Array.length Sys.argv = 2); (* Prevent accidentally running in quickcheck mode *) *) add_test ~name:"blit" [cstruct; int; cstruct; int; int] (fun src srcoff dst dstoff len -> try Cstruct.blit src srcoff dst dstoff len with Invalid_argument _ -> check (srcoff < 0 || srcoff > Cstruct.length src || dstoff < 0 || dstoff > Cstruct.length src || len < 0 || len > Cstruct.length src - srcoff || len > Cstruct.length dst - dstoff) ); add_test ~name:"sexp" [buffer] (fun b -> b |> Cstruct_sexp.sexp_of_buffer |> Cstruct_sexp.buffer_of_sexp |> check_eq ~cmp:(fun x y -> Cstruct.compare (Cstruct.of_bigarray x) (Cstruct.of_bigarray y)) b ); add_test ~name:"of_bigarray" [buffer; option int; option int] (fun b off len -> match Cstruct.of_bigarray b ?off ?len with | c -> check (Cstruct.length c <= Bigarray.Array1.dim b) | exception Invalid_argument _ -> () ); add_test ~name:"get_char" [cstruct; int] (fun c off -> let in_range = off >= 0 && off < Cstruct.length c in match Cstruct.get_char c off with | _ -> check in_range | exception Invalid_argument _ -> check (not in_range) ); add_test ~name:"set_char" [cstruct; int] (fun c off -> let in_range = off >= 0 && off < Cstruct.length c in match Cstruct.set_char c off 'x' with | () -> check in_range | exception Invalid_argument _ -> check (not in_range) ); add_test ~name:"sub" [cstruct; int; int] (fun base off len -> match Cstruct.sub base off len with | sub -> check_within ~base sub; check (Cstruct.length sub = len) | exception Invalid_argument _ -> check (off < 0 || len < 0 || off + len < 0 || off + len > Cstruct.length base) ); add_test ~name:"shift" [cstruct; int] (fun base off -> match Cstruct.shift base off with | sub -> check_within ~base sub; check (Cstruct.length sub = max (Cstruct.length base - off) 0); | exception Invalid_argument _ -> check (off < 0 || off > Cstruct.length base) ); add_test ~name:"shiftv" [list cstruct; int] (fun ts n -> match Cstruct.shiftv ts n with | exception Invalid_argument _ -> check (n < 0 || n > Cstruct.lenv ts) | ts' -> assert (Cstruct.equal (Cstruct.concat ts') (Cstruct.shift (Cstruct.concat ts) n)); assert ((Cstruct.lenv ts = n) = (ts' = [])); match ts' with | hd :: _ -> assert (not (Cstruct.is_empty hd)) | [] -> () ); add_test ~name:"copy" [cstruct; int; int] (fun base off len -> match Cstruct.copy base off len with | x -> check (String.length x = len); check (String.equal x (Cstruct.sub base off len |> Cstruct.to_string)) | exception Invalid_argument _ -> check (off < 0 || len < 0 || off + len < 0 || off + len > Cstruct.length base) ); add_test ~name:"blit_from_bytes" [bytes; int; cstruct; int; int] (fun src srcoff dst dstoff len -> match Cstruct.blit_from_bytes src srcoff dst dstoff len with | () -> check (Cstruct.equal (Cstruct.sub (Cstruct.of_bytes src) srcoff len) (Cstruct.sub dst dstoff len)) | exception Invalid_argument _ -> check (srcoff < 0 || srcoff > Bytes.length src || dstoff < 0 || dstoff > Bytes.length src || len < 0 || len > Bytes.length src - srcoff || len > Cstruct.length dst - dstoff) ); add_test ~name:"blit_to_bytes" [cstruct; int; bytes; int; int] (fun src srcoff dst dstoff len -> match Cstruct.blit_to_bytes src srcoff dst dstoff len with | () -> check (Cstruct.equal (Cstruct.sub src srcoff len) (Cstruct.sub (Cstruct.of_bytes dst) dstoff len)) | exception Invalid_argument _ -> check (srcoff < 0 || srcoff > Cstruct.length src || dstoff < 0 || dstoff > Cstruct.length src || len < 0 || len > Cstruct.length src - srcoff || len > Bytes.length dst - dstoff) ); add_test ~name:"memset" [cstruct; int; int] (fun c x i -> guard (i >= 0 && i < Cstruct.length c); Cstruct.memset c x; check (Cstruct.get_uint8 c i = x land 0xff) ); add_test ~name:"split" [cstruct; option int; int] (fun base start len -> match Cstruct.split ?start base len with | c1, c2 -> check_within ~base c1; check_within ~base c2; let start = match start with None -> 0 | Some x -> x in check (Cstruct.equal (Cstruct.sub base start len) c1); check (Cstruct.equal (Cstruct.shift base (start + len)) c2) | exception Invalid_argument _ -> () ); add_test ~name:"BE.set_uint64" [cstruct; int] (fun c off -> let in_range = off >= 0 && off < Cstruct.length c - 7 in match Cstruct.BE.set_uint64 c off 42L with | () -> check in_range | exception Invalid_argument _ -> check (not in_range) ); add_test ~name:"lenv" [list cstruct] (fun cs -> check (Cstruct.lenv cs >= 0) ); add_test ~name:"copyv" [list cstruct] (fun cs -> check (String.equal (Cstruct.copyv cs) (Cstruct.concat cs |> Cstruct.to_string)) ); add_test ~name:"fillv" [list cstruct; cstruct] (fun src dst -> let copied, rest = Cstruct.fillv ~src ~dst in check (copied + Cstruct.lenv rest = Cstruct.lenv src); (* OCaml tends to underestimate how much space bigarrays are using: *) Gc.minor () ); add_test ~name:"concat" [list cstruct] (fun cs -> let x = Cstruct.concat cs in check (Cstruct.length x = Cstruct.lenv cs) ); add_test ~name:"span" [ cstruct; list char ] (fun cs p -> let sat chr = List.exists ((=) chr) p in let a, b = Cstruct.span ~sat cs in let r = Cstruct.concat [ a; b ] in check (Cstruct.to_string r = Cstruct.to_string cs)); add_test ~name:"cut" [ cstruct; cstruct; ] (fun buf sep -> guard (Cstruct.length sep > 0); ( match Cstruct.cut ~sep buf with | Some (l, r) -> let r = Cstruct.concat [ l; sep; r; ] in check (Cstruct.to_string r = Cstruct.to_string buf) | None -> () )); add_test ~name:"cuts" [ cstruct; cstruct; ] (fun buf sep -> guard (Cstruct.length sep > 0); let lst = Cstruct.cuts ~sep buf in let lst = List.map Cstruct.to_string lst in let res = String.concat (Cstruct.to_string sep) lst in check (res = Cstruct.to_string buf)); ocaml-cstruct-6.2.0/fuzz/input/000077500000000000000000000000001437471254600164515ustar00rootroot00000000000000ocaml-cstruct-6.2.0/fuzz/input/start000066400000000000000000000000111437471254600175210ustar00rootroot00000000000000bactrian ocaml-cstruct-6.2.0/lib/000077500000000000000000000000001437471254600150625ustar00rootroot00000000000000ocaml-cstruct-6.2.0/lib/cstruct.js000066400000000000000000000036461437471254600171200ustar00rootroot00000000000000/* * Copyright (c) 2015 Citrix Inc * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ //Provides: caml_blit_bigstring_to_bigstring //Requires: caml_bigstring_blit_ba_to_ba var caml_blit_bigstring_to_bigstring = caml_bigstring_blit_ba_to_ba //Provides: caml_blit_bigstring_to_string //Requires: caml_bigstring_blit_ba_to_bytes var caml_blit_bigstring_to_string = caml_bigstring_blit_ba_to_bytes //Provides: caml_blit_string_to_bigstring //Requires: caml_bigstring_blit_string_to_ba var caml_blit_string_to_bigstring = caml_bigstring_blit_string_to_ba //Provides: caml_compare_bigstring //Requires: caml_int_compare, caml_ba_get_1 function caml_compare_bigstring(buf1, buf1_off, buf2, buf2_off, len) { var i, r; for (i = 0; i < len; i++) { r = caml_int_compare(caml_ba_get_1(buf1, buf1_off + i), caml_ba_get_1(buf2, buf2_off + i)); if (r != 0) return r; } return 0; } //Provides: caml_fill_bigstring //Requires: caml_ba_set_1 function caml_fill_bigstring(buf, buf_off, buf_len, v) { var i; for (i = 0; i < buf_len; i++) { caml_ba_set_1(buf, buf_off + i, v); } return 0; } //Provides: caml_check_alignment_bigstring function caml_check_alignment_bigstring(buf, ofs, alignment) { return true; // FIXME: No concept of a fixed buffer address? } ocaml-cstruct-6.2.0/lib/cstruct.ml000066400000000000000000001005051437471254600171040ustar00rootroot00000000000000(* * Copyright (c) 2012 Anil Madhavapeddy * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) type buffer = (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t (* Note: * * We try to maintain the property that no constructed [t] can ever point out of * its underlying buffer. This property is guarded by all of the constructing * functions and the fact that the type is private, and used by various * functions that would otherwise be completely unsafe. * * Furthermore, no operation on [t] is allowed to extend the view on the * underlying Bigarray structure, only narrowing is allowed. * * All well-intended souls are kindly invited to cross-check that the code * indeed maintains this invariant. *) type t = { buffer: buffer; off : int; len : int; } let pp_t ppf t = Format.fprintf ppf "[%d,%d](%d)" t.off t.len (Bigarray.Array1.dim t.buffer) let string_t ppf str = Format.fprintf ppf "[%d]" (String.length str) let bytes_t ppf str = Format.fprintf ppf "[%d]" (Bytes.length str) let err fmt = let b = Buffer.create 20 in (* for thread safety. *) let ppf = Format.formatter_of_buffer b in let k ppf = Format.pp_print_flush ppf (); invalid_arg (Buffer.contents b) in Format.kfprintf k ppf fmt let err_of_bigarray t = err "Cstruct.of_bigarray off=%d len=%d" t let err_sub t = err "Cstruct.sub: %a off=%d len=%d" pp_t t let err_shift t = err "Cstruct.shift %a %d" pp_t t let err_shiftv n = err "Cstruct.shiftv short by %d" n let err_copy_to_string caller t = err "Cstruct.%s %a off=%d len=%d" caller pp_t t let err_to_hex_string t = err "Cstruct.to_hex_string %a off=%d len=%d" pp_t t let err_blit_src src dst = err "Cstruct.blit src=%a dst=%a src-off=%d len=%d" pp_t src pp_t dst let err_blit_dst src dst = err "Cstruct.blit src=%a dst=%a dst-off=%d len=%d" pp_t src pp_t dst let err_blit_from_string_src src dst = err "Cstruct.blit_from_string src=%a dst=%a src-off=%d len=%d" string_t src pp_t dst let err_blit_from_string_dst src dst = err "Cstruct.blit_from_string src=%a dst=%a dst-off=%d len=%d" string_t src pp_t dst let err_blit_from_bytes_src src dst = err "Cstruct.blit_from_bytes src=%a dst=%a src-off=%d len=%d" bytes_t src pp_t dst let err_blit_from_bytes_dst src dst = err "Cstruct.blit_from_bytes src=%a dst=%a dst-off=%d len=%d" bytes_t src pp_t dst let err_blit_to_bytes_src src dst = err "Cstruct.blit_to_bytes src=%a dst=%a src-off=%d len=%d" pp_t src bytes_t dst let err_blit_to_bytes_dst src dst= err "Cstruct.blit_to_bytes src=%a dst=%a dst-off=%d len=%d" pp_t src bytes_t dst let err_invalid_bounds f = err "invalid bounds in Cstruct.%s %a off=%d len=%d" f pp_t [@@inline never] let err_split t = err "Cstruct.split %a start=%d off=%d" pp_t t let err_iter t = err "Cstruct.iter %a i=%d len=%d" pp_t t let of_bigarray ?(off=0) ?len buffer = let dim = Bigarray.Array1.dim buffer in let len = match len with | None -> dim - off | Some len -> len in if off < 0 || len < 0 || off + len < 0 || off + len > dim then err_of_bigarray off len else { buffer; off; len } let to_bigarray buffer = Bigarray.Array1.sub buffer.buffer buffer.off buffer.len let create_unsafe len = let buffer = Bigarray.(Array1.create char c_layout len) in { buffer ; len ; off = 0 } let check_bounds t len = len >= 0 && Bigarray.Array1.dim t.buffer >= len let empty = create_unsafe 0 external check_alignment_bigstring : buffer -> int -> int -> bool = "caml_check_alignment_bigstring" let check_alignment t alignment = if alignment > 0 then check_alignment_bigstring t.buffer t.off alignment else invalid_arg "check_alignment must be positive integer" type byte = char let byte (i:int) : byte = Char.chr i let byte_to_int (b:byte) = int_of_char b type uint8 = int type uint16 = int type uint32 = int32 type uint64 = int64 let debug t = let max_len = Bigarray.Array1.dim t.buffer in if t.off+t.len > max_len || t.len < 0 || t.off < 0 then ( Format.printf "ERROR: t.off+t.len=%d %a\n%!" (t.off+t.len) pp_t t; assert false; ) else Format.asprintf "%a" pp_t t let sub t off len = (* from https://github.com/mirage/ocaml-cstruct/pull/245 Cstruct.sub should select what a programmer intuitively expects a sub-cstruct to be. I imagine holding out my hands, with the left representing the start offset and the right the end. I think of a sub-cstruct as any span within this range. If I move my left hand only to the right (new_start >= t.off), and my right hand only to the left (new_end <= old_end), and they don't cross (new_start <= new_end), then I feel sure the result will be a valid sub-cstruct. And if I violate any one of these constraints (e.g. moving my left hand further left), then I feel sure that the result wouldn't be something I'd consider to be a sub-cstruct. Wrapping considerations in modular arithmetic: Note that if x is non-negative, and x + y wraps, then x + y must be negative. This is easy to see with modular arithmetic because if y is negative then the two arguments will cancel to some degree the result cannot be further from zero than one of the arguments. If y is positive then x + y can wrap, but even max_int + max_int doesn't wrap all the way to zero. The three possibly-wrapping operations are: new_start = t.off + off. t.off is non-negative so if this wraps then new_start will be negative and will fail the new_start >= t.off test. new_end = new_start + len. The above test ensures that new_start is non-negative in any successful return. So if this wraps then new_end will be negative and will fail the new_start <= new_end test. old_end = t.off + t.len. This uses only the existing trusted values. It could only wrap if the underlying bigarray had a negative length! *) let new_start = t.off + off in let new_end = new_start + len in let old_end = t.off + t.len in if new_start >= t.off && new_end <= old_end && new_start <= new_end then { t with off = new_start ; len } else err_sub t off len let shift t amount = let off = t.off + amount in let len = t.len - amount in if amount < 0 || amount > t.len || not (check_bounds t (off+len)) then err_shift t amount else { t with off; len } let rec skip_empty = function | t :: ts when t.len = 0 -> skip_empty ts | x -> x let rec shiftv ts = function | 0 -> skip_empty ts | n -> match ts with | [] -> err_shiftv n | t :: ts when n >= t.len -> shiftv ts (n - t.len) | t :: ts -> shift t n :: ts external unsafe_blit_bigstring_to_bigstring : buffer -> int -> buffer -> int -> int -> unit = "caml_blit_bigstring_to_bigstring" [@@noalloc] external unsafe_blit_string_to_bigstring : string -> int -> buffer -> int -> int -> unit = "caml_blit_string_to_bigstring" [@@noalloc] external unsafe_blit_bytes_to_bigstring : Bytes.t -> int -> buffer -> int -> int -> unit = "caml_blit_string_to_bigstring" [@@noalloc] external unsafe_blit_bigstring_to_bytes : buffer -> int -> Bytes.t -> int -> int -> unit = "caml_blit_bigstring_to_string" [@@noalloc] external unsafe_compare_bigstring : buffer -> int -> buffer -> int -> int -> int = "caml_compare_bigstring" [@@noalloc] external unsafe_fill_bigstring : buffer -> int -> int -> int -> unit = "caml_fill_bigstring" [@@noalloc] let copy_to_string caller src srcoff len = if len < 0 || srcoff < 0 || src.len - srcoff < len then err_copy_to_string caller src srcoff len else let b = Bytes.create len in unsafe_blit_bigstring_to_bytes src.buffer (src.off+srcoff) b 0 len; (* The following call is safe, since b is not visible elsewhere. *) Bytes.unsafe_to_string b let copy = copy_to_string "copy" let blit src srcoff dst dstoff len = if len < 0 || srcoff < 0 || src.len - srcoff < len then err_blit_src src dst srcoff len else if dstoff < 0 || dst.len - dstoff < len then err_blit_dst src dst dstoff len else unsafe_blit_bigstring_to_bigstring src.buffer (src.off+srcoff) dst.buffer (dst.off+dstoff) len let sub_copy cstr off len : t = let cstr2 = create_unsafe len in blit cstr off cstr2 0 len; cstr2 let blit_from_string src srcoff dst dstoff len = if len < 0 || srcoff < 0 || dstoff < 0 || String.length src - srcoff < len then err_blit_from_string_src src dst srcoff len else if dst.len - dstoff < len then err_blit_from_string_dst src dst dstoff len else unsafe_blit_string_to_bigstring src srcoff dst.buffer (dst.off+dstoff) len let blit_from_bytes src srcoff dst dstoff len = if len < 0 || srcoff < 0 || dstoff < 0 || Bytes.length src - srcoff < len then err_blit_from_bytes_src src dst srcoff len else if dst.len - dstoff < len then err_blit_from_bytes_dst src dst dstoff len else unsafe_blit_bytes_to_bigstring src srcoff dst.buffer (dst.off+dstoff) len let blit_to_bytes src srcoff dst dstoff len = if len < 0 || srcoff < 0 || dstoff < 0 || src.len - srcoff < len then err_blit_to_bytes_src src dst srcoff len else if Bytes.length dst - dstoff < len then err_blit_to_bytes_dst src dst dstoff len else unsafe_blit_bigstring_to_bytes src.buffer (src.off+srcoff) dst dstoff len let compare t1 t2 = let l1 = t1.len and l2 = t2.len in match compare l1 l2 with | 0 -> ( match unsafe_compare_bigstring t1.buffer t1.off t2.buffer t2.off l1 with | 0 -> 0 | r -> if r < 0 then -1 else 1 ) | r -> r let equal t1 t2 = compare t1 t2 = 0 (* Note that this is only safe as long as all [t]s are coherent. *) let memset t x = unsafe_fill_bigstring t.buffer t.off t.len x let create len = let t = create_unsafe len in memset t 0; t let set_uint8 t i c = if i >= t.len || i < 0 then err_invalid_bounds "set_uint8" t i 1 else Bigarray.Array1.set t.buffer (t.off+i) (Char.unsafe_chr c) let set_char t i c = if i >= t.len || i < 0 then err_invalid_bounds "set_char" t i 1 else Bigarray.Array1.set t.buffer (t.off+i) c let get_uint8 t i = if i >= t.len || i < 0 then err_invalid_bounds "get_uint8" t i 1 else Char.code (Bigarray.Array1.get t.buffer (t.off+i)) let get_char t i = if i >= t.len || i < 0 then err_invalid_bounds "get_char" t i 1 else Bigarray.Array1.get t.buffer (t.off+i) external ba_set_int16 : buffer -> int -> uint16 -> unit = "%caml_bigstring_set16u" external ba_set_int32 : buffer -> int -> uint32 -> unit = "%caml_bigstring_set32u" external ba_set_int64 : buffer -> int -> uint64 -> unit = "%caml_bigstring_set64u" external ba_get_int16 : buffer -> int -> uint16 = "%caml_bigstring_get16u" external ba_get_int32 : buffer -> int -> uint32 = "%caml_bigstring_get32u" external ba_get_int64 : buffer -> int -> uint64 = "%caml_bigstring_get64u" external swap16 : int -> int = "%bswap16" external swap32 : int32 -> int32 = "%bswap_int32" external swap64 : int64 -> int64 = "%bswap_int64" let set_uint16 swap p t i c = if i > t.len - 2 || i < 0 then err_invalid_bounds (p ^ ".set_uint16") t i 2 else ba_set_int16 t.buffer (t.off+i) (if swap then swap16 c else c) [@@inline] let set_uint32 swap p t i c = if i > t.len - 4 || i < 0 then err_invalid_bounds (p ^ ".set_uint32") t i 4 else ba_set_int32 t.buffer (t.off+i) (if swap then swap32 c else c) [@@inline] let set_uint64 swap p t i c = if i > t.len - 8 || i < 0 then err_invalid_bounds (p ^ ".set_uint64") t i 8 else ba_set_int64 t.buffer (t.off+i) (if swap then swap64 c else c) [@@inline] let get_uint16 swap p t i = if i > t.len - 2 || i < 0 then err_invalid_bounds (p ^ ".get_uint16") t i 2 else let r = ba_get_int16 t.buffer (t.off+i) in if swap then swap16 r else r [@@inline] let get_uint32 swap p t i = if i > t.len - 4 || i < 0 then err_invalid_bounds (p ^ ".get_uint32") t i 4 else let r = ba_get_int32 t.buffer (t.off+i) in if swap then swap32 r else r [@@inline] let get_uint64 swap p t i = if i > t.len - 8 || i < 0 then err_invalid_bounds (p ^ ".get_uint64") t i 8 else let r = ba_get_int64 t.buffer (t.off+i) in if swap then swap64 r else r [@@inline] module BE = struct let set_uint16 t i c = set_uint16 (not Sys.big_endian) "BE" t i c [@@inline] let set_uint32 t i c = set_uint32 (not Sys.big_endian) "BE" t i c [@@inline] let set_uint64 t i c = set_uint64 (not Sys.big_endian) "BE" t i c [@@inline] let get_uint16 t i = get_uint16 (not Sys.big_endian) "BE" t i [@@inline] let get_uint32 t i = get_uint32 (not Sys.big_endian) "BE" t i [@@inline] let get_uint64 t i = get_uint64 (not Sys.big_endian) "BE" t i [@@inline] end module LE = struct let set_uint16 t i c = set_uint16 Sys.big_endian "LE" t i c [@@inline] let set_uint32 t i c = set_uint32 Sys.big_endian "LE" t i c [@@inline] let set_uint64 t i c = set_uint64 Sys.big_endian "LE" t i c [@@inline] let get_uint16 t i = get_uint16 Sys.big_endian "LE" t i [@@inline] let get_uint32 t i = get_uint32 Sys.big_endian "LE" t i [@@inline] let get_uint64 t i = get_uint64 Sys.big_endian "LE" t i [@@inline] end module HE = struct let set_uint16 t i c = set_uint16 false "HE" t i c [@@inline] let set_uint32 t i c = set_uint32 false "HE" t i c [@@inline] let set_uint64 t i c = set_uint64 false "HE" t i c [@@inline] let get_uint16 t i = get_uint16 false "HE" t i [@@inline] let get_uint32 t i = get_uint32 false "HE" t i [@@inline] let get_uint64 t i = get_uint64 false "HE" t i [@@inline] end let length { len ; _ } = len (** [sum_lengths ~caller acc l] is [acc] plus the sum of the lengths of the elements of [l]. Raises [Invalid_argument caller] if arithmetic overflows. *) let rec sum_lengths_aux ~caller acc = function | [] -> acc | h :: t -> let sum = length h + acc in if sum < acc then invalid_arg caller else sum_lengths_aux ~caller sum t let sum_lengths ~caller l = sum_lengths_aux ~caller 0 l let lenv l = sum_lengths ~caller:"Cstruct.lenv" l let copyv ts = let sz = sum_lengths ~caller:"Cstruct.copyv" ts in let dst = Bytes.create sz in let _ = List.fold_left (fun off src -> let x = length src in unsafe_blit_bigstring_to_bytes src.buffer src.off dst off x; off + x ) 0 ts in (* The following call is safe, since dst is not visible elsewhere. *) Bytes.unsafe_to_string dst let fillv ~src ~dst = let rec aux dst n = function | [] -> n, [] | hd::tl -> let avail = length dst in let first = length hd in if first <= avail then ( blit hd 0 dst 0 first; aux (shift dst first) (n + first) tl ) else ( blit hd 0 dst 0 avail; let rest_hd = shift hd avail in (n + avail, rest_hd :: tl) ) in aux dst 0 src let to_string ?(off=0) ?len:sz t = let len = match sz with None -> length t - off | Some l -> l in copy_to_string "to_string" t off len let to_hex_string ?(off=0) ?len:sz t : string = let[@inline] nibble_to_char (i:int) : char = if i < 10 then Char.chr (i + Char.code '0') else Char.chr (i - 10 + Char.code 'a') in let len = match sz with None -> length t - off | Some l -> l in if len < 0 || off < 0 || t.len - off < len then err_to_hex_string t off len else ( let out = Bytes.create (2 * len) in for i=0 to len-1 do let c = Char.code @@ Bigarray.Array1.get t.buffer (i+t.off+off) in Bytes.set out (2*i) (nibble_to_char (c lsr 4)); Bytes.set out (2*i+1) (nibble_to_char (c land 0xf)); done; Bytes.unsafe_to_string out ) let to_bytes ?off ?len t = Bytes.unsafe_of_string (to_string ?off ?len t) let [@inline always] of_data_abstract blitfun lenfun ?allocator ?(off=0) ?len buf = let buflen = match len with | None -> lenfun buf - off | Some len -> len in match allocator with | None -> let c = create_unsafe buflen in blitfun buf off c 0 buflen; c | Some fn -> let c = fn buflen in blitfun buf off c 0 buflen; { c with len = buflen } let of_string ?allocator ?off ?len buf = of_data_abstract blit_from_string String.length ?allocator ?off ?len buf let of_bytes ?allocator ?off ?len buf = of_data_abstract blit_from_bytes Bytes.length ?allocator ?off ?len buf let of_hex ?(off=0) ?len str = let str = let l = match len with None -> String.length str - off | Some l -> l in String.sub str off l in let string_fold ~f ~z str = let st = ref z in ( String.iter (fun c -> st := f !st c) str ; !st ) in let hexdigit p = function | 'a' .. 'f' as x -> int_of_char x - 87 | 'A' .. 'F' as x -> int_of_char x - 55 | '0' .. '9' as x -> int_of_char x - 48 | x -> Format.ksprintf invalid_arg "of_hex: invalid character at pos %d: %C" p x in let whitespace = function | ' ' | '\t' | '\r' | '\n' -> true | _ -> false in match string_fold ~f:(fun (cs, i, p, acc) -> let p' = succ p in function | char when whitespace char -> (cs, i, p', acc) | char -> match acc, hexdigit p char with | (None , x) -> (cs, i, p', Some (x lsl 4)) | (Some y, x) -> set_uint8 cs i (x lor y) ; (cs, succ i, p', None)) ~z:(create_unsafe (String.length str lsr 1), 0, 0, None) str with | _ , _, _, Some _ -> Format.ksprintf invalid_arg "of_hex: odd numbers of characters" | cs, i, _, _ -> sub cs 0 i let hexdump_pp fmt t = let before fmt = function | 0 -> () | 8 -> Format.fprintf fmt " "; | _ -> Format.fprintf fmt " " in let after fmt = function | 15 -> Format.fprintf fmt "@;" | _ -> () in Format.pp_open_vbox fmt 0 ; for i = 0 to length t - 1 do let column = i mod 16 in let c = Char.code (Bigarray.Array1.get t.buffer (t.off+i)) in Format.fprintf fmt "%a%.2x%a" before column c after column done ; Format.pp_close_box fmt () let hexdump = Format.printf "@\n%a@." hexdump_pp let hexdump_to_buffer buf t = let f = Format.formatter_of_buffer buf in Format.fprintf f "@\n%a@." hexdump_pp t let split ?(start=0) t off = try let header =sub t start off in let body = sub t (start+off) (length t - off - start) in header, body with Invalid_argument _ -> err_split t start off type 'a iter = unit -> 'a option let iter lenfn pfn t = let body = ref (Some t) in let i = ref 0 in fun () -> match !body with |Some buf when length buf = 0 -> body := None; None |Some buf -> begin match lenfn buf with |None -> body := None; None |Some plen -> incr i; let p,rest = try split buf plen with Invalid_argument _ -> err_iter buf !i plen in body := Some rest; Some (pfn p) end |None -> None let rec fold f next acc = match next () with | None -> acc | Some v -> fold f next (f acc v) let append cs1 cs2 = let l1 = length cs1 and l2 = length cs2 in let cs = create_unsafe (l1 + l2) in blit cs1 0 cs 0 l1 ; blit cs2 0 cs l1 l2 ; cs let concat = function | [] -> create_unsafe 0 | [cs] -> cs | css -> let result = create_unsafe (sum_lengths ~caller:"Cstruct.concat" css) in let aux off cs = let n = length cs in blit cs 0 result off n ; off + n in ignore @@ List.fold_left aux 0 css ; result let rev t = let n = length t in let out = create_unsafe n in for i_src = 0 to n - 1 do let byte = get_uint8 t i_src in let i_dst = n - 1 - i_src in set_uint8 out i_dst byte done; out (* Convenience function. *) external unsafe_blit_string_to_bigstring : string -> int -> buffer -> int -> int -> unit = "caml_blit_string_to_bigstring" [@@noalloc] let get { buffer; off; len; } zidx = if zidx < 0 || zidx >= len then invalid_arg "index out of bounds" ; Bigarray.Array1.get buffer (off + zidx) let get_byte { buffer; off; len; } zidx = if zidx < 0 || zidx >= len then invalid_arg "index out of bounds" ; Char.code (Bigarray.Array1.get buffer (off + zidx)) let string ?(off= 0) ?len str = let str_len = String.length str in let len = match len with None -> str_len | Some len -> len in if off < 0 || len < 0 || off + len > str_len then invalid_arg "index out of bounds" ; let buffer = Bigarray.(Array1.create char c_layout str_len) in unsafe_blit_string_to_bigstring str 0 buffer 0 str_len ; of_bigarray ~off ~len buffer let buffer ?(off= 0) ?len buffer = let buffer_len = Bigarray.Array1.dim buffer in let len = match len with None -> buffer_len - off | Some len -> len in if off < 0 || len < 0 || off + len > buffer_len then invalid_arg "index out of bounds" ; of_bigarray ~off ~len buffer let start_pos { off; _ } = off let stop_pos { off; len; _ } = off + len let head ?(rev= false) ({ len; _ } as cs) = if len = 0 then None else Some (get_char cs (if rev then len - 1 else 0)) let tail ?(rev= false) ({ buffer; off; len; } as cs) = if len = 0 then cs else if rev then of_bigarray ~off ~len:(len - 2) buffer else of_bigarray ~off:(off + 1) ~len:(len - 1) buffer let is_empty { len; _ } = len = 0 let is_prefix ~affix:({ len= alen; _ } as affix) ({ len; _ } as cs) = if alen > len then false else let max_zidx = alen - 1 in let rec loop i = if i > max_zidx then true else if get_char affix i <> get_char cs i then false else loop (succ i) in loop 0 let is_infix ~affix:({ len= alen; _ } as affix) ({ len; _ } as cs) = if alen > len then false else let max_zidx_a = alen - 1 in let max_zidx_s = len - alen in let rec loop i k = if i > max_zidx_s then false else if k > max_zidx_a then true else if k > 0 then if get_char affix k = get_char cs (i + k) then loop i (succ k) else loop (succ i) 0 else if get_char affix 0 = get_char cs i then loop i 1 else loop (succ i) 0 in loop 0 0 let is_suffix ~affix:({ len= alen; _ } as affix) ({ len; _ } as cs) = if alen > len then false else let max_zidx = alen - 1 in let max_zidx_a = alen - 1 in let max_zidx_s = len - 1 in let rec loop i = if i > max_zidx then true else if get_char affix (max_zidx_a - i) <> get_char cs (max_zidx_s - i) then false else loop (succ i) in loop 0 let for_all sat cs = let rec go acc i = if i < length cs then go (sat (get_char cs i) && acc) (succ i) else acc in go true 0 let exists sat cs = let rec go acc i = if i < length cs then go (sat (get_char cs i) || acc) (succ i) else acc in go false 0 let start { buffer; off; _ } = of_bigarray buffer ~off ~len:0 let stop { buffer; off; len; } = of_bigarray buffer ~off:(off + len) ~len:0 let is_white = function ' ' | '\t' .. '\r' -> true | _ -> false let trim ?(drop = is_white) ({ buffer; off; len; } as cs) = if len = 0 then cs else let max_zpos = len in let max_zidx = len - 1 in let rec left_pos i = if i > max_zidx then max_zpos else if drop (get_char cs i) then left_pos (succ i) else i in let rec right_pos i = if i < 0 then 0 else if drop (get_char cs i) then right_pos (pred i) else succ i in let left = left_pos 0 in if left = max_zpos then of_bigarray buffer ~off:((off * 2 + len) / 2) ~len:0 else let right = right_pos max_zidx in if left = 0 && right = max_zpos then cs else of_bigarray buffer ~off:(off + left) ~len:(right - left) let fspan ~min ~max ~sat ({ buffer= v; off; len; } as cs) = if min < 0 then invalid_arg "span: negative min" ; if max < 0 then invalid_arg "span: negative max" ; if min > max || max = 0 then (buffer ~off:off ~len:0 v, cs) else let max_zidx = len - 1 in let max_zidx = let k = max - 1 in if k > max_zidx || k < 0 then max_zidx else k in let need_zidx = min in let rec loop i = if i <= max_zidx && sat (get_char cs i) then loop (i + 1) else if i < need_zidx || i = 0 then buffer ~off:off ~len:0 v, cs else if i = len then (cs, buffer ~off:(off + len) ~len:0 v) else buffer ~off:off ~len:i v, buffer ~off:(off + i) ~len:(len - i) v in loop 0 let rspan ~min ~max ~sat ({ buffer= v; off; len; } as cs) = if min < 0 then invalid_arg "span: negative min" ; if max < 0 then invalid_arg "span: negative max" ; if min > max || max = 0 then (cs, buffer ~off:(off + len) ~len:0 v) else let max_zidx = len - 1 in let min_zidx = let k = len - max in if k < 0 then 0 else k in let need_zidx = len - min - 1 in let rec loop i = if i >= min_zidx && sat (get_char cs i) then loop (i - 1) else if i > need_zidx || i = max_zidx then (cs, buffer ~off:(off + len) ~len:0 v) else if i < 0 then (buffer ~off:off ~len:0 v, cs) else (buffer ~off:off ~len:(i + 1) v, buffer ~off:(off + i + 1) ~len:(len - (i + 1)) v) in loop max_zidx let span ?(rev= false) ?(min= 0) ?(max= max_int) ?(sat= fun _ -> true) cs = match rev with | true -> rspan ~min ~max ~sat cs | false -> fspan ~min ~max ~sat cs let take ?(rev= false) ?min ?max ?sat cs = (if rev then snd else fst) @@ span ~rev ?min ?max ?sat cs let drop ?(rev= false) ?min ?max ?sat cs = (if rev then fst else snd) @@ span ~rev ?min ?max ?sat cs let fcut ~sep:({ len= sep_len; _ } as sep) ({ buffer= v; off; len; } as cs) = if sep_len = 0 then invalid_arg "cut: empty separator" ; let max_sep_zidx = sep_len - 1 in let max_s_zidx = len - sep_len in let rec check_sep i k = if k > max_sep_zidx then Some (buffer ~off:off ~len:i v, buffer ~off:(off + i + sep_len) ~len:(len - i - sep_len) v) else if get_char cs (i + k) = get_char sep k then check_sep i (k + 1) else scan (i + 1) and scan i = if i > max_s_zidx then None else if get_char cs i = get_char sep 0 then check_sep i 1 else scan (i + 1) in scan 0 let rcut ~sep:({ len= sep_len; _ } as sep) ({ buffer= v; off; len; } as cs) = if sep_len = 0 then invalid_arg "cut: empty separator" ; let max_sep_zidx = sep_len - 1 in let max_s_zidx = len - 1 in let rec check_sep i k = if k > max_sep_zidx then Some (buffer ~off:off ~len:i v, buffer ~off:(off + i + sep_len) ~len:(len - i - sep_len) v) else if get_char cs (i + k) = get_char sep k then check_sep i (k + 1) else rscan (i - 1) and rscan i = if i < 0 then None else if get_char cs i = get_char sep 0 then check_sep i 1 else rscan (i - 1) in rscan (max_s_zidx - max_sep_zidx) let cut ?(rev= false) ~sep cs = match rev with | true -> rcut ~sep cs | false -> fcut ~sep cs let add_sub ~no_empty buf ~off ~len acc = if len = 0 then ( if no_empty then acc else buffer ~off ~len buf :: acc ) else buffer ~off ~len buf :: acc let fcuts ~no_empty ~sep:({ len= sep_len; _ } as sep) ({ buffer; off; len; } as cs) = if sep_len = 0 then invalid_arg "cuts: empty separator" ; let max_sep_zidx = sep_len - 1 in let max_s_zidx = len - sep_len in let rec check_sep zanchor i k acc = if k > max_sep_zidx then let new_start = i + sep_len in scan new_start new_start (add_sub ~no_empty buffer ~off:(off + zanchor) ~len:(i - zanchor) acc) else if get_char cs (i + k) = get_char sep k then check_sep zanchor i (k + 1) acc else scan zanchor (i + 1) acc and scan zanchor i acc = if i > max_s_zidx then if zanchor = 0 then (if no_empty && len = 0 then [] else [ cs ]) else List.rev (add_sub ~no_empty buffer ~off:(off + zanchor) ~len:(len - zanchor) acc) else if get_char cs i = get_char sep 0 then check_sep zanchor i 1 acc else scan zanchor (i + 1) acc in scan 0 0 [] let rcuts ~no_empty ~sep:({ len= sep_len; _ } as sep) ({ buffer; len; _ } as cs) = if sep_len = 0 then invalid_arg "cuts: empty separator" ; let s_len = len in let max_sep_zidx = sep_len - 1 in let max_s_zidx = len - 1 in let rec check_sep zanchor i k acc = if k > max_sep_zidx then let off = i + sep_len in rscan i (i - sep_len) (add_sub ~no_empty buffer ~off ~len:(zanchor - off) acc) else if get_char cs (i + k) = get_char cs k then check_sep zanchor i (k + 1) acc else rscan zanchor (i - 1) acc and rscan zanchor i acc = if i < 0 then if zanchor = s_len then ( if no_empty && s_len = 0 then [] else [ cs ]) else add_sub ~no_empty buffer ~off:0 ~len:zanchor acc else if get_char cs i = get_char sep 0 then check_sep zanchor i 1 acc else rscan zanchor (i - 1) acc in rscan s_len (max_s_zidx - max_sep_zidx) [] let cuts ?(rev= false) ?(empty= true) ~sep cs = match rev with | true -> rcuts ~no_empty:(not empty) ~sep cs | false -> fcuts ~no_empty:(not empty) ~sep cs let fields ?(empty= false) ?(is_sep= is_white) ({ buffer; off; len; } as cs) = let no_empty = not empty in let max_pos = len in let rec loop i end_pos acc = if i < 0 then begin if end_pos = len then ( if no_empty && len = 0 then [] else [ cs ]) else add_sub ~no_empty buffer ~off:off ~len:(end_pos - (i + 1)) acc end else begin if not (is_sep (get_char cs i)) then loop (i - 1) end_pos acc else loop (i - 1) i (add_sub ~no_empty buffer ~off:(off + i + 1) ~len:(end_pos - (i + 1)) acc) end in loop (max_pos - 1) max_pos [] let ffind sat ({ buffer= v; len; _ } as cs) = let max_idx = len - 1 in let rec loop i = if i > max_idx then None else if sat (get_char cs i) then Some (buffer ~off:i ~len:1 v) else loop (i + 1) in loop 0 let rfind sat ({ buffer= v; len; _ } as cs) = let rec loop i = if i < 0 then None else if sat (get_char cs i) then Some (buffer ~off:i ~len:1 v) else loop (i - 1) in loop (len - 1) let find ?(rev= false) sat cs = match rev with | true -> rfind sat cs | false -> ffind sat cs let ffind_sub ~sub:({ len= sub_len; _ } as sub) ({ buffer= v; off; len; } as cs) = if sub_len > len then None else let max_zidx_sub = sub_len - 1 in let max_zidx_s = len - sub_len in let rec loop i k = if i > max_zidx_s then None else if k > max_zidx_sub then Some (buffer v ~off:(off + i) ~len:sub_len) else if k > 0 then ( if get_char sub k = get_char cs (i + k) then loop i (k + 1) else loop (i + 1) 0 ) else if get_char sub 0 = get_char cs i then loop i 1 else loop (i + 1) 0 in loop 0 0 let rfind_sub ~sub:({ len= sub_len; _ } as sub) ({ buffer= v; len; _ } as cs) = if sub_len > len then None else let max_zidx_sub = sub_len - 1 in let rec loop i k = if i < 0 then None else if k > max_zidx_sub then Some (buffer v ~off:i ~len:sub_len) else if k > 0 then ( if get_char sub k = get_char cs (i + k) then loop i (k + 1) else loop (i - 1) 0 ) else if get_char sub 0 = get_char cs i then loop i 1 else loop (i - 1) 0 in loop (len - sub_len) 0 let find_sub ?(rev= false) ~sub cs = match rev with | true -> rfind_sub ~sub cs | false -> ffind_sub ~sub cs let filter sat ({ len; _ } as cs) = if len = 0 then empty else let b = create len in let max_zidx = len - 1 in let rec loop b k i = if i > max_zidx then (if k = len then b else sub b 0 k) else let chr = get_char cs i in if sat chr then ( set_char b k chr ; loop b (k + 1) (i + 1)) else loop b k (i + 1) in loop b 0 0 let filter_map f ({ len; _ } as cs) = if len = 0 then empty else let b = create len in let max_zidx = len - 1 in let rec loop b k i = if i > max_zidx then (if k = len then b else sub b 0 k) else match f (get_char cs i) with | Some chr -> set_char b i chr ; loop b (k + 1) (i + 1) | None -> loop b k (i + 1) in loop b 0 0 let map f ({ len; _ } as cs) = if len = 0 then empty else let b = create len in for i = 0 to len - 1 do set_char b i (f (get_char cs i)) done ; b let mapi f ({ len; _ } as cs) = if len = 0 then empty else let b = create len in for i = 0 to len - 1 do set_char b i (f i (get_char cs i)) done ; b ocaml-cstruct-6.2.0/lib/cstruct.mli000066400000000000000000000761401437471254600172640ustar00rootroot00000000000000(* * Copyright (c) 2012-2014 Anil Madhavapeddy * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) (** Manipulate external memory buffers as C-like structures. Cstruct is a library and ppx rewriter to make it easier to access C-like structures directly from OCaml. It supports both reading and writing to these memory buffers, and they are accessed via the [Bigarray] module. The library interface below is intended to be used in conjunction with the ppx rewriter that is also supplied with this library (in the [cstruct-ppx] ocamlfind package). An example description for the pcap packet format is: {[ [%%cstruct type pcap_header = { magic_number: uint32_t; (* magic number *) version_major: uint16_t; (* major version number *) version_minor: uint16_t; (* minor version number *) thiszone: uint32_t; (* GMT to local correction *) sigfigs: uint32_t; (* accuracy of timestamps *) snaplen: uint32_t; (* max length of captured packets, in octets *) network: uint32_t; (* data link type *) } [@@little_endian] ] [%%cstruct type pcap_packet = { ts_sec: uint32_t; (* timestamp seconds *) ts_usec: uint32_t; (* timestamp microseconds *) incl_len: uint32_t; (* number of octets of packet saved in file *) orig_len: uint32_t; (* actual length of packet *) } [@@little_endian] ] [%%cstruct type ethernet = { dst: uint8_t; [@len 6]; src: uint8_t; [@len 6]; ethertype: uint16_t; } [@@big_endian] ] [%%cstruct type ipv4 = { hlen_version: uint8_t; tos: uint8_t; len: uint16_t; id: uint16_t; off: uint16_t; ttl: uint8_t; proto: uint8_t; csum: uint16_t; src: uint8_t; [@len 4]; dst: uint8_t; [@len 4] } [@@big_endian] ] ]} These will expand to get and set functions for every field, with types appropriate to the particular definition. For instance: {[ val get_pcap_packet_ts_sec : Cstruct.t -> Cstruct.uint32 val set_pcap_packet_ts_sec : Cstruct.t -> Cstruct.uint32 -> unit val get_pcap_packet_ts_usec : Cstruct.t -> Cstruct.uint32 val set_pcap_packet_ts_usec : Cstruct.t -> Cstruct.uint32 -> unit val get_pcap_packet_incl_len : Cstruct.t -> Cstruct.uint32 val set_pcap_packet_incl_len : Cstruct.t -> Cstruct.uint32 -> unit val get_pcap_packet_orig_len : Cstruct.t -> Cstruct.uint32 val set_pcap_packet_orig_len : Cstruct.t -> Cstruct.uint32 -> unit val hexdump_pcap_packet_to_buffer : Buffer.t -> Cstruct.t -> unit ]} The buffers generate a different set of functions. For the [ethernet] definitions, we have: {[ val sizeof_ethernet : int val get_ethernet_dst : Cstruct.t -> Cstruct.t val copy_ethernet_dst : Cstruct.t -> string val set_ethernet_dst : string -> int -> Cstruct.t -> unit val blit_ethernet_dst : Cstruct.t -> int -> Cstruct.t -> unit val get_ethernet_src : Cstruct.t -> Cstruct.t val copy_ethernet_src : Cstruct.t -> string ]} You can also declare C-like enums: {[ [%%cenum type foo32 = | ONE32 | TWO32 [@id 0xfffffffel] | THREE32 [@@uint32_t] ] [%%cenum type bar16 = | ONE [@id 1] | TWO | FOUR [@id 4 | FIVE [@@uint16_t] ] ]} This generates signatures of the form: {[ type foo32 = | ONE32 | TWO32 | THREE32 val int_to_foo32 : int32 -> foo32 option val foo32_to_int : foo32 -> int32 val foo32_to_string : foo32 -> string val string_to_foo32 : string -> foo32 option type bar16 = | ONE | TWO | FOUR | FIVE val int_to_bar16 : int -> bar16 option val bar16_to_int : bar16 -> int val bar16_to_string : bar16 -> string val string_to_bar16 : string -> bar16 option ]} *) (** {2 Base types } *) type buffer = (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t (** Type of a buffer. A cstruct is composed of an underlying buffer and position/length within this buffer. *) type t = private { buffer: buffer; off : int; len : int; } (** Type of a cstruct. *) type byte = char (** A single byte type *) val byte : int -> byte (** [byte v] convert [v] to a single byte. @raise Invalid_argument if [v] is negative or greater than 255. *) type uint8 = int (** 8-bit unsigned integer. The representation is currently an unboxed OCaml integer. *) type uint16 = int (** 16-bit unsigned integer. The representation is currently an unboxed OCaml integer. *) type uint32 = int32 (** 32-bit unsigned integer. The representation is currently a boxed OCaml int32. *) type uint64 = int64 (** 64-bit unsigned integer. The representation is currently a boxed OCaml int64. *) (** {2 Creation and conversion} *) val empty : t (** [empty] is the cstruct of length 0. *) val of_bigarray: ?off:int -> ?len:int -> buffer -> t (** [of_bigarray ~off ~len b] is the cstruct contained in [b] starting at offset [off] (default [0]) of length [len] (default [Bigarray.Array1.dim b - off]). *) val to_bigarray: t -> buffer (** [to_bigarray t] converts a {!t} into a {!type:buffer} Bigarray, using the Bigarray slicing to allocate a fresh array that preserves sharing of the underlying buffer. *) val create : int -> t (** [create len] is a fresh cstruct of size [len] with an offset of 0, filled with zero bytes. *) val create_unsafe : int -> t (** [create_unsafe len] is a cstruct of size [len] with an offset of 0. Note that the returned cstruct will contain arbitrary data, likely including the contents of previously-deallocated cstructs. Beware! Forgetting to replace this data could cause your application to leak sensitive information. *) val of_string: ?allocator:(int -> t) -> ?off:int -> ?len:int -> string -> t (** [of_string ~allocator ~off ~len str] is the cstruct representation of [str] slice located at offset [off] (default [0]) and of length [len] (default [String.length str - off]), with the underlying buffer allocated by [alloc]. If [allocator] is not provided, [create] is used. @raise Invalid_argument if [off] or [len] is negative, or [String.length str - off] < [len]. *) val of_bytes: ?allocator:(int -> t) -> ?off:int -> ?len:int -> bytes -> t (** [of_bytes ~allocator byt] is the cstruct representation of [byt] slice located at offset [off] (default [0]) and of length [len] (default [Bytes.length byt - off]), with the underlying buffer allocated by [alloc]. If [allocator] is not provided, [create] is used. @raise Invalid_argument if [off] or [len] is negative, or [Bytes.length str - off] < [len]. *) val of_hex: ?off:int -> ?len:int -> string -> t (** [of_hex ~off ~len str] is the cstruct [cs]. Every pair of hex-encoded characters in [str] starting at offset [off] (default [0]) of length [len] (default [String.length str - off]) are converted to one byte in [cs]. Whitespaces (space, newline, tab, carriage return) in [str] are skipped. @raise Invalid_argument if the input string contains invalid characters or has an odd numbers of non-whitespace characters, or if [off] or [len] are negative, or [String.length str - off] < [len]. *) (** {2 Comparison } *) val equal : t -> t -> bool (** [equal t1 t2] is [true] iff [t1] and [t2] correspond to the same sequence of bytes. *) val compare : t -> t -> int (** [compare t1 t2] gives an unspecified total ordering over {!t}. *) (** {2 Getters and Setters } *) val byte_to_int : byte -> int (** Convert a byte to an integer *) val check_bounds : t -> int -> bool (** [check_bounds cstr len] is [true] if [len] is a non-negative integer and [cstr.buffer]'s size is greater or equal than [len] [false] otherwise.*) val check_alignment : t -> int -> bool (** [check_alignment cstr alignment] is [true] if the first byte stored within [cstr] is at a memory address where [address mod alignment = 0], [false] otherwise. Typical uses are to check a buffer is aligned to a page or disk sector boundary. @raise Invalid_argument if [alignment] is not a positive integer. *) val get_char: t -> int -> char (** [get_char t off] returns the character contained in the cstruct at offset [off]. @raise Invalid_argument if the offset exceeds cstruct length. *) val get_uint8: t -> int -> uint8 (** [get_uint8 t off] returns the byte contained in the cstruct at offset [off]. @raise Invalid_argument if the offset exceeds cstruct length. *) val set_char: t -> int -> char -> unit (** [set_char t off c] sets the byte contained in the cstruct at offset [off] to character [c]. @raise Invalid_argument if the offset exceeds cstruct length. *) val set_uint8: t -> int -> uint8 -> unit (** [set_uint8 t off c] sets the byte contained in the cstruct at offset [off] to byte [c]. @raise Invalid_argument if the offset exceeds cstruct length. *) val sub: t -> int -> int -> t (** [sub cstr off len] is [{ t with off = t.off + off; len }] @raise Invalid_argument if the offset exceeds cstruct length. *) val sub_copy: t -> int -> int -> t (** [sub_copy cstr off len] is a new copy of [sub cstr off len], that does not share the underlying buffer of [cstr]. @raise Invalid_argument if the offset exceeds cstruct length. *) val shift: t -> int -> t (** [shift cstr len] is [{ cstr with off=t.off+len; len=t.len-len }] @raise Invalid_argument if the offset exceeds cstruct length. *) val copy: t -> int -> int -> string [@@ocaml.alert deprecated "this is just like [to_string] without defaults, were you looking for [sub_copy]?"] (** [copy cstr off len] is the string representation of the segment of [t] starting at [off] of size [len]. It is equivalent to [Cstruct.to_string cstr ~off ~len]. @raise Invalid_argument if [off] and [len] do not designate a valid segment of [t]. *) val blit: t -> int -> t -> int -> int -> unit (** [blit src srcoff dst dstoff len] copies [len] characters from cstruct [src], starting at index [srcoff], to cstruct [dst], starting at index [dstoff]. It works correctly even if [src] and [dst] are the same string, and the source and destination intervals overlap. @raise Invalid_argument if [srcoff] and [len] do not designate a valid segment of [src], or if [dstoff] and [len] do not designate a valid segment of [dst]. *) val blit_from_string: string -> int -> t -> int -> int -> unit (** [blit_from_string src srcoff dst dstoff len] copies [len] characters from string [src], starting at index [srcoff], to cstruct [dst], starting at index [dstoff]. @raise Invalid_argument if [srcoff] and [len] do not designate a valid substring of [src], or if [dstoff] and [len] do not designate a valid segment of [dst]. *) val blit_from_bytes: bytes -> int -> t -> int -> int -> unit (** [blit_from_bytes src srcoff dst dstoff len] copies [len] characters from bytes [src], starting at index [srcoff], to cstruct [dst], starting at index [dstoff]. @raise Invalid_argument if [srcoff] and [len] do not designate a valid subsequence of [src], or if [dstoff] and [len] do not designate a valid segment of [dst]. *) val blit_to_bytes: t -> int -> bytes -> int -> int -> unit (** [blit_to_bytes src srcoff dst dstoff len] copies [len] characters from cstruct [src], starting at index [srcoff], to the [dst] buffer, starting at index [dstoff]. @raise Invalid_argument if [srcoff] and [len] do not designate a valid segment of [src], or if [dstoff] and [len] do not designate a valid segment of [dst]. *) val memset: t -> int -> unit (** [memset t x] sets all the bytes of [t] to [x land 0xff]. *) val split: ?start:int -> t -> int -> t * t (** [split ~start cstr len] is a tuple containing the cstruct extracted from [cstr] at offset [start] (default: 0) of length [len] as first element, and the rest of [cstr] as second element. @raise Invalid_argument if [start] exceeds the cstruct length, or if there is a bounds violation of the cstruct via [len+start]. *) val to_string: ?off:int -> ?len:int -> t -> string (** [to_string ~off ~len t] will allocate a fresh OCaml [string] and copy the contents of the cstruct starting at offset [off] (default [0]) of length [len] (default [Cstruct.length t - off]) into it, and return that string. @raise Invalid_argument if [off] or [len] is negative, or [Cstruct.length t - off] < [len]. *) val to_hex_string : ?off:int -> ?len:int -> t -> string (** [to_hex_string ~off ~len t] is a fresh OCaml [string] containing the hex representation of [sub t off len]. It is therefore of length [2 * len]. This string can be read back into a Cstruct using {!of_hex}. @raise Invalid_argument if [off] or [len] is negative, or if [Cstruct.length t - off < len]. @since 6.2 *) val to_bytes: ?off:int -> ?len:int -> t -> bytes (** [to_bytes ~off ~len t] will allocate a fresh OCaml [bytes] and copy the contents of the cstruct starting at offset [off] (default [0]) of length [len] (default [Cstruct.length t - off]) into it, and return that bytes. @raise Invalid_argument if [off] or [len] is negative, or [Cstruct.length str - off] < [len]. *) module BE : sig (** Get/set big-endian integers of various sizes. The second argument of those functions is the position relative to the current offset of the cstruct. *) val get_uint16: t -> int -> uint16 (** [get_uint16 cstr off] is the 16 bit long big-endian unsigned integer stored in [cstr] at offset [off]. @raise Invalid_argument if the buffer is too small. *) val get_uint32: t -> int -> uint32 (** [get_uint32 cstr off] is the 32 bit long big-endian unsigned integer stored in [cstr] at offset [off]. @raise Invalid_argument if the buffer is too small. *) val get_uint64: t -> int -> uint64 (** [get_uint64 cstr off] is the 64 bit long big-endian unsigned integer stored in [cstr] at offset [off]. @raise Invalid_argument if the buffer is too small. *) val set_uint16: t -> int -> uint16 -> unit (** [set_uint16 cstr off i] writes the 16 bit long big-endian unsigned integer [i] at offset [off] of [cstr]. @raise Invalid_argument if the buffer is too small. *) val set_uint32: t -> int -> uint32 -> unit (** [set_uint32 cstr off i] writes the 32 bit long big-endian unsigned integer [i] at offset [off] of [cstr]. @raise Invalid_argument if the buffer is too small. *) val set_uint64: t -> int -> uint64 -> unit (** [set_uint64 cstr off i] writes the 64 bit long big-endian unsigned integer [i] at offset [off] of [cstr]. @raise Invalid_argument if the buffer is too small. *) end module LE : sig (** Get/set little-endian integers of various sizes. The second argument of those functions is the position relative to the current offset of the cstruct. *) val get_uint16: t -> int -> uint16 (** [get_uint16 cstr off] is the 16 bit long little-endian unsigned integer stored in [cstr] at offset [off]. @raise Invalid_argument if the buffer is too small. *) val get_uint32: t -> int -> uint32 (** [get_uint32 cstr off] is the 32 bit long little-endian unsigned integer stored in [cstr] at offset [off]. @raise Invalid_argument if the buffer is too small. *) val get_uint64: t -> int -> uint64 (** [get_uint64 cstr off] is the 64 bit long little-endian unsigned integer stored in [cstr] at offset [off]. @raise Invalid_argument if the buffer is too small. *) val set_uint16: t -> int -> uint16 -> unit (** [set_uint16 cstr off i] writes the 16 bit long little-endian unsigned integer [i] at offset [off] of [cstr]. @raise Invalid_argument if the buffer is too small. *) val set_uint32: t -> int -> uint32 -> unit (** [set_uint32 cstr off i] writes the 32 bit long little-endian unsigned integer [i] at offset [off] of [cstr]. @raise Invalid_argument if the buffer is too small. *) val set_uint64: t -> int -> uint64 -> unit (** [set_uint64 cstr off i] writes the 64 bit long little-endian unsigned integer [i] at offset [off] of [cstr]. @raise Invalid_argument if the buffer is too small. *) end module HE : sig (** Get/set host-endian integers of various sizes. The second argument of those functions is the position relative to the current offset of the cstruct. *) val get_uint16: t -> int -> uint16 (** [get_uint16 cstr off] is the 16 bit long host-endian unsigned integer stored in [cstr] at offset [off]. @raise Invalid_argument if the buffer is too small. *) val get_uint32: t -> int -> uint32 (** [get_uint32 cstr off] is the 32 bit long host-endian unsigned integer stored in [cstr] at offset [off]. @raise Invalid_argument if the buffer is too small. *) val get_uint64: t -> int -> uint64 (** [get_uint64 cstr off] is the 64 bit long host-endian unsigned integer stored in [cstr] at offset [off]. @raise Invalid_argument if the buffer is too small. *) val set_uint16: t -> int -> uint16 -> unit (** [set_uint16 cstr off i] writes the 16 bit long host-endian unsigned integer [i] at offset [off] of [cstr]. @raise Invalid_argument if the buffer is too small. *) val set_uint32: t -> int -> uint32 -> unit (** [set_uint32 cstr off i] writes the 32 bit long host-endian unsigned integer [i] at offset [off] of [cstr]. @raise Invalid_argument if the buffer is too small. *) val set_uint64: t -> int -> uint64 -> unit (** [set_uint64 cstr off i] writes the 64 bit long host-endian unsigned integer [i] at offset [off] of [cstr]. @raise Invalid_argument if the buffer is too small. *) end (** {2 Debugging } *) val hexdump: t -> unit (** When the going gets tough, the tough hexdump their cstructs and peer at it until the bug disappears. This will directly prettyprint the contents of the cstruct to the standard output. *) val hexdump_to_buffer: Buffer.t -> t -> unit (** [hexdump_to_buffer buf c] will append the pretty-printed hexdump of the cstruct [c] to the buffer [buf]. *) val hexdump_pp: Format.formatter -> t -> unit (** [hexdump_pp f c] pretty-prints a hexdump of [c] to [f]. *) val debug: t -> string (** [debug t] will print out the internal details of a cstruct such as its base offset and the length, and raise an assertion failure if invariants have been violated. Not intended for casual use. *) (** {2 List of buffers} *) val lenv: t list -> int (** [lenv cstrs] is the combined length of all cstructs in [cstrs]. @raise Invalid_argument if computing the sum overflows. *) val copyv: t list -> string (** [copyv cstrs] is the string representation of the concatenation of all cstructs in [cstrs]. @raise Invalid_argument if the length of the result would exceed [Sys.max_string_length]. *) val fillv: src:t list -> dst:t -> int * t list (** [fillv ~src ~dst] copies from [src] to [dst] until [src] is exhausted or [dst] is full. Returns the number of bytes copied and the remaining data from [src], if any. This is useful if you want buffer data into fixed-sized chunks. *) val shiftv: t list -> int -> t list (** [shiftv ts n] is [ts] without the first [n] bytes. It has the property that [equal (concat (shiftv ts n)) (shift (concat ts) n)]. This operation is fairly fast, as it will share the tail of the list. The first item in the returned list is never an empty cstruct, so you'll get [[]] if and only if [lenv ts = n]. *) (** {2 Iterations} *) type 'a iter = unit -> 'a option (** Type of an iterator. *) val iter: (t -> int option) -> (t -> 'a) -> t -> 'a iter (** [iter lenf of_cstr cstr] is an iterator over [cstr] that returns elements of size [lenf cstr] and type [of_cstr cstr]. *) val fold: ('b -> 'a -> 'b) -> 'a iter -> 'b -> 'b (** [fold f iter acc] is [(f iterN accN ... (f iter acc)...)]. *) val append: t -> t -> t (** [append t1 t2] is the concatenation [t1 || t2]. *) val concat: t list -> t (** [concat ts] is the concatenation of all the [ts]. It is not guaranteed that * the result is a newly created [t] in the zero- and one-element cases. *) val rev: t -> t (** [rev t] is [t] in reverse order. The return value is a freshly allocated cstruct, and the argument is not modified. *) (** {1 Helpers to parse.} [Cstruct] is used to manipulate {i payloads} which can be formatted according an {{:https://perdu.com/}RFC} or an user-defined format. In such context, this module provides utilities to be able to easily {i parse} {i payloads}. Due to the type {!Cstruct.t}, no copy are done when you use these utilities and you are able to extract your information without a big performance cost. More precisely, each values returned by these utilities will be located into the minor-heap where the base buffer will never be copied or relocated. For instance, to parse a Git tree object: {v entry := perm ' ' name '\000' 20byte tree := entry * v} {[ open Cstruct let ( >>= ) = Option.bind let rec hash_of_name ~name payload = if is_empty payload then raise Not_found else cut ~sep:(v " ") payload >>= fun (_, payload) -> cut ~sep:(v "\000") payload >>= fun (name', payload) -> if name = name' then with_range ~len:20 payload else hash_of_name ~name (shift payload 20) ]} A [Cstruct] defines a possibly empty subsequence of bytes in a {e base} buffer (a {!Bigarray.Array1.t}). The positions of a buffer [b] of length [l] are the slits found before each byte and after the last byte of the buffer. They are labelled from left to right by increasing number in the range \[[0];[l]\]. {v positions 0 1 2 3 4 l-1 l +---+---+---+---+ +-----+ indices | 0 | 1 | 2 | 3 | ... | l-1 | +---+---+---+---+ +-----+ v} The [i]th byte index is between positions [i] and [i+1]. Formally we define a subbuffer of [b] as being a subsequence of bytes defined by a {e off} position and a {e len} number. When [len] is [0] the subbuffer is {e empty}. Note that for a given base buffer there are as many empty subbuffers as there are positions in the buffer. Like in strings, we index the bytes of a subbuffer using zero-based indices. *) val get : t -> int -> char (** [get cs zidx] is the byte of [cs] at its zero-based index [zidx]. It's an alias of {!get_char}. @raise Invalid_argument if [zidx] is not an index of [cs]. *) val get_byte : t -> int -> int (** [get_byte cs zidx] is [Char.code (get cs zidx)]. It's an alias of {!get_uint8}. *) val string : ?off:int -> ?len:int -> string -> t (** [string ~off ~len str] is the subbuffer of [str] that starts at position [off] (defaults to [0]) and stops at position [off + len] (defaults to [String.length str]). [str] is fully-replaced by an fresh allocated {!type:buffer}. @raise Invalid_argument if [off] or [off + len] are not positions of [str]. *) val buffer : ?off:int -> ?len:int -> buffer -> t (** [buffer ~off ~len buffer] is the sub-part of [buffer] that starts at position [off] (default to [0]) and stops at position [off + len] (default to [Bigarray.Array1.dim buffer]). [buffer] is used as the base buffer of the returned value (no major-heap allocation are performed). @raise Invalid_argument if [off] or [off + len] are not positions of [buffer]. *) val start_pos : t -> int (** [start_pos cs] is [cs]'s start position in the base {!type:buffer}. *) val stop_pos : t -> int (** [stop_pos cs] is [cs]'s stop position in the base {!type:buffer}. *) val length : t -> int (** Returns the length of the current cstruct view. Note that this length is potentially smaller than the actual size of the underlying buffer, as the [sub] function can construct a smaller view. *) val head : ?rev:bool -> t -> char option (** [head cs] is [Some (get cs h)] with [h = 0] if [rev = false] (default) or [h = length cs - 1] if [rev = true]. [None] is returned if [cs] is empty. *) val tail : ?rev:bool -> t -> t (** [tail cs] is [cs] without its first ([rev] is [false], default) or last ([rev] is [true]) byte or [cs] is empty. *) val is_empty : t -> bool (** [is_empty cs] is [length cs = 0]. *) val is_prefix : affix:t -> t -> bool (** [is_prefix ~affix cs] is [true] iff [affix.[zidx] = cs.[zidx]] for all indices [zidx] of [affix]. *) val is_suffix : affix:t -> t -> bool (** [is_suffix ~affix cs] is [true] iff [affix.[n - zidx] = cs.[m - zidx]] for all indices [zidx] of [affix] with [n = length affix - 1] and [m = length cs - 1]. *) val is_infix : affix:t -> t -> bool (** [is_infix ~affix cs] is [true] iff there exists an index [z] in [cs] such that for all indices [zidx] of [affix] we have [affix.[zidx] = cs.[z + zidx]]. *) val for_all : (char -> bool) -> t -> bool (** [for_all p cs] is [true] iff for all indices [zidx] of [cs], [p cs.[zidx] = true]. *) val exists : (char -> bool) -> t -> bool (** [exists p cs] is [true] iff there exists an index [zidx] of [cs] with [p cs.[zidx] = true]. *) val start : t -> t (** [start cs] is the empty sub-part at the start position of [cs]. *) val stop : t -> t (** [stop cs] is the empty sub-part at the stop position of [cs]. *) val trim : ?drop:(char -> bool) -> t -> t (** [trim ~drop cs] is [cs] with prefix and suffix bytes satisfying [drop] in [cs] removed. [drop] defaults to [function ' ' | '\r' .. '\t' -> true | _ -> false]. *) val span : ?rev:bool -> ?min:int -> ?max:int -> ?sat:(char -> bool) -> t -> t * t (** [span ~rev ~min ~max ~sat cs] is [(l, r)] where: {ul {- if [rev] is [false] (default), [l] is at least [min] and at most [max] consecutive [sat] satisfying initial bytes of [cs] or {!empty} if there are no such bytes. [r] are the remaining bytes of [cs].} {- if [rev] is [true], [r] is at least [min] and at most [max] consecutive [sat] satisfying final bytes of [cs] or {!empty} if there are no such bytes. [l] are the remaining bytes of [cs].}} If [max] is unspecified the span is unlimited. If [min] is unspecified it defaults to [0]. If [min > max] the condition can't be satisfied and the left or right span, depending on [rev], is always empty. [sat] defaults to [(fun _ -> true)]. The invariant [l ^ r = s] holds. For instance, the {i ABNF} expression: {v time := 1*10DIGIT v} can be translated to: {[ let (time, _) = span ~min:1 ~max:10 is_digit cs in ]} @raise Invalid_argument if [max] or [min] is negative. *) val take : ?rev:bool -> ?min:int -> ?max:int -> ?sat:(char -> bool) -> t -> t (** [take ~rev ~min ~max ~sat cs] is the matching span of {!span} without the remaining one. In other words: {[(if rev then snd else fst) @@ span ~rev ~min ~max ~sat cs]} *) val drop : ?rev:bool -> ?min:int -> ?max:int -> ?sat:(char -> bool) -> t -> t (** [drop ~rev ~min ~max ~sat cs] is the remaining span of {!span} without the matching one. In other words: {[(if rev then fst else snd) @@ span ~rev ~min ~max ~sat cs]} *) val cut : ?rev:bool -> sep:t -> t -> (t * t) option (** [cut ~sep cs] is either the pair [Some (l, r)] of the two (possibly empty) sub-buffers of [cs] that are delimited by the first match of the non empty separator string [sep] or [None] if [sep] can't be matched in [cs]. Matching starts from the beginning of [cs] ([rev] is [false], default) or the end ([rev] is [true]). The invariant [l ^ sep ^ r = s] holds. For instance, the {i ABNF} expression: {v field_name := *PRINT field_value := *ASCII field := field_name ":" field_value v} can be translated to: {[ match cut ~sep:":" value with | Some (field_name, field_value) -> ... | None -> invalid_arg "invalid field" ]} @raise Invalid_argument if [sep] is the empty buffer. *) val cuts : ?rev:bool -> ?empty:bool -> sep:t -> t -> t list (** [cuts ~sep cs] is the list of all sub-buffers of [cs] that are delimited by matches of the non empty separator [sep]. Empty sub-buffers are omitted in the list if [empty] is [false] (default to [true]). Matching separators in [cs] starts from the beginning of [cs] ([rev] is [false], default) or the end ([rev] is [true]). Once one is found, the separator is skipped and matching starts again, that is separator matches can't overlap. If there is no separator match in [cs], the list [[cs]] is returned. The following invariants hold: {ul {- [concat ~sep (cuts ~empty:true ~sep cs) = cs]} {- [cuts ~empty:true ~sep cs <> []]}} For instance, the {i ABNF} expression: {v arg := *(ASCII / ",") ; any characters exclude "," args := arg *("," arg) v} can be translated to: {[ let args = cuts ~sep:"," buffer in ]} @raise Invalid_argument if [sep] is the empty buffer. *) val fields : ?empty:bool -> ?is_sep:(char -> bool) -> t -> t list (** [fields ~empty ~is_sep cs] is the list of (possibly empty) sub-buffers that are delimited by bytes for which [is_sep] is [true]. Empty sub-buffers are omitted in the list if [empty] is [false] (defaults to [true]). [is_sep c] if it's not define by the user is [true] iff [c] is an US-ASCII white space character, that is one of space [' '] ([0x20]), tab ['\t'] ([0x09]), newline ['\n'] ([0x0a]), vertical tab ([0x0b]), form feed ([0x0c]), carriage return ['\r'] ([0x0d]). *) val find : ?rev:bool -> (char -> bool) -> t -> t option (** [find ~rev sat cs] is the sub-buffer of [cs] (if any) that spans the first byte that satisfies [sat] in [cs] after position [start cs] ([rev] is [false], default) or before [stop cs] ([rev] is [true]). [None] is returned if there is no matching byte in [s]. *) val find_sub : ?rev:bool -> sub:t -> t -> t option (** [find_sub ~rev ~sub cs] is the sub-buffer of [cs] (if any) that spans the first match of [sub] in [cs] after position [start cs] ([rev] is [false], default) or before [stop cs] ([rev] is [true]). Only bytes are compared and [sub] can be on a different base buffer. [None] is returned if there is no match of [sub] in [s]. *) val filter : (char -> bool) -> t -> t (** [filter sat cs] is the buffer made of the bytes of [cs] that satisfy [sat], in the same order. *) val filter_map : (char -> char option) -> t -> t (** [filter_map f cs] is the buffer made of the bytes of [cs] as mapped by [f], in the same order. *) val map : (char -> char) -> t -> t (** [map f cs] is [cs'] with [cs'.[i] = f cs.[i]] for all indices [i] of [cs]. [f] is invoked in increasing index order. *) val mapi : (int -> char -> char) -> t -> t (** [map f cs] is [cs'] with [cs'.[i] = f i cs.[i]] for all indices [i] of [cs]. [f] is invoked in increasing index order. *) (**/**) val sum_lengths : caller:string -> t list -> int (** [sum_lengths ~caller acc l] is [acc] plus the sum of the lengths of the elements of [l]. Raises [Invalid_argument caller] if arithmetic overflows. *) ocaml-cstruct-6.2.0/lib/cstruct_cap.ml000066400000000000000000000043661437471254600177370ustar00rootroot00000000000000(* * Copyright (c) 2012-2019 Anil Madhavapeddy * Copyright (c) 2019 Romain Calascibetta * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) include (Cstruct : module type of Cstruct with type t := Cstruct.t) type 'a rd = < rd: unit; .. > as 'a type 'a wr = < wr: unit; .. > as 'a type 'a t = Cstruct.t type rdwr = < rd: unit; wr: unit; > type ro = < rd: unit; > type wo = < wr: unit; > external ro : 'a rd t -> ro t = "%identity" external wo : 'a wr t -> wo t = "%identity" let of_string = Cstruct.of_string ?allocator:None let of_bytes = Cstruct.of_bytes ?allocator:None let pp ppf t = Cstruct.hexdump_pp ppf t let length = Cstruct.length let blit src ~src_off dst ~dst_off ~len = Cstruct.blit src src_off dst dst_off len [@@inline] let blit_from_string src ~src_off dst ~dst_off ~len = Cstruct.blit_from_string src src_off dst dst_off len [@@inline] let blit_from_bytes src ~src_off dst ~dst_off ~len = Cstruct.blit_from_bytes src src_off dst dst_off len [@@inline] let blit_to_bytes src ~src_off dst ~dst_off ~len = Cstruct.blit_to_bytes src src_off dst dst_off len [@@inline] let sub t ~off ~len = Cstruct.sub t off len [@@inline] let sub_copy t ~off ~len = Cstruct.sub_copy t off len [@@inline] let unsafe_to_bigarray = Cstruct.to_bigarray let concat vss = let res = create_unsafe (Cstruct.sum_lengths ~caller:"Cstruct.Cap.concat" vss) in let go off v = let len = Cstruct.length v in Cstruct.blit v 0 res off len ; off + len in let len = List.fold_left go 0 vss in assert (len = Cstruct.length res) ; res ocaml-cstruct-6.2.0/lib/cstruct_cap.mli000066400000000000000000000666441437471254600201170ustar00rootroot00000000000000(* * Copyright (c) 2012-2019 Anil Madhavapeddy * Copyright (c) 2019 Romain Calascibetta * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) (** Raw memory buffers with capabilities [Cstruct_cap] wraps OCaml Stdlib's {{:http://caml.inria.fr/pub/docs/manual-ocaml/libref/Bigarray.html}Bigarray} module. Each [t] consists of a proxy (consisting of offset, length, and the actual {!Bigarray.t} buffer). The goal of this module is two-fold: enable zero-copy - the underlying buffer is shared by most of the functions - and static checking of read and write capabilities to the underlying buffer (using phantom types). Each ['a t] is parameterized by the available capabilities: read ([rd]) and write ([wr]): to access the contents of the buffer the [read] capability is necessary, for modifying the content of the buffer the [write] capability is necessary. Capabilities can only be dropped, never gained, to a buffer. If code only has read capability, this does not mean that there is no other code fragment with write capability to the underlying buffer. The functions that retrieve bytes ({!get_uint8} etc.) require a [read] capability, functions mutating the underlying buffer ({!set_uint8} etc.) require a [write] capability. Allocation of a buffer (via {!create}, ...) returns a [t] with read and write capabilities. {!val:ro} drops the write capability, {!val:wo} drops the read capability. The only exception is {!unsafe_to_bigarray} that returns the underlying [Bigarray.t]. Accessors and mutators for fixed size integers (8, 16, 32, 64 bit) are provided for big-endian and little-endian encodings. *) (** {2 Types} *) type 'a rd = < rd: unit; .. > as 'a (** Type of read capability. *) type 'a wr = < wr: unit; .. > as 'a (** Type of write capability. *) type 'a t (** Type of cstruct with capabilities ['a]. *) type buffer = (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t (** Type of buffer. A {!t} is composed of an underlying buffer. *) type rdwr = < rd: unit; wr: unit; > (** Type of both read and write capability. *) type ro = < rd: unit; > (** Type of only read capability. *) type wo = < wr: unit; > (** Type of only write capability. *) type uint8 = int (** 8-bit unsigned integer. *) type uint16 = int (** 16-bit unsigned integer. *) type uint32 = int32 (** 32-bit unsigned integer. *) type uint64 = int64 (** 64-bit unsigned integer. *) (** {2 Capabilities} *) val ro : 'a rd t -> ro t (** [ro t] is [t'] with only read capability. *) val wo : 'a wr t -> wo t (** [wo t] is [t'] with only write capability. *) (** {2 Basic operations} *) val equal : 'a rd t -> 'b rd t -> bool (** [equal a b] is [true] iff [a] and [b] correspond to the same sequence of bytes (it uses [memcmp] internally). Both [a] and [b] need at least read capability {!rd}. *) val compare : 'a rd t -> 'b rd t -> int (** [compare a b] gives an unspecified total ordering over {!t}. Both [a] and [b] need at least read capability {!rd}. *) val pp : Format.formatter -> 'a rd t -> unit (** [pp ppf t] pretty-prints [t] on [ppf]. [t] needs read capability {!rd}. *) val length : 'a t -> int (** [length t] return length of [t]. Note that this length is potentially smaller than the actual size of the underlying buffer, as functions such as {!sub}, {!shift}, and {!split} can construct a smaller view. *) val check_alignment : 'a t -> int -> bool (** [check_alignment t alignment] is [true] if the first byte stored in the underlying buffer of [t] is at a memory address where [address mod alignment = 0], [false] otherwise. The [mod] used has the C/OCaml semantic (which differs from Python). Typical uses are to check a buffer is aligned to a page or disk sector boundary. @raise Invalid_argument if [alignment] is not a positive integer. *) val lenv : 'a t list -> int (** [lenv vs] is the combined length of all {!t} in [vs]. @raise Invalid_argument if computing the sum overflows. *) (** {2 Constructors} *) val create : int -> rdwr t (** [create len] allocates a buffer and proxy with both read and write capabilities of size [len]. It is filled with zero bytes. *) val create_unsafe : int -> rdwr t (** [create_unsafe len] allocates a buffer and proxy with both read and write capabilities of size [len]. Note that the returned [t] will contain arbitrary data, likely including the contents of previously-deallocated cstructs. Beware! Forgetting to replace this data could cause your application to leak sensitive information. *) (** {2 Subviews} *) val sub : 'a t -> off:int -> len:int -> 'a t (** [sub t ~off ~len] returns a proxy which shares the underlying buffer of [t]. It is sliced at offset [off] and of length [len]. The returned value has the same capabilities as [t]. @raise Invalid_argument if the offset exceeds [t] length. *) val sub_copy : 'a t -> off:int -> len:int -> rdwr t (** [sub_copy t ~off ~len] is a new copy of [sub t ~off ~len], that does not share the underlying buffer of [t]. The returned value has read-write capabilities because it doesn't affect [t]. @raise Invalid_argument if the offset exceeds [t] length. *) val shift : 'a t -> int -> 'a t (** [shift t len] returns a proxy which shares the underlying buffer of [t]. The returned value starts [len] bytes later than the given [t]. The returned value has the same capabilities as [t]. @raise Invalid_argument if the offset exceeds [t] length. *) val shiftv: 'a t list -> int -> 'a t list (** [shiftv ts n] is [ts] without the first [n] bytes. It has the property that [equal (concat (shiftv ts n)) (shift (concat ts) n)]. This operation is fairly fast, as it will share the tail of the list. The first item in the returned list is never an empty cstruct, so you'll get [[]] if and only if [lenv ts = n]. *) val split : ?start:int -> 'a t -> int -> 'a t * 'a t (** [split ~start t len] returns two proxies extracted from [t]. The first starts at offset [start] (default [0]), and is of length [len]. The second is the remainder of [t]. The underlying buffer is shared, the capabilities are preserved. @raise Invalid_argument if [start] exceeds the length of [t], or if there is a bounds violation of [t] via [len + start]. *) val copy : 'a t -> int -> int -> string [@@ocaml.alert deprecated "this is just like [to_string] without defaults, were you looking for [sub_copy]?"] (** [copy cstr off len] is the same as [Cstruct.to_string cstr ~off ~len]. *) (** {2 Construction from existing t} *) val append : 'a rd t -> 'b rd t -> rdwr t (** [append a b] allocates a buffer [r] of size [length a + length b]. Then the content of [a] is copied at the start of the buffer [r], and [b] is copied behind [a]'s end in [r]. [a] and [b] need at least read capability {!rd}, the returned value has both read and write capabilities. *) val concat : 'a rd t list -> rdwr t (** [concat vss] allocates a buffer [r] of size [lenv vss]. Each [v] of [vss] is copied into the buffer [r]. Each [v] of [vss] need at least read capability {!rd}, the returned value has both read and write capabilities. *) val fillv : src:'a rd t list -> dst:'b wr t -> int * 'a rd t list (** [fillv ~src ~dst] copies from [src] to [dst] until [src] is exhausted or [dst] is full. It returns the number of bytes copied and the remaining data from [src], if any. This is useful if you want to {i bufferize} data into fixed-sized chunks. Each {!t} of [src] need at least read capability {!rd}. [dst] needs at least write capability {!wr}. *) val rev : 'a rd t -> rdwr t (** [rev t] allocates a buffer [r] of size [length t], and fills it with the bytes of [t] in reverse order. The given [t] needs at least read capability {!rd}, the returned value has both read and write capabilities. *) (** {2 Mutation of the underlying buffer} *) val memset : 'a wr t -> int -> unit (** [memset t x] sets all bytes of [t] to [x land 0xFF]. [t] needs at least write capability {!wr}. *) val blit : 'a rd t -> src_off:int -> 'b wr t -> dst_off:int -> len:int -> unit (** [blit src ~src_off dst ~dst_off ~len] copies [len] bytes from [src] starting at index [src_off] to [dst] starting at index [dst_off]. It works correctly even if [src] and [dst] refer to the same underlying buffer, and the [src] and [dst] intervals overlap. This function uses [memmove] internally. [src] needs at least read capability {!rd}. [dst] needs at least write capability {!wr}. @raise Invalid_argument if [src_off] and [len] do not designate a valid segment of [src], or if [dst_off] and [len] do not designate a valid segment of [dst]. *) val blit_from_string : string -> src_off:int -> 'a wr t -> dst_off:int -> len:int -> unit (** [blit_from_string src ~src_off dst ~dst_off ~len] copies [len] byres from [src] starting at index [src_off] to [dst] starting at index [dst_off]. This function uses [memcpy] internally. [dst] needs at least write capability {!wr}. @raise Invalid_argument if [src_off] and [len] do not designate a valid sub-string of [src], or if [dst_off] and [len] do not designate a valid segment of [dst]. *) val blit_from_bytes : bytes -> src_off:int -> 'a wr t -> dst_off:int -> len:int -> unit (** [blit_from_bytes src ~src_off dst ~dst_off ~len] copies [len] bytes from [src] starting at index [src_off] to [dst] starting at index [dst_off]. This uses [memcpy] internally. [dst] needs at least write capability {!wr}. @raise Invalid_argument if [src_off] and [len] do not designate a valid sub-sequence of [src], or if [dst_off] and [len] do no designate a valid segment of [dst]. *) (** {2 Converters: string, bytes, bigarray} *) val of_string : ?off:int -> ?len:int -> string -> rdwr t (** [of_string ~off ~len s] allocates a buffer and copies the contents of [s] into it starting at offset [off] (default [0]) and of length [len] (default [String.length s - off]). The returned value has both read and write capabilities. @raise Invalid_argument if [off] and [len] does not designate a valid segment of [s]. *) val to_string : ?off:int -> ?len:int -> 'a rd t -> string (** [to_string ~off ~len t] is the string representation of the segment of [t] starting at [off] (default [0]) of size [len] (default [length t - off]). [t] needs at least read capability {!rd}. @raise Invalid_argument if [off] and [len] does not designate a valid segment of [t]. *) val to_hex_string : ?off:int -> ?len:int -> _ rd t -> string (** [to_hex_string ~off ~len t] is a fresh OCaml [string] containing the hex representation of [sub t off len]. See {!Cstruct.to_hex_string}. @raise Invalid_argument if [off] or [len] is negative, or if [Cstruct.length t - off < len]. @since 6.2 *) val of_hex : ?off:int -> ?len:int -> string -> rdwr t (** [of_hex ~off ~len s] allocates a buffer and copies the content of [s] starting at offset [off] (default [0]) of length [len] (default [String.length s - off]), decoding the hex-encoded characters. Whitespaces in the string are ignored, every pair of hex-encoded characters in [s] are converted to one byte in the returned {!t}, which is exactly half the size of the non-whitespace characters of [s] from [off] of length [len]. @raise Invalid_argument is the input string contains invalid characters or an off number of non-whitespace characters. *) val copyv : 'a rd t list -> string (** [copy vs] is the string representation of the concatenation of all {!t} in [vs]. Each {!t} need at least read capability {!rd}. @raise Invalid_argument if the length of the result would exceed {!Sys.max_string_length}. *) val of_bytes : ?off:int -> ?len:int -> bytes -> rdwr t (** [of_bytes ~off ~len b] allocates a buffer and copies the contents of [b] into it starting at offset [off] (default [0]) and of length [len] (default [Bytes.length b - off]). The returned value has both read and write capabilities. @raise Invalid_argument if [off] and [len] does not designate a valid segment of [s]. *) val to_bytes : ?off:int -> ?len:int -> 'a rd t -> bytes (** [to_bytes ~off ~len t] is the bytes representation of the segment of [t] starting at [off] (default [0]) of size [len] (default [length t - off]). [t] needs at least read capability {!rd}. @raise Invalid_argument if [off] and [len] do not designate a valid segment of [t]. *) val blit_to_bytes : 'a rd t -> src_off:int -> bytes -> dst_off:int -> len:int -> unit (** [blit_to_bytes src ~src_off dst ~dst_off ~len] copies length [len] bytes from [src], starting at index [src_off], to sequences [dst], starting at index [dst_off]. [blit_to_bytes] uses [memcpy] internally. [src] needs at least read capability {!rd}. @raise Invalid_argument if [src_off] and [len] do not designate a valid segment of [src], or if [dst_off] and [len] do not designate a valid sub-seuqnce of [dst]. *) val of_bigarray: ?off:int -> ?len:int -> buffer -> rdwr t (** [of_bigarray ~off ~len b] is a proxy that contains [b] with offset [off] (default [0]) of length [len] (default [Bigarray.Array1.dim b - off]). The returned value has both read and write capabilties. @raise Invalid_argument if [off] and [len] do not designate a valid segment of [b]. *) val unsafe_to_bigarray : 'a t -> buffer (** [unsafe_to_bigarray t] converts [t] into a {!buffer} Bigarray, using the Bigarray slicing to allocate a fresh {i proxy} Bigarray that preserves sharing of the underlying buffer. In other words: {[let t = Cstruct_cap.create 10 in let b = Cstruct_cap.unsafe_to_bigarray t in Bigarray.Array1.set b 0 '\x42' ; assert (Cstruct_cap.get_char t 0 = '\x42')]} *) (** {2 Higher order functions} *) type 'a iter = unit -> 'a option (** Type of iterator. *) val iter : ('a rd t -> int option) -> ('a rd t -> 'v) -> 'a rd t -> 'v iter (** [iter lenf of_cstruct t] is an iterator over [t] that returns elements of size [lenf t] and type [of_cstruct t]. [t] needs at least read capability {!rd} and [iter] keeps capabilities of [t] on [of_cstruct]. *) val fold : ('acc -> 'x -> 'acc) -> 'x iter -> 'acc -> 'acc (** [fold f iter acc] is [(f iterN accN ... (f iter acc)...)]. *) (** {2 Accessors and mutators} *) val get_char : 'a rd t -> int -> char (** [get_char t off] returns the character contained in [t] at offset [off]. [t] needs at least read capability {!rd}. @raise Invalid_argument if the offset exceeds [t] length. *) val set_char : 'a wr t -> int -> char -> unit (** [set_char t off c] sets the character contained in [t] at offset [off] to character [c]. [t] needs at least write capability {!wr}. @raise Invalid_argument if the offset exceeds [t] length. *) val get_uint8 : 'a rd t -> int -> uint8 (** [get_uint8 t off] returns the byte contained in [t] at offset [off]. [t] needs at least read capability {!rd}. @raise Invalid_argument if the offset exceeds [t] length. *) val set_uint8 : 'a wr t -> int -> uint8 -> unit (** [set_uint8 t off x] sets the byte contained in [t] at offset [off] to byte [x]. [t] needs at least write capability {!wr}. @raise Invalid_argument if the offset exceeds [t] length. *) module BE : sig (** {3 Big-endian Byte Order} The following operations assume a big-endian byte ordering of the cstruct. If the machine-native byte ordering differs, then the get operations will reorder the bytes so that they are in machine-native byte order before returning the result, and the set operations will reorder the bytes so that they are written out in the appropriate order. Network byte order is big-endian, so you may need these operations when dealing with raw frames, for example, in a userland networking stack. *) val get_uint16 : 'a rd t -> int -> uint16 (** [get_uint16 t off] returns the two bytes in [t] starting at offset [off], interpreted as an {!uint16}. [t] needs at least read capability {!rd}. @raise Invalid_argument if offset [off] exceeds [length t - 2]. *) val get_uint32 : 'a rd t -> int -> uint32 (** [get_uint32 t off] returns the four bytes in [t] starting at offset [off]. [t] needs at least read capability {!rd}. @raise Invalid_argument if offset [off] exceeds [length t - 4]. *) val get_uint64 : 'a rd t -> int -> uint64 (** [get_uint64 t off] returns the eight bytes in [t] starting at offset [off]. [t] needs at least read capability {!rd}. @raise Invalid_argument if offset [off] exceeds [length t - 8]. *) val set_uint16 : 'a wr t -> int -> uint16 -> unit (** [set_uint16 t off v] sets the two bytes in [t] starting at offset [off] to the value [v]. [t] needs at least write capability {!wr}. @raise Invalid_argument if offset [off] exceeds [length t - 2]. *) val set_uint32 : 'a wr t -> int -> uint32 -> unit (** [set_uint32 t off v] sets the four bytes in [t] starting at offset [off] to the value [v]. [t] needs at least write capability {!wr}. @raise Invalid_argument if offset [off] exceeds [length t - 4]. *) val set_uint64 : 'a wr t -> int -> uint64 -> unit (** [set_uint64 t off v] sets the eight bytes in [t] starting at offset [off] to the value [v]. [t] needs at least write capability {!wr}. @raise Invalid_argument if offset [off] exceeds [length t - 8]. *) end module LE : sig (** {3 Little-endian Byte Order} The following operations assume a little-endian byte ordering of the cstruct. If the machine-native byte ordering differs, then the get operations will reorder the bytes so that they are in machine-native byte order before returning the result, and the set operations will reorder the bytes so that they are written out in the appropriate order. Most modern processor architectures are little-endian, so more likely than not, these operations will not do any byte reordering. *) val get_uint16 : 'a rd t -> int -> uint16 (** [get_uint16 t off] returns the two bytes in [t] starting at offset [off], interpreted as an {!uint16}. [t] needs at least read capability {!rd}. @raise Invalid_argument if offset [off] exceeds [length t - 2]. *) val get_uint32 : 'a rd t -> int -> uint32 (** [get_uint32 t off] returns the four bytes in [t] starting at offset [off]. [t] needs at least read capability {!rd}. @raise Invalid_argument if offset [off] exceeds [length t - 4]. *) val get_uint64 : 'a rd t -> int -> uint64 (** [get_uint64 t off] returns the eight bytes in [t] starting at offset [off]. [t] needs at least read capability {!rd}. @raise Invalid_argument if offset [off] exceeds [length t - 8]. *) val set_uint16 : 'a wr t -> int -> uint16 -> unit (** [set_uint16 t off v] sets the two bytes in [t] starting at offset [off] to the value [v]. [t] needs at least write capability {!wr}. @raise Invalid_argument if offset [off] exceeds [length t - 2]. *) val set_uint32 : 'a wr t -> int -> uint32 -> unit (** [set_uint32 t off v] sets the four bytes in [t] starting at offset [off] to the value [v]. [t] needs at least write capability {!wr}. @raise Invalid_argument if offset [off] exceeds [length t - 4]. *) val set_uint64 : 'a wr t -> int -> uint64 -> unit (** [set_uint64 t off v] sets the eight bytes in [t] starting at offset [off] to the value [v]. [t] needs at least write capability {!wr}. @raise Invalid_argument if offset [off] exceeds [length t - 8]. *) end (** {2 Helpers to parse with capabilities.} As [Cstruct], capabilities interface provides helpers functions to help the user to parse contents. *) val head : ?rev:bool -> 'a rd t -> char option (** [head cs] is [Some (get cs h)] with [h = 0] if [rev = false] (default) or [h = length cs - 1] if [rev = true]. [None] is returned if [cs] is empty. *) val tail : ?rev:bool -> 'a rd t -> 'a rd t (** [tail cs] is [cs] without its first ([rev] is [false], default) or last ([rev] is [true]) byte or [cs] is empty. *) val is_empty : 'a rd t -> bool (** [is_empty cs] is [length cs = 0]. *) val is_prefix : affix:'a rd t -> 'a rd t -> bool (** [is_prefix ~affix cs] is [true] iff [affix.[zidx] = cs.[zidx]] for all indices [zidx] of [affix]. *) val is_suffix : affix:'a rd t -> 'a rd t -> bool (** [is_suffix ~affix cs] is [true] iff [affix.[n - zidx] = cs.[m - zidx]] for all indices [zidx] of [affix] with [n = length affix - 1] and [m = length cs - 1]. *) val is_infix : affix:'a rd t -> 'a rd t -> bool (** [is_infix ~affix cs] is [true] iff there exists an index [z] in [cs] such that for all indices [zidx] of [affix] we have [affix.[zidx] = cs.[z + zidx]]. *) val for_all : (char -> bool) -> 'a rd t -> bool (** [for_all p cs] is [true] iff for all indices [zidx] of [cs], [p cs.[zidx] = true]. *) val exists : (char -> bool) -> 'a rd t -> bool (** [exists p cs] is [true] iff there exists an index [zidx] of [cs] with [p cs.[zidx] = true]. *) val start : 'a rd t -> 'a rd t (** [start cs] is the empty sub-part at the start position of [cs]. *) val stop : 'a rd t -> 'a rd t (** [stop cs] is the empty sub-part at the stop position of [cs]. *) val trim : ?drop:(char -> bool) -> 'a rd t -> 'a rd t (** [trim ~drop cs] is [cs] with prefix and suffix bytes satisfying [drop] in [cs] removed. [drop] defaults to [function ' ' | '\r' .. '\t' -> true | _ -> false]. *) val span : ?rev:bool -> ?min:int -> ?max:int -> ?sat:(char -> bool) -> 'a rd t -> 'a rd t * 'a rd t (** [span ~rev ~min ~max ~sat cs] is [(l, r)] where: {ul {- if [rev] is [false] (default), [l] is at least [min] and at most [max] consecutive [sat] satisfying initial bytes of [cs] or {!is_empty} if there are no such bytes. [r] are the remaining bytes of [cs].} {- if [rev] is [true], [r] is at least [min] and at most [max] consecutive [sat] satisfying final bytes of [cs] or {!is_empty} if there are no such bytes. [l] are the remaining bytes of [cs].}} If [max] is unspecified the span is unlimited. If [min] is unspecified it defaults to [0]. If [min > max] the condition can't be satisfied and the left or right span, depending on [rev], is always empty. [sat] defaults to [(fun _ -> true)]. The invariant [l ^ r = s] holds. For instance, the {i ABNF} expression: {v time := 1*10DIGIT v} can be translated to: {[ let (time, _) = span ~min:1 ~max:10 is_digit cs in ]} @raise Invalid_argument if [max] or [min] is negative. *) val take : ?rev:bool -> ?min:int -> ?max:int -> ?sat:(char -> bool) -> 'a rd t -> 'a rd t (** [take ~rev ~min ~max ~sat cs] is the matching span of {!span} without the remaining one. In other words: {[(if rev then snd else fst) @@ span ~rev ~min ~max ~sat cs]} *) val drop : ?rev:bool -> ?min:int -> ?max:int -> ?sat:(char -> bool) -> 'a rd t -> 'a rd t (** [drop ~rev ~min ~max ~sat cs] is the remaining span of {!span} without the matching one. In other words: {[(if rev then fst else snd) @@ span ~rev ~min ~max ~sat cs]} *) val cut : ?rev:bool -> sep:'a rd t -> 'a rd t -> ('a rd t * 'a rd t) option (** [cut ~sep cs] is either the pair [Some (l, r)] of the two (possibly empty) sub-buffers of [cs] that are delimited by the first match of the non empty separator string [sep] or [None] if [sep] can't be matched in [cs]. Matching starts from the beginning of [cs] ([rev] is [false], default) or the end ([rev] is [true]). The invariant [l ^ sep ^ r = s] holds. For instance, the {i ABNF} expression: {v field_name := *PRINT field_value := *ASCII field := field_name ":" field_value v} can be translated to: {[ match cut ~sep:":" value with | Some (field_name, field_value) -> ... | None -> invalid_arg "invalid field" ]} @raise Invalid_argument if [sep] is the empty buffer. *) val cuts : ?rev:bool -> ?empty:bool -> sep:'a rd t -> 'a rd t -> 'a rd t list (** [cuts ~sep cs] is the list of all sub-buffers of [cs] that are delimited by matches of the non empty separator [sep]. Empty sub-buffers are omitted in the list if [empty] is [false] (default to [true]). Matching separators in [cs] starts from the beginning of [cs] ([rev] is [false], default) or the end ([rev] is [true]). Once one is found, the separator is skipped and matching starts again, that is separator matches can't overlap. If there is no separator match in [cs], the list [[cs]] is returned. The following invariants hold: {ul {- [concat ~sep (cuts ~empty:true ~sep cs) = cs]} {- [cuts ~empty:true ~sep cs <> []]}} For instance, the {i ABNF} expression: {v arg := *(ASCII / ",") ; any characters exclude "," args := arg *("," arg) v} can be translated to: {[ let args = cuts ~sep:"," buffer in ]} @raise Invalid_argument if [sep] is the empty buffer. *) val fields : ?empty:bool -> ?is_sep:(char -> bool) -> 'a rd t -> 'a rd t list (** [fields ~empty ~is_sep cs] is the list of (possibly empty) sub-buffers that are delimited by bytes for which [is_sep] is [true]. Empty sub-buffers are omitted in the list if [empty] is [false] (defaults to [true]). [is_sep c] if it's not define by the user is [true] iff [c] is an US-ASCII white space character, that is one of space [' '] ([0x20]), tab ['\t'] ([0x09]), newline ['\n'] ([0x0a]), vertical tab ([0x0b]), form feed ([0x0c]), carriage return ['\r'] ([0x0d]). *) val find : ?rev:bool -> (char -> bool) -> 'a rd t -> 'a rd t option (** [find ~rev sat cs] is the sub-buffer of [cs] (if any) that spans the first byte that satisfies [sat] in [cs] after position [start cs] ([rev] is [false], default) or before [stop cs] ([rev] is [true]). [None] is returned if there is no matching byte in [s]. *) val find_sub : ?rev:bool -> sub:'a rd t -> 'a rd t -> 'a rd t option (** [find_sub ~rev ~sub cs] is the sub-buffer of [cs] (if any) that spans the first match of [sub] in [cs] after position [start cs] ([rev] is [false], default) or before [stop cs] ([rev] is [true]). Only bytes are compared and [sub] can be on a different base buffer. [None] is returned if there is no match of [sub] in [s]. *) val filter : (char -> bool) -> 'a rd t -> 'a rd t (** [filter sat cs] is the buffer made of the bytes of [cs] that satisfy [sat], in the same order. *) val filter_map : (char -> char option) -> 'a rd t -> rdwr t (** [filter_map f cs] is the buffer made of the bytes of [cs] as mapped by [f], in the same order. *) val map : (char -> char) -> 'a rd t -> rdwr t (** [map f cs] is [cs'] with [cs'.[i] = f cs.[i]] for all indices [i] of [cs]. [f] is invoked in increasing index order. *) val mapi : (int -> char -> char) -> 'a rd t -> rdwr t (** [map f cs] is [cs'] with [cs'.[i] = f i cs.[i]] for all indices [i] of [cs]. [f] is invoked in increasing index order. *) ocaml-cstruct-6.2.0/lib/cstruct_sexp.ml000066400000000000000000000026341437471254600201470ustar00rootroot00000000000000(* * Copyright (c) 2012-2019 Anil Madhavapeddy * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) open Sexplib type buffer = Cstruct.buffer type t = Cstruct.t let buffer_of_sexp b = Conv.bigstring_of_sexp b let sexp_of_buffer b = Conv.sexp_of_bigstring b let t_of_sexp = function | Sexp.Atom str -> let n = String.length str in let t = Cstruct.create_unsafe n in Cstruct.blit_from_string str 0 t 0 n ; t | sexp -> Conv.of_sexp_error "Cstruct.t_of_sexp: atom needed" sexp let sexp_of_t t = let n = Cstruct.length t in let str = Bytes.create n in Cstruct.blit_to_bytes t 0 str 0 n ; (* The following call is safe, since str is not visible elsewhere. *) Sexp.Atom (Bytes.unsafe_to_string str) ocaml-cstruct-6.2.0/lib/cstruct_sexp.mli000066400000000000000000000032151437471254600203140ustar00rootroot00000000000000(* * Copyright (c) 2012-2019 Anil Madhavapeddy * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) (** Sexpression serialisers for {!Cstruct.t} values *) type buffer = Cstruct.buffer (** [buffer] is an alias for the corresponding {!type:Cstruct.buffer} type *) val sexp_of_buffer : Cstruct.buffer -> Sexplib.Sexp.t (** [sexp_of_buffer b] returns the s-expression representation of the raw memory buffer [b] *) val buffer_of_sexp : Sexplib.Sexp.t -> Cstruct.buffer (** [buffer_of_sexp s] returns a fresh memory buffer from the s-expression [s]. [s] should have been constructed using {!sexp_of_buffer}. *) type t = Cstruct.t (** [t] is an alias for the corresponding {!Cstruct.t} type *) val sexp_of_t : t -> Sexplib.Sexp.t (** [sexp_of_t t] returns the s-expression representation of the Cstruct [t] *) val t_of_sexp : Sexplib.Sexp.t -> t (** [t_of_sexp s] returns a fresh {!Cstruct.t} that represents the s-expression previously serialised by {!sexp_of_t}. *) ocaml-cstruct-6.2.0/lib/cstruct_stubs.c000066400000000000000000000053541437471254600201440ustar00rootroot00000000000000/* * Copyright (c) 2012 Anil Madhavapeddy * Copyright (c) 2012 Pierre Chambart * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include #ifndef Bytes_val #define Bytes_val String_val #endif CAMLprim value caml_blit_bigstring_to_string(value val_buf1, value val_ofs1, value val_buf2, value val_ofs2, value val_len) { memcpy(Bytes_val(val_buf2) + Long_val(val_ofs2), (char*)Caml_ba_data_val(val_buf1) + Long_val(val_ofs1), Long_val(val_len)); return Val_unit; } CAMLprim value caml_blit_string_to_bigstring(value val_buf1, value val_ofs1, value val_buf2, value val_ofs2, value val_len) { memcpy((char*)Caml_ba_data_val(val_buf2) + Long_val(val_ofs2), String_val(val_buf1) + Long_val(val_ofs1), Long_val(val_len)); return Val_unit; } CAMLprim value caml_blit_bigstring_to_bigstring(value val_buf1, value val_ofs1, value val_buf2, value val_ofs2, value val_len) { memmove((char*)Caml_ba_data_val(val_buf2) + Long_val(val_ofs2), (char*)Caml_ba_data_val(val_buf1) + Long_val(val_ofs1), Long_val(val_len)); return Val_unit; } CAMLprim value caml_compare_bigstring(value val_buf1, value val_ofs1, value val_buf2, value val_ofs2, value val_len) { int res = memcmp((char*)Caml_ba_data_val(val_buf1) + Long_val(val_ofs1), (char*)Caml_ba_data_val(val_buf2) + Long_val(val_ofs2), Long_val(val_len)); return Val_int(res); } CAMLprim value caml_fill_bigstring(value val_buf, value val_ofs, value val_len, value val_byte) { memset((char*)Caml_ba_data_val(val_buf) + Long_val(val_ofs), Int_val(val_byte), Long_val(val_len)); return Val_unit; } CAMLprim value caml_check_alignment_bigstring(value val_buf, value val_ofs, value val_alignment) { uint64_t address = (uint64_t) ((char *)Caml_ba_data_val(val_buf) + Long_val(val_ofs)); uintnat alignment = Unsigned_long_val(val_alignment); return Val_bool(address % alignment == 0); } ocaml-cstruct-6.2.0/lib/dune000066400000000000000000000004711437471254600157420ustar00rootroot00000000000000(library (name cstruct) (public_name cstruct) (foreign_stubs (language c) (names cstruct_stubs)) (wrapped false) (js_of_ocaml (javascript_files cstruct.js)) (modules cstruct cstruct_cap)) (library (name cstruct_sexp) (public_name cstruct-sexp) (modules cstruct_sexp) (libraries cstruct sexplib)) ocaml-cstruct-6.2.0/lib_test/000077500000000000000000000000001437471254600161215ustar00rootroot00000000000000ocaml-cstruct-6.2.0/lib_test/bounds.ml000066400000000000000000000443041437471254600177520ustar00rootroot00000000000000(* * Copyright (c) 2014 Anil Madhavapeddy * Copyright (c) 2013 Citrix Systems Inc * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) let to_string { Cstruct.buffer; off; len } = Printf.sprintf "buffer length = %d; off=%d; len=%d" (Bigarray.Array1.dim buffer) off len (* Check we can create and use an empty cstruct *) let test_empty_cstruct () = let x = Cstruct.create 0 in Alcotest.(check int) "empty len" 0 (Cstruct.length x); let y = Cstruct.to_string x in Alcotest.(check string) "empty" "" y (* Check that we can't create a cstruct with a negative length *) let test_anti_cstruct () = try let x = Cstruct.create (-1) in failwith (Printf.sprintf "test_anti_cstruct: %s" (to_string x)) with Invalid_argument _ -> () (* Check we can shift in the +ve direction *) let test_positive_shift () = let x = Cstruct.create 1 in let y = Cstruct.shift x 1 in Alcotest.(check int) "positive shift" 0 (Cstruct.length y) (* Check that negative shifts are forbidden. *) let test_negative_shift () = let x = Cstruct.create 2 in let y = Cstruct.sub x 1 1 in try let z = Cstruct.shift x (-1) in failwith (Printf.sprintf "test_negative_shift/outer: %s" (to_string z)) with Invalid_argument _ -> try let z = Cstruct.shift y (-1) in failwith (Printf.sprintf "test_negative_shift/inner: %s" (to_string z)) with Invalid_argument _ -> () (* Check that an attempt to shift beyond the end of the buffer fails *) let test_bad_positive_shift () = let x = Cstruct.create 10 in try let y = Cstruct.shift x 11 in failwith (Printf.sprintf "test_bad_positive_shift: %s" (to_string y)) with Invalid_argument _ -> () (* Check that 'sub' works *) let test_sub () = let x = Cstruct.create 100 in let y = Cstruct.sub x 10 80 in Alcotest.(check int) "sub 1" 10 y.Cstruct.off; Alcotest.(check int) "sub 2" 80 y.Cstruct.len; let z = Cstruct.sub y 10 60 in Alcotest.(check int) "sub 3" 20 z.Cstruct.off; Alcotest.(check int) "sub 4" 60 z.Cstruct.len let test_sub_copy () = let x = Cstruct.create 100 in let y = Cstruct.sub_copy x 10 80 in Alcotest.(check int) "sub_copy 1" 0 y.Cstruct.off; Alcotest.(check int) "sub_copy 2" 80 y.Cstruct.len; let z = Cstruct.sub_copy y 10 60 in Alcotest.(check int) "sub_copy 3" 0 z.Cstruct.off; Alcotest.(check int) "sub_copy 4" 60 z.Cstruct.len; Cstruct.set_uint8 x 50 42; Alcotest.(check int) "x changed" 42 (Cstruct.get_uint8 x 50); Alcotest.(check int) "y unchanged" 0 (Cstruct.get_uint8 y 50); () let test_negative_sub () = let x = Cstruct.create 2 in let y = Cstruct.sub x 1 1 in try let z = Cstruct.sub x (-1) 0 in failwith (Printf.sprintf "test_negative_sub/outer: %s" (to_string z)) with Invalid_argument _ -> try let z = Cstruct.sub y (-1) 0 in failwith (Printf.sprintf "test_negative_sub/inner: %s" (to_string z)) with Invalid_argument _ -> () (* Check that 'sub' can't set 'len' too big *) let test_sub_len_too_big () = let x = Cstruct.create 0 in try let y = Cstruct.sub x 0 1 in failwith (Printf.sprintf "test_sub_len_too_big: %s" (to_string y)) with Invalid_argument _ -> () let test_sub_len_too_small () = let x = Cstruct.create 0 in try let y = Cstruct.sub x 0 (-1) in failwith (Printf.sprintf "test_sub_len_too_small: %s" (to_string y)) with Invalid_argument _ -> () let test_sub_offset_too_big () = let x = Cstruct.create 10 in begin try let y = Cstruct.sub x 11 0 in failwith (Printf.sprintf "test_sub_offset_too_big: %s" (to_string y)) with Invalid_argument _ -> () end; let y = Cstruct.sub x 1 9 in begin try let z = Cstruct.sub y 10 0 in failwith (Printf.sprintf "test_sub_offset_too_big: %s" (to_string z)) with Invalid_argument _ -> () end let test_of_bigarray_negative_params () = let ba = Bigarray.(Array1.create char c_layout 1) in try let x = Cstruct.of_bigarray ~off:(-1) ba in failwith (Printf.sprintf "test_of_bigarray_negative_params: negative ~off: %s" (to_string x)) with Invalid_argument _ -> try let x = Cstruct.of_bigarray ~len:(-1) ba in failwith (Printf.sprintf "test_of_bigarray_negative_params: negative ~len: %s" (to_string x)) with Invalid_argument _ -> () let test_of_bigarray_large_offset () = let ba = Bigarray.(Array1.create char c_layout 1) in let _ = Cstruct.of_bigarray ~off:1 ~len:0 ba and _ = Cstruct.of_bigarray ~off:1 ba in try let x = Cstruct.of_bigarray ~off:2 ~len:0 ba in failwith (Printf.sprintf "test_of_bigarray_large_offset: %s" (to_string x)) with Invalid_argument _ -> try let x = Cstruct.of_bigarray ~off:2 ba in failwith (Printf.sprintf "test_of_bigarray_large_offset: large ~off: %s" (to_string x)) with Invalid_argument _ -> () let test_of_bigarray_large_length () = let ba = Bigarray.(Array1.create char c_layout 1) in try let x = Cstruct.of_bigarray ~off:0 ~len:2 ba in failwith (Printf.sprintf "test_of_bigarray_large_length: %s" (to_string x)) with Invalid_argument _ -> try let x = Cstruct.of_bigarray ~off:1 ~len:1 ba in failwith (Printf.sprintf "test_of_bigarray_large_length: %s" (to_string x)) with Invalid_argument _ -> try let x = Cstruct.of_bigarray ~off:2 ~len:0 ba in failwith (Printf.sprintf "test_of_bigarray_large_length: %s" (to_string x)) with Invalid_argument _ -> try let x = Cstruct.of_bigarray ~off:2 ba in failwith (Printf.sprintf "test_of_bigarray_large_length: %s" (to_string x)) with Invalid_argument _ -> () let test_blit_offset_too_big () = let x = Cstruct.create 1 in let y = Cstruct.create 1 in try Cstruct.blit x 2 y 1 1; failwith "test_blit_offset_too_big" with Invalid_argument _ -> () let test_blit_offset_too_small () = let x = Cstruct.create 1 in let y = Cstruct.create 1 in try Cstruct.blit x (-1) y 1 1; failwith "test_blit_offset_too_small" with Invalid_argument _ -> () let test_blit_dst_offset_too_big () = let x = Cstruct.create 1 in let y = Cstruct.create 1 in try Cstruct.blit x 1 y 2 1; failwith "test_blit_dst_offset_too_big" with Invalid_argument _ -> () let test_blit_dst_offset_too_small () = let x = Cstruct.create 1 in let y = Cstruct.create 1 in try Cstruct.blit x 1 y (-1) 1; failwith "test_blit_dst_offset_too_small" with Invalid_argument _ -> () let test_blit_dst_offset_negative () = let x = Cstruct.create 1 in let y = Cstruct.create 1 in try Cstruct.blit x 0 y (-1) 1; failwith "test_blit_dst_offset_negative" with Invalid_argument _ -> () let test_blit_len_too_big () = let x = Cstruct.create 1 in let y = Cstruct.create 2 in try Cstruct.blit x 0 y 0 2; failwith "test_blit_len_too_big" with Invalid_argument _ -> () let test_blit_len_too_big2 () = let x = Cstruct.create 2 in let y = Cstruct.create 1 in try Cstruct.blit x 0 y 0 2; failwith "test_blit_len_too_big2" with Invalid_argument _ -> () let test_blit_len_too_small () = let x = Cstruct.create 1 in let y = Cstruct.create 1 in try Cstruct.blit x 0 y 0 (-1); failwith "test_blit_len_too_small" with Invalid_argument _ -> () let test_view_bounds_too_small () = let src = Cstruct.create 4 in let dst = Cstruct.create 4 in let dst_small = Cstruct.sub dst 0 2 in try Cstruct.blit src 0 dst_small 0 3; failwith "test_view_bounds_too_small" with Invalid_argument _ -> () let test_view_bounds_too_small_get_u8 () = let x = Cstruct.create 2 in let x' = Cstruct.sub x 0 1 in try let _ = Cstruct.get_uint8 x' 1 in failwith "test_view_bounds_too_small_get_u8" with Invalid_argument _ -> () let test_view_bounds_too_small_get_char () = let x = Cstruct.create 2 in let x' = Cstruct.sub x 0 1 in try let _ = Cstruct.get_char x' 1 in failwith "test_view_bounds_too_small_get_char" with Invalid_argument _ -> () let test_view_bounds_too_small_get_be16 () = let x = Cstruct.create 4 in let x' = Cstruct.sub x 0 1 in try let _ = Cstruct.BE.get_uint16 x' 0 in failwith "test_view_bounds_too_small_get_be16" with Invalid_argument _ -> () let test_view_bounds_too_small_get_be32 () = let x = Cstruct.create 8 in let x' = Cstruct.sub x 2 5 in try let _ = Cstruct.BE.get_uint32 x' 2 in failwith "test_view_bounds_too_small_get_be32" with Invalid_argument _ -> () let test_view_bounds_too_small_get_be64 () = let x = Cstruct.create 9 in let x' = Cstruct.sub x 1 5 in try let _ = Cstruct.BE.get_uint64 x' 0 in failwith "test_view_bounds_too_small_get_be64" with Invalid_argument _ -> () let test_view_bounds_too_small_get_le16 () = let x = Cstruct.create 4 in let x' = Cstruct.sub x 0 1 in try let _ = Cstruct.LE.get_uint16 x' 0 in failwith "test_view_bounds_too_small_get_le16" with Invalid_argument _ -> () let test_view_bounds_too_small_get_le32 () = let x = Cstruct.create 8 in let x' = Cstruct.sub x 2 5 in try let _ = Cstruct.LE.get_uint32 x' 2 in failwith "test_view_bounds_too_small_get_le32" with Invalid_argument _ -> () let test_view_bounds_too_small_get_le64 () = let x = Cstruct.create 9 in let x' = Cstruct.sub x 1 5 in try let _ = Cstruct.LE.get_uint64 x' 0 in failwith "test_view_bounds_too_small_get_le64" with Invalid_argument _ -> () let test_view_bounds_too_small_get_he16 () = let x = Cstruct.create 4 in let x' = Cstruct.sub x 0 1 in try let _ = Cstruct.HE.get_uint16 x' 0 in failwith "test_view_bounds_too_small_get_he16" with Invalid_argument _ -> () let test_view_bounds_too_small_get_he32 () = let x = Cstruct.create 8 in let x' = Cstruct.sub x 2 5 in try let _ = Cstruct.HE.get_uint32 x' 2 in failwith "test_view_bounds_too_small_get_he32" with Invalid_argument _ -> () let test_view_bounds_too_small_get_he64 () = let x = Cstruct.create 9 in let x' = Cstruct.sub x 1 5 in try let _ = Cstruct.HE.get_uint64 x' 0 in failwith "test_view_bounds_too_small_get_he64" with Invalid_argument _ -> () let test_lenv_overflow () = if Sys.word_size = 32 then ( (* free-up some space *) Gc.major (); let b = Cstruct.create max_int and c = Cstruct.create 3 in try let _ = Cstruct.lenv [b; b; c] in failwith "test_lenv_overflow" with Invalid_argument _ -> ()) let test_copyv_overflow () = if Sys.word_size = 32 then ( (* free-up some space *) Gc.major (); let b = Cstruct.create max_int and c = Cstruct.create 3 in try let _ = Cstruct.copyv [b; b; c] in failwith "test_copyv_overflow" with Invalid_argument _ -> ()) (* Steamroll over a buffer and a contained subview, checking that only the * contents of the subview is visible. *) let test_subview_containment_get_char, test_subview_containment_get_8, test_subview_containment_get_be16, test_subview_containment_get_be32, test_subview_containment_get_be64, test_subview_containment_get_le16, test_subview_containment_get_le32, test_subview_containment_get_le64, test_subview_containment_get_he16, test_subview_containment_get_he32, test_subview_containment_get_he64 = let open Cstruct in let test get zero () = let x = create 24 in let x' = sub x 8 8 in for i = 0 to length x - 1 do set_uint8 x i 0xff done ; for i = 0 to length x' - 1 do set_uint8 x' i 0x00 done ; for i = -8 to 8 do try let v = get x' i in if v <> zero then failwith "test_subview_containment_get" with Invalid_argument _ -> () done in test get_char '\000', test get_uint8 0, test BE.get_uint16 0, test BE.get_uint32 0l, test BE.get_uint64 0L, test LE.get_uint16 0, test LE.get_uint32 0l, test LE.get_uint64 0L, test HE.get_uint16 0, test HE.get_uint32 0l, test HE.get_uint64 0L (* Steamroll over a buffer and a contained subview, checking that only the * contents of the subview is writable. *) let test_subview_containment_set_char, test_subview_containment_set_8, test_subview_containment_set_be16, test_subview_containment_set_be32, test_subview_containment_set_be64, test_subview_containment_set_le16, test_subview_containment_set_le32, test_subview_containment_set_le64, test_subview_containment_set_he16, test_subview_containment_set_he32, test_subview_containment_set_he64 = let open Cstruct in let test set ff () = let x = create 24 in let x' = sub x 8 8 in for i = 0 to length x - 1 do set_uint8 x i 0x00 done ; for i = -8 to 8 do try set x' i ff with Invalid_argument _ -> () done; let acc = ref 0 in for i = 0 to length x - 1 do acc := !acc + get_uint8 x i done ; if !acc <> (length x' * 0xff) then failwith "test_subview_containment_set" in test set_char '\255', test set_uint8 0xff, test BE.set_uint16 0xffff, test BE.set_uint32 0xffffffffl, test BE.set_uint64 0xffffffffffffffffL, test LE.set_uint16 0xffff, test LE.set_uint32 0xffffffffl, test LE.set_uint64 0xffffffffffffffffL, test HE.set_uint16 0xffff, test HE.set_uint32 0xffffffffl, test HE.set_uint64 0xffffffffffffffffL let regression_244 () = let whole = Cstruct.create 44943 in let empty = Cstruct.sub whole 0 0 in try let _big = Cstruct.sub empty 0 204 in Alcotest.fail "could get a bigger buffer via sub" with Invalid_argument _ -> () let suite = [ "test empty cstruct", `Quick, test_empty_cstruct; "test anti cstruct", `Quick, test_anti_cstruct; "test positive shift", `Quick, test_positive_shift; "test negative shift", `Quick, test_negative_shift; "test bad positive shift", `Quick, test_bad_positive_shift; "test sub", `Quick, test_sub; "test sub_copy", `Quick, test_sub_copy; "test negative sub", `Quick, test_negative_sub; "test sub len too big", `Quick, test_sub_len_too_big; "test sub len too small", `Quick, test_sub_len_too_small; "test sub offset too big", `Quick, test_sub_offset_too_big; "test of_bigarray negative params", `Quick, test_of_bigarray_negative_params; "test of_bigarray large offset", `Quick, test_of_bigarray_large_offset; "test of_bigarray large length", `Quick, test_of_bigarray_large_length; "test blit offset too big", `Quick, test_blit_offset_too_big; "test blit offset too small", `Quick, test_blit_offset_too_small; "test blit dst offset too big", `Quick, test_blit_dst_offset_too_big; "test blit dst offset too small", `Quick, test_blit_dst_offset_too_small; "test blit dst offset negative", `Quick, test_blit_dst_offset_negative; "test blit len too big", `Quick, test_blit_len_too_big; "test blit len too big2", `Quick, test_blit_len_too_big2; "test blit len too small", `Quick, test_blit_len_too_small; "test view bounds too small", `Quick, test_view_bounds_too_small; "test_view_bounds_too_small_get_u8" , `Quick, test_view_bounds_too_small_get_u8; "test_view_bounds_too_small_get_char" , `Quick, test_view_bounds_too_small_get_char; "test_view_bounds_too_small_get_be16" , `Quick, test_view_bounds_too_small_get_be16; "test_view_bounds_too_small_get_be32" , `Quick, test_view_bounds_too_small_get_be32; "test_view_bounds_too_small_get_be64" , `Quick, test_view_bounds_too_small_get_be64; "test_view_bounds_too_small_get_le16" , `Quick, test_view_bounds_too_small_get_le16; "test_view_bounds_too_small_get_le32" , `Quick, test_view_bounds_too_small_get_le32; "test_view_bounds_too_small_get_le64" , `Quick, test_view_bounds_too_small_get_le64; "test_view_bounds_too_small_get_he16" , `Quick, test_view_bounds_too_small_get_he16; "test_view_bounds_too_small_get_he32" , `Quick, test_view_bounds_too_small_get_he32; "test_view_bounds_too_small_get_he64" , `Quick, test_view_bounds_too_small_get_he64; "test_lenv_overflow", `Quick, test_lenv_overflow; "test_copyv_overflow", `Quick, test_copyv_overflow; "test_subview_containment_get_char", `Quick, test_subview_containment_get_char; "test_subview_containment_get_8" , `Quick, test_subview_containment_get_8; "test_subview_containment_get_be16", `Quick, test_subview_containment_get_be16; "test_subview_containment_get_be32", `Quick, test_subview_containment_get_be32; "test_subview_containment_get_be64", `Quick, test_subview_containment_get_be64; "test_subview_containment_get_le16", `Quick, test_subview_containment_get_le16; "test_subview_containment_get_le32", `Quick, test_subview_containment_get_le32; "test_subview_containment_get_le64", `Quick, test_subview_containment_get_le64; "test_subview_containment_get_le16", `Quick, test_subview_containment_get_he16; "test_subview_containment_get_le32", `Quick, test_subview_containment_get_he32; "test_subview_containment_get_le64", `Quick, test_subview_containment_get_he64; "test_subview_containment_set_char", `Quick, test_subview_containment_set_char; "test_subview_containment_set_8" , `Quick, test_subview_containment_set_8; "test_subview_containment_set_be16", `Quick, test_subview_containment_set_be16; "test_subview_containment_set_be32", `Quick, test_subview_containment_set_be32; "test_subview_containment_set_be64", `Quick, test_subview_containment_set_be64; "test_subview_containment_set_le16", `Quick, test_subview_containment_set_le16; "test_subview_containment_set_le32", `Quick, test_subview_containment_set_le32; "test_subview_containment_set_le64", `Quick, test_subview_containment_set_le64; "test_subview_containment_set_le16", `Quick, test_subview_containment_set_he16; "test_subview_containment_set_le32", `Quick, test_subview_containment_set_he32; "test_subview_containment_set_le64", `Quick, test_subview_containment_set_he64; "regression 244", `Quick, regression_244; ] ocaml-cstruct-6.2.0/lib_test/bounds.mli000066400000000000000000000000501437471254600201110ustar00rootroot00000000000000val suite: unit Alcotest.test_case list ocaml-cstruct-6.2.0/lib_test/dune000066400000000000000000000005101437471254600167730ustar00rootroot00000000000000(executable (libraries cstruct alcotest cstruct-sexp) (modules bounds tests) (name tests)) (executable (libraries cstruct alcotest) (modules parse) (name parse)) (rule (alias runtest) (package cstruct-sexp) (action (run ./tests.exe -e))) (rule (alias runtest) (package cstruct) (action (run ./parse.exe -e))) ocaml-cstruct-6.2.0/lib_test/parse.ml000066400000000000000000001135371437471254600175770ustar00rootroot00000000000000(* (c) 2016 Daniel C. Bünzli (c) 2020 Romain Calascibetta *) open Cstruct let cstruct = let pp ppf x = Format.fprintf ppf "%S" (Cstruct.to_string x) in let equal a b = String.equal (Cstruct.to_string a) (Cstruct.to_string b) in Alcotest.testable pp equal module Alcotest = struct include Alcotest let string = Alcotest.testable (Fmt.fmt "%S") String.equal end let misc = Alcotest.test_case "misc" `Quick @@ fun () -> Alcotest.(check cstruct) "empty" empty (Cstruct.create 0) ; Alcotest.(check cstruct) "abc" (string "abc") (Cstruct.of_string "abc") ; Alcotest.(check cstruct) "abc" (string ~off:0 ~len:1 "abc") (Cstruct.of_string "a") ; Alcotest.(check cstruct) "abc" (string ~off:1 ~len:1 "abc") (Cstruct.of_string "b") ; Alcotest.(check cstruct) "abc" (string ~off:1 ~len:2 "abc") (Cstruct.of_string "bc") ; Alcotest.(check cstruct) "abc" (string ~off:2 ~len:1 "abc") (Cstruct.of_string "c") ; Alcotest.(check cstruct) "abc" (string ~off:3 ~len:0 "abc") (Cstruct.create 0) ; let sub = string ~off:2 ~len:1 "abc" in Alcotest.(check int) "start_pos" (start_pos sub) 2 ; Alcotest.(check int) "stop_pos" (stop_pos sub) 3 ; Alcotest.(check int) "length" (length sub) 1 ; let index_out_of_bounds = Invalid_argument "index out of bounds" in Alcotest.check_raises "get" index_out_of_bounds @@ fun () -> ignore @@ get sub 3 ; Alcotest.check_raises "get" index_out_of_bounds @@ fun () -> ignore @@ get sub 2 ; Alcotest.check_raises "get" index_out_of_bounds @@ fun () -> ignore @@ get sub 1 ; Alcotest.(check char) "get" (get sub 0) 'c' ; Alcotest.(check int) "get_byte" (get_byte sub 0) 0x63 ; ;; let head = Alcotest.test_case "head" `Quick @@ fun () -> let { Cstruct.buffer= v; _ } = Cstruct.of_string "abc" in let empty = buffer ~off:2 ~len:0 v in let bc = buffer ~off:1 ~len:2 v in Alcotest.(check (option char)) "empty" (head empty) None ; Alcotest.(check (option char)) "empty" (head ~rev:true empty) None ; Alcotest.(check (option char)) "bc" (head bc) (Some 'b') ; Alcotest.(check (option char)) "bc" (head ~rev:true bc) (Some 'c') ; ;; let start = Alcotest.test_case "start" `Quick @@ fun () -> let empty_pos cs pos = Alcotest.(check int) "length" (length cs) 0 ; Alcotest.(check int) "start_pos" (start_pos cs) pos in let { Cstruct.buffer= abc; _ } = Cstruct.of_string "abc" in empty_pos (start @@ string "") 0 ; empty_pos (start @@ buffer ~off:0 ~len:0 abc) 0 ; empty_pos (start @@ buffer ~off:0 ~len:1 abc) 0 ; empty_pos (start @@ buffer ~off:0 ~len:2 abc) 0 ; empty_pos (start @@ buffer ~off:0 ~len:3 abc) 0 ; empty_pos (start @@ buffer ~off:1 ~len:0 abc) 1 ; empty_pos (start @@ buffer ~off:1 ~len:1 abc) 1 ; empty_pos (start @@ buffer ~off:1 ~len:2 abc) 1 ; empty_pos (start @@ buffer ~off:2 ~len:0 abc) 2 ; empty_pos (start @@ buffer ~off:2 ~len:1 abc) 2 ; empty_pos (start @@ buffer ~off:3 ~len:0 abc) 3 ; ;; let stop = Alcotest.test_case "stop" `Quick @@ fun () -> let empty_pos cs pos = Alcotest.(check int) "length" (length cs) 0 ; Alcotest.(check int) "start_pos" (start_pos cs) pos in let { Cstruct.buffer= abc; _ } = Cstruct.of_string "abc" in empty_pos (stop @@ string "") 0 ; empty_pos (stop @@ buffer ~off:0 ~len:0 abc) 0 ; empty_pos (stop @@ buffer ~off:0 ~len:1 abc) 1 ; empty_pos (stop @@ buffer ~off:0 ~len:2 abc) 2 ; empty_pos (stop @@ buffer ~off:0 ~len:3 abc) 3 ; empty_pos (stop @@ buffer ~off:1 ~len:0 abc) 1 ; empty_pos (stop @@ buffer ~off:1 ~len:1 abc) 2 ; empty_pos (stop @@ buffer ~off:1 ~len:2 abc) 3 ; empty_pos (stop @@ buffer ~off:2 ~len:0 abc) 2 ; empty_pos (stop @@ buffer ~off:2 ~len:1 abc) 3 ; empty_pos (stop @@ buffer ~off:3 ~len:0 abc) 3 ; ;; let tail = Alcotest.test_case "tail" `Quick @@ fun () -> let empty_pos cs pos = Alcotest.(check int) "length" (length cs) 0 ; Alcotest.(check int) "start_pos" (start_pos cs) pos in let { Cstruct.buffer= abc; _ } = Cstruct.of_string "abc" in empty_pos (tail @@ string "") 0 ; empty_pos (tail @@ buffer ~off:0 ~len:0 abc) 0 ; empty_pos (tail @@ buffer ~off:0 ~len:1 abc) 1 ; Alcotest.(check cstruct) "b" (tail @@ buffer ~off:0 ~len:2 abc) (string "b") ; Alcotest.(check cstruct) "bc" (tail @@ buffer ~off:0 ~len:3 abc) (string "bc") ; empty_pos (tail @@ buffer ~off:1 ~len:0 abc) 1 ; empty_pos (tail @@ buffer ~off:1 ~len:1 abc) 2 ; Alcotest.(check cstruct) "c" (tail @@ buffer ~off:1 ~len:2 abc) (string "c") ; empty_pos (tail @@ buffer ~off:2 ~len:0 abc) 2 ; empty_pos (tail @@ buffer ~off:2 ~len:1 abc) 3 ; empty_pos (tail @@ buffer ~off:3 ~len:0 abc) 3 ; ;; let is_empty = Alcotest.test_case "is_empty" `Quick @@ fun () -> Alcotest.(check bool) "empty" (is_empty (string "")) true ; let { Cstruct.buffer= abcd; _ } = Cstruct.of_string "abcd" in let { Cstruct.buffer= huyi; _ } = Cstruct.of_string "huyi" in Alcotest.(check bool) "empty" (is_empty (buffer ~off:4 ~len:0 abcd)) true ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:0 ~len:0 huyi)) true ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:0 ~len:1 huyi)) false ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:0 ~len:2 huyi)) false ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:0 ~len:3 huyi)) false ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:0 ~len:4 huyi)) false ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:1 ~len:0 abcd)) true ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:1 ~len:1 huyi)) false ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:1 ~len:2 huyi)) false ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:1 ~len:3 huyi)) false ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:2 ~len:0 abcd)) true ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:2 ~len:1 huyi)) false ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:2 ~len:2 huyi)) false ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:3 ~len:0 abcd)) true ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:3 ~len:1 huyi)) false ; Alcotest.(check bool) "empty" (is_empty (buffer ~off:4 ~len:0 huyi)) true ; ;; let is_prefix = Alcotest.test_case "is_prefix" `Quick @@ fun () -> let { Cstruct.buffer= ugoadfj; _ } = Cstruct.of_string "ugoadf" in let { Cstruct.buffer= dfkdjf; _ } = Cstruct.of_string "dfkdjf" in let { Cstruct.buffer= abhablablu; _ } = Cstruct.of_string "abhablablu" in let { Cstruct.buffer= hadfdffdf; _ } = Cstruct.of_string "hadfdffdf" in let { Cstruct.buffer= hadhabfdffdf; _ } = Cstruct.of_string "hadhabfdffdf" in let { Cstruct.buffer= iabla; _ } = Cstruct.of_string "iabla" in let empty0 = buffer ~off:3 ~len:0 ugoadfj in let empty1 = buffer ~off:4 ~len:0 dfkdjf in let habla = buffer ~off:2 ~len:5 abhablablu in let h = buffer ~off:0 ~len:1 hadfdffdf in let ha = buffer ~off:0 ~len:2 hadfdffdf in let hab = buffer ~off:3 ~len:3 hadhabfdffdf in let abla = buffer ~off:1 ~len:4 iabla in Alcotest.(check cstruct) "empty" empty0 (Cstruct.of_string "") ; Alcotest.(check cstruct) "empty" empty1 (Cstruct.of_string "") ; Alcotest.(check cstruct) "habla" habla (Cstruct.of_string "habla") ; Alcotest.(check cstruct) "h" h (Cstruct.of_string "h") ; Alcotest.(check cstruct) "ha" ha (Cstruct.of_string "ha") ; Alcotest.(check cstruct) "hab" hab (Cstruct.of_string "hab") ; Alcotest.(check cstruct) "abla" abla (Cstruct.of_string "abla") ; Alcotest.(check bool) "is_prefix empty0 empty0" (is_prefix ~affix:empty0 empty1) true ; Alcotest.(check bool) "is_prefix empty0 habla" (is_prefix ~affix:empty0 habla) true ; Alcotest.(check bool) "is_prefix ha empty1" (is_prefix ~affix:ha empty1) false ; Alcotest.(check bool) "is_prefix ha h" (is_prefix ~affix:ha h) false ; Alcotest.(check bool) "is_prefix ha ha" (is_prefix ~affix:ha ha) true ; Alcotest.(check bool) "is_prefix ha hab" (is_prefix ~affix:ha hab) true ; Alcotest.(check bool) "is_prefix ha habla" (is_prefix ~affix:ha habla) true ; Alcotest.(check bool) "is_prefix ha abla" (is_prefix ~affix:ha abla) false ; ;; let is_infix = Alcotest.test_case "is_infix" `Quick @@ fun () -> let { Cstruct.buffer= ugoadfj; _ } = Cstruct.of_string "ugoadfj" in let { Cstruct.buffer= dfkdjf; _ } = Cstruct.of_string "dfkdjf" in let { Cstruct.buffer= aasdflablu; _ } = Cstruct.of_string "aasdflablu" in let { Cstruct.buffer= cda; _ } = Cstruct.of_string "cda" in let { Cstruct.buffer= h; _ } = Cstruct.of_string "h" in let { Cstruct.buffer= uhadfdffdf; _ } = Cstruct.of_string "uhadfdffdf" in let { Cstruct.buffer= ah; _ } = Cstruct.of_string "ah" in let { Cstruct.buffer= aaaha; _ } = Cstruct.of_string "aaaha" in let { Cstruct.buffer= ahaha; _ } = Cstruct.of_string "ahaha" in let { Cstruct.buffer= hahbdfdf; _ } = Cstruct.of_string "hahbdfdf" in let { Cstruct.buffer= blhahbdfdf; _ } = Cstruct.of_string "blhahbdfdf" in let { Cstruct.buffer= fblhahbdfdfl; _ } = Cstruct.of_string "fblhahbdfdfl" in let empty0 = buffer ~off:1 ~len:0 ugoadfj in let empty1 = buffer ~off:2 ~len:0 dfkdjf in let asdf = buffer ~off:1 ~len:4 aasdflablu in let a = buffer ~off:2 ~len:1 cda in let h = buffer ~off:0 ~len:1 h in let ha = buffer ~off:1 ~len:2 uhadfdffdf in let ah = buffer ~off:0 ~len:2 ah in let aha = buffer ~off:2 ~len:3 aaaha in let haha = buffer ~off:1 ~len:4 ahaha in let hahb = buffer ~off:0 ~len:4 hahbdfdf in let blhahb = buffer ~off:0 ~len:6 blhahbdfdf in let blha = buffer ~off:1 ~len:4 fblhahbdfdfl in let blh = buffer ~off:1 ~len:3 fblhahbdfdfl in Alcotest.(check cstruct) "asdf" asdf (Cstruct.of_string "asdf") ; Alcotest.(check cstruct) "ha" ha (Cstruct.of_string "ha") ; Alcotest.(check cstruct) "h" h (Cstruct.of_string "h") ; Alcotest.(check cstruct) "a" a (Cstruct.of_string "a") ; Alcotest.(check cstruct) "aha" aha (Cstruct.of_string "aha") ; Alcotest.(check cstruct) "haha" haha (Cstruct.of_string "haha") ; Alcotest.(check cstruct) "hahb" hahb (Cstruct.of_string "hahb") ; Alcotest.(check cstruct) "blhahb" blhahb (Cstruct.of_string "blhahb") ; Alcotest.(check cstruct) "blha" blha (Cstruct.of_string "blha") ; Alcotest.(check cstruct) "blh" blh (Cstruct.of_string "blh") ; Alcotest.(check bool) "is_infix empty0 empty1" (is_infix ~affix:empty0 empty1) true ; Alcotest.(check bool) "is_infix empty0 asdf" (is_infix ~affix:empty0 asdf) true ; Alcotest.(check bool) "is_infix empty0 ha" (is_infix ~affix:empty0 ha) true ; Alcotest.(check bool) "is_infix ha empty1" (is_infix ~affix:ha empty1) false ; Alcotest.(check bool) "is_infix ha a" (is_infix ~affix:ha a) false ; Alcotest.(check bool) "is_infix ha h" (is_infix ~affix:ha h) false ; Alcotest.(check bool) "is_infix ha ah" (is_infix ~affix:ha ah) false ; Alcotest.(check bool) "is_infix ha ha" (is_infix ~affix:ha ha) true ; Alcotest.(check bool) "is_infix ha aha" (is_infix ~affix:ha aha) true ; Alcotest.(check bool) "is_infix ha haha" (is_infix ~affix:ha haha) true ; Alcotest.(check bool) "is_infix ha hahb" (is_infix ~affix:ha hahb) true ; Alcotest.(check bool) "is_infix ha blhahb" (is_infix ~affix:ha blhahb) true ; Alcotest.(check bool) "is_infix ha blha" (is_infix ~affix:ha blha) true ; Alcotest.(check bool) "is_infix ha blh" (is_infix ~affix:ha blh) false ; ;; let is_suffix = Alcotest.test_case "is_suffix" `Quick @@ fun () -> let { Cstruct.buffer= ugoadfj; _ } = Cstruct.of_string "ugoadfj" in let { Cstruct.buffer= dfkdjf; _ } = Cstruct.of_string "dfkdjf" in let { Cstruct.buffer= aasdflablu; _ } = Cstruct.of_string "aasdflablu" in let { Cstruct.buffer= cda; _ } = Cstruct.of_string "cda" in let { Cstruct.buffer= h; _ } = Cstruct.of_string "h" in let { Cstruct.buffer= uhadfdffdf; _ } = Cstruct.of_string "uhadfdffdf" in let { Cstruct.buffer= ah; _ } = Cstruct.of_string "ah" in let { Cstruct.buffer= aaaha; _ } = Cstruct.of_string "aaaha" in let { Cstruct.buffer= ahaha; _ } = Cstruct.of_string "ahaha" in let { Cstruct.buffer= hahbdfdf; _ } = Cstruct.of_string "hahbdfdf" in let empty0 = buffer ~off:1 ~len:0 ugoadfj in let empty1 = buffer ~off:2 ~len:0 dfkdjf in let asdf = buffer ~off:1 ~len:4 aasdflablu in let a = buffer ~off:2 ~len:1 cda in let h = buffer ~off:0 ~len:1 h in let ha = buffer ~off:1 ~len:2 uhadfdffdf in let ah = buffer ~off:0 ~len:2 ah in let aha = buffer ~off:2 ~len:3 aaaha in let haha = buffer ~off:1 ~len:4 ahaha in let hahb = buffer ~off:0 ~len:4 hahbdfdf in Alcotest.(check cstruct) "asdf" asdf (Cstruct.of_string "asdf") ; Alcotest.(check cstruct) "ha" ha (Cstruct.of_string "ha") ; Alcotest.(check cstruct) "h" h (Cstruct.of_string "h") ; Alcotest.(check cstruct) "a" a (Cstruct.of_string "a") ; Alcotest.(check cstruct) "aha" aha (Cstruct.of_string "aha") ; Alcotest.(check cstruct) "haha" haha (Cstruct.of_string "haha") ; Alcotest.(check cstruct) "hahb" hahb (Cstruct.of_string "hahb") ; Alcotest.(check bool) "is_suffix empty0 empty1" (is_suffix ~affix:empty0 empty1) true ; Alcotest.(check bool) "is_suffix empty0 asdf" (is_suffix ~affix:empty0 asdf) true ; Alcotest.(check bool) "is_suffix ha empty1" (is_suffix ~affix:ha empty1) false ; Alcotest.(check bool) "is_suffix ha a" (is_suffix ~affix:ha a) false ; Alcotest.(check bool) "is_suffix ha h" (is_suffix ~affix:ha h) false ; Alcotest.(check bool) "is_suffix ha ah" (is_suffix ~affix:ha ah) false ; Alcotest.(check bool) "is_suffix ha ha" (is_suffix ~affix:ha ha) true ; Alcotest.(check bool) "is_suffix ha aha" (is_suffix ~affix:ha aha) true ; Alcotest.(check bool) "is_suffix ha haha" (is_suffix ~affix:ha haha) true ; Alcotest.(check bool) "is_suffix ha hahb" (is_suffix ~affix:ha hahb) false ; ;; let () = Printexc.record_backtrace true let for_all = Alcotest.test_case "for_all" `Quick @@ fun () -> let { Cstruct.buffer= asldfksaf; _ } = Cstruct.of_string "asldfksaf" in let { Cstruct.buffer= sf123df; _ } = Cstruct.of_string "sf123df" in let { Cstruct.buffer= _412; _ } = Cstruct.of_string "412" in let { Cstruct.buffer= aaa142; _ } = Cstruct.of_string "aaa142" in let { Cstruct.buffer= aad124; _ } = Cstruct.of_string "aad124" in let empty = buffer ~off:3 ~len:0 asldfksaf in let s123 = buffer ~off:2 ~len:3 sf123df in let s412 = buffer _412 in let s142 = buffer ~off:3 aaa142 in let s124 = buffer ~off:3 aad124 in Alcotest.(check cstruct) "empty" empty (Cstruct.of_string "") ; Alcotest.(check cstruct) "123" s123 (Cstruct.of_string "123") ; Alcotest.(check cstruct) "412" s412 (Cstruct.of_string "412") ; Alcotest.(check cstruct) "142" s142 (Cstruct.of_string "142") ; Alcotest.(check cstruct) "124" s124 (Cstruct.of_string "124") ; Alcotest.(check bool) "for_all" (for_all (fun _ -> false) empty) true ; Alcotest.(check bool) "for_all" (for_all (fun _ -> true) empty) true ; Alcotest.(check bool) "for_all" (for_all (fun c -> Char.code c < 0x34) s123) true ; Alcotest.(check bool) "for_all" (for_all (fun c -> Char.code c < 0x34) s412) false ; Alcotest.(check bool) "for_all" (for_all (fun c -> Char.code c < 0x34) s142) false ; Alcotest.(check bool) "for_all" (for_all (fun c -> Char.code c < 0x34) s124) false ; ;; let exists = Alcotest.test_case "exists" `Quick @@ fun () -> let { Cstruct.buffer= asldfksaf; _ } = Cstruct.of_string "asldfksaf" in let { Cstruct.buffer= a541; _ } = Cstruct.of_string "a541" in let { Cstruct.buffer= a154; _ } = Cstruct.of_string "a154" in let { Cstruct.buffer= _654adf; _ } = Cstruct.of_string "654adf" in let empty = buffer ~off:3 ~len:0 asldfksaf in let s541 = buffer ~off:1 ~len:3 a541 in let s154 = buffer ~off:1 a154 in let s654 = buffer ~len:3 _654adf in Alcotest.(check cstruct) "empty" empty (Cstruct.of_string "") ; Alcotest.(check cstruct) "541" s541 (Cstruct.of_string "541") ; Alcotest.(check cstruct) "154" s154 (Cstruct.of_string "154") ; Alcotest.(check cstruct) "654" s654 (Cstruct.of_string "654") ; Alcotest.(check bool) "exists" (exists (fun _ -> false) empty) false ; Alcotest.(check bool) "exists" (exists (fun _ -> true) empty) false ; Alcotest.(check bool) "exists" (exists (fun c -> Char.code c < 0x34) s541) true ; Alcotest.(check bool) "exists" (exists (fun c -> Char.code c < 0x34) s154) true ; Alcotest.(check bool) "exists" (exists (fun c -> Char.code c < 0x34) s654) false ; ;; let trim = Alcotest.test_case "trim" `Quick @@ fun () -> let drop_a c = c = 'a' in let { Cstruct.buffer= base; _ } = Cstruct.of_string "00aaaabcdaaaa00" in let aaaabcdaaaa = buffer ~off:2 ~len:11 base in let aaaabcd = buffer ~off:2 ~len:7 base in let bcdaaaa = buffer ~off:6 ~len:7 base in let aaaa = buffer ~off:2 ~len:4 base in Alcotest.(check cstruct) "trim" (trim (string "\t abcd \t")) (Cstruct.of_string "abcd") ; Alcotest.(check cstruct) "trim" (trim aaaabcdaaaa) (Cstruct.of_string "aaaabcdaaaa") ; Alcotest.(check cstruct) "trim" (trim ~drop:drop_a aaaabcdaaaa) (Cstruct.of_string "bcd") ; Alcotest.(check cstruct) "trim" (trim ~drop:drop_a aaaabcd) (Cstruct.of_string "bcd") ; Alcotest.(check cstruct) "trim" (trim ~drop:drop_a bcdaaaa) (Cstruct.of_string "bcd") ; let empty_pos cs pos = Alcotest.(check int) "length" (length cs) 0 ; Alcotest.(check int) "start_pos" (start_pos cs) pos in empty_pos (trim ~drop:drop_a aaaa) 4 ; empty_pos (trim (string " ")) 2 ; ;; let span = Alcotest.test_case "span" `Quick @@ fun () -> (* XXX(dinosaure): clash of names between [start] and [Cstruct.start]. *) let open Cstruct in let test ?(rev= false) ?min ?max ?sat cs (cl, cr as expect) = let res = span ~rev ?min ?max ?sat cs in let t = take ~rev ?min ?max ?sat cs in let d = drop ~rev ?min ?max ?sat cs in Alcotest.(check (pair cstruct cstruct)) "span" res expect ; Alcotest.(check cstruct) "take" t (if rev then cr else cl) ; Alcotest.(check cstruct) "drop" d (if rev then cl else cr) in let invalid ?rev ?min ?max ?sat cs = Alcotest.check_raises "invalid" (Invalid_argument "span") (fun () -> try ignore @@ span ?rev ?min ?max ?sat cs with Invalid_argument _ -> invalid_arg "span") in let is_white = function ' ' | '\t' .. '\r' -> true | _ -> false in let is_letter = function 'A' .. 'Z' | 'a' .. 'z' -> true | _ -> false in let { Cstruct.buffer= base; _ } = Cstruct.of_string "0ab cd0" in let empty = buffer ~off:3 ~len:0 base in let ab_cd = buffer ~off:1 ~len:5 base in let ab = buffer ~off:1 ~len:2 base in let _cd = buffer ~off:3 ~len:3 base in let cd = buffer ~off:4 ~len:2 base in let ab_ = buffer ~off:1 ~len:3 base in let a = buffer ~off:1 ~len:1 base in let b_cd = buffer ~off:2 ~len:4 base in let b = buffer ~off:2 ~len:1 base in let d = buffer ~off:5 ~len:1 base in let ab_c = buffer ~off:1 ~len:4 base in test ~rev:false ~min:1 ~max:0 ab_cd (start ab_cd, ab_cd) ; test ~rev:true ~min:1 ~max:0 ab_cd (ab_cd, stop ab_cd) ; test ~sat:is_white ab_cd (start ab_cd, ab_cd) ; test ~sat:is_letter ab_cd (ab, _cd) ; test ~max:1 ~sat:is_letter ab_cd (a, b_cd) ; test ~max:0 ~sat:is_letter ab_cd (start ab_cd, ab_cd) ; test ~rev:true ~sat:is_white ab_cd (ab_cd, stop ab_cd) ; test ~rev:true ~sat:is_letter ab_cd (ab_, cd) ; test ~rev:true ~max:1 ~sat:is_letter ab_cd (ab_c, d) ; test ~rev:true ~max:0 ~sat:is_letter ab_cd (ab_cd, stop ab_cd) ; test ~sat:is_letter ab (ab, stop ab) ; test ~max:1 ~sat:is_letter ab (a, b) ; test ~sat:is_letter b (b, empty) ; test ~rev:true ~max:1 ~sat:is_letter ab (a, b) ; test ~max:1 ~sat:is_white ab (start ab, ab) ; test ~rev:true ~sat:is_white empty (empty, empty) ; test ~sat:is_white empty (empty, empty) ; (* TODO: invalid *) invalid ~rev:false ~min:(-1) empty ; invalid ~rev:true ~min:(-1) empty ; invalid ~rev:false ~max:(-1) empty ; invalid ~rev:true ~max:(-1) empty ; test ~rev:false empty (empty, empty) ; test ~rev:true empty (empty, empty) ; test ~rev:false ~min:0 ~max:0 empty (empty, empty) ; test ~rev:true ~min:0 ~max:0 empty (empty, empty) ; test ~rev:false ~min:1 ~max:0 empty (empty, empty) ; test ~rev:true ~min:1 ~max:0 empty (empty, empty) ; test ~rev:false ~max:0 ab_cd (start ab_cd, ab_cd) ; test ~rev:true ~max:0 ab_cd (ab_cd, stop ab_cd) ; test ~rev:false ~max:2 ab_cd (ab, _cd) ; test ~rev:true ~max:2 ab_cd (ab_, cd) ; test ~rev:false ~min:6 ab_cd (start ab_cd, ab_cd) ; test ~rev:true ~min:6 ab_cd (ab_cd, stop ab_cd) ; test ~rev:false ab_cd (ab_cd, stop ab_cd) ; test ~rev:true ab_cd (start ab_cd, ab_cd) ; test ~rev:false ~max:30 ab_cd (ab_cd, stop ab_cd) ; test ~rev:true ~max:30 ab_cd (start ab_cd, ab_cd) ; test ~rev:false ~sat:is_white ab_cd (start ab_cd, ab_cd) ; test ~rev:true ~sat:is_white ab_cd (ab_cd, stop ab_cd) ; test ~rev:false ~sat:is_letter ab_cd (ab, _cd) ; test ~rev:true ~sat:is_letter ab_cd (ab_, cd) ; test ~rev:false ~sat:is_letter ~max:0 ab_cd (start ab_cd, ab_cd) ; test ~rev:true ~sat:is_letter ~max:0 ab_cd (ab_cd, stop ab_cd) ; test ~rev:false ~sat:is_letter ~max:1 ab_cd (a, b_cd) ; test ~rev:true ~sat:is_letter ~max:1 ab_cd (ab_c, d) ; test ~rev:false ~sat:is_letter ~min:2 ~max:1 ab_cd (start ab_cd, ab_cd) ; test ~rev:true ~sat:is_letter ~min:2 ~max:1 ab_cd (ab_cd, stop ab_cd) ; test ~rev:false ~sat:is_letter ~min:3 ab_cd (start ab_cd, ab_cd) ; test ~rev:true ~sat:is_letter ~min:3 ab_cd (ab_cd, stop ab_cd) ; ;; let cut = Alcotest.test_case "cut" `Quick @@ fun () -> let s str = string ~off:1 ~len:(String.length str) (Fmt.str "\x00%s\x00" str) in let cut ?rev ~sep str = cut ?rev ~sep:(s sep) (s str) in let invalid_cut_argument = Invalid_argument "cut: empty separator" in Alcotest.check_raises "invalid" invalid_cut_argument (fun () -> ignore (cut ~sep:"" "")) ; Alcotest.check_raises "invalid" invalid_cut_argument (fun () -> ignore (cut ~sep:"" "123")) ; let opc = Alcotest.(option (pair cstruct cstruct)) in Alcotest.(check opc) "0" (cut ~sep:"," "") None ; Alcotest.(check opc) "1" (cut ~sep:"," ",") (Some (string "", string "")) ; Alcotest.(check opc) "2" (cut ~sep:"," ",,") (Some (string "", string ",")) ; Alcotest.(check opc) "3" (cut ~sep:"," ",,,") (Some (string "", string ",,")) ; Alcotest.(check opc) "4" (cut ~sep:"," "123") None ; Alcotest.(check opc) "5" (cut ~sep:"," ",123") (Some (string "", string "123")) ; Alcotest.(check opc) "6" (cut ~sep:"," "123,") (Some (string "123", string "")) ; Alcotest.(check opc) "7" (cut ~sep:"," "1,2,3") (Some (string "1", string "2,3")) ; Alcotest.(check opc) "8" (cut ~sep:"," " 1,2,3") (Some (string " 1", string "2,3")) ; Alcotest.(check opc) "9" (cut ~sep:"<>" "") None ; Alcotest.(check opc) "10" (cut ~sep:"<>" "<>") (Some (string "", string "")) ; Alcotest.(check opc) "11" (cut ~sep:"<>" "<><>") (Some (string "", string "<>")) ; Alcotest.(check opc) "12" (cut ~sep:"<>" "<><><>") (Some (string "", string "<><>")) ; Alcotest.(check opc) "13" (cut ~rev:true ~sep:"<>" "1") None ; Alcotest.(check opc) "14" (cut ~sep:"<>" "123") None ; Alcotest.(check opc) "15" (cut ~sep:"<>" "<>123") (Some (string "", string "123")) ; Alcotest.(check opc) "16" (cut ~sep:"<>" "123<>") (Some (string "123", string "")) ; Alcotest.(check opc) "17" (cut ~sep:"<>" "1<>2<>3") (Some (string "1", string "2<>3")) ; Alcotest.(check opc) "18" (cut ~sep:"<>" ">>><>>>><>>>><>>>>") (Some (string ">>>", string ">>><>>>><>>>>")) ; Alcotest.(check opc) "19" (cut ~sep:"<->" "<->>->") (Some (string "", string ">->")) ; Alcotest.(check opc) "20" (cut ~rev:true ~sep:"<->" "<-") None ; Alcotest.(check opc) "21" (cut ~sep:"aa" "aa") (Some (string "", string "")) ; Alcotest.(check opc) "22" (cut ~sep:"aa" "aaa") (Some (string "", string "a")) ; Alcotest.(check opc) "23" (cut ~sep:"aa" "aaaa") (Some (string "", string "aa")) ; Alcotest.(check opc) "24" (cut ~sep:"aa" "aaaaa") (Some (string "", string "aaa")) ; Alcotest.(check opc) "25" (cut ~sep:"aa" "aaaaaa") (Some (string "", string "aaaa")) ; Alcotest.(check opc) "26" (cut ~sep:"ab" "faaaa") None ; let rev = true in Alcotest.check_raises "invalid" invalid_cut_argument (fun () -> ignore (cut ~rev ~sep:"" "")) ; Alcotest.check_raises "invalid" invalid_cut_argument (fun () -> ignore (cut ~rev ~sep:"" "123")) ; Alcotest.(check opc) "27" (cut ~rev ~sep:"," "") None ; Alcotest.(check opc) "28" (cut ~rev ~sep:"," ",") (Some (string "", string "")) ; Alcotest.(check opc) "29" (cut ~rev ~sep:"," ",,") (Some (string ",", string "")) ; Alcotest.(check opc) "30" (cut ~rev ~sep:"," ",,,") (Some (string ",,", string "")) ; Alcotest.(check opc) "31" (cut ~rev ~sep:"," "123") None ; Alcotest.(check opc) "32" (cut ~rev ~sep:"," ",123") (Some (string "", string "123")) ; Alcotest.(check opc) "33" (cut ~rev ~sep:"," "123,") (Some (string "123", string "")) ; Alcotest.(check opc) "34" (cut ~rev ~sep:"," "1,2,3") (Some (string "1,2", string "3")) ; Alcotest.(check opc) "35" (cut ~rev ~sep:"," "1,2,3 ") (Some (string "1,2", string "3 ")) ; Alcotest.(check opc) "36" (cut ~rev ~sep:"<>" "") None ; Alcotest.(check opc) "37" (cut ~rev ~sep:"<>" "<>") (Some (string "", string "")) ; Alcotest.(check opc) "38" (cut ~rev ~sep:"<>" "<><>") (Some (string "<>", string "")) ; Alcotest.(check opc) "39" (cut ~rev ~sep:"<>" "<><><>") (Some (string "<><>", string "")) ; Alcotest.(check opc) "40" (cut ~rev ~sep:"<>" "1") None ; Alcotest.(check opc) "41" (cut ~rev ~sep:"<>" "123") None ; Alcotest.(check opc) "42" (cut ~rev ~sep:"<>" "<>123") (Some (string "", string "123")) ; Alcotest.(check opc) "43" (cut ~rev ~sep:"<>" "123<>") (Some (string "123", string "")) ; Alcotest.(check opc) "44" (cut ~rev ~sep:"<>" "1<>2<>3") (Some (string "1<>2", string "3")) ; Alcotest.(check opc) "45" (cut ~rev ~sep:"<>" "1<>2<>3 ") (Some (string "1<>2", string "3 ")) ; Alcotest.(check opc) "46" (cut ~rev ~sep:"<>" ">>><>>>><>>>><>>>>") (Some (string ">>><>>>><>>>>", string ">>>")) ; Alcotest.(check opc) "47" (cut ~rev ~sep:"<->" "<->>->") (Some (string "", string ">->")) ; Alcotest.(check opc) "48" (cut ~rev ~sep:"<->" "<-") None ; Alcotest.(check opc) "49" (cut ~rev ~sep:"aa" "aa") (Some (string "", string "")) ; Alcotest.(check opc) "50" (cut ~rev ~sep:"aa" "aaa") (Some (string "a", string "")) ; Alcotest.(check opc) "51" (cut ~rev ~sep:"aa" "aaaa") (Some (string "aa", string "")) ; Alcotest.(check opc) "52" (cut ~rev ~sep:"aa" "aaaaa") (Some (string "aaa", string "")) ; Alcotest.(check opc) "53" (cut ~rev ~sep:"aa" "aaaaaa") (Some (string "aaaa", string "")) ; Alcotest.(check opc) "54" (cut ~rev ~sep:"ab" "afaaaa") None ; (* TODO: incomplete, see [astring]. *) ;; let cuts = Alcotest.test_case "cuts" `Quick @@ fun () -> let ls = Alcotest.(list string) in let invalid_cuts_argument = Invalid_argument "cuts: empty separator" in let s str = string ~off:1 ~len:(String.length str) (Fmt.str "\x00%s\x00" str) in let cuts ?empty ?rev ~sep str = let res = cuts ?empty ?rev ~sep:(s sep) (s str) in List.map Cstruct.to_string res in Alcotest.check_raises "invalid" invalid_cuts_argument (fun () -> ignore (cuts ~sep:"" "")) ; Alcotest.check_raises "invalid" invalid_cuts_argument (fun () -> ignore (cuts ~sep:"" "")) ; Alcotest.(check ls) "0" (cuts ~empty:true ~sep:"," "") [""] ; Alcotest.(check ls) "1" (cuts ~empty:false ~sep:"," "") [] ; Alcotest.(check ls) "2" (cuts ~empty:true ~sep:"," "") [""]; Alcotest.(check ls) "3" (cuts ~empty:false ~sep:"," "") []; Alcotest.(check ls) "4" (cuts ~empty:true ~sep:"," ",") [""; ""]; Alcotest.(check ls) "5" (cuts ~empty:false ~sep:"," ",") []; Alcotest.(check ls) "6" (cuts ~empty:true ~sep:"," ",,") [""; ""; ""]; Alcotest.(check ls) "7" (cuts ~empty:false ~sep:"," ",,") []; Alcotest.(check ls) "8" (cuts ~empty:true ~sep:"," ",,,") [""; ""; ""; ""]; Alcotest.(check ls) "9" (cuts ~empty:false ~sep:"," ",,,") []; Alcotest.(check ls) "10" (cuts ~empty:true ~sep:"," "123") ["123"]; Alcotest.(check ls) "11" (cuts ~empty:false ~sep:"," "123") ["123"]; Alcotest.(check ls) "12" (cuts ~empty:true ~sep:"," ",123") [""; "123"]; Alcotest.(check ls) "13" (cuts ~empty:false ~sep:"," ",123") ["123"]; Alcotest.(check ls) "14" (cuts ~empty:true ~sep:"," "123,") ["123"; ""]; Alcotest.(check ls) "15" (cuts ~empty:false ~sep:"," "123,") ["123";]; Alcotest.(check ls) "16" (cuts ~empty:true ~sep:"," "1,2,3") ["1"; "2"; "3"]; Alcotest.(check ls) "17" (cuts ~empty:false ~sep:"," "1,2,3") ["1"; "2"; "3"]; Alcotest.(check ls) "18" (cuts ~empty:true ~sep:"," "1, 2, 3") ["1"; " 2"; " 3"]; Alcotest.(check ls) "19" (cuts ~empty:false ~sep:"," "1, 2, 3") ["1"; " 2"; " 3"]; Alcotest.(check ls) "20" (cuts ~empty:true ~sep:"," ",1,2,,3,") [""; "1"; "2"; ""; "3"; ""]; Alcotest.(check ls) "21" (cuts ~empty:false ~sep:"," ",1,2,,3,") ["1"; "2"; "3";]; Alcotest.(check ls) "22" (cuts ~empty:true ~sep:"," ", 1, 2,, 3,") [""; " 1"; " 2"; ""; " 3"; ""]; Alcotest.(check ls) "23" (cuts ~empty:false ~sep:"," ", 1, 2,, 3,") [" 1"; " 2";" 3";]; Alcotest.(check ls) "24" (cuts ~empty:true ~sep:"<>" "") [""]; Alcotest.(check ls) "25" (cuts ~empty:false ~sep:"<>" "") []; Alcotest.(check ls) "26" (cuts ~empty:true ~sep:"<>" "<>") [""; ""]; Alcotest.(check ls) "27" (cuts ~empty:false ~sep:"<>" "<>") []; Alcotest.(check ls) "28" (cuts ~empty:true ~sep:"<>" "<><>") [""; ""; ""]; Alcotest.(check ls) "29" (cuts ~empty:false ~sep:"<>" "<><>") []; Alcotest.(check ls) "30" (cuts ~empty:true ~sep:"<>" "<><><>") [""; ""; ""; ""]; Alcotest.(check ls) "31" (cuts ~empty:false ~sep:"<>" "<><><>") []; Alcotest.(check ls) "32" (cuts ~empty:true ~sep:"<>" "123") [ "123" ]; Alcotest.(check ls) "33" (cuts ~empty:false ~sep:"<>" "123") [ "123" ]; Alcotest.(check ls) "34" (cuts ~empty:true ~sep:"<>" "<>123") [""; "123"]; Alcotest.(check ls) "35" (cuts ~empty:false ~sep:"<>" "<>123") ["123"]; Alcotest.(check ls) "36" (cuts ~empty:true ~sep:"<>" "123<>") ["123"; ""]; Alcotest.(check ls) "37" (cuts ~empty:false ~sep:"<>" "123<>") ["123"]; Alcotest.(check ls) "38" (cuts ~empty:true ~sep:"<>" "1<>2<>3") ["1"; "2"; "3"]; Alcotest.(check ls) "39" (cuts ~empty:false ~sep:"<>" "1<>2<>3") ["1"; "2"; "3"]; Alcotest.(check ls) "40" (cuts ~empty:true ~sep:"<>" "1<> 2<> 3") ["1"; " 2"; " 3"]; Alcotest.(check ls) "41" (cuts ~empty:false ~sep:"<>" "1<> 2<> 3") ["1"; " 2"; " 3"]; Alcotest.(check ls) "42" (cuts ~empty:true ~sep:"<>" "<>1<>2<><>3<>") [""; "1"; "2"; ""; "3"; ""]; Alcotest.(check ls) "43" (cuts ~empty:false ~sep:"<>" "<>1<>2<><>3<>") ["1"; "2";"3";]; Alcotest.(check ls) "44" (cuts ~empty:true ~sep:"<>" "<> 1<> 2<><> 3<>") [""; " 1"; " 2"; ""; " 3";""]; Alcotest.(check ls) "45" (cuts ~empty:false ~sep:"<>" "<> 1<> 2<><> 3<>")[" 1"; " 2"; " 3"]; Alcotest.(check ls) "46" (cuts ~empty:true ~sep:"<>" ">>><>>>><>>>><>>>>") [">>>"; ">>>"; ">>>"; ">>>" ]; Alcotest.(check ls) "47" (cuts ~empty:false ~sep:"<>" ">>><>>>><>>>><>>>>") [">>>"; ">>>"; ">>>"; ">>>" ]; Alcotest.(check ls) "48" (cuts ~empty:true ~sep:"<->" "<->>->") [""; ">->"]; Alcotest.(check ls) "49" (cuts ~empty:false ~sep:"<->" "<->>->") [">->"]; Alcotest.(check ls) "50" (cuts ~empty:true ~sep:"aa" "aa") [""; ""]; Alcotest.(check ls) "51" (cuts ~empty:false ~sep:"aa" "aa") []; Alcotest.(check ls) "52" (cuts ~empty:true ~sep:"aa" "aaa") [""; "a"]; Alcotest.(check ls) "53" (cuts ~empty:false ~sep:"aa" "aaa") ["a"]; Alcotest.(check ls) "54" (cuts ~empty:true ~sep:"aa" "aaaa") [""; ""; ""]; Alcotest.(check ls) "55" (cuts ~empty:false ~sep:"aa" "aaaa") []; Alcotest.(check ls) "56" (cuts ~empty:true ~sep:"aa" "aaaaa") [""; ""; "a"]; Alcotest.(check ls) "57" (cuts ~empty:false ~sep:"aa" "aaaaa") ["a"]; Alcotest.(check ls) "58" (cuts ~empty:true ~sep:"aa" "aaaaaa") [""; ""; ""; ""]; Alcotest.(check ls) "59" (cuts ~empty:false ~sep:"aa" "aaaaaa") []; ;; let fields = Alcotest.test_case "fields" `Quick @@ fun () -> let ls = Alcotest.(list string) in let s str = string ~off:1 ~len:(String.length str) (Fmt.str "\x00%s\x00" str) in let fields ?empty ?is_sep str = let res = fields ?empty ?is_sep (s str) in List.map Cstruct.to_string res in let is_a chr = chr = 'a' in Alcotest.(check ls) "0" (fields ~empty:true "a") ["a"]; Alcotest.(check ls) "1" (fields ~empty:false "a") ["a"]; Alcotest.(check ls) "2" (fields ~empty:true "abc") ["abc"]; Alcotest.(check ls) "3" (fields ~empty:false "abc") ["abc"]; Alcotest.(check ls) "4" (fields ~empty:true ~is_sep:is_a "bcdf") ["bcdf"]; Alcotest.(check ls) "5" (fields ~empty:false ~is_sep:is_a "bcdf") ["bcdf"]; Alcotest.(check ls) "6" (fields ~empty:true "") [""]; Alcotest.(check ls) "7" (fields ~empty:false "") []; Alcotest.(check ls) "8" (fields ~empty:true "\n\r") ["";"";""]; Alcotest.(check ls) "9" (fields ~empty:false "\n\r") []; Alcotest.(check ls) "10" (fields ~empty:true " \n\rabc") ["";"";"";"abc"]; Alcotest.(check ls) "11" (fields ~empty:false " \n\rabc") ["abc"]; Alcotest.(check ls) "12" (fields ~empty:true " \n\racd de") ["";"";"";"acd";"de"]; Alcotest.(check ls) "13" (fields ~empty:false " \n\racd de") ["acd";"de"]; Alcotest.(check ls) "14" (fields ~empty:true " \n\racd de ") ["";"";"";"acd";"de";""]; Alcotest.(check ls) "15" (fields ~empty:false " \n\racd de ") ["acd";"de"]; Alcotest.(check ls) "16" (fields ~empty:true "\n\racd\nde \r") ["";"";"acd";"de";"";""]; Alcotest.(check ls) "17" (fields ~empty:false "\n\racd\nde \r") ["acd";"de"]; Alcotest.(check ls) "18" (fields ~empty:true ~is_sep:is_a "") [""]; Alcotest.(check ls) "19" (fields ~empty:false ~is_sep:is_a "") []; Alcotest.(check ls) "20" (fields ~empty:true ~is_sep:is_a "abaac aaa") ["";"b";"";"c ";"";"";""]; Alcotest.(check ls) "21" (fields ~empty:false ~is_sep:is_a "abaac aaa") ["b"; "c "]; Alcotest.(check ls) "22" (fields ~empty:true ~is_sep:is_a "aaaa") ["";"";"";"";""]; Alcotest.(check ls) "23" (fields ~empty:false ~is_sep:is_a "aaaa") []; Alcotest.(check ls) "24" (fields ~empty:true ~is_sep:is_a "aaaa ") ["";"";"";"";" "]; Alcotest.(check ls) "25" (fields ~empty:false ~is_sep:is_a "aaaa ") [" "]; Alcotest.(check ls) "26" (fields ~empty:true ~is_sep:is_a "aaaab") ["";"";"";"";"b"]; Alcotest.(check ls) "27" (fields ~empty:false ~is_sep:is_a "aaaab") ["b"]; Alcotest.(check ls) "28" (fields ~empty:true ~is_sep:is_a "baaaa") ["b";"";"";"";""]; Alcotest.(check ls) "29" (fields ~empty:false ~is_sep:is_a "baaaa") ["b"]; Alcotest.(check ls) "30" (fields ~empty:true ~is_sep:is_a "abaaaa") ["";"b";"";"";"";""]; Alcotest.(check ls) "31" (fields ~empty:false ~is_sep:is_a "abaaaa") ["b"]; Alcotest.(check ls) "32" (fields ~empty:true ~is_sep:is_a "aba") ["";"b";""]; Alcotest.(check ls) "33" (fields ~empty:false ~is_sep:is_a "aba") ["b"]; Alcotest.(check ls) "34" (fields ~empty:false "tokenize me please") ["tokenize"; "me"; "please"]; ;; let find = Alcotest.test_case "find" `Quick @@ fun () -> let { Cstruct.buffer= abcbd; _ } = Cstruct.of_string "abcbd" in let empty = buffer ~off:3 ~len:0 abcbd in let a = buffer ~off:0 ~len:1 abcbd in let ab = buffer ~off:0 ~len:2 abcbd in let c = buffer ~off:2 ~len:1 abcbd in let b0 = buffer ~off:1 ~len:1 abcbd in let b1 = buffer ~off:3 ~len:1 abcbd in let abcbd = buffer abcbd in Alcotest.(check (option cstruct)) "0" (find (fun c -> c = 'b') empty) None; Alcotest.(check (option cstruct)) "1" (find ~rev:true (fun c -> c = 'b') empty) None; Alcotest.(check (option cstruct)) "2" (find (fun c -> c = 'b') a) None; Alcotest.(check (option cstruct)) "3" (find ~rev:true (fun c -> c = 'b') a) None; Alcotest.(check (option cstruct)) "4" (find (fun c -> c = 'b') c) None; Alcotest.(check (option cstruct)) "5" (find ~rev:true (fun c -> c = 'b') c) None; Alcotest.(check (option cstruct)) "6" (find (fun c -> c = 'b') abcbd) (Some b0); Alcotest.(check (option cstruct)) "7" (find ~rev:true (fun c -> c = 'b') abcbd) (Some b1); Alcotest.(check (option cstruct)) "8" (find (fun c -> c = 'b') ab) (Some b0); Alcotest.(check (option cstruct)) "9" (find ~rev:true (fun c -> c = 'b') ab) (Some b0); ;; let find_sub = Alcotest.test_case "find_sub" `Quick @@ fun () -> let { Cstruct.buffer= abcbd; _ } = Cstruct.of_string "abcbd" in let empty = buffer ~off:3 ~len:0 abcbd in let ab = buffer ~off:0 ~len:2 abcbd in let b0 = buffer ~off:1 ~len:1 abcbd in let b1 = buffer ~off:3 ~len:1 abcbd in let abcbd = buffer abcbd in Alcotest.(check (option cstruct)) "0" (find_sub ~sub:ab empty) None; Alcotest.(check (option cstruct)) "1" (find_sub ~rev:true ~sub:ab empty) None; Alcotest.(check (option cstruct)) "2" (find_sub ~sub:(Cstruct.of_string "") empty) (Some empty); Alcotest.(check (option cstruct)) "3" (find_sub ~rev:true ~sub:(Cstruct.of_string "") empty) (Some empty); Alcotest.(check (option cstruct)) "4" (find_sub ~sub:ab abcbd) (Some ab); Alcotest.(check (option cstruct)) "5" (find_sub ~rev:true ~sub:ab abcbd) (Some ab); Alcotest.(check (option cstruct)) "6" (find_sub ~sub:empty abcbd) (Some (Cstruct.start abcbd)); Alcotest.(check (option cstruct)) "7" (find_sub ~rev:true ~sub:empty abcbd) (Some (Cstruct.stop abcbd)); Alcotest.(check (option cstruct)) "8" (find_sub ~sub:(Cstruct.of_string "b") abcbd) (Some b0); Alcotest.(check (option cstruct)) "9" (find_sub ~rev:true ~sub:(Cstruct.of_string "b") abcbd) (Some b1); Alcotest.(check (option cstruct)) "10" (find_sub ~sub:b1 ab) (Some b0); Alcotest.(check (option cstruct)) "11" (find_sub ~rev:true ~sub:b1 ab) (Some b0); ;; let () = Alcotest.run "cstruct.parse" [ "parse", [ misc; head; start; stop; tail ; is_empty; is_prefix; is_infix; is_suffix ; for_all; exists ; trim ; span ; cut; cuts ; fields ; find; find_sub ] ] ocaml-cstruct-6.2.0/lib_test/tests.ml000066400000000000000000000200521437471254600176140ustar00rootroot00000000000000let _ = Random.self_init () let random_cs ?(len = Random.int 128) () = let cs = Cstruct.create len in for i = 0 to len - 1 do Cstruct.set_uint8 cs i (Random.int 256) done; cs let to_string_as_sexp cs = Sexplib.Sexp.to_string_mach (Cstruct_sexp.sexp_of_t cs) let of_string_as_sexp str = Cstruct_sexp.t_of_sexp (Sexplib.Sexp.of_string str) let assert_cs_equal ?(msg="cstruct") cs1 cs2 = let cstruct = Alcotest.testable (Fmt.of_to_string Cstruct.to_string) Cstruct.equal in Alcotest.check cstruct msg cs1 cs2 let assert_string_equal ?(msg="string") s1 s2 = Alcotest.(check string) msg s1 s2 let sexp_repr = let open Cstruct in let cs1 = of_string "abcdefgh" in let cs2 = shift cs1 2 and cs3 = sub cs1 2 4 in let cs4 = of_string "a b\nc" in let cs5 = sub cs4 2 1 in [ (cs1, "abcdefgh") ; (cs2, "cdefgh") ; (cs3, "cdef") ; (cs4, "\"a b\\nc\"") ; (cs5, "b") ] let sexp_writer () = sexp_repr |> List.iter @@ fun (cs, str) -> assert_string_equal str (to_string_as_sexp cs) let sexp_reader () = sexp_repr |> List.iter @@ fun (cs, str) -> assert_cs_equal cs (of_string_as_sexp str) let sexp_invertibility ~n () = for _i = 1 to n do let cs1 = random_cs () in let s1 = to_string_as_sexp cs1 in let cs2 = of_string_as_sexp s1 in let s2 = to_string_as_sexp cs2 in assert_cs_equal ~msg:"recovered cstruct" cs1 cs2 ; assert_string_equal ~msg:"recovered string" s1 s2 done let concat_ex = let open Cstruct in List.map (fun (ss, s) -> (List.map of_string ss, of_string s)) [ ([], "") ; (["abcd"], "abcd") ; ([""], "") ; ([""; ""], "") ; ([""; "ab"; ""; "cd"], "abcd") ; (["ab"; "cd"; "ef"], "abcdef") ] let concat_samples () = concat_ex |> List.iter @@ fun (css, cs) -> assert_cs_equal cs (Cstruct.concat css) let concat_random ~n () = let rec explode cs = let n = Cstruct.length cs in if n = 0 then [] else let k = Random.int (n + 1) in Cstruct.sub cs 0 k :: explode (Cstruct.shift cs k) in for _i = 1 to n do let cs = random_cs () in let css = explode cs in assert_cs_equal cs (Cstruct.concat css) done let append_is_concat ~n () = for _i = 1 to n do let (cs1, cs2) = (random_cs (), random_cs ()) in assert_cs_equal (Cstruct.concat [cs1; cs2]) (Cstruct.append cs1 cs2) done let fillv () = let test src buf_size = let dst = Cstruct.create buf_size in let src_len = Cstruct.lenv src in let len, remaining = Cstruct.fillv ~src ~dst in assert (len = min src_len buf_size); let whole = Cstruct.concat (Cstruct.sub dst 0 len :: remaining) in assert (Cstruct.equal whole (Cstruct.concat src)) in test [] 0; test [] 16; test [Cstruct.of_string "abc"] 0; test [Cstruct.of_string "abc"] 2; test [Cstruct.of_string "abc"] 16; test [Cstruct.of_string "abc"; Cstruct.of_string ""; Cstruct.of_string "def"] 0; test [Cstruct.of_string "abc"; Cstruct.of_string ""; Cstruct.of_string "def"] 3; test [Cstruct.of_string "abc"; Cstruct.of_string ""; Cstruct.of_string "def"] 5; test [Cstruct.of_string "abc"; Cstruct.of_string ""; Cstruct.of_string "def"] 6; test [Cstruct.of_string "abc"; Cstruct.of_string ""; Cstruct.of_string "def"] 7 let check_alignment alignment () = (* Make the buffer big enough to find 4 aligned offsets within it *) let expected = 4 in let buf = Cstruct.create (expected * alignment) in (* How many aligned offsets are there in this buffer? *) let actual = ref 0 in for i = 0 to Cstruct.length buf - 1 do if Cstruct.(check_alignment (shift buf i) alignment) then incr actual done; Alcotest.(check int) "alignement" expected !actual let check_alignment_zero () = let buf = Cstruct.create 512 in try let _ = Cstruct.check_alignment buf 0 in Alcotest.fail "alignement zero should raise" with Invalid_argument _ -> () let check_alignment_large () = let check () = Cstruct.check_alignment (Cstruct.create 1) (Int64.to_int 4294967296L) in if Sys.word_size > 32 then let msg = Fmt.str "alignement large: int-size:%d len=%d" Sys.word_size (Int64.to_int 4294967296L) in Alcotest.(check bool) msg (check ()) false else try let _ = check () in Alcotest.fail "alignement should raise" with Invalid_argument _ -> () let rev_empty () = assert_cs_equal Cstruct.empty (Cstruct.rev Cstruct.empty) let rev_len_1 () = let cs = Cstruct.of_string "a" in assert_cs_equal cs (Cstruct.rev cs) let rev_len_5 () = let cs = Cstruct.of_string "abcde" in let expected = Cstruct.of_string "edcba" in assert_cs_equal expected (Cstruct.rev cs) let test_hexdump ?(format=("%a" : _ format4)) cs expected = let got = Format.asprintf format Cstruct.hexdump_pp cs in Alcotest.(check string) "hexdump output" expected got let hexdump_empty () = test_hexdump Cstruct.empty "" let hexdump_small () = test_hexdump (Cstruct.of_hex "00010203") "00 01 02 03" let hex_multiline = Cstruct.of_hex "000102030405060708090a0b0c0d0e0f101112" let hex_to_string_empty () = let c = Cstruct.of_string "" in let s = Cstruct.to_hex_string c in assert_string_equal ~msg:"encoded" s "" let hex_to_string_small () = let c = Cstruct.of_string "hello world \x00 !" in let s = Cstruct.to_hex_string c in assert_string_equal ~msg:"encoded" "68656c6c6f20776f726c6420002021" s; let c' = Cstruct.of_hex s in assert_cs_equal ~msg:"decoded again" c c' let hex_to_string_small_slice () = let c = Cstruct.of_string "This_1s Not @ Dr1LL" in let s = Cstruct.to_hex_string ~off:2 ~len:11 c in assert_string_equal ~msg:"encoded" "69735f3173204e6f742040" s; let c' = Cstruct.of_hex s in assert_cs_equal ~msg:"decoded again" (Cstruct.sub c 2 11) c'; assert_string_equal ~msg:"decoded as str" "is_1s Not @" (Cstruct.to_string c') let hex_to_string_small_slice_of_slice () = let c = Cstruct.of_string "This_1s Not @ Dr1LL" in let c_slice = Cstruct.sub c 2 11 in let s = Cstruct.to_hex_string ~off:3 ~len:6 c_slice in assert_string_equal ~msg:"encoded" "3173204e6f74" s; let c' = Cstruct.of_hex s in assert_cs_equal ~msg:"decoded again" (Cstruct.sub c_slice 3 6) c'; assert_string_equal ~msg:"decoded as str" "1s Not" (Cstruct.to_string c') let hexdump_multiline () = test_hexdump hex_multiline ( "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n" ^ "10 11 12") let hexdump_aligned () = test_hexdump (Cstruct.of_hex "000102030405060708090a0b0c0d0e0f") "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n" let hexdump_aligned_to_half () = test_hexdump (Cstruct.of_hex "0001020304050607") "00 01 02 03 04 05 06 07" let hexdump_in_box () = test_hexdump ~format:"This is a box : %a" hex_multiline ( "This is a box : 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n" ^ " 10 11 12" ) let suite = [ "fillv", [ "fillv", `Quick, fillv ]; "sexp", [ "sexp_of_t" , `Quick, sexp_writer; "t_of_sexp" , `Quick, sexp_reader; "sexp invertibility", `Quick, sexp_invertibility ~n:5000; ]; "concat", [ "concat samples", `Quick, concat_samples; "concat random" , `Quick, concat_random ~n:5000; ]; "append", [ "append is concat", `Quick, append_is_concat ~n:5000 ]; "alignment", [ "aligned to 4096" , `Quick, check_alignment 4096; "aligned to 512" , `Quick, check_alignment 512; "aligned to 0" , `Quick, check_alignment_zero; "aligned to large", `Quick, check_alignment_large; ]; "rev", [ "empty", `Quick, rev_empty; "len = 1", `Quick, rev_len_1; "len = 5", `Quick, rev_len_5; ]; "hexdump", [ "empty", `Quick, hexdump_empty; "small", `Quick, hexdump_small; "multiline", `Quick, hexdump_multiline; "aligned", `Quick, hexdump_aligned; "aligned to half", `Quick, hexdump_aligned_to_half; "in box", `Quick, hexdump_in_box; ]; "hex_to_string", [ "empty", `Quick, hex_to_string_empty; "small", `Quick, hex_to_string_small; "small_slice", `Quick, hex_to_string_small_slice; "small_slice_of_slice", `Quick, hex_to_string_small_slice_of_slice; ] ] let () = Alcotest.run "cstruct" (("bounds", Bounds.suite) :: suite) ocaml-cstruct-6.2.0/lib_test/tests.mli000066400000000000000000000000141437471254600177610ustar00rootroot00000000000000(* empty *) ocaml-cstruct-6.2.0/lwt/000077500000000000000000000000001437471254600151225ustar00rootroot00000000000000ocaml-cstruct-6.2.0/lwt/dune000066400000000000000000000001501437471254600157740ustar00rootroot00000000000000(library (name cstruct_lwt) (wrapped false) (public_name cstruct-lwt) (libraries cstruct lwt.unix)) ocaml-cstruct-6.2.0/lwt/lwt_cstruct.ml000066400000000000000000000025701437471254600200350ustar00rootroot00000000000000(* * Copyright (c) 2012 Anil Madhavapeddy * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) let read fd t = Lwt_bytes.read fd t.Cstruct.buffer t.Cstruct.off t.Cstruct.len let write fd t = Lwt_bytes.write fd t.Cstruct.buffer t.Cstruct.off t.Cstruct.len let complete op t = let open Lwt in let rec loop t = op t >>= fun n -> let t = Cstruct.shift t n in if Cstruct.length t = 0 then return () else if n = 0 then fail End_of_file else loop t in loop t let sendto fd t flags dst = Lwt_bytes.sendto fd t.Cstruct.buffer t.Cstruct.off t.Cstruct.len flags dst let recvfrom fd t flags = Lwt_bytes.recvfrom fd t.Cstruct.buffer t.Cstruct.off t.Cstruct.len flags ocaml-cstruct-6.2.0/lwt/lwt_cstruct.mli000066400000000000000000000037521437471254600202110ustar00rootroot00000000000000(* * Copyright (c) 2012-2014 Anil Madhavapeddy * Copyright (c) 2012-2014 Citrix Systems Inc * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) (** Blocking Lwt functions to read and write from Cstruct buffers. *) val read: Lwt_unix.file_descr -> Cstruct.t -> int Lwt.t (** [read fd t] reads data from the file descriptor [fd] into the [t] cstruct. @return the numbers of bytes actually read. *) val write: Lwt_unix.file_descr -> Cstruct.t -> int Lwt.t (** [write fd t] writes data from the [t] cstruct to the file descriptor [fd]. @return the numbers of bytes actually written. *) val complete: (Cstruct.t -> int Lwt.t) -> Cstruct.t -> unit Lwt.t (** [complete (read fd) t] fills [t] with data from [fd]. [complete (write fd) t] fully-writes [t] to [fd]. @raise End_of_file if the file descriptor operation fails. *) val sendto: Lwt_unix.file_descr -> Cstruct.t -> Unix.msg_flag list -> Unix.sockaddr -> int Lwt.t (** [sendto fd t flags sa] invokes {!Lwt_unix.sendto} on the [t] cstruct. @return the number of bytes sent. *) val recvfrom: Lwt_unix.file_descr -> Cstruct.t -> Unix.msg_flag list -> (int * Unix.sockaddr) Lwt.t (** [recvfrom fd t flags sa] invokes {!Lwt_unix.recvfrom} on the [t] cstruct. @return the number of bytes read and the socket address of the remote side. *) ocaml-cstruct-6.2.0/ppx/000077500000000000000000000000001437471254600151235ustar00rootroot00000000000000ocaml-cstruct-6.2.0/ppx/dune000066400000000000000000000003021437471254600157740ustar00rootroot00000000000000(library (name ppx_cstruct) (public_name ppx_cstruct) (kind ppx_rewriter) (wrapped false) (ppx_runtime_libraries cstruct) (preprocess (pps ppxlib.metaquot)) (libraries sexplib ppxlib)) ocaml-cstruct-6.2.0/ppx/ppx_cstruct.ml000066400000000000000000000467151437471254600200500ustar00rootroot00000000000000(* * Copyright (c) 2015 Nicolas Ojeda Bar * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) open Printf open Ppxlib open Ast_helper module Ast = struct include Ast_builder.Default let econstr ~loc tag xs = pexp_construct ~loc (Loc.make ~loc (lident tag)) ( match xs with | [] -> None | _ -> Some (pexp_tuple ~loc xs) ) let pconstr ~loc tag xs = ppat_construct ~loc (Loc.make ~loc (lident tag)) ( match xs with | [] -> None | _ -> Some (ppat_tuple ~loc xs) ) let tconstr ~loc tag xs = ptyp_constr ~loc (Loc.make ~loc (lident tag)) xs end type mode = Big_endian | Little_endian | Host_endian | Bi_endian type prim = | Char | UInt8 | UInt16 | UInt32 | UInt64 type ty = | Prim of prim | Buffer of prim * int type raw_field = { name: string; ty: ty; definition_loc: Location.t; } type named_field = { name: string; ty: ty; definition_loc: Location.t; off: int; } type field = | Named_field of named_field | Ignored_field let field_is_ignored name = String.get name 0 = '_' type t = { name: string; fields: field list; len: int; endian: mode; } let ty_of_string = function |"char_t" |"char" -> Some Char |"uint8_t" |"uint8" |"int8" |"int8_t" -> Some UInt8 |"uint16_t"|"uint16"|"int16"|"int16_t" -> Some UInt16 |"uint32_t"|"uint32"|"int32"|"int32_t" -> Some UInt32 |"uint64_t"|"uint64"|"int64"|"int64_t" -> Some UInt64 |_ -> None let width_of_prim = function | Char -> 1 | UInt8 -> 1 | UInt16 -> 2 | UInt32 -> 4 | UInt64 -> 8 let width_of_ty = function | Prim p -> width_of_prim p | Buffer (p, len) -> width_of_prim p * len let width_of_field f = width_of_ty f.ty let field_to_string f = let rec string = function |Prim Char -> "char_t" |Prim UInt8 -> "uint8_t" |Prim UInt16 -> "uint16_t" |Prim UInt32 -> "uint32_t" |Prim UInt64 -> "uint64_t" |Buffer (prim, len) -> sprintf "%s[%d]" (string (Prim prim)) len in sprintf "%s %s" (string f.ty) f.name let loc_err loc fmt = Location.raise_errorf ~loc ("ppx_cstruct: " ^^ fmt) let parse_field loc name field_type sz = match ty_of_string field_type with |None -> loc_err loc "Unknown type %s" field_type |Some ty -> begin let ty = match ty,sz with |_,None -> Prim ty |prim,Some sz -> Buffer (prim, sz) in { name; ty; definition_loc = loc } end let check_for_duplicates fields = let module StringSet = Set.Make(String) in let _ : StringSet.t = List.fold_left (fun seen f -> match f with | Ignored_field -> seen | Named_field {name; definition_loc; _} -> if StringSet.mem name seen then loc_err definition_loc "field %s is present several times in this type" name else StringSet.add name seen ) StringSet.empty fields in () let create_struct loc endian name fields = let endian = match endian with |"little_endian" -> Little_endian |"big_endian" -> Big_endian |"host_endian" -> Host_endian |"bi_endian" -> Bi_endian |_ -> loc_err loc "unknown endian %s, should be little_endian, big_endian, host_endian or bi_endian" endian in let len, fields = List.fold_left (fun (off,acc) ({name; ty; definition_loc}:raw_field) -> let field = if field_is_ignored name then Ignored_field else Named_field { name; ty; off; definition_loc } in let off = width_of_ty ty + off in let acc = acc @ [field] in (off, acc) ) (0,[]) fields in check_for_duplicates fields; { fields; name = name.txt; len; endian } let ($.) l x = Longident.Ldot (l, x) let cstruct_id = Longident.Lident "Cstruct" let mode_mod s = function |Big_endian -> cstruct_id$."BE"$.s |Little_endian -> cstruct_id$."LE"$.s |Host_endian -> cstruct_id$."HE"$.s |Bi_endian -> cstruct_id$."BL"$.s let mode_mod loc x s = Exp.ident ~loc {loc ; txt = mode_mod s x} type op = | Op_get of named_field | Op_set of named_field | Op_copy of named_field | Op_blit of named_field | Op_sizeof | Op_hexdump | Op_hexdump_to_buffer let op_name s op = let parts = match op with | Op_get f -> ["get"; s.name; f.name] | Op_set f -> ["set"; s.name; f.name] | Op_copy f -> ["copy"; s.name; f.name] | Op_blit f -> ["blit"; s.name; f.name] | Op_sizeof -> ["sizeof"; s.name] | Op_hexdump -> ["hexdump"; s.name] | Op_hexdump_to_buffer -> ["hexdump"; s.name; "to_buffer"] in String.concat "_" parts let op_pvar ~loc s op = Ast.pvar ~loc (op_name s op) let op_evar ~loc s op = Ast.evar ~loc (op_name s op) let get_expr loc s f = let m = mode_mod loc s.endian in let num x = Ast.eint ~loc x in match f.ty with |Buffer (_, _) -> let len = width_of_field f in [%expr fun src -> Cstruct.sub src [%e num f.off] [%e num len] ] |Prim prim -> [%expr fun v -> [%e match prim with |Char -> [%expr Cstruct.get_char v [%e num f.off]] |UInt8 -> [%expr Cstruct.get_uint8 v [%e num f.off]] |UInt16 -> [%expr [%e m "get_uint16"] v [%e num f.off]] |UInt32 -> [%expr [%e m "get_uint32"] v [%e num f.off]] |UInt64 -> [%expr [%e m "get_uint64"] v [%e num f.off]]]] let type_of_int_field ~loc = function |Char -> [%type: char] |UInt8 -> [%type: Cstruct.uint8] |UInt16 -> [%type: Cstruct.uint16] |UInt32 -> [%type: Cstruct.uint32] |UInt64 -> [%type: Cstruct.uint64] let set_expr loc s f = let m = mode_mod loc s.endian in let num x = Ast.eint ~loc x in match f.ty with |Buffer (_,_) -> let len = width_of_field f in [%expr fun src srcoff dst -> Cstruct.blit_from_string src srcoff dst [%e num f.off] [%e num len]] |Prim prim -> [%expr fun v x -> [%e match prim with |Char -> [%expr Cstruct.set_char v [%e num f.off] x] |UInt8 -> [%expr Cstruct.set_uint8 v [%e num f.off] x] |UInt16 -> [%expr [%e m "set_uint16"] v [%e num f.off] x] |UInt32 -> [%expr [%e m "set_uint32"] v [%e num f.off] x] |UInt64 -> [%expr [%e m "set_uint64"] v [%e num f.off] x]]] let type_of_set ~loc f = match f.ty with |Buffer (_,_) -> [%type: string -> int -> Cstruct.t -> unit] |Prim prim -> let retf = type_of_int_field ~loc prim in [%type: Cstruct.t -> [%t retf] -> unit] let hexdump_expr ~loc s = [%expr fun v -> let buf = Buffer.create 128 in Buffer.add_string buf [%e Ast.estring ~loc (s.name ^ " = {\n")]; [%e op_evar ~loc s Op_hexdump_to_buffer] buf v; print_endline (Buffer.contents buf); print_endline "}" ] let hexdump_to_buffer_expr ~loc s = let prim_format_string = function | Char -> [%expr "%c\n"] | UInt8 | UInt16 -> [%expr "0x%x\n"] | UInt32 -> [%expr "0x%lx\n"] | UInt64 -> [%expr "0x%Lx\n"] in let hexdump_field = function | Ignored_field -> [%expr ()] | Named_field f -> let get_f = op_evar ~loc s (Op_get f) in let expr = match f.ty with |Prim p -> [%expr Printf.bprintf buf [%e prim_format_string p] ([%e get_f] v)] |Buffer (_,_) -> [%expr Printf.bprintf buf "" [%e Ast.estring ~loc (field_to_string f)]; Cstruct.hexdump_to_buffer buf ([%e get_f] v)] in [%expr Printf.bprintf buf " %s = " [%e Ast.estring ~loc f.name]; [%e expr]] in [%expr fun buf v -> [%e Ast.esequence ~loc (List.map hexdump_field s.fields)]] let op_expr loc s = function | Op_sizeof -> Ast.eint ~loc s.len | Op_hexdump -> hexdump_expr ~loc s | Op_hexdump_to_buffer -> hexdump_to_buffer_expr ~loc s | Op_get f -> get_expr loc s f | Op_set f -> set_expr loc s f | Op_copy f -> let len = width_of_field f in [%expr fun src -> Cstruct.to_string src ~off:[%e Ast.eint ~loc f.off] ~len:[%e Ast.eint ~loc len] ] | Op_blit f -> let len = width_of_field f in [%expr fun src srcoff dst -> Cstruct.blit src srcoff dst [%e Ast.eint ~loc f.off] [%e Ast.eint ~loc len]] let field_ops_for = function | Ignored_field -> [] | Named_field f -> let if_buffer x = match f.ty with |Buffer (_,_) -> [x] |Prim _ -> [] in List.concat [ [Op_get f] ; if_buffer (Op_copy f) ; [Op_set f] ; if_buffer (Op_blit f) ] let ops_for s = ( [Op_sizeof] @ List.concat (List.map field_ops_for s.fields) @ [Op_hexdump_to_buffer; Op_hexdump; ]) (** Generate functions of the form {get/set}__ *) let output_struct_one_endian loc s = List.map (fun op -> [%stri let[@ocaml.warning "-32"] [%p op_pvar ~loc s op] = [%e op_expr loc s op]]) (ops_for s) let output_struct _loc s = match s.endian with | Bi_endian -> (* In case of Bi-endian, create two modules - one for BE and one for LE *) let expr_be = Mod.structure (output_struct_one_endian _loc {s with endian = Big_endian}) and expr_le = Mod.structure (output_struct_one_endian _loc {s with endian = Little_endian}) in [{pstr_desc = Pstr_module {pmb_name = {txt = Some "BE"; loc = _loc}; pmb_expr = expr_be; pmb_attributes = []; pmb_loc = _loc;}; pstr_loc = _loc;}; {pstr_desc = Pstr_module {pmb_name = {txt = Some "LE"; loc = _loc}; pmb_expr = expr_le; pmb_attributes = []; pmb_loc = _loc;}; pstr_loc = _loc;} ] | _ -> output_struct_one_endian _loc s let type_of_get ~loc f = match f.ty with |Buffer (_,_) -> [%type: Cstruct.t -> Cstruct.t] |Prim prim -> let retf = type_of_int_field ~loc prim in [%type: Cstruct.t -> [%t retf]] let op_typ ~loc = function | Op_sizeof -> [%type: int] | Op_hexdump_to_buffer -> [%type: Buffer.t -> Cstruct.t -> unit] | Op_hexdump -> [%type: Cstruct.t -> unit] | Op_get f -> type_of_get ~loc f | Op_set f -> type_of_set ~loc f | Op_copy _ -> [%type: Cstruct.t -> string] | Op_blit _ -> [%type: Cstruct.t -> int -> Cstruct.t -> unit] (** Generate signatures of the form {get/set}__ *) let output_struct_sig loc s = List.map (fun op -> Sig.value (Val.mk (Loc.make (op_name s op) ~loc) (op_typ ~loc op))) (ops_for s) type enum_op = | Enum_to_sexp | Enum_of_sexp | Enum_get | Enum_set | Enum_print | Enum_parse | Enum_compare type cenum = { name : string Loc.t; fields : (string Loc.t * int64) list; prim : prim; sexp : bool; } let enum_op_name cenum = let s = cenum.name.txt in function | Enum_to_sexp -> sprintf "sexp_of_%s" s | Enum_of_sexp -> sprintf "%s_of_sexp" s | Enum_get -> sprintf "int_to_%s" s | Enum_set -> sprintf "%s_to_int" s | Enum_print -> sprintf "%s_to_string" s | Enum_parse -> sprintf "string_to_%s" s | Enum_compare -> sprintf "compare_%s" s let enum_pattern ~loc {prim; _} = let pat_integer f suffix i = Pat.constant (Pconst_integer(f i, suffix)) in match prim with | Char -> (fun i -> Ast.pchar ~loc (Char.chr (Int64.to_int i))) | (UInt8 | UInt16) -> pat_integer Int64.to_string None | UInt32 -> pat_integer (fun i -> Int32.to_string (Int64.to_int32 i)) (Some 'l') | UInt64 -> pat_integer Int64.to_string (Some 'L') let enum_integer ~loc {prim; _} = let expr_integer f suffix i = Exp.constant (Pconst_integer(f i, suffix)) in match prim with | Char -> (fun i -> Ast.echar ~loc (Char.chr (Int64.to_int i))) | (UInt8 | UInt16) -> expr_integer Int64.to_string None | UInt32 -> expr_integer (fun i -> Int32.to_string (Int64.to_int32 i)) (Some 'l') | UInt64 -> expr_integer Int64.to_string (Some 'L') let declare_enum_expr ~loc ({fields; _} as cenum) = function | Enum_to_sexp -> [%expr fun x -> Sexplib.Sexp.Atom ([%e Ast.evar ~loc (enum_op_name cenum Enum_print)] x) ] | Enum_of_sexp -> [%expr fun x -> match x with | Sexplib.Sexp.List _ -> raise (Sexplib.Pre_sexp.Of_sexp_error (Failure "expected Atom, got List", x)) | Sexplib.Sexp.Atom v -> match [%e Ast.evar ~loc (enum_op_name cenum Enum_parse)] v with | None -> raise (Sexplib.Pre_sexp.Of_sexp_error (Failure "unable to parse enum string", x)) | Some r -> r ] | Enum_get -> let getters = (List.map (fun ({txt = f; _},i) -> Exp.case (enum_pattern ~loc cenum i) [%expr Some [%e Ast.econstr ~loc f []]] ) fields) @ [Exp.case [%pat? _] [%expr None]] in Exp.function_ getters | Enum_set -> let setters = List.map (fun ({txt = f; _},i) -> Exp.case (Ast.pconstr ~loc f []) (enum_integer ~loc cenum i) ) fields in Exp.function_ setters | Enum_print -> let printers = List.map (fun ({txt = f; _},_) -> Exp.case (Ast.pconstr ~loc f []) (Ast.estring ~loc f) ) fields in Exp.function_ printers | Enum_parse -> let parsers = List.map (fun ({txt = f; _},_) -> Exp.case (Ast.pstring ~loc f) [%expr Some [%e Ast.econstr ~loc f []]] ) fields in Exp.function_ (parsers @ [Exp.case [%pat? _] [%expr None]]) | Enum_compare -> [%expr fun x y -> let to_int = [%e Ast.evar ~loc (enum_op_name cenum Enum_set)] in Stdlib.compare (to_int x) (to_int y) ] let enum_ops_for {sexp; _} = Enum_get :: Enum_set :: Enum_compare :: Enum_print :: Enum_parse :: if sexp then [ Enum_to_sexp ; Enum_of_sexp ] else [] let enum_type_decl {name; fields; _} = let decls = List.map (fun (f,_) -> Type.constructor f) fields in Type.mk ~kind:(Ptype_variant decls) name let output_enum ~loc cenum = Str.type_ Recursive [enum_type_decl cenum] :: List.map (fun op -> [%stri let[@ocaml.warning "-32"] [%p Ast.pvar ~loc (enum_op_name cenum op)] = [%e declare_enum_expr ~loc cenum op] ]) (enum_ops_for cenum) let enum_op_type ~loc {name; prim; _} = let cty = Ast.tconstr ~loc name.txt [] in let oty = match prim with | Char -> [%type: char] | (UInt8|UInt16) -> [%type: int] | UInt32 -> [%type: int32] | UInt64 -> [%type: int64] in function | Enum_get -> [%type: [%t oty] -> [%t cty] option] | Enum_set -> [%type: [%t cty] -> [%t oty]] | Enum_print -> [%type: [%t cty] -> string] | Enum_parse -> [%type: string -> [%t cty] option] | Enum_to_sexp -> [%type: [%t cty] -> Sexplib.Sexp.t] | Enum_of_sexp -> [%type: Sexplib.Sexp.t -> [%t cty]] | Enum_compare -> [%type: [%t cty] -> [%t cty] -> int] let output_enum_sig loc (cenum:cenum) = Sig.type_ Recursive [enum_type_decl cenum] :: List.map (fun op -> let name = enum_op_name cenum op in let typ = enum_op_type ~loc cenum op in Sig.value (Val.mk (Loc.make name ~loc) typ)) (enum_ops_for cenum) let constr_enum = function | {pcd_name = f; pcd_args = Pcstr_tuple []; pcd_attributes = attrs; _} -> let id = match attrs with | [{attr_name = {txt = "id";_}; attr_payload = PStr [{ pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant cst; pexp_loc = loc; _}, _); _}] ;_ }] -> let cst = match cst with | Pconst_integer(i, _) -> Int64.of_string i | _ -> loc_err loc "invalid id" in Some cst | _ -> None in (f, id) | {pcd_loc = loc; _} -> loc_err loc "invalid cenum variant" let get_len = function | [{attr_name = {txt = "len"; loc}; attr_payload = PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant (Pconst_integer (sz, None)); _}, _); _}] ; _}] -> let n = int_of_string sz in if n > 0 then Some n else loc_err loc "[@len] argument should be > 0" | [{attr_name = {txt = "len"; loc}; _} ] -> loc_err loc "[@len] argument should be an integer" | _ -> None let constr_field {pld_name = fname; pld_type = fty; pld_loc = loc; pld_attributes = att; _} = let sz = match get_len fty.ptyp_attributes, get_len att with | Some sz, None | None, Some sz -> Some sz | Some _, Some _ -> loc_err loc "multiple field length attribute" | None, None -> None in let fty = match fty.ptyp_desc with | Ptyp_constr ({txt = Lident fty; _}, []) -> fty | _ -> loc_err fty.ptyp_loc "type identifier expected" in parse_field loc fname.txt fty sz let cstruct decl = let {ptype_name = name; ptype_kind = kind; ptype_attributes = attrs; ptype_loc = loc; _} = decl in let fields = match kind with | Ptype_record fields -> List.map constr_field fields | _ -> loc_err loc "record type declaration expected" in let endian = match attrs with | [{attr_name = {txt = endian; _}; attr_payload = PStr []; _}] -> endian | [_] -> loc_err loc "no attribute payload expected" | _ -> loc_err loc "too many attributes" in create_struct loc endian name fields let cenum decl = let {ptype_name = name; ptype_kind = kind; ptype_attributes = attrs; ptype_loc = loc; _} = decl in let fields = match kind with | Ptype_variant fields -> fields | _ -> loc_err loc "expected variant type" in let width, sexp = match attrs with | ({attr_name = {txt = width; _};attr_payload= PStr [];_}) :: ({attr_name = {txt = "sexp"; _};attr_payload = PStr []; _}) :: [] -> width, true | ({attr_name = {txt = width; _};attr_payload= PStr [];_}) :: [] -> width, false | _ -> loc_err loc "invalid cenum attributes" in let n = ref Int64.minus_one in let incr_n () = n := Int64.succ !n in let fields = List.map constr_enum fields in let fields = List.map (function | (f, None) -> incr_n (); (f, !n) | (f, Some i) -> n := i; (f, i) ) fields in let prim = match ty_of_string width with | None -> loc_err loc "enum: unknown width specifier %s" width | Some p -> p in { name; fields; prim; sexp; } let signature_item' mapper = function | {psig_desc = Psig_extension (({txt = "cstruct"; _}, PStr [{pstr_desc = Pstr_type(_, [decl]); _}]), _); psig_loc = loc} -> output_struct_sig loc (cstruct decl) | {psig_desc = Psig_extension (({txt = "cenum"; _}, PStr [{pstr_desc = Pstr_type(_, [decl]); _}]), _); psig_loc = loc} -> output_enum_sig loc (cenum decl) | other -> [mapper other] let structure_item' mapper = function | {pstr_desc = Pstr_extension (({txt = "cstruct"; _}, PStr [{pstr_desc = Pstr_type(_, [decl]); _}]), _); pstr_loc = loc} -> output_struct loc (cstruct decl) | {pstr_desc = Pstr_extension (({txt = "cenum"; _}, PStr [{pstr_desc = Pstr_type(_, [decl]); _}]), _); pstr_loc = loc ; _ } -> output_enum ~loc (cenum decl) | other -> [mapper other] class mapper = object inherit Ast_traverse.map as super method! signature s = List.concat (List.map (signature_item' super#signature_item) s) method! structure s = List.concat (List.map (structure_item' super#structure_item) s) end let () = let mapper = new mapper in Driver.register_transformation "ppx_cstruct" ~impl:mapper#structure ~intf:mapper#signature ocaml-cstruct-6.2.0/ppx/ppx_cstruct.mli000066400000000000000000000000001437471254600201720ustar00rootroot00000000000000ocaml-cstruct-6.2.0/ppx_cstruct.opam000066400000000000000000000024771437471254600175620ustar00rootroot00000000000000opam-version: "2.0" maintainer: "anil@recoil.org" authors: ["Anil Madhavapeddy" "Richard Mortier" "Thomas Gazagnaire" "Pierre Chambart" "David Kaloper" "Jeremy Yallop" "David Scott" "Mindy Preston" "Thomas Leonard" "Etienne Millon" ] homepage: "https://github.com/mirage/ocaml-cstruct" license: "ISC" dev-repo: "git+https://github.com/mirage/ocaml-cstruct.git" bug-reports: "https://github.com/mirage/ocaml-cstruct/issues" doc: "https://mirage.github.io/ocaml-cstruct/" tags: [ "org:mirage" "org:ocamllabs" ] build: [ ["dune" "subst"] {dev} ["dune" "build" "-p" name "-j" jobs] ["dune" "runtest" "-p" name "-j" jobs] {with-test} ] depends: [ "ocaml" {>= "4.08.0"} "dune" {>= "2.0.0"} "cstruct" {=version} "ounit" {with-test} "ppxlib" {>= "0.16.0"} "ppx_sexp_conv" {with-test} "sexplib" {>="v0.9.0"} "cstruct-sexp" {with-test} "cppo" {with-test} "cstruct-unix" {with-test & =version} "ocaml-migrate-parsetree" {>= "2.1.0" & with-test} "lwt_ppx" {>= "2.0.2" & with-test} ] synopsis: "Access C-like structures directly from OCaml" description: """ Cstruct is a library and syntax extension to make it easier to access C-like structures directly from OCaml. It supports both reading and writing to these structures, and they are accessed via the `Bigarray` module.""" ocaml-cstruct-6.2.0/ppx_test/000077500000000000000000000000001437471254600161625ustar00rootroot00000000000000ocaml-cstruct-6.2.0/ppx_test/basic.expected000066400000000000000000000003051437471254600207640ustar00rootroot00000000000000deadbeef deadbeef foo = { a = 0x7 b = 0x2c c = 0xbeef d = 61 62 63 64 65 66 67 68 } "\007\000,\000\000\190\239abcdefgh" with_ignored_field = { a = 0x1 c = 0x3 } ocaml-cstruct-6.2.0/ppx_test/basic.ml000066400000000000000000000115331437471254600176000ustar00rootroot00000000000000(* * Copyright (c) 2016 Hannes Mehnert * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) [%%cstruct type foo = { a : uint8_t; b : uint16_t; c : uint32_t; d : uint8_t [@len 8] } [@@big_endian] ] [%%cstruct type bar = { a : uint8_t; b : uint16_t; c : uint32_t; d : uint8_t [@len 8] } [@@big_endian] ] [%%cstruct type lbar = { a : uint8_t; b : uint16_t; c : uint32_t; d : uint8_t [@len 8] } [@@little_endian] ] (* see #72 [%%cstruct type hbar = { a : uint8_t; b : uint16_t; c : uint32_t; d : uint8_t [@len 8] } [@@host_endian] ] *) [%%cstruct type bibar = { a : uint8_t; b : uint16_t; c : uint32_t; d : uint8_t [@len 8] } [@@bi_endian] ] (** This should not emit any warnings *) [%%cstruct type unused = { a : uint8_t; b : uint16_t; c : uint32_t; d : uint8_t; e : uint8_t; [@len 16] } [@@big_endian] ] let set_with_ignored_field__b = true let _ : bool = set_with_ignored_field__b [%%cstruct type with_ignored_field = { a : uint8_t; _b : uint8_t; c : uint8_t; } [@@little_endian] ] let _ : bool = set_with_ignored_field__b (** This should not emit any warnings either *) [%%cenum type unused_cenum = | DROPPED [@id 0xfffe] | ERROR [@id 0xffff] | OKAY [@id 0] | NULL [@id 1] [@@int16_t] [@@sexp] ] (** Duplicate _ fields are OK *) [%%cstruct type with_several_ignored = { x : int8_t ; _y : int8_t ; z : int8_t ; _y : int8_t } [@@little_endian] ] let tests () = (* Test basic set/get functions *) let be = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_foo)) in for i = 0 to 255 do set_bar_a be i; assert(get_bar_a be = i) done; let le = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_bar)) in for i = 0 to 255 do set_foo_a le i; assert(get_foo_a le = i) done; let bibe = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout BE.sizeof_bibar)) in for i = 0 to 255 do BE.set_bibar_a bibe i; assert(BE.get_bibar_a bibe = i) done; let bile = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout LE.sizeof_bibar)) in for i = 0 to 255 do LE.set_bibar_a bile i; assert(LE.get_bibar_a bile = i) done; let be = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_foo)) in for i = 0 to 65535 do set_bar_b be i; assert(get_bar_b be = i) done; let le = Cstruct.of_bigarray(Bigarray.(Array1.create char c_layout sizeof_bar)) in for i = 0 to 65535 do set_foo_b le i; assert(get_foo_b le = i) done; let bibe = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout BE.sizeof_bibar)) in for i = 0 to 65535 do BE.set_bibar_a bibe i; assert(BE.get_bibar_a bibe = i mod 256) done; let bile = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout LE.sizeof_bibar)) in for i = 0 to 65535 do LE.set_bibar_a bile i; assert(LE.get_bibar_a bile = i mod 256) done; let be = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_foo)) in let rec fn = function |i when i < 0l -> () |i -> set_bar_c be i; assert(get_bar_c be = i); fn (Int32.sub i 0x10l) in fn 0xffffffff_l; let le = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_bar)) in let rec fn = function |i when i < 0l -> () |i -> set_foo_c le i; assert(get_foo_c le = i); fn (Int32.sub i 0x10l) in fn 0xffffffff_l; (* Get/set buffers and blits *) let s1 = "deadbeef" in set_foo_d s1 0 be; assert(copy_foo_d be = s1); let sb1 = get_foo_d be in blit_bar_d sb1 0 le; assert(copy_bar_d le = s1); Printf.printf "%s %s\n" (copy_foo_d be) (copy_bar_d le); (* Create sub-view and shift it back *) let be = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_foo)) in set_foo_a be 7; set_foo_b be 44; set_foo_c be 0xbeef_l; set_foo_d "abcdefgh" 0 be; (* get a subview *) let be2 = Cstruct.shift be 3 in assert(Cstruct.BE.get_uint32 be2 0 = 0xbeef_l); assert(Cstruct.BE.get_uint32 be 3 = 0xbeef_l); assert(get_foo_b be = 44); assert(get_foo_a be = 7); hexdump_foo be; print_endline (Sexplib.Sexp.to_string_hum (Cstruct_sexp.sexp_of_t be)); hexdump_with_ignored_field (Cstruct.of_hex "010203") let () = tests () ocaml-cstruct-6.2.0/ppx_test/basic.mli000066400000000000000000000000001437471254600177340ustar00rootroot00000000000000ocaml-cstruct-6.2.0/ppx_test/dune000066400000000000000000000002321437471254600170350ustar00rootroot00000000000000(tests (names pcap basic enum) (deps http.cap) (libraries cstruct-unix sexplib cstruct-sexp) (preprocess (pps ppx_cstruct)) (package ppx_cstruct)) ocaml-cstruct-6.2.0/ppx_test/enum.ml000066400000000000000000000041411437471254600174600ustar00rootroot00000000000000(* * Copyright (c) 2016 Hannes Mehnert * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) [%%cenum type foo64 = | ONE64 | TWO64 | THREE64 [@@uint64_t] [@@sexp] ] [%%cenum type bar64 = | ONE64 | TWO64 [@id 0xfffffffffffffffeL] | THREE64 [@@uint64_t] [@@sexp] ] [%%cenum type foo32 = | ONE32 | TWO32 [@id 0xfffffffel] | THREE32 [@@uint32_t] ] [%%cenum type bar16 = | ONE [@id 1] | TWO | FOUR [@id 4] | FIVE [@@uint16_t] ] [%%cenum type foo16 = | ONE16 | TWO16 | THREE16 [@@uint16_t] ] [%%cenum type foo8 = | ONE8 | TWO8 | THREE8 [@@uint8_t] ] [%%cenum type reversed = | ONE_R [@id 2] | TWO_R [@id 1] [@@uint8_t] ] let tests () = ignore(int_to_foo64 2L); ignore(int_to_foo32 1l); ignore(int_to_foo16 1); ignore(int_to_foo8 1); ignore(foo64_to_int ONE64); ignore(foo32_to_int ONE32); ignore(foo16_to_int ONE16); ignore(foo8_to_int ONE8); assert(bar16_to_int FOUR = 4); assert(bar16_to_int FIVE = 5); assert(foo32_to_int TWO32 = 0xfffffffel); assert(foo32_to_int THREE32 = 0xffffffffl); assert(int_to_foo32 0xfffffffel = Some (TWO32)); assert(int_to_foo32 0xffffffffl = Some (THREE32)); assert(string_to_foo16 "ONE16" = Some ONE16); assert(foo8_to_string ONE8 = "ONE8"); assert(compare_foo8 ONE8 TWO8 = -1); assert(compare_foo8 TWO8 ONE8 = 1); assert(compare_foo8 TWO8 TWO8 = 0); assert(compare_reversed ONE_R TWO_R = 1) let () = tests () ocaml-cstruct-6.2.0/ppx_test/errors/000077500000000000000000000000001437471254600174765ustar00rootroot00000000000000ocaml-cstruct-6.2.0/ppx_test/errors/README.md000066400000000000000000000012051437471254600207530ustar00rootroot00000000000000This tests error cases for `ppx_cstruct`. It only deals with the errors raised by the ppx itself (such as when the type is not supported), not errors in the generated code. To add a test case: - create a file in this directory named `something.ml` with the error case - create an empty file named `something.ml.expected` - don't forget to add these files to git - run `dune runtest`: it displays a diff on `dune.inc` - run `dune promote`: it updates `dune.inc` with the generated test case - run `dune runtest`: it runs the test and displays a diff against the empty expected output - run `dune promote`: it updates `something.ml.expected` ocaml-cstruct-6.2.0/ppx_test/errors/cenum_id_payload.ml000066400000000000000000000000571437471254600233260ustar00rootroot00000000000000[%%cenum type t = A [@id ""] [@@uint8_t] ] ocaml-cstruct-6.2.0/ppx_test/errors/cenum_id_payload.ml.expected000066400000000000000000000000371437471254600251240ustar00rootroot00000000000000Error: ppx_cstruct: invalid id ocaml-cstruct-6.2.0/ppx_test/errors/cenum_invalid_type.ml000066400000000000000000000000551437471254600237060ustar00rootroot00000000000000[%%cenum type t = A of int [@@uint8_t] ] ocaml-cstruct-6.2.0/ppx_test/errors/cenum_invalid_type.ml.expected000066400000000000000000000000521437471254600255030ustar00rootroot00000000000000Error: ppx_cstruct: invalid cenum variant ocaml-cstruct-6.2.0/ppx_test/errors/cenum_no_attribute.ml000066400000000000000000000000361437471254600237150ustar00rootroot00000000000000[%%cenum type t = | A ] ocaml-cstruct-6.2.0/ppx_test/errors/cenum_no_attribute.ml.expected000066400000000000000000000000551437471254600255160ustar00rootroot00000000000000Error: ppx_cstruct: invalid cenum attributes ocaml-cstruct-6.2.0/ppx_test/errors/cenum_not_a_variant.ml000066400000000000000000000000561437471254600240440ustar00rootroot00000000000000[%%cenum type t = { x : uint8_t } ] ocaml-cstruct-6.2.0/ppx_test/errors/cenum_not_a_variant.ml.expected000066400000000000000000000000521437471254600256400ustar00rootroot00000000000000Error: ppx_cstruct: expected variant type ocaml-cstruct-6.2.0/ppx_test/errors/cenum_unknown_attribute.ml000066400000000000000000000000541437471254600250000ustar00rootroot00000000000000[%%cenum type t = | A [@@uint9_t] ] ocaml-cstruct-6.2.0/ppx_test/errors/cenum_unknown_attribute.ml.expected000066400000000000000000000000721437471254600266000ustar00rootroot00000000000000Error: ppx_cstruct: enum: unknown width specifier uint9_t ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_attribute_payload.ml000066400000000000000000000001071437471254600253110ustar00rootroot00000000000000[%%cstruct type t = { a : uint8_t } [@@little_endian ""] ] ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_attribute_payload.ml.expected000066400000000000000000000000621437471254600271110ustar00rootroot00000000000000Error: ppx_cstruct: no attribute payload expected ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_duplicate_field.ml000066400000000000000000000001331437471254600247110ustar00rootroot00000000000000[%%cstruct type dup = { x : uint8_t; y : uint8_t; x : uint8_t; } [@@little_endian] ] ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_duplicate_field.ml.expected000066400000000000000000000001021437471254600265050ustar00rootroot00000000000000Error: ppx_cstruct: field x is present several times in this type ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_len_int32.ml000066400000000000000000000001131437471254600233670ustar00rootroot00000000000000[%%cstruct type t = { a: uint8_t [@len 8l] } [@@little_endian] ] ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_len_int32.ml.expected000066400000000000000000000000711437471254600251720ustar00rootroot00000000000000Error: ppx_cstruct: [@len] argument should be an integer ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_len_not_int.ml000066400000000000000000000001131437471254600241020ustar00rootroot00000000000000[%%cstruct type t = { a: uint8_t [@len ""] } [@@little_endian] ] ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_len_not_int.ml.expected000066400000000000000000000000711437471254600257050ustar00rootroot00000000000000Error: ppx_cstruct: [@len] argument should be an integer ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_len_zero.ml000066400000000000000000000001121437471254600234060ustar00rootroot00000000000000[%%cstruct type t = { a: uint8_t [@len 0] } [@@little_endian] ] ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_len_zero.ml.expected000066400000000000000000000000621437471254600252120ustar00rootroot00000000000000Error: ppx_cstruct: [@len] argument should be > 0 ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_multiple_len.ml000066400000000000000000000001261437471254600242670ustar00rootroot00000000000000[%%cstruct type t = { a : (uint8_t [@len 2]) [@len 3] } [@@little_endian] ] ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_multiple_len.ml.expected000066400000000000000000000000641437471254600260700ustar00rootroot00000000000000Error: ppx_cstruct: multiple field length attribute ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_not_a_record.ml000066400000000000000000000000341437471254600242320ustar00rootroot00000000000000[%%cstruct type t = int ] ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_not_a_record.ml.expected000066400000000000000000000000651437471254600260360ustar00rootroot00000000000000Error: ppx_cstruct: record type declaration expected ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_not_an_identifier.ml000066400000000000000000000001071437471254600252550ustar00rootroot00000000000000[%%cstruct type t = { a : uint8_t list } [@@little_endian] ] ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_not_an_identifier.ml.expected000066400000000000000000000000551437471254600270570ustar00rootroot00000000000000Error: ppx_cstruct: type identifier expected ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_several_attributes.ml000066400000000000000000000001251437471254600255040ustar00rootroot00000000000000[%%cstruct type t = { a : uint8_t } [@@little_endian] [@@other_attr] ] ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_several_attributes.ml.expected000066400000000000000000000000501437471254600273010ustar00rootroot00000000000000Error: ppx_cstruct: too many attributes ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_unknown_endian.ml000066400000000000000000000000771437471254600246200ustar00rootroot00000000000000[%%cstruct type t = { a : uint8_t } [@@unknown_endian] ] ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_unknown_endian.ml.expected000066400000000000000000000001611437471254600264120ustar00rootroot00000000000000Error: ppx_cstruct: unknown endian unknown_endian, should be little_endian, big_endian, host_endian or bi_endian ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_unknown_type.ml000066400000000000000000000000761437471254600243420ustar00rootroot00000000000000[%%cstruct type t = { a : uint9_t } [@@little_endian] ] ocaml-cstruct-6.2.0/ppx_test/errors/cstruct_unknown_type.ml.expected000066400000000000000000000000511437471254600261330ustar00rootroot00000000000000Error: ppx_cstruct: Unknown type uint9_t ocaml-cstruct-6.2.0/ppx_test/errors/dune000066400000000000000000000006661437471254600203640ustar00rootroot00000000000000(executable (name pp) (modules pp) (preprocess (action (run %{bin:cppo} -V OCAML:%{ocaml_version} %{input-file}))) (libraries ppx_cstruct ocaml-migrate-parsetree)) (executable (name gen_tests) (modules gen_tests)) (include dune.inc) (rule (targets dune.inc.gen) (deps (source_tree .)) (action (with-stdout-to %{targets} (run ./gen_tests.exe)))) (rule (alias runtest) (action (diff dune.inc dune.inc.gen))) ocaml-cstruct-6.2.0/ppx_test/errors/dune.inc000066400000000000000000000140141437471254600211240ustar00rootroot00000000000000 (rule (deps pp.exe (:input cenum_id_payload.ml)) (targets cenum_id_payload.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cenum_id_payload.ml.expected cenum_id_payload.ml.errors))) (rule (deps pp.exe (:input cenum_invalid_type.ml)) (targets cenum_invalid_type.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cenum_invalid_type.ml.expected cenum_invalid_type.ml.errors))) (rule (deps pp.exe (:input cenum_no_attribute.ml)) (targets cenum_no_attribute.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cenum_no_attribute.ml.expected cenum_no_attribute.ml.errors))) (rule (deps pp.exe (:input cenum_not_a_variant.ml)) (targets cenum_not_a_variant.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cenum_not_a_variant.ml.expected cenum_not_a_variant.ml.errors))) (rule (deps pp.exe (:input cenum_unknown_attribute.ml)) (targets cenum_unknown_attribute.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cenum_unknown_attribute.ml.expected cenum_unknown_attribute.ml.errors))) (rule (deps pp.exe (:input cstruct_attribute_payload.ml)) (targets cstruct_attribute_payload.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cstruct_attribute_payload.ml.expected cstruct_attribute_payload.ml.errors))) (rule (deps pp.exe (:input cstruct_duplicate_field.ml)) (targets cstruct_duplicate_field.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cstruct_duplicate_field.ml.expected cstruct_duplicate_field.ml.errors))) (rule (deps pp.exe (:input cstruct_len_int32.ml)) (targets cstruct_len_int32.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cstruct_len_int32.ml.expected cstruct_len_int32.ml.errors))) (rule (deps pp.exe (:input cstruct_len_not_int.ml)) (targets cstruct_len_not_int.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cstruct_len_not_int.ml.expected cstruct_len_not_int.ml.errors))) (rule (deps pp.exe (:input cstruct_len_zero.ml)) (targets cstruct_len_zero.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cstruct_len_zero.ml.expected cstruct_len_zero.ml.errors))) (rule (deps pp.exe (:input cstruct_multiple_len.ml)) (targets cstruct_multiple_len.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cstruct_multiple_len.ml.expected cstruct_multiple_len.ml.errors))) (rule (deps pp.exe (:input cstruct_not_a_record.ml)) (targets cstruct_not_a_record.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cstruct_not_a_record.ml.expected cstruct_not_a_record.ml.errors))) (rule (deps pp.exe (:input cstruct_not_an_identifier.ml)) (targets cstruct_not_an_identifier.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cstruct_not_an_identifier.ml.expected cstruct_not_an_identifier.ml.errors))) (rule (deps pp.exe (:input cstruct_several_attributes.ml)) (targets cstruct_several_attributes.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cstruct_several_attributes.ml.expected cstruct_several_attributes.ml.errors))) (rule (deps pp.exe (:input cstruct_unknown_endian.ml)) (targets cstruct_unknown_endian.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cstruct_unknown_endian.ml.expected cstruct_unknown_endian.ml.errors))) (rule (deps pp.exe (:input cstruct_unknown_type.ml)) (targets cstruct_unknown_type.ml.errors) (action (progn (with-stderr-to %{targets} (run ./pp.exe -no-color --impl %{input})) (bash "sed -i.bak '1d' %{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff cstruct_unknown_type.ml.expected cstruct_unknown_type.ml.errors))) ocaml-cstruct-6.2.0/ppx_test/errors/gen_tests.ml000066400000000000000000000012051437471254600220210ustar00rootroot00000000000000let output_stanzas name = Printf.printf {| (rule (deps pp.exe (:input %s)) (targets %s.errors) (action (progn (with-stderr-to %%{targets} (run ./pp.exe -no-color --impl %%{input})) (bash "sed -i.bak '1d' %%{targets}")))) (rule (alias runtest) (package ppx_cstruct) (action (diff %s.expected %s.errors))) |} name name name name let is_test = function | "pp.ml" -> false | "pp.pp.ml" -> false | "gen_tests.ml" -> false | e -> Filename.check_suffix e ".ml" let () = Sys.readdir "." |> Array.to_list |> List.sort String.compare |> List.filter is_test |> List.iter output_stanzas ocaml-cstruct-6.2.0/ppx_test/errors/pp.ml000066400000000000000000000005321437471254600204470ustar00rootroot00000000000000(* we can just use exit from 4.07 onwards, but 4.06 * and earlier executed at_exit recursively *) external sys_exit : int -> 'a = "caml_sys_exit" let () = at_exit (fun () -> sys_exit 0) #if OCAML_VERSION >= (4,8,0) let () = Clflags.(error_style := Some Short) #endif let () = Clflags.(color := Some Never) let () = Ppxlib.Driver.standalone () ocaml-cstruct-6.2.0/ppx_test/http.cap000066400000000000000000006473451437471254600176510ustar00rootroot00000000000000Ôò¡ÿÿƒ³L_ó 66Ìà/Ÿì³³jûE (Sâ@øì•$§ gÁ—Míè:ŒPHу³L¨O BBÌà/Ÿì³³jûE 4i7@0Ÿ/•$§ gÁ—Mîè:€Nùá €e\û2¶ qƒ³L,q BB³³jûÌà/ŸìE4 @@6| •$§Á—gè:MÐñR 2¶ ¨€dãÑ'ƒ³LFé LL³³jûÌà/ŸìE>¢4ÿx  Õû5*O?ažen wikipediaorg(ƒ³LßË Ìà/Ÿì³³jûEp@Bm  5Õûú¢—až€en wikipediaorgÀ  text wikimediaÀÀ.Y textpmtpaÀ3ÀK ÐP˜À£c0org afilias-nstinfoÀ£a0ÀwÀ£b2org afilias-nstÀÀ£d0À­À£b0À­À£a2Àw(ƒ³LL© LL³³jûÌà/ŸìE>i~ÿ:.  Õû5*O?ažen wikipediaorg(ƒ³L{« Ìà/Ÿì³³jûE~ @ã¼  5Õûúã‚až€en wikipediaorgÀ  text wikimediaÀÀ.X textpmtpaÀ3ÀK ÐP˜À£d0org afilias-nstÀÀ£a0org afilias-nstinfoÀ£a2À˜À£c0À˜À£b2ÀwÀ£b0Àw(ƒ³LsÙ NN³³jûÌà/ŸìE@3!@@“B ÐP˜ÁšP“hÃs°ÿÿkü´ 2¶ 2(ƒ³Lªž JJÌà/Ÿì³³jûE <@2ÔGÐP˜ PÁšÅì “hÃt  ej gœ®2¶ 2 (ƒ³L$­ BB³³jûÌà/ŸìE4ü@@Êj ÐP˜ÁšP“hÃtÅ쀀Ð)ä 2¶ 2gœ®(ƒ³Lcë ¿¿³³jûÌà/ŸìE±K(@@yÊ ÐP˜ÁšP“hÃtÅ쀀Ðêî 2¶ 2gœ®GET / HTTP/1.1 Host: en.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive (ƒ³LE¤ BBÌà/Ÿì³³jûE 4p½@2c’ÐP˜ PÁšÅì“hÄñ€©" gœµ2¶ 2(ƒ³LD¬ ttÌà/Ÿì³³jûE fp¾@2a_ÐP˜ PÁšÅì“hÄñ€›£ gœµ2¶ 2HTTP/1.0 301 Moved Permanently Date: Mon, 11 Oct 2010 21:35:13 GMT Server: Apache Cache-Control: s-maxage=1200, must-revalidate, max-age=0 Vary: Accept-Encoding,Cookie Last-Modified: Mon, 11 Oct 2010 21:35:13 GMT Location: http://en.wikipedia.org/wiki/Main_Page Content-Encoding: gzip Content-Length: 20 Content-Type: text/html; charset=utf-8 X-Cache: HIT from sq61.wikimedia.org X-Cache-Lookup: HIT from sq61.wikimedia.org:3128 Age: 23 X-Cache: HIT from sq64.wikimedia.org X-Cache-Lookup: HIT from sq64.wikimedia.org:80 Connection: keep-alive (ƒ³Lù¬ VVÌà/Ÿì³³jûE Hp¿@2c|ÐP˜ PÁšÅî@“hÄñ€|F gœµ2¶ 2‹(ƒ³LÝÊ BB³³jûÌà/ŸìE4Íj@@ù ÐP˜ÁšP“hÄñÅî@€€C&º 2¶ 3gœµ(ƒ³L Ì BB³³jûÌà/ŸìE4*@@¸E ÐP˜ÁšP“hÄñÅîT€€>&« 2¶ 3gœµ(ƒ³L‡æ Íͳ³jûÌà/ŸìE¿³@@Ñ ÐP˜ÁšP“hÄñÅîT€€Ð# 2¶ 4gœµGET /wiki/Main_Page HTTP/1.1 Host: en.wikipedia.org Accept-Encoding: gzip, deflate Accept-Language: en-us User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 Connection: keep-alive (ƒ³L²©QQÌà/Ÿì³³jûE CpÀ@2a€ÐP˜ PÁšÅîT“hÆ|€b˜ gœÂ2¶ 4HTTP/1.0 200 OK Date: Mon, 11 Oct 2010 21:35:31 GMT Server: Apache Cache-Control: private, s-maxage=0, max-age=0, must-revalidate Content-Language: en Vary: Accept-Encoding,Cookie Last-Modified: Mon, 11 Oct 2010 21:35:16 GMT Content-Encoding: gzip Content-Length: 15474 Content-Type: text/html; charset=UTF-8 X-Cache: HIT from sq75.wikimedia.org X-Cache-Lookup: HIT from sq75.wikimedia.org:3128 Age: 5 X-Cache: HIT from sq64.wikimedia.org X-Cache-Lookup: HIT from sq64.wikimedia.org:80 Connection: keep-alive (ƒ³LÛ­  Ìà/Ÿì³³jûE ’pÁ@2^0ÐP˜ PÁšÅðc“hÆ|€éÿ gœÂ2¶ 4‹Õ}kÉqàçå¯ÈíõŠ$Ä~Î 9rJÎËYq–ÎpWWhdwew§ºª¶3lÊ È°†ïƒqg?`È'Ø€ ßá$ù ^û«°ú$÷ÅÆáp÷."òQY¯™n²÷­Nç;222ã‘‘Q÷ß=xºú«ÇÙ,ûìøùƒ'‡û¬Õîv?ÙØïvNØ·Ÿ=aýNƦ»-´˜ëÅ»-?©½à.üI½ÔÎ'Þ™ ×ã·X:l ÁD0^Œý²ïwe½k÷ç"å Çk‹Ï2ï|·µ©Òöé"-6–©ÝV*^¥]ÿÏxœˆt÷ùé£öv‹u/ëå$]ø¢¶¯q’Xm>»­©DÌÓ0¶*!¼8ÀyÿöÅ|²)›ù^pÆbáï¶xÁi˜gmÚµØ,ƒEt.4:—åú(˜–ûLfaœŽ³”Ùv'üœÀ?•‚ÇãY‹¥0U ’7æ¸Â]Àx K]‘Œc/Âܯ¿Â•TÝ^Xu†X©Í"è —h·eÖ’ÝÁÍò¸ã0ZÄÞt––f=Ž .Æá| M@Âa’îhÑNxw£ÓëVpé§"x*êf+3—€W@Ûƒ"6µ&å®x…Sù†¬~‰±ÇýgÀH÷g@Æ"ùŸG÷°á.ö^Á*’O2¢<½‘—&´¬s³¬É™$í~g« ³êι´awt€Ô¾1ØÞx­ç”Óµ†a[¸ŸÖ1¸Dx7M"Ü_ÈÐòÏqìéÕãGXím†¿èB—@V@ I÷yÂGžï¥‹ÃŽ7"@ AyàcîS¿§$îû_9@ŠD^~–‰xÑÎ<ÀßÎ@‚†¿o] õ›slgŸÖÇ"âÏ1O¦c>ž‰Ý…ÚcÇ~ðHWLæüŸŠÝÁí;Û›½åñ1îÌݘ_P²Xã+œƒ¡®_Ô–¤ÛK'ñ˜îLøî/r3Ã[Nåc¢ç_Fšj_=&el°Kã]5¾ä±vµ—üœË\”ÎyÌðÈÜmÉ3 uëÁñt¶Ô1 .¦Ïcÿ8ÓpúJ^ûôÓO?íÂÿ SIžœØe^<ÎÓ0š‰8O§ÂDš§ƒÀnzƾ{è˳€Ãùié_ ÄùkÉy`Š Ð½8õƾ8¦ÙuqJÝ_éSÉ aDXYõñ¹Û"A$/). |Ìc©=Ì„û‰ ±iQ1/ÙýÎçÔˆÏEÜ(šQû<9ü@&L">†e,(AâHëäšeóŒÓÃLS­uÁ“ÔÝ©”a0“™L 2І'.lüº»ý­­íÞÆMÌ=LTþng4ôóDÄ4Jù¾Îø ³()d=©'CÚFžf%ÝJþàÎÅ8£|‚ûYüLœ{¸8ÑÆö­Í-€‰BÄrÍŒ˜Œ¹>òÅÞñ¡Tæ|{i!û6‰Þ¤ÕLÂx~Šõv_îY«õm¬sàM½ô’rD%b²³  OSášE¢hµ­&e|ì§ÝǤZ_ÌèaPÁ)÷Ï0A›˜ØÐ –ªâMÌ1²)ælrLÅÛ˜ýÈó&îè„)Þ6°aS̹[È1û橘G>ŠÎ˜Ó·sòŠùcáG”ÚЩ¼Á¾m¦a¼ œ-;Ç’Æ<5EbªßëçV5šÄƒ0TÉ»:)«|^Ø6‡.®(ƒ³Lб  Ìà/Ÿì³³jûE ’pÂ@2^/ÐP˜ PÁšÅõÁ“hÆ|€0• gœÂ2¶ 4 yP­=€‰Z Höq¡wXþPÛ†9.èŸCU´i³·!½i§u¥-Èœ úwØmõSÝ4‚ ½m§u¥»ŠÆ:€Ó³ÒºNœ!Æá÷@ý6…æXcÒ›VÚTB0#‰h¤g’¦F!’1±­y1zi4¤jêÞ7‡œ;ý6“—‡%lQypY´Lç ÁçÁz!÷å©>‹€E[ñ““l êUªI°Y¾…Ø#†¬˜p®Œ~újp[þÚýŽü{*âyò9æætþŽù)K9²äÔÊÚò/zß.Àw$’f@錩Æ(¼#Áa!‡Ú>ƒTì¬]/…–É" £JáQx.Š…|}¹p„&ÇpÚÍ‘ÚS>Måßi…§™üé‹sá'ŠÀ?Ë8*ŠÆAîX\¶Ï?—ë”âIhËÄv>ÑÒÃQˆÁ^‚yyôÂ퇾ϣă?âç²ñ™€5LR‹jÀ± ìN\èãßT“á1ˆ]"$³‡YÆ2)Oè` q¾dîZë½k÷»R´u´à›Äã•ÌXLõ^Ö˜ lÑÙŒt…Œ½2R W‘0Ô ¶j¯ü%õsZu˜ù…¢øõU ®ÒyÒ•žAN 4Aƒw_ÑØ ”ùÙ°Q&é¯ uȦ«Uà·¦¡âü¢“é¡;Üu5ÛºñëRlϳö<ŒÅõëGð‡ ö(Û'×oéÚÖaÖV¡öÁÏáKg^Â"hÁæ|ÁÆ+¶3–†Ìá7h…Gû)åÏø9VuEçÓàpBYÇ ‘Û1/¸EYc0uHËÔÀPn >m!;…ŒOa b¡,¤Þbå|¤“ÏÂ>JÛòÌBòü†Zh×½@Î7Ot:ëŸß¼×@RoÕöã<DŒzS 8ñÒKün»ý›0?e‡ÙoɉŠÙ àŒBwñ‘¤za¼“Åþ T{+æe¨; #îÌÒqëæç0öæÜ÷…\oòív»2‹åŒhéxiì8d«CRÖ’“¾ n„p:lìó$ÙÍ%h@BÌ`>=ü'ÉFÈWˆâÚFI&+I[Iœkï¼sßõΙçB/mª:â ^ëÈ®ƒPšä¨W®°\YÖGßû0ÄžÕ…Ê&8Þ¹Ï)˜*¶æ2ÏìeÒžËý „Œ‹²‹Â ˆÁ‹ Ä=kLüÆM@؈˪¡ó±H2`hH0$1÷eì2î&l»[æ=SÕnµ_]4ñâ$} xÁ-¨ÇœõiH»Ì`¬éíºo XÛ-– ì°›OÑ*“(–M@6öá,5Pr’ZΣ8œ³«o ¶%Œ•~i²mŠêhjñiÀJ_•föTåe6àä¬t‹ùí4l£ø©š~YpÊî0 1i±|OoËjÞ”.ÂænÉy½H€-GþÕ„ùNâ<¦wt))’ªÒhD'Ÿ!ê ÏMg; ¾øølƒÜèî¼7¹ÿ»!þŒ wú˜C­0vE¼Ó^±$ô=—½çºî=¼>NcüÇ-v}»=cƒcð½^¯'+L…jƒí^ôÊtN[̆Gí¹†1T(ƒ³Lµ††Ìà/Ÿì³³jûE xpÃ@2^HÐP˜ PÁšÅû“hÆ|€¿Å gœÂ2¶ 4cœx­i°ƒÛKÄ÷ØÅ ¨¬Mz#ôqó¨ .¥êmD¬æµØéß¼_‚Fbb§wÎ8wÆN§ø(t÷‰ðAxÈeͲJΓëß•›ÏV~×Nd¡VÛ† ñÿõž\€Ê»[ïØ¸_Jƒ=‚í3Ôç3™9q‡áh妭Mgš2⾄.ÒOç»sˆLÖ͈AU'_,v@,lí½þíÞ=6ä”tp Ž$i.õ-ÒujIº†$rômúJpk 4òÕôqb`®)r6nmnlß î"< ŠC¼Ây•̆Z³pKFÂk9*{Ôî¦.ýÓ¿¸}Lfy3ô7Þ¯Òȵû™O÷*åéJ[ß(®ù<í<ÿ•@ãKzxà…SØ^³E¹›¼À1?—éTÚúóÇü´:ìÒL׈›Ç°ÖhÚ+¡³õc™9qجs^ ªš"ÇJ,ÓíÉØC±ºÜ¥ÎvÔ¯I'!Œ‘V¤³õc™ÙœŠñ,€CuZéÍ*qòߥ>G Ý*Ù$QéÊTÊ=ß—ç´Ôª¥Õá°´3 L7‹¢ ÃeòxR<å6ðÒþ¯Êó"†<‡!§³¡ìô½ÉƒJ#mm½_dzÇb2½ÏßšL&ü…$Å;2upïiààj‚¾˜ä§o]ãšAò)ÌtKÍVj†³[&¼=˜!Ö6H`°ºÖs²Øø §iùB ‡ÓÎ(ôÝ:|ðÑdÔ/0 œVaâ†ñ#f½Î&°c` °6ÑŽ¤¨‡¢i‹À? ]¾è î$Éài w¨¸Ð0–]O˜.ÑüT0èèl6 ªš +‰?5¢L޲V bÙVôª,ô€ò‘ÊÉj§³EÓ»«'Éz6‰—\;GãiŒ×—Q®bȉœÏû¾ÇçìhüU…޼ù”q?­)+˜q²µ¢²!G‹ ]^²ù¨ëvÝA׆¤ {+zÕ.G›a—®¼@ÏBR€ÄÖ¼î·ùlTs~(0‡9˜s+çèƒÝèooÞþùwÿ}ÿn¿“]ð„ñŠ„°—$pH’v0DÃóˆÜÔXV!3…¯É•‚ˆ;÷àKt«3¥ñ>öP-÷x0q.ê™\†¹N!IÒ)ÈÔ!óä°‹€h©²á&1š{JÎÄð‘‚nøDði–Ó”1]ÆTI´¥L94ƒÊ)bà0A^Ï›ùTQO–\:loB›‡d› ¦Yæp^Í’™[ì3ÏròßRÒ­Èõ¼P=ñ¹ioe9ùoÝ>)Ë"6Ê8#’ÑÇË€P#rBSIÇ¥¿šÄØHŒù§}ú瀺óC8‚sÔŒýlT%·íc X>|ÔÙïX¤Œ 8VŽ&o<ƒ}Äð"Æ„i‰y ²0!à\H¸¾2#¤‚ÏI.Fé–°4AD_—ꈘÚÃXz¬xÁ S£s{a–°1G>˜z"¹ÙІúŽb‘x.´¸Å¤)º!о èçA‡¬¿½½} H £]£Ž40`1óyŒ¦Í±€j›%MgÃÆ3Ï`<§=ÎæB ¹Äá(Ȥœ`–š+ô¢Ñ€ÓL4}‰:¹{еA ]Cÿ·ØÔ#ž tK‘ýÀø 2ÄÜÞ+ä" !e‚Cÿ‰àI³?•–ZÄ$L>Ë) µQrGrÚ íØöÀh½å ñHÍ–Âà Ð.9ŸJîäRë #ŽB F½´(f±fJ•è„ô(ƒ³LY BB³³jûÌà/ŸìE4’Y@@4 ÐP˜ÁšP“hÆ|Åðc€€L"õ 2¶ 4gœÂ)ƒ³LèBB³³jûÌà/ŸìE4ó4@@Ó: ÐP˜ÁšP“hÆ|Åû€x  2¶ 5gœÂ)ƒ³LõBB³³jûÌà/ŸìE4ws@@Nü ÐP˜ÁšP“hÆ|Æc€~' 2¶ 5gœÂ)ƒ³L¨…  Ìà/Ÿì³³jûE ’pÄ@2^-ÐP˜ PÁšÆc“hÆ|€/† gœÉ2¶ 4“0ozűbõg‹]¡xÀX%´GoPéÞM¢P(*œÊW4óhHÑŠSEËœZÇ)îEòüö°5'h»Çj.°ø¢9À-3Ç(L‹iCõY„$¨QJ›˜g)ôKÄOí­]Ùa7ÞŠoáMC§ÓÑìêæýnDÌPºYhZBÙa­ò*„ý,ÍæÚC¦ró{n1`€µ8ÒI¡‹)ìË,ÃÉð1ðÈUdªÄt%vˆÔ +9—•Ò‚Ö Âþy¸~p¼µeF‘yŒò+!±ÕIMÊk¾bŽ®Y mî ™ïý:y°û.ØÛÃA¯ß«1”4I‹º£v °gpþуfoD®… _á1Q¾'Cg@ØlTæ“°ëBÆ¢­jûfª %{Fl¶S®ê/êô©G1·í£* ç’äR ú+½Ap4@$ªºI6š{ètlk5R 8Y I”»‘^¦ ºÅ “||+ D/ý[ÁŠÊí»oŠì[57ODBx˜#W¥õCªtk¹®¨[kí¸‚‚]]ˆx5p"壣§YÓò V«BFÙ\'zrÚBQ^ØBÙÁ’jQñ‚J–"\v©3¯Ë–ƒ¥AYBb)Py­Q[Žc`ñb˜Œga˜xT6SÙNTHãkÜ€G<>>Š=á‚´7¼ñèøäðf>s(dº©B§«Wæ–mõ!ÅÈKPg9‘f¼`')èç°¸‡€*/ÍRÐbåûÕì&ÔŠE´agÀ$Ô\QãÖ·h6í;®!ëO8ZV’ÔÒ¬,'ÿ]KßÇ"’…Š<· ?V¦c§dŠŽfh÷‚íÿ2¡ D ÁÂõÜ7^¢ÍêÆèÔs÷ý‡ƒ÷·{ïßÝø(<m-t‡O'tf;ÖžV•õëj,¯æ\^n6Ú(ÏÁ“xb*j¨×tTºž=™â·"ácOâ$} @|ÃG^à"WÏIA°¼À)ç˜I+Ò-÷ ÂU ]¢ GĹ,*‹˜]äTóC¾Ôô:ÜÃ$ïXg3™íÓÔ!²ôB’.~•ŽðiäE9]˜tÝÒŒd¡‚tæù@Ó´Ÿ]bƒrg«·´±èÚÐÆ—¦ ö°úÙ€hͽácüòÙÉlf²ë@*ÖÉ9âÝ;oL:dsÙÚ®œ§âÏ“)‡þÔ¹E<Q6ÂWìèØ§‹áçBÁD’ŸžyEF™ªÈtE'¯Q7ÐóÎIgx"Ôûy%üAÓyuh)ƒ³LWËBB³³jûÌà/ŸìE4”.@@2A ÐP˜ÁšP“hÆ|ÆÁ€€Ð  2¶ 5gœÉ)ƒ³L:Ì  Ìà/Ÿì³³jûE ’pÅ@2^,ÐP˜ PÁšÆÁ“hÆ|€3õ gœÉ2¶ 4³*ÔõùQ8GyÆôgÒu}²°? ÃOf(£,žæÓÌÎwJf·Eq…‰2úÊ1™ðsWÑ2:l,O²( 0î#‡ÍÑc#˜©:LÕ©EWsšöË ½;D²æ½Žq}˜o÷‡øz,Ð êMáÄÎE@–¡O΄´k¢ÙÜL;€|»ÏLS&›2h zuÞìí-Ç´È9v-\ƒ®7‚k€£l¬—l‘Ã…'N-l9l›oÛŽ´¹ l²E“ü¹ ¶Xwù  g\UEÞÑý B‰W#ÚÜ\Þèû{{Ã#Í'_ ‡r䜕ãc+Ë1 [±#T·a‡,oÃì6uû©¦é8ÑÐËš¥Ù‡Á8•wx †Oø4´TÊg‚Q¾SÊÐë{=·âO„`1ºÇW/úöèâÈÇûRýôsY#/aªÄÙ{~ð+ØýFopk«×ÓìsÐëm«[…³¹¸¹KS—&ƒÁô ƒ µÏˆ|ã »û6óAV €ûp2bc–óAŠÞÁ‹ùxÝvÌm‰Lš½V3V¿‘9î*ty_º’Bm<#ªÃ`%¥u÷ 8¿c4â"÷œ¸tÐSûaçŽmµë½íŽm*:GÖˆex•UЗm× |÷*ö`º–‹€²šúWùûl6ùû¸“É âŠÃ'“ZŸŠºé¨q±\ÂáG¹Üá§hm÷Ò`9k»œÓZÛ{£ÉW`m? †°Ó‡L¡åÊm‰5XÙKvÀR­+ÏêöíŸî ÷~ôðäáÐ÷²WGáp ’l¾KlÝO¼Œ}‹*ÛVm+÷zàw»W‚¤ ÐK€^ëúƒ‰·µF71ˆ*c€CÑðˆ:ýid»àÈ”FÊå”ñ`Z«þ~7:É€ÆbÔ:M˜Ï¬|§”aŽI2ÏSEË,$7’еíÂK_—ú·ó+! aø`l{£³"ƒ¯qÜ ¦÷: Éðyh Ol¯Ãt#sTò2Y÷€ûbxÚ…1>¥žÂiwÚay‰CY&mV/©îÏðY7…cA˜½$á±çZ·˜V ÞªáØEy~>b <çBº[Õ‰}áHø ÷ÍÑX࣌üZ ½`ø ,kW÷­]dŸÒm _{ßbäýuV‘…hš9ɤ#ÿÖkž‹Ø2Ê”CÞD>,¯ÌöÖ _L8ø¯YÍz-çsŒ˜.ç' 7 û W…ˆ,UèÔå6®ær–Rl^õ×”Â.}¦Ç…ÅB! ‘áYÌŒì§íJS‚lË춸Æy[–·uÊ•J¥¤çT<›fò5Yá´ˆ7©7,½Õ·Üy°¢Æ_ O XÃ'܇)>S´ à 3ô‚Æ^~× uÕeT—Yu™®ë,Q‰`3ïùpn©Ö ¾èHF]÷j—žíSÔ¤Þš|ooYä ÿ½‚|Aæ 7?à 8 @çò ~TÈ å…N]nN¾¾|“UÓyæ„Së¾³˜ÌròßMF$弦ßiI²²›~¬¥JÚlI’#1y²ŽíϹ7æã—iGýP­3¥LdÜ÷´æø~/ÎRJ'Y„/÷’ZTèMù¾¹ ˜œ}ËÃêÝg*aÂÀ¢sël]TƇ†³`øpa™ödÃFN9ggèÝÛÖŠ ÿmzZv g‡õ[ß:<<´ô¶HH¸d¾SÊ þXmv¨š×€ „ø1úÆò rÈb¦Šó=_ŸŸÓw®êW¼½ÐX³:+:ô÷gYl=z&]Êtií#…BÕÚ5ã»T¼H&K´=­¼ˆé"GTò4§¾;gêÛ¯ú¶½êÛ´ê¹t¿.ÔˆÜ*r$°5õ+j=iyò½IÚ'V0A]²(Ò‚F1­¤ µd=³K@Æ œæ½ÖÕöâ2“Ù;Ù˹&ü·ž«9F1†Þ™—gª³bZùO®mVB{l{^ „°”¹7±ñ¡¤)ëIÞR’9>‰®yð¿Ïa¢æç Ûž)²¶ÅŸPkTb"_¼nlÚOc€Iê¦ š2jª­°L6eª)ƒ¦Nþ[¨z%J~å-ÂÖ0.êvºVª|䇱g©¬:í¨k9·ïX;è:w§é\<‰=@mp† èÛ>4¹Ý ™,dTȰЩ˥×}¬æÞð0pÑ7KZd¿)>€’+kY×±Š2Áª*r)ƒ³LVæBB³³jûÌà/ŸìE4i@@]Y ÐP˜ÁšP“hÆ|Æ €x  2¶ 5gœÉ)ƒ³LmæBB³³jûÌà/ŸìE4Y @@mb ÐP˜ÁšP“hÆ|Æ}€€ÐO 2¶ 5gœÉ)ƒ³LÂû  Ìà/Ÿì³³jûE ’pÇ@2^*ÐP˜ PÁšÆ}“hÆ|€xÈ gœÌ2¶ 5ѸÞT¦®m·VwüS-(ù…¥\›|&óR†ÑÒѸ * a:ýšÝù!ŸL›{SÒ‘¥S¸¶×VØòHC§<-Ÿò9 ÿ¡ð­Í›WÔ>ˆUd²¢sU MÜd½£x½:C°¼˜bÆÆsrþ“ï="tݪ¿ò•Ûµì êœ.Ö”¡‹ëØN}]›ö¥4’ˆá¬$Q–ã­æ[Á>W cìs¹ ÅØäz–}®gÙçŒ=øa”ƒ/?ò yäAuä5ò 0rɶó¶.‹'äLŽÈíÅÔ°ÕxꬾÁ/Ý{z-‹KC T…™Uäñ¼b¸é/¯Q¾S¸|¬ç J8‡)Þ¯áŲԆFǶ&öÿß[£ÂY/±Šêm\6¤î‡pêç¨;TÚ2¬Ê)Šem7U˜©Â¨ŠóütŸl®Õá£füXV"o4¢ tCL·š.ÄìovT>¦¯ÇìˆÒÔ¥M§xíÓeLK~¢+'(ê]à%×d›Y{¼°Ñåê_Œ¡ä[S¯xÏ´™Îkd»ž zªÛšÈ·ñ¡äïÊ1ÄÝêQôFaJ_¯\6ŽžƾË]ÅÛ6DË\áé¹¾ÑÞ£[¬~…÷Áõ”U\O•¼Í½T.ô{•Æ:Ž$2BdCLZ‰„Ëm9¦íû­iW}€drù«.²Á¡ßÇzÕ·trr¶ðñðàÈYgbxàÉÞܪ UÃöðÃ,ÃA¯w÷’›Õ}C¢³ÞèfdÒÜîàÞìÁÃŒ»ƒ-ô~£¶æzú°îWn[÷+%‡ýÓ*z§¼vª»1ø(£Lý(8¢ìòêrÆãs|››(c€4¿^T£Ï ‘ZöG•tFô×¼ŸôÒ~ÖajÄ„H¿-`µƒtÖ¤È×wÖ»{ÅhPÁ9…1ŒŸ0Ž Æ ñÆ] ½l_5Ì6ºŸýóg#Bö(¦]¬5UÔ‰cÉ4´+°”«Ât©æ&1o±d€®2J¬íÒ°X¦N),–Î_.,V.‰­*¥\]fVÜcu^Ò—6‘%ê )÷XQ¯òÚÁn‡pŒp2g€üŽ%ŒJû¦¤ÈñMëKPŽßSį¨ŸÕ š¾µHeŽùYX˽äŒ}–©ÏÍáY'+†Hœæu.‹WõL0§ SATL ÂϦ" €›s/ÆKæ{£˜>½šÜÊAƒÖÏ0 dœ0|ãï ùõž|FpDpd—‚Åøù DµúúK²ä¼(fáT £l^óz]̨رS…= É®4ÎÈê«1O¸žð'vœPIÄw0z8)´^’d* b„w Ö.9 üwà%¹ú°cu&¦ SUœrNaF€»b8QíMɵÁòÀÎ…E+@¥,][5S+/IŽšõ’súŸ­UçAÙ~L’U\"ÑÓ3’CÛ@šE¨ˆÃó-ôiúŠ ²àS·ŸhÑVbFK‚ý…‚áÃùŽŒE üTÎt)ƒ³LNÿ  Ìà/Ÿì³³jûE ’pÈ@2^)ÐP˜ PÁšÆÛ“hÆ|€<î gœÌ2¶ 5¹#“B&+4ešµ^RÈÇrÑÆ’?ÂúøyÜ":sÒ—m½dÖ©s­´ŽEê(ÉG]~^ Š#5QX_ ÁÌTh(¦xäE޵+„+þm Ri†ù*0Z^" G9W]ø0пÛ-ÖÓ!›¥ä¦¢¸a„W„%LC¹¥eû…Q&9qÇÞ§™…—z›ši¿ó4Ëñ„q–4Æ(j`dt9Õ‹Ïx¬Ø––Ó€Òøx–†—*x;Åg½ý­æ{%ZÑØ$YF‹Š×W£Wu-ÛÕ±U4µ¢Šv·{×íª¶ LÃöhù(Ȩ~®?möÕ'‰¼ üÔDi‚U_îú9.i“RС‡dÁkô-I³±ˆÂÄ“_ð(¹òjÔzv|lÇÀWy+®Äíîí^W7–K±U^Š-k)6š5ÙU–¢<Á%AZ³ mýµ6Y¾ž wÒxQ¿ª°´ :wÅu˜t'ƒnÞ|™•ØZãJØ]~-T«ÒjÈOcÐ9Å’žÅYRó.à­wÆ) [„ÊÊ{Df®¸8›ÝÍÛ]Óz‰µ¹äÀZvkä3[aoP£Òrà7šó°HXƒ˜ÞÚöˆ‡Ÿo:¦¨¬¼2sÅ5¸Ó½3éšÖŠil•™ÆÖRûcÙ5Èg¶ÂP£:6-¨¶Åœ} hM« åú†e…åuP¹+.Ĩ;’›A6_f%î¼õJX³[a)d«Ë˜…T]k=šè‰­¸\”"èd½Êª¨ìÕ—EîÕ~‰uy›Sª~’«¬ì Â;äg7ÈØTYÓQÞÅ Ë¡JËË¡³W\Ñ]«½\ŽÍ2ÓØ´úà­·‰=ÃÖÂrH/Z*†yèÅã~Ùrðö«3)¿t³A…6Âi¯Mž¹úFw©õWËCj¦µä’˜©•$ו²ÉÆú¶Ÿ4åK ¯–Ým«Y LˆdÛVÛ.Š6= “›Èñ“©¤ö2ü6‰/^Eœ>£.¯&èÃ2ÛÂEL!×öÌ£(_ògÐëõåÜk>ÉÜrä‹×ìŒÐËÒM FïÔéEƒ´R¹èº]JDÜ4¬|DK‘ùéã?ص|(´ÃŽðCìÒäa)¯çø9÷|$‡{,ÁúƒJ<žÊÏÈOý %‡îפñB¿ýÒkÙÞTWd£Úêõnõz=3þNÅÎ⊲ŸˆÜÓµFWìè+zój¾ÖsJn¶hI±V‹½šû;&åˆ,M0òº¢@î–µâR ×öþ›v±©À­xÚrpÃÄKpŸDøI§»Epäæ9à¸B›/þãq¯òI¼䓸 ¹ bÏn@‰|Û€CÊÁ÷_|{É:!÷Ò ÷Ò2䇩 šxŠ è^jƒî¡§¬®òÀ_òÀ/C~¥ˆr(0p¾ w@/­\_e}¿ä+@þ’—!§×¾"ì”à_rxH9ÿööoøÿëûÿi°G«`=ª`£Êã,´G´GN5ôdÁk{2*d޲iFH,J ”)GÕüâûk¥˜8[ü8+ƒ¯¾/Ân@‘=ÎlØ!å|ùG?ùŸüúO~ýË}ùƒ/hÃo–´a³¤þÖU,i¼ É+$¿ÏáÁ Œ-Š(~Lù¡Ú´NÌWáIã OÚ-ð”[i\àH(Wüãïˆäl±N¨g«ÐˬB/³`J·ÊìÆÌ¢˜Yb åñéÝ?Öxª‡«œêaòÂøBL r(ÌOö°p²‡-ççßý>ÔMÎØQx6ÿâÏü›?ÿî_¬U$ðV ¼Š)ƒ³L\  Ìà/Ÿì³³jûE ’pÉ@2^(ÐP˜ PÁšÆ9“hÆ|€O gœÌ2¶ 5HàR˜¢\&ð 2(e'Y8_ëA¯‚ÿ¸‚z$( ýqýÂÇ„_üIð¿±NГó@OÎ+âã4DŒC‘<9·!‡”s‚N}g|€§«HiEz<Íâ3<µÄÇ´ >BÊ9ýâ¿Çg_|O¬òìlȳ³2äÏÏbPˈ\ ÐÀžÙ°CÊùòO¿üÑO¾ûå_ýä¾ü;àP¿ê¯Ö9׳æñzV9åe¬4vŠÌ,^ÏìY@ÊùŸ?øËûýߺœ¯ |õJU¯B:¼B:{1ycvƒ[”à ”ƒoø~ö½þÍŸýðgý³?ÿçßþÙ^«öᮢ}¸í#pC@¼T@\Kq ˆÛrðO83 Ö9‰Ñt…IŒ¦åI<È|Íl¡ÐÌa4µç)çËßýÉoù·_þ lƒïJ!m³pW‘ÐÜŠ„v to×ÐÜ‚€†/W¡ú´­Ñd° »võ0Á'A²ÂâW¢À¯DHFYq­"Â*(ŸTP~Œ¦c$›‰…óIçrþù×ö=Ø»ó?~g°Ÿ­‚ø³ â¿ g‚~faý¬€uH9ÿ÷÷þðÿ׿ü?¿ÿ_Ö*¯b›U¬cÅ( [Ö±YÁ:)ç§òÓßýéŸÿô?þôûëÝ_E‹õ+Zì/eJ<ó--Ö/h±>~ñËivîýÓ߬U>[EXH*‰žs×KRH ’ºÏb-üã¿ó‚µžñÉ*f¤böP€Xv¤`÷H| ü?ýñúÁ_ELH*b‰ˆGD5‰%'$9RΗ 2ÚßKÖĺì$ŽÖlÅ9_E§:¯èTUã×kPR;·Ôªó‚Z)çÔû×ý}0e{ÿú·¿•^.±õ‹Æù+¶ù*ö„yÅžpÄ}¾`7æ–=a^°'@J ;Gêfkå¶«œ?¢rþ<įÝ ëô…ÓãÚ>D7õµÂ½Êî•ÝûA,<ÂÚ»¢°w!åüø÷~ü·ð¿ÿöã¿ûñü£¯Õ–x€d•-L *Û˜rµ“3ìfY+ßÑ”.ìj™ã[®uiV±T‰Š¥êO>Ë`; ËL% f*H93ÐØãµž¨ÓUHjZ%)Žïp+L-ªš¨ RÔÓµ ³UXÁ¬Â öã§Ò2hñ‚Y@ÊyŸótÍÇPyÿ~™m0¸Ä6øÑƒ—Ýd7 Zn% VÂÀ¶ªÅš­„é*†‡´bx8qÝH-«CZ°:@Êù—þæ¿üàþåRecõï^ÖgÆI¾êU²¬ÓMF³È¯Æ›¸t°£ãUXµUü¥TÞ• ëÂ]»vÿÝv›]ûH\C«¹—’xœ^;†¿q8IÆ,]!¿±ƒgÛ¾ƒ_$Âÿ®‡IÚ&O W=>Âïé¾;lkÐÛìuáŸmdô£E*’kæƒc<žf GÖí÷·î”ëâ§苽?'Á³ftU€lnv·‚vÛQÓ8áçÒwB5ãç”åsâ3±`"@4ïD”½ã¹Àûg;ý­­íÞÆÍvïÝþ»½w]1ᙟ¾û®ÞÝ|?}° B zÃjѧæéa#ü¯?èol ú ‡·_ZÒ;ËIÊw/Ï~5ä\‡çjUNõÚšÇnw–«‡«ÛRkúüGèèŽBw4I0¾£þ£¢1O¥£‹.ÑD}]—\Wó1¦ P¸?ó\W×5å#Vú5£Z:÷’ŒûûèµÕrr ­_ú}å)»35Ô`ÅBÌCç Xx•c6ªôªÆÖÁÁ$éôòu¤Ø"íHÄ †i6°)ƒ³Lo#BB³³jûÌà/ŸìE4á2@@å< ÐP˜ÁšP“hÆ|Æ —€€Ðò1 2¶ 5gœÌ)ƒ³Lc©  Ìà/Ÿì³³jûE ’pÊ@2^'ÐP˜ PÁ冗“hÆ|€9ý gœÐ2¶ 5öýÙ–s¬ X†è YP€çƒœ(H¼²‹´ÁJ'@~ãY±Òæú½A°ícó<á#Ï÷ÒÅaàoÁ8¦°M''42A*ÛµBÿk…=äÔ£Aü‚ z*›X(iÓéEOv0ÎŒ žªëåGae’~8õìY] ¾ˆŸ`u5Í9Ò°Ü_ 3rùlõ˜¾±•† F‚Í}Í ü 9¹.Qp•]Ž.™ö"üv‹ñ1\°éw[ø jŠÖ8tøŒé)LªpÄKšèö4çcb’¶~îMÕs0ÂG ‘…Áúr4Ÿ“ãè)%šœ>2•šIiÌÛF¨mcàÓW¢b9UB^Xø´º r¨Ò{Ö°ã"ªÆŠi:{ú{%>X ¿Yÿ?&YÄy¿ª(± PZ(ÕåMë`j^;™è—WæœÌÈiy]ŽD1àPé|!O\% ÅǪ™†AOû½–‚G. uÔ‹Ëd'ùª°ï”ø°ºo.? 5Ô%aiÚ;÷èU#Ù!AÔSœZYì`%RS8zm3ÝXwÿKŽÚ MÈ”s¢:Õá—ð(%%@; Oöîá1‚1`q8Š "Çd/D‘Ì„&3Ú&Ú!ÿŠ9¨ØèG*R‡Ï)ß`V¦;c´æ ‘Ó3½CŸä¦Ø‹YþY~ÕÓZ6ÊXB·ÔFÉ÷ÉÞX=ÞùJ·‰L Ê 'Àêð# Ÿã‡ˆ€£!cÉaeøÙ,Jf°ÜÀ„œ©),ô6–=HöˆÐzØK‘ؽ®D"†§>œ\…ª9ç~&,Y [·(s)ãÁ‰Üôœ)¡V«)Ê[Ò=;·@b™å§übR$– ÔU`Ñ'”q´Q–â'¹óáP†áz’@1PS».+_oQƺb%Ȥ;¼íþ>ò*±Aÿ ’v¿³Õ•Ö¥¸KIWBÓöÓÝß¿1ØÞxÝRq—Ðó]BTá.S™r•¶$SHÌ*  RRA½L)[¢ë~.[$ŠtDèï!ç1±hÞ;,‹ýË=Pï…ñ#·ó òÙÀù  Â% îæ½ÖÕBâ¥*¬iP¨|ÈíZÒ* Ó’x͹RURá"P·ˆ,öuÝÈ?:§æ\@@c´Â¤‡ж+’qìE’-6³¨æ©²¯‹»ä5ºl©ÂèZIeLýÙ*]nŒY~éeYŒU “‚Ú»¬Þ8žp£ÆmÖÄÐÑõŒ«”£…®Ÿ÷?F¢d.h9åºÍHô§¹0Qÿy¯Gp¾Z† Å—ô4ÐïÌg¿ŠŸk„T7œ+ ®ÇðŒªäêì0•?À©î$Ø‹WEšxÕržj4B@ò%‘ýù5zŽD‚ÒªÒǪ#&dé|(%“]7ÄЙ&O…l¾›ixl²Çðƒ{Ó`7‰ðQG ð3!Ô”vÉuRœâ¹ïÔsÝÒ&W&—‡{Ïö[ÝJއ–0ÉS¯8¬šúx8̳V?HË€½^¥Cè;{X§H¨š”âë´œ½bFãÒëØ7«GÒÙ3:‘z9…±ÝxЉHŠuCÌx²‰G¯ÖáIšâìÔí Š®6žaô‘ê^5›ƒjí«Z¹ ›e?Lu¤?†°qqÓÄæs€ªö¥§)WO5uTch}„öqxèPm˧i!«qà™ð£Ê¨îªþçr*Ä{4t–È訖Øãc«l¯ò6‘Ù§OŸ>yðô[—m(Ò‘–wOÃÐ…¯.Û+Õ’¶‘ÐÈp‡ôÕHŸ@­)ƒ³LE±  Ìà/Ÿì³³jûE ’pË@2^&ÐP˜ PÁšÆ%õ“hÆ|€I¤ gœÐ2¶ 5'Xë1Ôªa¬Ú$Í}ßÜåbaD1„Ô 3d}ÒR(?¸©5›—EêyÙrpPU+­¢5‡qcƒ}µ–ÄŸPÝšù<«¹œƒì\G¢7°Ÿa§e*¦R-é_õ_>5)^²3žË Æ]”’pH`HªY.д¬òZ˜ò‘Õ§˜#~Ù¡þóiMÄm$ýAg‰¾Ÿú ´1»Â Eøê®÷ùJ-;ô]h½±}gks«·‘ÊᘞðÉWöÁ™!ÆXœ{‰õ t)L+—6·o\f8L~ßSl»/\ íaQ>R'˜Ó!œ|…´órÚ>hd4Ú¤Ô Å+úàùÞO®`Íê%;m„'ùkôeÙ³C¢¾­MVñ|Qx«z§T¢ÊptE·¤+½¦ìõ0ž[¦ÉåÝ SuU¿z yR¨ÉÓ¬E_gü‚“&Dz€¾Ð*#ÿ“½Ê÷ưÏD«¤*ÔòÊܾŽ=£k>õ¼s1T‘Ö‡{i{£ -€í“Åžï‰áF§7| %H¸Ã'jHG·fª5«oÍT"ŠKÁ«uÐx„\ÕLº£E;á]€¤k(Ø!ïI÷Ž{×0F$ÅÂÆHñ “Ä´ÙQ˜ªàÓWÞÕÃJ÷ñK_ã—󯸽_üÏašñ%| úÖºU¹ –ªÄìÌïåÉ |dm_Í¢KZÝù9Fâ/p§êèö­)NQí¨Õ¼ùäÁ¤½ùÌPCÓëp{ûÕF_ƶ5mû&Îíö¶r÷;–Mñ;.GØQ™‡½-cªnžŸX–ÞíÙê9˜ºméuXË‹àÚ³0š+ß‘©“7ÆW2;£D¾ŸÅ"‡'žï½â~4ã:OzÇYþ¢ ìžs™ <Û›°0…À /:^rtrøpk‹Ý4½Ü¸yÝïÊÚÖ¨Å1®]1Ž¡†ˆ³à)Ý=󛬄±ò¡.ï²@…Sz~«1‹ÊñŒÓ¡¿&I)‰Ï½»x±ßëô6{,㤃¢åÀ+¿féæÿëÙ¶ëì)ƒ³LæÛBB³³jûÌà/ŸìE4æ@@à` ÐP˜ÁšP“hÆ|Æ,Õ€}Àèþ 2¶ 6gœÐ)ƒ³LÔNN³³jûÌà/ŸìE@Ùÿʦ  çÈ5,)ÏÌbits wikimediaorg)ƒ³LÃÕ³³jûÌà/ŸìE  @@¼ ÐP˜ÁšP“hÆ|Æ,Õ€€Ð{¤ 2¶ 7gœÐGET /w/index.php?title=MediaWiki:Common.css&usemsgcache=yes&ctype=text%2Fcss&smaxage=2678400&action=raw&maxage=2678400 HTTP/1.1 Host: en.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: text/css,*/*;q=0.1 Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³LÙÕNN³³jûÌà/ŸìE@ÈP@@þ ÐP˜Á›P¼%¹°ÿÿá´ 2¶ 7)ƒ³L^'NN³³jûÌà/ŸìE@v@@µí ÐP˜ÁœP?^ °ÿÿ]†´ 2¶ 7)ƒ³Lw'NN³³jûÌà/ŸìE@}l@@H÷ ÐP˜ÁPŒ ¤°ÿÿ/Œ´ 2¶ 7)ƒ³L 77Ìà/Ÿì³³jûE )pÍ@2aÐP˜ PÁšÆ,Õ“hÈS€Ã gœä2¶ 7HTTP/1.0 200 OK Date: Mon, 11 Oct 2010 21:35:35 GMT Server: Apache Cache-Control: public, s-maxage=2678400, max-age=2678400, max-age=2592000 Content-Encoding: gzip Vary: Accept-Encoding Content-Length: 6625 Expires: Wed, 10 Nov 2010 21:35:35 GMT Content-Type: text/css; charset=UTF-8 X-Cache: HIT from sq75.wikimedia.org X-Cache-Lookup: HIT from sq75.wikimedia.org:3128 Age: 2 X-Cache: HIT from sq64.wikimedia.org X-Cache-Lookup: HIT from sq64.wikimedia.org:80 Connection: keep-alive )ƒ³L€¤  Ìà/Ÿì³³jûE ’pÎ@2^#ÐP˜ PÁšÆ.Ê“hÈS€éa gœä2¶ 7‹Í<ýsÔ¸’¿ç¯Ð›Ü°o<_É„$î ,u°Ë-콺¢R”ÆÖÌxã±ülÃ,Åÿ~Ý-É–ly&°{¡*Ä–Üjµú[j dO ¹ÎCÁž..zaQôž±‡ì`ø#{Ãã”e|!Ø<þ, |§¥È7ñ]„r•%¢I\”ì˃Ÿ¹LË`#âŲƒ\GqÉ6qÉ +¥Lf<§Y˜¿ÕàKñd’}~BoV<_Äi J¹:g'ø^A|C-L5gOeòŒñ4bO× Qí0ˆ´d2é³êaôW›N£õ¼NƘ£ÁT¬êQï+—°LHl9g¹˜‹\¤!¬ ¬Ñ‡ï,/Åù¯bŽ}noY±âI"h¾ƒº{@¯ÙV/Xÿ!ÎÙÙè3ÚO@ŽI$Ã;ÕÃáh³d ÈH [’±”мŒeŠÉÄŠ=tÏK˜–(ûÅ:«Ûê·Oa\ýÖ 7ãáÝ"—ë4^K$,íáÕõMµ´i±ÎbF$(ù,€D^Т(rÝ8 ù $~d°j0Ì ±uPò±p*s Ö‹Tå6õ{ÀQyoãtAο ð…™ò À‡pA P–®W33ãH†ërÔ««¢Ï6K˜EB¨n,ðm*‚K¹I€à¬s!R$gK€+õñÓÙºÄ~k Ü ×>LÖ@@zÐ,Gm±O€àr3þ·•ˆb°_Ó³vèÁ~™&[ÝÞÒŠ(_õü¯Äœ¯Àè@b[Ì7“ZC#  Þ'Y?ágõ%4 „–€@ÈwÎÙ8ûÌ ™Ä;äœ#›8*—Ð0a•¤ž3¾.%¶;ŠÇªÓÓðM)>—pÝ> jP|›ñ(¶¡q‰ÌÿΚAFƒî€nÚ8ÑøÂº”\<ýÎ6S_(bTZTå9 p EFR(ÀhwDÔW×'}ZørÉË“w|ûH ¿hœ‚2.ѯùL~3‘ÈMßJ¹¤åõ¡Ââ=‚"&(C£GÏC+HÄsŒª±~™+q+…iBÝ‘µXà%½µÖ}³± €5C’E¾æšüji]÷=¨õ™Á±XÏ4š¶ÂU7ð߃ö‹ª‘2t—¢²ÁŠ)*}YA#²†N+^†Kk$4½°¾EtP ág>¯P|->[Ž}mÞp–§~¬(á`Ñ4‚ŸÖ ß -ˆjÄ6íÛX¶‡'â¤5ì‘oXhI=ËùÿUß_c§œx<34 E-eÎSàR0Våñ ôiC8J Ï ñb ŽDjó?|ôµþƒáƒe‰(å%š*ÐÖy´Mù*ÁAØ*ÙŽO$/8 f[2—j¸xå=2LÁ~çŸ8€8+ÑP(­ÑeZ¨Þ Ùø¸•ç—rµ’éà÷âöæª5bhË,Pmá4X±Ú²§h²Bày¹Š  XãGƒÒÊ]éòj˜‡ŒýUZ©×>ÍÉ9DbjZŠ'­U?ùo("üüS$È¢ƒ?™Ë•íǽÇqx~{Û×j·‰¾ËÌšì;¸f3å-|%õìÓWé\’`ëk•8ˆu“2ÊÝvÑë¢ÍÏðŸjÖïf t³kíݲ‘þ_ë)ƒ³Lå§  Ìà/Ÿì³³jûE ’pÏ@2^"ÐP˜ PÁšÆ4(“hÈS€~  gœä2¶ 7LË$ŽóÎá@VÙ[ýækp ^Ký°Ô÷¤D¦6 ¶Ðù*ä¹¶gFÖ;Aw4·û1DäÐ&0¼rÎÌ_þlü¬·Ë=”öÒ¼`Í!FäSV`?Džåòwš`NsîdT-D;X¨@°qð]Á¹¾ëžN8 Gg£nÞ9|æNØÜAÉ®>;èjQŽ¥v4Ðû©¾6ܱ‰ÎJ'º-l ±ˆ­zk¡JîX·gI,–"‡Í+rªÝø-Véx/f÷@«{Xi2.„\€#µÜ:¢Â u ö ž(b§§-KÅŸb " “bê^†ŽÒ¶ _ÃÿÒ2è‡=Ù'žØ šW&ø“Æé ‹=#»Ä´ß»4Tk©È…„«×ÒRwǨ'ô»úÛ‘„z€ÌÖÙéO¢4±QÚ1Ü~„v1Y=ø7¬Ò&û‡·úùHâr»ÉÅì&”Ýü8€©¡DE'’U‡½$²sC1ŽsPÞãYæ]/•é ôH~!Qð(Ê’˜3z—‰0æÉùó$Áä8\:W¤ 6ê϶à4sÝË4{j<ƒ×«Pê<å(D1ÎFa»:¯Ñø¤àé @ëýˆõc mDút|^¢7duøOð»d×wŸ°Ñ|†© Ð0ÌÊXZv•XçÉÃÞ²,³óáp÷ 0áI³È|1ħ Ÿ†!9«Åðhx4¾LåJ|,€úw"O%ÌòãÑ(û<ÈÒEz:T<ÕyEÒ,_ªò( ¢éYÔôT“XÁJ56¹9ÌóÚ¹² n&‹˜2nè Ù ³î’ ˜9êúOÄÔ]'.¡©˜ (·™Ð¹Öl‹WÀ@vb§ò½°“Xƒ7Tk¥F}ŸT_ÙJ|üÃ?$CþË%OÊiKËÇrÌY \Œ5„Ï#‰I0|+„iÔ·W7lÚ!tL¢‡€é8Ì€YË0P ”Þ½c…H@tdÖR“oä1X$’É_2‘s'‹Ì?,s1ÿ—‹Þ ‹æ½ÛÁ¬Ïš}~T}þõ>íN¾Á`R{á@ŸýƒA§Æ`VÖ{çìÚý:fØÙñ^·gê‡ç™mgG{à¶’ùå2Nކ¤Mô8@†ûÈÃ\Îx9XÄóÞ#OS‘-±6Ï×í´V:ßÈõ<ÝRR™>€©R×0á…bÿ‚­!ÎfAõ Û²J!ë®ìýza¦‘ŒÒ«ë>[§$‘Ò/G(alFâî:ºmÿïI­±F[,“õ L#E¨â¬p_§T)Ëš]ªÞÊ8£ÂÓŸV?•§BåZŸën:Òú-…~w4ÒÖdžyt˜GGƒ£6Ô‰êñý¡N¦m˜ã©æô`zf?žX¶÷ „È`™ìlˆ óVuß΅èO+dŒí£ÔZéj?ÁòòT䫊rdw…¶³Ó0ìÆi$¦óù“VÔdö%ܱ0Õ’êô´w4œ¡çMÌÅüþ£ýµY›ÊÇðµIñé4ÜÄŒã[õP[ɨ˜ Êç©åb)’¤(vÀÔ¬nvqí;ÓHÈó_8 {ÿÉ™ÕÀ5らâk‡¬jËב‰£Sã'ÚÛUFú:snfËæß1oåf6£ê)…ÕŒlý_¡Õ´‡7§×Ï_<¯¶v/aõb¡¼rŽ,0,éwL¿Cú-é÷œ~Gø›éÉZû’KÅ?(}ˆÿê'¢Çm0°‚õ‡ÑÄ$IL2Ù°‘å^ÛSJ©ÎêT3€¤gÒ‰Ce²Ü¼´ÚÓT]érÊJ!íf!Â\»S: "žˆt-´)ƒ³L«††Ìà/Ÿì³³jûE xpÐ@2^;ÐP˜ PÁšÆ9†“hÈS€ÝF gœä2¶ 7ñ`fDN¾»ëÆìù!*LuÂÙÝgjÄæêw5;gj}Úœ9óóí66±T|ña©šö éÁ’PRbi°„#5~ –`ŒÊm@ã±1|ž2jb)Ï1•qO «ÐÐ,~mŸcŠ<±¹ï³µýªv‰ùMÈiÄ f7V,Pà/vJ°ÁCàÎå Ï”£ êâ<¡P4±mTfgaô¾ê¨î2g#½g èÁ˜q(zꀊÀÙ„›á?EbkJf¯]OÙ{í]vÐút †$d`im²£ºSÐ\±¯Þ¶Åßå¿]Z -òÓ†ÈO["ÿµ9r[Lw˧W§¶0NýÂèÙ½=2×°é. ›Ú¬m-l ØÃMúíã­š•† ŠLˆh»Òl‚?Ò¯À5^žÂÙ¬Wã-6­±csß6¶ ÈÄQ{ Í'§ÓQEë_rŠÛ¡ôÕ>PÇáñQê¿`‰Awµ@­@mìƒtvv4×jg‰©,—%xvõÞ^7¹ÀÕª ÿ2çÛ`þ¡b"LfWîÒŽ±G;í¸g7‚9ºðè/St´}@xYêÆ`ª¢+k‹¯}Û¸îVÞ¯£õYÐþ3 ôöWiðZû ´pœç½((kQEc- ޵é²hï“ïÄlJvÜ%ÙŒï”i4Ç]Ò¼<„OŽû$8î`ÈÙý²ëÀØ'µñ.©uɲK^m` pDZìÀéôÔ†tÅó;¶pþe}Ñu¿¾~|yÝ-´a[hÝÏoÎêÁÛâ¶ÄÕþúúøÊZ•¶ †‚êÀ¸cÃcR!O{Š;™[þe†µÉÞµØ7ù¸[èŒ^Åà²Ûôt÷²¡-d·é™üO˜Ùmzöç‚ð›žñýMì4=ãû›ÙezÆ÷7=r·é™ÜÓôPÙÌ{LkeûüÅr[§ÎÖ)Å]Làeêçœúðm‘àîsÝ6³ñÙÊ=>u½ V¯éÃÕAœË®´£ÄÕwèÔ÷"-¹:î©…-ô¨Þ¬–FóŸóÁtiõ6äE, EFD µB»n0ý*£?Nè¦m')wlØ´hcØÂO„ô[¡*ñìâ‰_穞(r{k“°"‘*¼PDòðØwO~'×ïžùJC˜n™Tò04Àª%°ŸàT„0a>'ù†Êð#d{)ƒ³LîÊ  Ìà/Ÿì³³jûE ’pÑ@2^ ÐP˜ PÁšÆ>Ê“hÈS€¾× gœä2¶ 7WNE ¢ €ëQý°å‡€/¶¿¤¢ ãK°^ç¦@Ï:œâBÓ½_ ò°Û„ †­êhãiÇþƬ¢zâ¾ê@Ȩe\«c£y]$±Î²wWqQ ©®Ð{6ªI;Œçâ3Ê y ÆÁƒ Óù°HWALY2´ÿs Ž.H&ÌYO)ÈED§»@5#}–k%Jî9É5lÕ…EáR„w:Â6HÅÆwç€&Þ5ëþÕ⮂YDޤÔÅZjº?•V7åë´· 1‹T!‹h S|õö¹Ÿø9>÷™~À‰²J(îá>Ÿ‚5ϺHºHî3~ÇÉ!:ãJBx•.¶“ÐD \éjrpA¨as"½ÉùJXrd^5wˆ"ÒJÎùlˆ¿`ú[ÇÙôsd¬Bìï̃gí–Öõø©cÛmŠ1-Èoã°åöÔ‡xÌѧ.bTN8g×h뇟ðˆ ªÖƒ'NqV³2Ù‹Tj¤êCเˆ=þ$ZCg}/*ú0ãÎF–ÙúÏŠHë1®Óh³Œ|ÊßЬqßGïåbQEjõù 8l]êeµ+=ôQÍ#Ç„vßÿк*ƒ—tÒ_Ý¿ C¨µ¾šœâBU$$ȃ,-ê4›8nù„E½UYÕBvÝbà³Ø!öŒaÝ\Q ¡\Ê<þoEHØo¯é̾ÂÛz_öo®ŽsŠßþâ7O)™bµOøÄgªÙkœµÇ83 Nü2NU™¹YÄÆAÓPY¶ç¯“U×\¨¬4X)úÙŠ( j)˵äxq†r›8˜œ –Kw ïMœ‹¹üü¯Ìp^]Ÿ¨³„-žoY!f_jP½(y›¿ZÝòF·Y"Ã;· Õ ùºà_ê#,„­ ŠS:窽¦ÂxÖÁcè4DNº½%Ó@l²ÑÕ ˜wZSY5fùŒ³Þ[Ùë³^"ÓE\)á$?¡WÕ·¦„üÃÀÜŠ0—säOôΈJ.Ђ ¤§Uaþ¡C͸58ŽÏ<¬««ˆìƒ›#6чFkñLâ(spV€p°áÒ$x¼Š¡ ¦RWÚÄ(™ï¹$Äì%1 JpÔ{Ö'~Æ“÷X®ßWd§V{üaáp8üU\\–¿°ß\ÐM)©dóuŽŠ¿|È †ÌÄ8¡Ì•°@Ÿú;à ¨gúj:šÔ,ÖIDWÁ§aH²º@m„Ÿ¼‘ïi鍿3!z!‚±Zêz®VÛ¤Ñvlµ5Ú¦VÛq£íÄj›6Ú[m'j}[¼Ù¼4©Ò9ÿ±cJA6ê®âÓÀl(ГágxD¬Òù zÎuóð¾á|9ñn£l¼ŠoƤu-T}èH…߀öÈ‚Ú4ÁÓÞôó3ü×éÞÜ\ß\M |›ã½%%ÑC]=E%:EŒw)ƒ³LvÍÅÅÌà/Ÿì³³jûE ·pÒ@2^úÐP˜ PÁšÆD(“hÈS€äS gœä2¶ 7Pî¥8'б×&ÐKÙ&%éú ˆ+‘?WZ|&Ø ÜëQ<Ó3ÜKÛbqYˆd®{ýôþÍkdPÏœ®«:zÑVÂ,t‰Œº¤%³`OÁ®ª½Ÿ€ ]ƒàë}À6¾í(‰ªYER¼ï>plå‹Q,õ²\% Êê0Î{=P}Wu}Fä„K$žº)p›öäÙÆJ«îÉ´uì"œ‡óãæ ê±©I.—`0âúÎ<§&fdÕļRYà>Uª…þˆ´ØÃPFt,6—°i0B¼ˆø#U¢]W< â „?%Q…÷ϪL‰"0_ XPÅ[°bqØ&û^\ uËLMÔJŽêÄâ¯"Z‡Â–suw,·¾¼¯XÏèö¾/‚¯U´RèN|aŽˆ¶)“ªP—ÞxSJ**õ1ØŽœSû²”SÜQQ޳† òt÷0Öê§*kW#­­;¡€úæé%P³µ Õp»‚njMœþÁ!Ö⟞]µßQß8N£á%¦ÃÀ ŒO>OTu:«K¼ñ¹4%Ý ¨R£0#´A*.ê3Ê#›Ã¨³ýY€›ª"›´F¬kV*\ÜÕ Z¨«ÈPaßѧ‹XM3Gù\ZµUOò«Ëè.-žnÍ [òƒÑm#?–e oè6…>Ãí/–ØXl ŠvÔ«ï0X ©Â¶¸eÔL<ºÚàÍcõ… th ){HûVjÜ€V‹qL5äºl¨hÔOWñ|î³+ÚÓ¢¢ó²-£«ªÌ-™ ×}p¸ˆ›lÆðW l7jе”]i}ë I  ¦î4#ÞOØ„¢!€õHêÒ{0dN:¹áGŸtˆ:” 5üêI³‰É ,UH÷i5ÜÙç3v'¸UE~ Unø;|‡hÂr‘·7ç«8Ùž À?Æäœ•±©’Bµkh¥Ÿnbô ØÓ²„€æ)ZfmÓ€!Ÿ©¡ñBU•õQ5[B,‰UV½+a®ð¤Ò.¼èëƒ3}öï2E…'ó>»\æØ®æÁµ1”è2å'Ó£³1F»I¬÷ÊJ¾«>JˆíãêY3ÐJ’|+°¼K;[ƒ —Úá¬*Šçñ„’@²Rj‡—è½N™Èi¯˹ø+¹º’¶uiEm”ýµr” ½Ÿ%ùèšx.á3ŒEµ÷’Hø`X@þ+!h¶é2c}ÿÊÇß`Ò¯±+SµBêïêüQÃm|ãf)X3M ƒ™+ mèªX˜êZm¹X ƒÏ¥ÁB©Û¡ ŒÕEï´™¢þ@ï@uÔV`Q'j¿ƒr¸ˆÛ‚öÆO‡êâiô¼þð”òï‡Z)ƒ³LùÍJJÌà/Ÿì³³jûE <@2ÔGÐP˜ PÁ›öà˜"¼%º  Æ%j $*bX2¶ 7 )ƒ³LåBB³³jûÌà/ŸìE4S@@¬ ÐP˜ÁšP“hÈSÆ.Ê€€R⊠2¶ 8gœä)ƒ³L!åBB³³jûÌà/ŸìE4÷R@@Ï ÐP˜ÁšP“hÈSÆ>Ê€~'Ôµ 2¶ 8gœä)ƒ³LnéBB³³jûÌà/ŸìE4˜@@.g ÐP˜ÁšP“hÈSÆD(€€ÐÌ® 2¶ 8gœä)ƒ³L°ïJJÌà/Ÿì³³jûE <@2ÔGÐP˜ PÁt_ÛŒ ¥  K0j þ2¶ 7 )ƒ³LÇòJJÌà/Ÿì³³jûE <@2ÔGÐP˜ PÁœs§ºR?^   j þ2¶ 7 )ƒ³LœöBB³³jûÌà/ŸìE4ƒ#@@CL ÐP˜ÁšP“hÈSÆH«€¯ÉL 2¶ 8gœä)ƒ³L®öBB³³jûÌà/ŸìE4ei@@a ÐP˜Á›P¼%ºöà˜#€€ÐŠx 2¶ 8$*bX)ƒ³L8Ìà/Ÿì³³jûE Ò@Þ  5çÈö!ÓÌ€bits wikimediaorgÀ  bits-geoÀÀ0X bitspmtpaÀÀG<ÐP˜vÀ¢ÿd0org afilias-nstÀÀ¢ÿc0org afilias-nstinfoÀ¢ÿb2ÀsÀ¢ÿb0ÀsÀ¢ÿa0À”À¢ÿa2À”)ƒ³L¢[³³jûÌà/ŸìE @@±Š ÐP˜Á›P¼%ºöà˜#€€Ð› 2¶ 8$*bXGET /w/index.php?title=MediaWiki:Print.css&usemsgcache=yes&ctype=text%2Fcss&smaxage=2678400&action=raw&maxage=2678400 HTTP/1.1 Host: en.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: text/css,*/*;q=0.1 Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³Lµ[BB³³jûÌà/ŸìE4áX@@å ÐP˜ÁPŒ ¥t_Ü€€Ðƒ 2¶ 8 þ)ƒ³LÀ[BB³³jûÌà/ŸìE4¶O@@ ÐP˜ÁœP?^ s§ºS€€Ðãc 2¶ 8 þ)ƒ³LÎ[³³jûÌà/ŸìE k@@ª+ ÐP˜ÁœP?^ s§ºS€€Ð4­ 2¶ 8 þGET /w/index.php?title=MediaWiki:Handheld.css&usemsgcache=yes&ctype=text%2Fcss&smaxage=2678400&action=raw&maxage=2678400 HTTP/1.1 Host: en.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: text/css,*/*;q=0.1 Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³LÛ[³³jûÌà/ŸìE )@@›… ÐP˜ÁPŒ ¥t_Ü€€Ð¤0 2¶ 8 þGET /w/index.php?title=MediaWiki:Vector.css&usemsgcache=yes&ctype=text%2Fcss&smaxage=2678400&action=raw&maxage=2678400 HTTP/1.1 Host: en.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: text/css,*/*;q=0.1 Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³LªkNN³³jûÌà/ŸìE@‘0@@4¿ ÐP˜vÁžPþÁ§;°ÿÿ]´ 2¶ 8)ƒ³LÄkNN³³jûÌà/ŸìE@è@@Ýë ÐP˜vÁŸP i°ÿÿÞ´ 2¶ 8)ƒ³L%nNN³³jûÌà/ŸìE@«|@@s ÐP˜vÁ P×.”®°ÿÿV{´ 2¶ 8)ƒ³LByNN³³jûÌà/ŸìE@u@@Pî ÐP˜vÁ¡PíZ^ó°ÿÿv ´ 2¶ 8)ƒ³L$±Ýݳ³jûÌà/ŸìEÏñ@@ÓÏ ÐP˜ÁšP“hÈSÆH«€€ÐÓ\ 2¶ 8gœäGET /w/index.php?title=-&action=raw&maxage=2678400&gen=css HTTP/1.1 Host: en.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: text/css,*/*;q=0.1 Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³Lf77Ìà/Ÿì³³jûE )úD@2ØÐP˜ PÁ›öà˜#¼'€p $*bb2¶ 8HTTP/1.0 200 OK Date: Mon, 11 Oct 2010 21:35:31 GMT Server: Apache Cache-Control: public, s-maxage=2678400, max-age=2678400, max-age=2592000 Content-Encoding: gzip Vary: Accept-Encoding Content-Length: 958 Expires: Wed, 10 Nov 2010 21:35:31 GMT Content-Type: text/css; charset=UTF-8 X-Cache: MISS from sq73.wikimedia.org X-Cache-Lookup: HIT from sq73.wikimedia.org:3128 Age: 6 X-Cache: HIT from sq36.wikimedia.org X-Cache-Lookup: HIT from sq36.wikimedia.org:80 Connection: keep-alive )ƒ³LphÌà/Ÿì³³jûE òúE@2ÖKÐP˜ PÁ›öàš¼'€ÙX $*bc2¶ 8‹UMoã6½ûWLKXR’v/Útt‹¢ŠE°Éb‹=PäHbM‘Iù‹þ÷ÎP’í8nu`D"‡3ï½×pÜà%‚¶ùy)CX¾ƒëb±(®áWÖEè½¶±\Àm Ÿ[´ -tBÛÐ ‰%<ø¨¥Aè0Ñ Tn‡aÅñô±b3¾CÐ!¢'4÷Ê8EÒAt•nÀh»>œVŽØºÇ¯Q 'ŒB‰(r޹+áÑëûˆÊ 1!I#t‡~•ö| zÐέÅñšñc O­Û­VÑ5Áµó 1¢º¢šR)ü§þ8ËȺDM¾ ¾r²È©·[Áü:V|×¶v´\LT·•¨8¿ãÂ\3­\ÕÎÑ™¬7D:•s9)zA:Ø|Êbt–XÉ?ˆÍs*‹‚§Tá["˜¨"˜}IX|»ø;©ý —߉µmˆªtOô´"Âw”€†è­Ñ£¥<–P{×C€ÃMǾ|yžÖÊXý j4Sƒ>}üpGIÍ™ò2nÈV[öVÊUâü¹ERP¶$ŠŽM -ÑN*‡p’¨à¡«Ð/“Þ‘N Þ¯`(ȵ=AŸÜÃ…~ÓéºÎl„¸'„)e¤±/‹m¾ÕkÝ“"w¾)š°³ÛüM1bLÿ“;¨¥~€!$N[d˜e)êÈÙ’\ƒrìÄq5¼zÊáÁÉ–Ôh÷’<ø¦˜Ìv%qD'x”ž©È#=àIsbá@Âÿ;;_r|§»Þù(lœôÉÎ^|ÑJ‘Ì¡PzâRô„»{öY$¶zlÂ1še£ æ[ÓFæÝ6ÍŠjˆã’ÂÐs6$rµa TI²óüy‰S'×ÜÅ5…UB®³ =‘¶çѲánzÔòðü~RàŒ’õ%'—0ÏϪºÀçïZ%;ºnšGgÞêØÂc·’y|çü…q‘R&ǘ¡³)¶z½Yg½ÛRG«j¯¥» ]¿÷ºiãë€4‰æ!û .L˜*á®I•N=ÌB3’å2,Ï3 Ðâxf¤ŒÆo£m ·Ø¾7oÓVå¼"¯Âm¿ƒ+!Qf´:ÝËfg–³5Óø;¹$¶+8}UÓµÿ…Ý Å •p“ßa÷ pBà¦Ë„Ñ %/É:è§ÌÈ{wƒU%\ývÇãFM˶Ȥ“±œQgÈRô#åÿͤßã/<ÿ¬ÿžÂKLð)ƒ³LiBBÌà/Ÿì³³jûE 4D\@2óÐP˜ PÁœs§ºS?_æ€bE þ2¶ 8)ƒ³LüjBBÌà/Ÿì³³jûE 4¡Ó@22|ÐP˜ PÁt_ÜŒ |€Žf þ2¶ 8)ƒ³L¡kJJÌà/Ÿì³³jûE <@2ÓÓÐP˜v PÁžÄÃn þÁ§<  Þ]j <ýõ2¶ 8 )ƒ³LnJJÌà/Ÿì³³jûE <@2ÓÓÐP˜v PÁŸÅ ^ j  ð"j <ýõ2¶ 8 )ƒ³LŽnJJÌà/Ÿì³³jûE <@2ÓÓÐP˜v PÁ ÄYŸ^×.”¯  è'j <ýõ2¶ 8 )ƒ³LýnJJÌà/Ÿì³³jûE <@2ÓÓÐP˜v PÁ¡ÄèTÇíZ^ô  Q¾j <ýõ2¶ 8 )ƒ³LÁp77Ìà/Ÿì³³jûE )¡Ô@20†ÐP˜ PÁt_ÜŒ |€?t þ2¶ 8HTTP/1.0 200 OK Date: Mon, 11 Oct 2010 21:35:34 GMT Server: Apache Cache-Control: public, s-maxage=2678400, max-age=2678400, max-age=2592000 Content-Encoding: gzip Vary: Accept-Encoding Content-Length: 1122 Expires: Wed, 10 Nov 2010 21:35:34 GMT Content-Type: text/css; charset=UTF-8 X-Cache: HIT from sq34.wikimedia.org X-Cache-Lookup: HIT from sq34.wikimedia.org:3128 Age: 3 X-Cache: HIT from sq75.wikimedia.org X-Cache-Lookup: HIT from sq75.wikimedia.org:80 Connection: keep-alive )ƒ³LÚq66Ìà/Ÿì³³jûE (D]@2þÐP˜ PÁœs§ºS?_æ€ú þ2¶ 8HTTP/1.0 200 OK Date: Mon, 11 Oct 2010 21:35:34 GMT Server: Apache Cache-Control: public, s-maxage=2678400, max-age=2678400, max-age=2592000 Content-Encoding: gzip Vary: Accept-Encoding Content-Length: 176 Expires: Wed, 10 Nov 2010 21:35:34 GMT Content-Type: text/css; charset=UTF-8 X-Cache: HIT from sq63.wikimedia.org X-Cache-Lookup: HIT from sq63.wikimedia.org:3128 Age: 3 X-Cache: HIT from sq75.wikimedia.org X-Cache-Lookup: HIT from sq75.wikimedia.org:80 Connection: keep-alive )ƒ³L±xBB³³jûÌà/ŸìE4Ù@@ín ÐP˜Á›P¼'öàš€€R‡  2¶ 9$*bb)ƒ³LÿyBB³³jûÌà/ŸìE4ïX@@× ÐP˜Á›P¼'öàÖ€c„P 2¶ 9$*bc)ƒ³LzBB³³jûÌà/ŸìE4zm@@KŽ ÐP˜vÁžPþÁ§<ÄÃn¡€€Ð¢° 2¶ 9<ýõ)ƒ³L-{BB³³jûÌà/ŸìE4™@@,Ü ÐP˜vÁŸP jÅ ^€€Ð´u 2¶ 9<ýõ)ƒ³LH€BB³³jûÌà/ŸìE4êK@@Û¯ ÐP˜vÁ P×.”¯ÄYŸ_€€Ð¬z 2¶ 9<ýõ)ƒ³Lô€¤¤Ìà/Ÿì³³jûE –¡Õ@2.ÐP˜ PÁtaÑŒ |€fN þ2¶ 8‹­VÛnÛF}®¾b*ÃHkˆ¤¤ÚN#'œJì¢¨Ó `¸Æ’’[-w‰Ý¡%Ùõ¿wv%JŠ/-ŠÆ0`sö2gæœ3dr¯im† „.ßô3çú?ÀAÒë%ð©B(ŒRf.u Â"üŠ i[rn³ëÆXa—Àah5I——¼ëV*%&£WGÇ/¯®@:ynÑ9ÌýÑ=' 4$9}.oàjaK©'0<û‡Ë1.¡s>J"UoWqh7‡£Ô™z#¬ý-ß–ñpüò˜±pz©›–öæÍE[×û]﫹̩šŒ†Ãý“Þ½?‰:Tí{£_#rKp¦FpÔ Ä-«…ÔЈýÔäËØ?Dç¾þɇ÷rTH˜]H[žÞCQÆ>³XCh#© )á¨6ù3;}—.Úô™U†@¨éÙ Õ(fˆŽ>¢È½îz]ÝÐF#|-=ó$4ù†=¤n"2M*´ö4õÖ4qˆy~x#2–S â~s¶ÆpÒ°$DêŒj Oz°:ÊôöÀʲ¢î¡PFðCˆñãFLñj¹añqÛ€’£ WWŒâ£$\P$”,õö¦“¬=ísùLÜ·ÈÉ[œÀ÷GûݲB»ÂØzÕÏ+nä‘¡Í­hB™¬¢)û¨«Î·V2ìòÕE!ñZo“÷—ò-é@ÿ¢13ÔpjYû ûÀ¦€þµ–·oÂ,>ï¾Î_ýÏ͌ơö55ë¦F£a³8Ùa~:?ƒyÔ³×rž\¿ûUo½ð:ŒyPVT¯Àìr4côÉ‘¼JúVµì]íÈ{Ñlpÿaâ{¦’‡Àõ.æ;f.œzîÞ­Þq ø‚_šZ¨ËÊb¼ ¼9&®5èÅþX"ÿ‡dÔÉ0“3uígÏuÊÀãRÌlÆ8x"„æniÞ¥rÝ÷ÑñVª¯“Õšÿ,ûz5ØÍ° )ƒ³LòòÌà/Ÿì³³jûE äD^@2AÐP˜ PÁœs§¼G?_æ€Û þ2¶ 8‹eA‚0E÷œbŒqCPp‹{ï1µÕ6–vR‡b¼»ˆÔвûïýægZ—p¶È¬°VСq@xSÀ(¬‹ƒïʺ˜øðã*!`áå» YÛŽöìI s*dg3¹~¦Wf^î‰âê—‹³HkP¼ïJÿÜôŰÈz‘%¼ i4þ¶aýåÓ‘ŒŽOcù4’u ǦÙ%Íû&èד)ƒ³Lî„66Ìà/Ÿì³³jûE (pÓ@2aˆÐP˜ PÁšÆH«“hÉÀ gœð2¶ 8HTTP/1.0 200 OK Date: Mon, 11 Oct 2010 21:35:31 GMT Server: Apache Cache-Control: public, s-maxage=2678400, max-age=2678400, max-age=2592000 Content-Encoding: gzip Vary: Accept-Encoding Content-Length: 92 Expires: Wed, 10 Nov 2010 21:35:31 GMT Content-Type: text/css; charset=UTF-8 X-Cache: MISS from sq59.wikimedia.org X-Cache-Lookup: HIT from sq59.wikimedia.org:3128 Age: 6 X-Cache: HIT from sq64.wikimedia.org X-Cache-Lookup: HIT from sq64.wikimedia.org:80 Connection: keep-alive )ƒ³Lð‹žžÌà/Ÿì³³jûE pÔ@2cÐP˜ PÁšÆJŸ“hÉî€}G gœð2¶ 8‹Ó×RHOÍK-J,IMQ(-N-R(.©ÌI-ÎHM-QÐÒçJÔËK-×QP.,ÍLÎNJ,R (T+$ççäY)(;;X+ÔrŽ&aK)ƒ³LôŽBB³³jûÌà/ŸìE4c_@@bœ ÐP˜vÁ¡PíZ^ôÄèTÈ€€Ð 2¶ 9<ýõ)ƒ³LBB³³jûÌà/ŸìE4j@@\U ÐP˜ÁPŒ |taÑ€€R + 2¶ 9 þ)ƒ³L BB³³jûÌà/ŸìE4ZS@@l ÐP˜ÁœP?_æs§¼G€€Sà  2¶ 9 þ)ƒ³Lãã³³jûÌà/ŸìEÕÐG@@ô ÐP˜vÁžPþÁ§<ÄÃn¡€€ÐF 2¶ 9<ýõGET /w/extensions/UsabilityInitiative/css/combined.min.css?117 HTTP/1.1 Host: bits.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: text/css,*/*;q=0.1 Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³Lc’BB³³jûÌà/ŸìE4ª @@O ÐP˜ÁPŒ |tf3€:á 2¶ 9 þ)ƒ³LÍšÊʳ³jûÌà/ŸìE¼‘&@@3M ÐP˜vÁ P×.”¯ÄYŸ_€€Ððì 2¶ 9<ýõGET /skins-1.5/common/shared.css?283z HTTP/1.1 Host: bits.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: text/css,*/*;q=0.1 Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³LášBB³³jûÌà/ŸìE4¢W@@$ ÐP˜ÁœP?_æs§¼÷€€'ß… 2¶ 9 þ)ƒ³LA°BB³³jûÌà/ŸìE4‡~@@>ñ ÐP˜ÁšP“hÉîÆJŸ€€SÅ  2¶ 9gœð)ƒ³LV°BB³³jûÌà/ŸìE4L>@@z1 ÐP˜ÁšP“hÉîÆJû€€<ÄÇ 2¶ 9gœð)ƒ³La°Ì̳³jûÌà/ŸìE¾k@@5 ÐP˜vÁ¡PíZ^ôÄèTÈ€€Ð  2¶ 9<ýõGET /skins-1.5/vector/main-ltr.css?283z HTTP/1.1 Host: bits.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: text/css,*/*;q=0.1 Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³Ln°Ïϳ³jûÌà/ŸìEÁÌ@@øQ ÐP˜vÁŸP jÅ ^€€Ð—# 2¶ 9<ýõGET /skins-1.5/common/commonPrint.css?283z HTTP/1.1 Host: bits.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: text/css,*/*;q=0.1 Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³Lí/»»³³jûÌà/ŸìE­îT@@Ö¡ ÐP˜ÁšP“hÉîÆJû€€Ðçü 2¶ 9gœðGET /wiki/Special:BannerController?283z HTTP/1.1 Host: en.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: */* Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³Lš<ÒÒ³³jûÌà/ŸìEÄ\s@@hl ÐP˜Á›P¼'öàÖ€€Ðä$ 2¶ 9$*bcGET /w/index.php?title=-&action=raw&gen=js&useskin=vector&283z HTTP/1.1 Host: en.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: */* Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³LVJBBÌà/Ÿì³³jûE 4“]@2@~ÐP˜v PÁžÄÃn¡þÁ¨Ý€!Ë <ýü2¶ 9)ƒ³LýM  Ìà/Ÿì³³jûE ’“^@2;ÐP˜v PÁžÄÃn¡þÁ¨Ý€”= <ýü2¶ 9HTTP/1.1 200 OK Server: Apache Last-Modified: Thu, 22 Jul 2010 14:18:47 GMT ETag: "585f-48bfa98b61fc0"-gzip Cache-Control: max-age=2592000 Expires: Fri, 05 Nov 2010 20:01:18 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Type: text/css Content-Length: 3883 Date: Mon, 11 Oct 2010 21:35:37 GMT X-Varnish: 3909035154 1406892841 Age: 437659 Via: 1.1 varnish Connection: keep-alive ‹½\ëoã¸ÿž¿BÝ`Þ!rüˆó°q{¸ööÐE¿´@?Z¢m"´¤Jrœ¬qÿ{ùŧDÉÙµ±‰6g~3$g†Ã¡&Õq·ƒUò¬:_å/°Üâü´Ú£4…ÙúªÈ+Dï­À¦Êñ±†ë«:/VÓâu}…á¶æW'”Ö{~¹ÉË–«,ÏÈ£_c”¥ðuõôD(4EÙn5]_@¹CÙ*ž¯Ñ”~×W^M qUÀ|nù—ƒ½¢<ïÊü˜¥q’ã¼\ý—0ÉOë«mžÕq…¾ÂÕtòë«äXVä~‘£¬†¥ÄFAiD™_öq“W1•7žSÙRT¼ ád›É| ÿE´‚2ï!ÚíëÕLüÍ®„Õ×DÝ–(§=ª¿§ˆN`ç+Îtƒ Œõ•Šà?ðµVÛëÂ2Y[µLgŠZœœb¿„YíÐÄõÝß—O¿Ü;tñ SŽ 4¡4ã.‡êWÑD\Äl f¶^±] ÞúiüïË7Ciœ`ý†á Õ£¤ŸÌžN>‡&*„_h×vjÐè&ìY yÁ±Î!ƨ¨P@ìaJØì›…O|0lrœÒfׇS\€ â ¡‹i¼Á0ÎÀK”¢—I‘—5åŠÌèvpu,ñ_'“[öŸêö&u^Þ*þ^nyãxSBð<)²Ýϳ´Ñ"MµS™ÅÚÝÔd*‹+{>GAÆ#«“EçÔù7›Ò3jþ$³.}›”5Ž‹ÛÚ7ª6ŽRãÅL9×PFûeÓ«×w¿ÒïZë,/«úÒ8(Ëü3 }%-§#‡ï`rwAÁs» ¬é&¯ëüÀ}Å@Å1©.†<›Ä]¨^†|Ú¯oñ7˜ª*ŸÞß-ùu¤zÙ@ðê÷-êXG£S©K‘=ê"ŒWÂÌ™Ž«&v&Na’—€Íîc‡¨¿¡lR"Â’:ªàÙC/©N5%Q@šIƒ&–ñôò‚%±¤5µÇ-¿†ÄçÔ‹ôÑØ¢²ªYoŽæm ¯”<Ø›<(AG ·€¸•ÁjŽ8ÂèlÜ@yî‚K­ÄkÓ [éêADˆ+B—P3ÕKP‚d³¼e°%ù¦¨¦g%ÀR¢6"Ωø÷ñ@n¾Ý´—ÿäŒnf"ä:¡gô™ÍËøˆ":3q—¤1uë›üuvÖvwîŒó,êúcÊ,úäæ© Z3Eàœøeª®µ+úO0$ÊÊë}³ì vÈ&^ž~þ¼}0BbLE¦ßvƒ(y”Ù)ƒ³LhQ  Ìà/Ÿì³³jûE ’“_@2;ÐP˜v PÁžÄÃsÿþÁ¨Ý€_ <ýü2¶ 9')×ù9H#gM•Xò½ bR5ýí®›.U°®lU›^Õt‘ TW)¢Eµb®[ÐïÚ^‹ƒÒ8pátPô’÷†_Í„„OeŽ+ßbN]FÎÚ%²Þu4ÊS}c Å·ÎWŒŸ¹Z1#Xø–œ5{Òf,îR¤¨6G‚?«Œžt"ãÖ®šæh˜ýrÂOûÐDü·ÇŽ;ôJ-u—nm»²]Я„Çeó*sX/ó F.Š=$|YŸnÊh”1C$ i÷ÉzýÁJcUÑm¯”h³`Ÿ 6¾0®‰lT/ž”ɬy)g“n¦rj!ìÐ&[5›úó^MÖK¬de¿ËV ä1lÚ™Í4pĺ_±Ô†“õ¡*rX±aÓ7wmŽ_}ÔFö-õÛ:Ïñ”·‚Åd‡¶Ñ,§DóLDª“ŒLÞ'ò¡äßÑ„€ ZSp¾‹HïbxÖ31¼ú›Euª†ˆ¬•yA¯¥{xA, £4é@Òò™m—Òd'Ó Q8¿ŒkTcHo%8¯àé§IýϽԠ>V×  #eÅQNõÕ\Ž¦í´¤v ‘~ T >‘{6¹c9¹{òSò‡vGxc7Í4|–V:>ä_ãÆ’‘x¬Vl Ç'¸!³ÚuKY5HQ¦“ÙÒ¨¦žË¿™øêcÖ̼÷ô«?¤‹9ýFþ™Å…­n¹ˆäÛm³`æÓ*&œI`¶vf‹èwQf3L…ʄ὇ó‡….œÑïÝï$Hht{3ºý6OŽ•©ƒ‡)ÑÁL×ÁfK¿á:P3HßVbçé„K¥ó|ØÒïÚ*aŸËgÃê;õîŠMwÖGÄþeíhµB²ÄÇí`Mü;Hõ<9‘{J¿r7vñ-!ò¾R#bá¹Ã¨÷(y¶lÝÀXÃ?^HÒ 30Ë‹{@÷Á®±” ÅA,åõƳÛ"ˆS¢-Ëà4ÓnHØ›D‹ž ¿I·‹‹c^û÷ú­€?Ѱà‹ôd¯t‰b—Ü©7;TÞ[Òѹo?ïëöݽõêRó_BM­‹D²‡É3òá‹•åiõt[í㺌ÆÑjRlOJ¼ u"l|ƧTc%0Ì—Í€³!]/ÂÔ$ .#µ¥ïÜA ß£Ln¼^?±O·{{NLÑsþ)HóŠ6,ô5äÚy,³G-[¹–6_NÙÈ!õ¶té’?P”/ ›ná ‹©´dŽzobºú.”¸±¼j'zŽÙ7ðtšÍÿñìHï¿'Úv]<À÷×*lï”nì©ÜÄB’.a¿!Š}‹âX ºº%E˜Ud™ÉMLådl}ØÀ'Q|€EÒ‚ûE{P¾31»ô!Ùæø¨O‡,n¥Ek”K'vDiDΈÁmp ëФ}]s£ì™¬5QFIM*_™,£éMÏC,Õˆþ¶P5¥,Ê(зm¸ —°M—]J¾¢ª®ú¤×šdy=¢•H« jC”ËŒU›©9hî.\µlW¾§šd„z‹åKé»Ç¶Lwgè×mþÃbÞ^ƒmC¼îpºZÃÑšõ ÃMø˜¶Š-Ó\õq¸Ö½­­šò›û¦Ði¼æÞ٘ĀbP:1u[ç–} &ì™2"ä Ù6H]‚¬¢µ*«¬Àõ+\;vÆçËæ)ƒ³LúT  Ìà/Ÿì³³jûE ’“`@2;ÐP˜v PÁžÄÃy]þÁ¨Ý€—” <ýü2¶ 9VâܵÿãæØÔŽh9é‡éGg]JW•ЇOï#ŽÛÇ"¶n±P¶ªE®)Õ껽jÙÊûbZ±¢¨8Ù#Ü®zb±Yùά0h9é"k›aAKˆØ’Ñ|¢ó'ÏWl£aT¿É’cOT)ã¦ÛÕl™°ú}Ðõoßá Ajm¯3R”ÏMä XaÝt51¹6cþã·IÖ$O>+•J–ï`\’‡mÇ{[÷ÖAO4fòb‡Xɋϖö*´8n0ªö-ßâíÊÌØÓv˜£aÅ‹õt~íœ8}å,\]Îr±ÎÚ&Ñ0šT0ì|EN¾yä©Ìò“ö‹Ù ä•Yäê­Ãr• ]ÿÊ>]u‚~}öOp”Ul@GŸIhö£(¤Û½ ú>ðˆéº ï]¥³†v3­OšT…Ø4ë™û7Å26 a¸†«I)ŽùyÞ¥©¦(ä|‰H.Ì͘QâÂî«C¼ÙÐgŸASÎ¥ÿ”F–žhÙÆï®m´즯—ã@™Ó¼¹ê÷î;k|MÖ¡ÚÅ¢*.Üå…÷Êf„PÙ½Rj–J&VÜ‹@é4¯Îujôµ‚OBwí¨ÄÕ£„¸"Ž#Ù»‘°·iÂY‰B9ó%ÔÙE9TzQ.Áßóƒ¬:R ;gêˆÀBaᚪ¢D5Lÿ&’6Þã>.÷ÀÚ íQ$­6ÐŒ¼#œ™g ¡XÎÕý8öóT£¼kÓDuÕœ»T…4Ó¥«1+³¤W¾"Y_2®±4Ä?9Èˈ:ÈFi$˜UÙ*~ k<ÈŠ*kZƒÔ¯ ½pûÑ6k3Öµš²Ì~VJ‹A:ÆUÛgç.uס½¢jwh‹Vͺç%>é©AŠQÎí¹õ¢ûþá#’\Ëÿ)Rµ*7¤›Âñà¡Ý4h5êcu¬”Ž=­ c[¶½“Cù(”î"ç(Ò±ÇÕ`Ìâvâ¹ü ËË’PÙÞxijU+67OÅÍ•€xeÇKå|>³éÜx²ë\eXl@æÑÄ•ÖUšÈô£ã<”ž¢qœAôÍžw˜.YmŽÓ‡Ã” Ä´ô+ï·q„Ä…µ0Î9u _ñ‚vÖ,Ñ@BW:4Y!¦•ïý3½ Ò ò¿—ÿDK³éøŸQ_¹3c{«®÷“¼Ç…Îq1ÿæït޳ûoÎq©sœšZmÞÉãã·Éóg vfε0§$›Í¦9 ä ½³£ŸM¯;Ó›ñc»Ê{[\I¬žUæ`¬S¯êÉ$'¯ÀúíúµüVw}®“WAýºsý±·Ký¸†(PCà:“¯¶¢Ç¢ˆ–W kJ_ÚJ_'_ûÖ*‡}Oݽ¯\: “ìÞxúÌ>ÁXüëXƒµrþXOG*k ëA=¯c Ýð!ë&\„& ÄÄÔ½e5xíß pàm…Ü‚Âo«CžåÌOŽEu  ‹%bøûÛÆhÞéǧû]а“P «¤DÌíŒC¢8«¥gf${P‚„p¾GÈÃÛï9lêÚ4Ð̆#5ùh†àêBN䥲HœµûY|ÆAœf ñ÷žš|T,€ŠÁ°eÆø+ö2íó »X?¢Ä çk3!ËU¦õ…Y}Ht2hG£ªV› X³¿È+¯ôÁZo±=YÇÜB¸ÈP|ˆá`¼? %X>2`zßËõSWÀ~B“ÁUCN~”4¼¸Ï!vÑsþ…Ì//D•Ìè^ÉôQEì¾™8ÎР)ÿ¼;øã„÷b7nâ!ÍD0Óéß)šèÀ#ðÊ*Š b˜'ï$Ë`*0ªnD%ƘÊáGº-êäzÅ”¹¢x iëä ,ï0lšRf Åâ!4+FSzI„õ²•Z„æVáö&Õ²À„ZæÜ‰iÔ…20ñ:z'—ä@|7½ò« ™‘;2„þX3º}í`×ñ+ˆHì h¥ŠQìˆ \â Ö–ÒE µ ¿¼ÔkH/iM4Ò¤$ >èÎÆ'^0uòÃyíHHÜåHõø—Ì|r‚óõåÓ0!QÊ{‚Ö΃ÿ+ÿø_ÏÖ¢•ȇ jÉm½ÄŸà-˜à Ã.€u²‹39³Åx=QhD7†X*@±\4l¿x­ø®ÃãpŽBùÀ•CᆞžmuPܹbR÷‰}øÖJŽ4éš–€Gã%¹°F‰ÌÍ,¤~,Ò8Ú–=GèN_ÒC˜¡íp$éüãØ7y}£¤sÃTg‚Xk„Yˆç§°òתpl}/g¼-þ¿4ÝÚ“ ?g ‰P&E‘v¢?µÔÊ{gh%2%x4Ÿoac U!˜7G›Òµz‹?GlS!î…ª£<*ÄNT©§XF—å¯_¡˜ë2ÚS~mõîC6µuËð:Ñ6ÊVïv…€œ #›½ù9(V¼1| ÖDzȃ~ÃÔénúJbóˆ3œûñÁ(„>¼X =sP§"ÁÏóløŽ>÷0Û9`¸êC50µŒ}/{mÁæ c¯T¦‡z(¯¦ ÇqΕ×u¬´2½BÎɨíBõj:%ÛS'„gR‰µhLSWŒƒ]lEcJhCÆd½^&B€Å †.±o² E6Îó MdíÞ<„è[^1ö¤åºüø.½áp§ìc½­NpÁµ¨.Žg\wÈô'|QSÒÄmiSö‚êGäH!ö;%*'kbÿ݉öÜ¥s‹”°öchû.‚ 7JÝàŠŸnÊG.5˃ZŸÏC^ÎkEá¿Qi&òß8Èÿ°Û‰n¬Åué1ĆØ–ý†ñ¡¯¯ÆèvÃTÕ•°î¤J øjè1HTK6W«8ýnÂ=ú2—*Ïgþ#«´Þÿ)>àwPêTÜnÞ¾õÌ›QNÅå‘nubVÓ0éVSKmCM¼ö¨*xÓÁ"ó›ãÙŒœÍw\±ùX”Óª¿)cþA~êïÛ‚SrêMc÷ÈM_.Të%HÖ*< †a{-û…*Ç«÷¯ß¾{3n«é]Ø‘`™)ƒ³Ll  Ìà/Ÿì³³jûE ’b¥@2kØÐP˜v PÁ ÄYª×.–7€vo <ýý2¶ 9ëÐõ`ŸhI‡Ý0Vʲ‡B`3SPçøÏx+ÙËxMu=ùBŠvuòŒBɯ±¡–ƒŠ¨&ØÈƒƒ2Y@n!ñòce)çÿhÖŒ$Û!ŬÉM*£Dšiµ¤$Ò7ªÆ9"®l½Q¢8Gixæ#»_å¦xŸÜ·¶²ýaTbU@üˆådÓ0B C>™¾¨ #Aö%ZŽL£ªn!«j#Øž2³1~ÀZì)ö® rÛ+BS¦ v¨ôçŒùˆ2i>ò½¥¬À ê±ç¦Ûc¨Ææ¹ª¿9pìtË¢#0M;ˆSÞå°ŽšöºrÏ~@Ê„½gàEÎ*±Wã‘ç±+@pð?@k×±OH$/6ïkìóo•¸8Ñw$Ô„~šÀù@÷b}šEd=ÖPÈiw¤¦–ú¦L7Nãé¢VÜÔ×È\v¼]È|ú>õÎ+ñIS ;™'‹q›‹Rýzà!Í_R5‹·Òý V-Mðgf8mÉ!†¼Ž­Ç¶Ú4â›Wx¼A{Úå`üRUÏŽÒ¡Y1(©«¬É±÷ÎÙ¿/¹,0„ ^´ÀYTÖh(±·ª2®b±¬àdAj§ã-ìÖH÷ÕÉ1|W(vÏiâz†^î<$¤´G1+ÕI"õjbi6ÉÕú½ÿÔŸ+1´ÈàVsNaJô¢,NVUüF·‹Ü¡…Õ®¡ïJX@áHà­É=¼¸G{ÝÛùØŠLÞÒ±ftJ½1;O–Bí² Àɲõ€«MCÈè0“¨í8c‚l]æFÔ¿ˆ¤`kàäæÙYò=o+T C zªÑ9änuÿÓrgJVI³¢ÞÙ7[ptÂÅ "vÌÞàìz Ý>`™¸MDÛô^Õó¥[1çVƒÆc]Œ9ñŇ7Þ}w5KvîÙp,‡Ï  9Ϻ¼ÞŸAÔ!žãÓˆDàÜÄ8ï=rç¦ /Šˆ²Ù0‹uµ Í…7 aRAÏJõÙÓ¤á8Ié¨nÓ&¹H®!ç\éG:“áPJ¦¢²PýE±( C–<Æïæ|£&lØÐϾ"Cß!L$ÁÞÇMµûê¹Æ¨T5PÕ€ŒÎª.çoìS*ö±ó¤vtQWl;>tëà¦!mDᬳŒi_ÅàøÖ° нX£1R«Ê#~Öoy²Ô¦QäaF‡¤àÒ|Š2ÈZPke»ÑCŒkÜøR½m3ÿÖW“€îH(‡1œI8ǹ`vþ|ܽÏ!vs¾Ú(òn§C¦Ã]á,E²/ðG-K—ƒb¬"ø¢FE[¹˜Íƒ=`j~SäLø>BõmìÞz6¸K7$‰€K¥L­májõ‹Dý†AOßë±p¹ú” Åÿœë,é¯ÙÆôSæàs+é†xÔ6;w ö~ÏÂ\U¸¯=:HɽZ†¢>ø°MÝ÷—“ éþzëPœš¥þæù…χübZ• ú“2±½XÒyqåvc‰5k§"â_?3kûžUùO² j Âù»Iár!°ñ56T¨ ²KVTU׿$s?ðâ=z»P"ŒÏv€Y‡ÝÈgïì>Yæ¶€ÍÍu›b ö+) Eÿ왈w±³èPÏ,‘(ë°Ì`#³õ[aLÑ!î‘;n)}Ô§£ÁN¨±C _=Œvà£e)Aèq̉ÃNz4P4‹å§ 1Ze0hâÔëêí32CÕ4Ì®C¨tÍ!ªï÷µn•%¢(€°TtI+•å P(ŸŸ ¨ï>ëî0¯Žœsø\lœÿŒ4åšöm™‡lÙÊû  9)ƒ³LlqBB³³jûÌà/ŸìE4Yg@@l” ÐP˜vÁžPþÁ¨ÝÄÃ~»€€Éõ 2¶ 9<ýü)ƒ³L´yBBÌà/Ÿì³³jûE 4©5@2*¦ÐP˜v PÁ¡ÄèTÈíZ`~€•A <ýý2¶ 9)ƒ³Lo}  Ìà/Ÿì³³jûE ’©6@2%GÐP˜v PÁ¡ÄèTÈíZ`~€Ò <ýý2¶ 9HTTP/1.1 200 OK Server: Apache Last-Modified: Tue, 21 Sep 2010 18:59:21 GMT ETag: "579b-490c9a06a7440"-gzip Cache-Control: max-age=2592000 Expires: Wed, 10 Nov 2010 07:46:24 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Type: text/css Content-Length: 5198 Date: Mon, 11 Oct 2010 21:35:37 GMT X-Varnish: 3909035245 3582196198 Age: 49753 Via: 1.1 varnish Connection: keep-alive ‹½9Mò°€ý?áH®`ÞÇÍdòïäúÌE4ll!àŽº\D0CQôß´ÉÙl'5Ñú¶Ìmô-˜Ãl\ò@ жH 0%Ãä]!ÖˆêЮQU첉Ä×µ#ÝsCî„t~«ðF”(|‘'QI¬$PÔ3‰(~܆A±®”óž7Ä·õåvô·7 ›´¸fiŠFwûÀñhø“EH0˜§íŠÁn8 â $æ=·—NÒêqÒÑRadnDMŸw"÷âÖ, s¡£Ï*%Q˜ƒò£•¯'<1ˆ$©²Y6EQ¨@ÆbR›%ï`&±|´W#jÃ%¨/h“aY2”ùŸº@òXÓmHîÔ«–iÌY3“Ôm’§Ü':·Ok>ðoáŠã6«KLpÁIÜÜïÞ3s‡£™×lm™ I1„îÙäh›(¾ã 5RøMøE’}T`ßÇúØ{—( @tÜ#ŸÀ³_ _ú5[ ÝÚhk±›Ö†ÖB)ƒ³L¿  Ìà/Ÿì³³jûE ’©7@2%FÐP˜v PÁ¡ÄèZ&íZ`~€M <ýý2¶ 9CÝñP¯á(øb²€¸æ²±»—õˆõÑ¡Gé•S–-l•†´ÄÖ=ÍòÃß­XíU”.¸Ôèã×ן?Ÿ¿zõúûåìåÇ÷ŸÞ¿øð…ýòù㯯?_ôCìRØZ`B å&“œ9hí¦«7„–…8É6<²\à}%¢ñ'¦=°ÌÁùÛ?¿~…Œ<}ÜÁ¹çïjUÌi Hz¹ˆàZ»i€_f™ hM'ûþ; ¨rÙ® ­T×R˜©wd×H?¨R×öp@«]œf|ì&¿¶‚•Næ<Àe€Ý9¥I!iÖ ¹a¸˜§š–ôÜÞ Mtî¹ÃÜaåí=®öŽÜË7›÷ãÝoŽ8PѰÃôwT çŽi·i9§ßB"ì6«- ‡ôCž[\“@øIÆ¥P6β :ÛôéN7æt»BgxFa>Ÿ??­÷ï+ÏBÒ…¿ð *ôî"ER^2áKR!ÑmÇiýºÍ³,ÙN°Ž0 !£ÒptìX:!ŸíTK‹LT=ˆÀY?a0ãnêÕf[6´,‡ |=ì0uÖ¥ ³çnmd ™ lgk„ç“:¼ê~Ôo¬,~: nËEYžK™¹Ã=-Ø*?'ã b<¥ªVL|O±¸7àsUj:;"vµ]p—%úw—ù¡½¯¼ôޝ‚Ùçø¬Ùx¹©4¹Y;0ã›0ÜLÅ?<#üÖ5ÿx®âûË;OC Ô¾îê_»xÞ³ë%Þ„WÂ%Q`Ԃ߀|“\ÝoEpLW§“MòÏ ¯' ½—25m×Àœ®ÀÃD~‡}/ûê"ÝU´Zar`‚Çò0úF^CÝCƒ0Q:7íJК1ËTêwŠëT»a¦;F&ä2‹Ýb9¼-^um,ª(Õƒ¼Ï¢(3€Z¬ßœ!7±d.m!˜'¶I€Oñ÷,O#Xò2*lT¦Î WiT ³2VÆ;Ï ¦ºÁÎÛ¡ž4l ’€.üvI]:r“È®ø»}»Bï0/.À$û몬—Ë«îe»¸¨iÇX·öm¥mujjÖÍ(Áxx 0ÖÂ8- ¦©ÎªÚxTÊÃM‰‹&jâq˜8½*H-È`!°à-xXÎ  d&tÍówü:)éà$ê„Xã°x{/ègÈRöE’;Õ[´ó”bK‹G–0íDúàPÙGɵ™^C4÷@j|±K ÜÑ…òýt¥­Ô‚GJo£¢~®~ž|¾@²Û±P¼L¹––õa&Ÿ0ƒUgj¹A*d{`fzä ly—¬’ïtáÇ^O6©\Yí©,VóAÎ)ƒ³Lº‚  Ìà/Ÿì³³jûE ’©8@2%EÐP˜v PÁ¡Äè_„íZ`~€­“ <ýý2¶ 9»­Á’¶¶šÞ‡‡,¯SG|q…úƒh»SÛÐÞÕ9l[2Ñ5&¾á2#±Ì’ \ÅÉ"I.=v^°mÕ·‡><‚]dÔ?–fÀÄg{oyÏd‚­Ë AGyÀ‘€M»¤v¯¥€(vq‚ó1†ã¼à02¦¾·d+2,•P{š\.”xSŠŽv QƆ6êìcù%­a¬4+È=V˜ÝÈ êa³IÛ +1Á0ûe3«]}–h_RBv²Ë<µlcÉ62:;¡ÃÛï© ç'Su·¶ó}f&zyQ.t ''³ZW¼‹-È€Ö¦JCúìŸNÕ’x«nõh?å"§êî2{._¤x |3€Ø¨*^–ê*jÝŽÖ™ñª€´ßÕbœ»m´º¡ÖÐm&©÷Tý©Ð¼(²Ò/Ê ÓQ]ŒGëüÂïüÎá÷X£VµÓ;6»£’åÈ=¥éíÈ6½ƒ™œK+]Ôð´UQª´HžªÏØ Ó«±OŸþpÆhÜAXÔ~FŸ4?”sfÖ³ói5Þýìñ‰œÓb”…¸‹9‹$ éCkáÙÚ³ðÉ1Ìqñ<²ÿ Æ»>í8·NkæN€ÇÖbø¼ïÆè`6ïF)Õ+˜Ü£lÏ¥lwؽGi]u6ko|±ÈÆ#îgI|½µý%qáù¶go¶<^òEŸÀ´m»Ð+å¸*¶e¼Öæ”<Óë„Þ!©Ê´~İÛÙ¯^ -£HfÏàí(鯦µæ¡Š¥Ö¬Â½l©yÉ… ‰]LƒÚù@d¿8eDvÍ|e.‚`€°ª›Æ ä Ž£¾ ~’[-¨ÄdF\*o³„Û °4ñŸ ¶EÍBMP%)\Ôéñ—õì9¾‰µ. I|r_®Ö¤(¤âK–5 ݧ̷£:Yªñ4 Rg—B¤j0¢Sm Üe”Í0£Œ=ϳ€7›HÅzœ )ƒ³LƒBBÌà/Ÿì³³jûE 4£é@2/òÐP˜v PÁŸÅ ^¡÷€3£ <ýý2¶ 9)ƒ³Ln†  Ìà/Ÿì³³jûE ’£ê@2*“ÐP˜v PÁŸÅ ^¡÷€s <ýý2¶ 9HTTP/1.1 200 OK Server: Apache Last-Modified: Fri, 09 Apr 2010 05:35:47 GMT ETag: "1182-483c72ad252c0"-gzip Cache-Control: max-age=2592000 Expires: Wed, 10 Nov 2010 07:46:24 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Type: text/css Content-Length: 1598 Date: Mon, 11 Oct 2010 21:35:37 GMT X-Varnish: 3909035251 3582196541 Age: 49753 Via: 1.1 varnish Connection: keep-alive ‹­W[oÛ6~Ž~Åi¡­aÉvÚ­üÔµÅ6 †uCž)‘²¸P¤FÑ·ùï;¼È¦|i2`rYäѹ~çÂé8á+£œÜò;¿i. tf't5c*¥áã·o×iIZRàr¡Õ¦cºËì›U»Ó|Yø‰š3·¼¼c¨ióét³Ùdd%¸Üf”Mñ ûÒ'¦ùšQ¨´jÀÔ Z¡$ƒ—á÷”)½œ¾òštCIÛI™†/¼áÉxš$Ó1üQy×Qð×;$k‰6{¦Dà±KY©älíZu¬Z `[£IȈdY¼K¶¹‡R ¥óQAfx-À aJY©41\É\¢ž xH’‘Q%ÜCxMÇ…Ò¨\>o·Ð)Á)Œ®«·)(ÀRœîw-ü.)ï–Z­$Mƒøê½ýøÝ–PÊå2¿i·‹ä!ÉP0GW`Ìî“«†è%—©`•Éáš5=ºŸEû…2F59Ì<ë<Þ%s |UBã}Œr+9¸5¯H)уÏÙMUÇ—4è®5[ÄÆÃ,»aM°ÿ¶æf°n85uO4Ãû;¼Ï³7Þ¦#[Ô²RÒ¤,9pƒÁ.p ´.9²Å.-`¨yöÚŠóBýÿÿÛgC°g6°Å©xÁ@[0J¦^5…$\ì#åV0´+ѵòŠžNÏE¿è1«ô%+£ü‚Z3*nr¨9E¬õj;á\JLÄû À.Ý5„.¼Æýg¼i•6Dš§ Þ»„ÿƒÚ¿óƒ_sɈÞYbàJL¦­^µiÍ,¦Õlð –8æáKàÒ|hB@ Þçq Q¢äÕƒHy× ² /CpXÈ©'§Ô“³!üß10ßüßÇ'o–Þ7žÚ–‘Þ/‘7©»újb\ŸÀr+)ÑÔÕ-e:މ×Ó[ òæmÿ|!íâ2‡î$qÿyod“J’BÑ]å=òY0G ›£N1dC!¹ó£@çkà/Nj&UkûëÄÆlôתiS£RIÖDÕúä»jdŠÈ™$öAµµ’“$Ã.m:VZ—L\a7j¹Ìÿö¹éTi«6L3Zìx©úµ²ï nMðÑš³M‰–÷D µò¿¼¥ ¼aÚ=¢ÎkRîP—f“z18 ì*ØoàgN±ƒ!\Gg‚5èî¸Æà±5zÍu\g?º‚ ‡yb„ý8jÛ±}ÑJÍ®µ•ëïÑž Ý‚Á”æLé'0<ƒ£’sÎéÞ>ŽÃ­‡dT)eBìeBœ)ƒ³L‰¶¶Ìà/Ÿì³³jûE ¨£ë@2-|ÐP˜v PÁŸÅ cr¡÷€6= <ýý2¶ 9+ |.˜i†ÑS& )õ§¥kü¾ÆïüÞà÷­•à¸a.o‘ð ÖN £ª\Yÿ~b]©y\´zÍ]]:5ÌŽiXγ0$ÄsD{˜¬ýþsä…¤ÕG•l†P‚##mwnI»–”¾V³“rþ®5ÇMæÐxö EöI.Gí|±±ðÁ·'ÃG0ôŒæƒ˜DACÞ‚´*ÚÿrH`€ï´´ßàн$·É5’¯9–@F‡òF7׳S8ÃJô´f=ÿãqVvh¶¦ÉiIDf_ÉI…O8·oc#± ßÕ!ý?o[,÷ðçï_º³‰˜åð^>bŒ~YkV½‚çøçõY Uq«IÛî9‡æ4ŸÍ~8ñ_ƒå¾o^ÇŒêÃSQÓ—Ýae‰*Á‰„ùQEб{RSœÐy_¿ýòyzË%PÅ:ùÂøH¹ /¸¬ñ¼d^¸óÉ$ІýÇ{³§kjHá'íÕ N«¢ïÞ• ÜŠA–eÿAfPó1©gÉP0ÎX÷#„éƒmqËö-"ú‘¯Á>$ b^Z"7Ç…ñ¹" ØUðœÊ+D³yô«BìÜxæð»Ó»Bm/Œ9ýÐxuy\½ ˆ„ùM¾ŠX[wXÞ‡jgË‚¿l Ü!™W`2£ˆ£d?CQ»~g¾‡4a¨ÛMÑJ‡D£Ê]1™|™Ñp„<ª9èªêçû¨ªw3wØ…½¯Ñ›ûœëEPÌE!V¡þtü˜Šã» Å%èöÌÈ0bîº,Ñ–CY¹_ì;.Ö½gúõãuø_<\ù‚)ƒ³LŒBB³³jûÌà/ŸìE4›}@@*~ ÐP˜vÁ P×.–7ÄYª€~!¢Ü 2¶ :<ýý)ƒ³L(ŒBB³³jûÌà/ŸìE4Um@@pŽ ÐP˜vÁ P×.–7ÄY¯y€€ÉšÖ 2¶ :<ýý)ƒ³L™™BB³³jûÌà/ŸìE4Î@@÷ë ÐP˜vÁ¡PíZ`~Äè_„€x  2¶ :<ýý)ƒ³L¤BB³³jûÌà/ŸìE4 P@@º« ÐP˜vÁ¡PíZ`~Äèd Ðd 2¶ :<ýý)ƒ³L4¤BB³³jûÌà/ŸìE4šD@@+· ÐP˜vÁŸP¡÷Å e怀3«ª 2¶ :<ýý)ƒ³L·ó88Ìà/Ÿì³³jûE *pÕ@2a„ÐP˜ PÁšÆJû“hËg€aë gœú2¶ 9HTTP/1.0 200 OK Date: Mon, 11 Oct 2010 21:35:35 GMT Server: Apache Cache-Control: public, s-maxage=3600, max-age=3600, max-age=2592000 Content-Encoding: gzip Vary: Accept-Encoding Content-Length: 1664 Expires: Wed, 10 Nov 2010 21:35:35 GMT Content-Type: text/javascript; charset=utf-8 X-Cache: HIT from sq76.wikimedia.org X-Cache-Lookup: HIT from sq76.wikimedia.org:3128 Age: 2 X-Cache: HIT from sq64.wikimedia.org X-Cache-Lookup: HIT from sq64.wikimedia.org:80 Connection: keep-alive )ƒ³LQö  Ìà/Ÿì³³jûE ’pÖ@2^ÐP˜ PÁšÆLñ“hËg€-Ž gœú2¶ 9‹WaoÛ6ýlÿ Ö "9Îd§6À‰,íPtH›®i·I60-Ó‘E—¤âxmþûÞ‘²,;ÎÚ q`éHÞß½{¤Û£²H¬T“…Úžð¢:¼v_¿UtÙçvkò[)ô" Ryû4…Õ<«¬LDÐfZÌD‘†lµ&ò¬{ؾo׬ʲ\øu¡s{Ë5+Ü;‹Yª’r ßQ&ì/¹ Ç“Åë4 6¶[rÄÂ'óÌ[>8·ç–[᜶¼Ç(ɹ1où”|oš"äœs¤$*Ïù̈4Øg¸›ñ"Å3i5ó}¡ÔÄôºg"7â¿«ý#Ö*ð£Á|°vkËVg~n¹p5û,•-\rä­]$1R:¤šÈxp(œ9ÊE‘Ùñ¡ìõhFË/äUdÈaTy¢òù§G¨6eê:Q —˜³—0†´Ya?È©™ "¸Ç.ë±ð§½g?ìý8 ÏÁ`0è‚\¬ßgªl.Ä÷7Wú&Æ2¦˜ cx&â çbö‚Cü¥&àPDV½zóáÜjYd.&̸Çý‰ÔlL\ÞÈ“|ÓîÚmikIÂe‘D¹ïÎFáFN¨lw€× æZZ‘açòîûÄËìb&âËŽw¶ŸsICâ²Xï@,¬Š<åyÎ>W¥çð~sAT3¯¹ôDfÿoáFÌë\%7´–¶Ñwû ¬;Øj;dKf„l‡9ìD|ÂïÎ…-gág–ðd,†ÌêR°{¢ÃN´¾×Øõ\r˃¡{n`Éï\zG«´î÷iƨ¨ÇsÅS¯j0­ðåZÖËF«:½–Ù±`Z|*…±ØªŸçÆ©îþõŠˆd‚ó™H$χÞÿ)" }ì§€w«½`·„ºæ¼È`ŸgñrŠ—~0–^;ëË“ÂÏ%téÑYÏ joOT 40¿*ªÞ7r;O´œYÊîÈøGÇ#O£ ¿åÞÚaF'qglílØïO…åÑ\Þ ÝRÉ#¥³>½õ©S[F“tžõ½‡ç½²àéŠkœ ÁŽ &Ó¸³VÈsêwȸµ™Žr̆M½d]ŸÇ`¿á^pÔG¬çszêyЬþ©4v™Pg·BktfMŒ4ýãûS¿E:p¶Îw 0pªî$/nNó µ\C¼Â Ú‘r‹ÇÈVOÍ"“§Y‰N{èeKâð#GóŠ|Ža/T¾Ù!gZMDbݨ/Í;oY#a#[Ór$™ÙÏ‹sñºZƒ,Ø9À ¸‘mwÅãªùàÀËC¸„¨Ôùp½<û~€áXžLpÿ*³)“Š;d:Š(+eÄɪ»ï׉Óß"¿)ÀuöâA)0uMxádÜ ך/6`Â&3FYE}™ÜI-Du=”‡gî ¿̔ڱJ“s¼*h™_b(®ßi5]‘xå²:ÙY³v¢¡Áº`#J6b9Vj×6BÚWIto`î‑Á!¾Ž‚¹×[56qVä ð8ÉK×ÒT‹2•60ƒCƒáß›”Z£ŽŒ´Ô{ÁíÅé ªÓòÝÝFdº§TÓ_>Ìà/Ÿì³³jûE 0úF@2Ø ÐP˜ PÁ›öàÖ¼) €« $*bn2¶ 9HTTP/1.0 200 OK Date: Mon, 11 Oct 2010 21:35:34 GMT Server: Apache Cache-Control: public, s-maxage=2678400, max-age=2678400, max-age=2592000 Content-Encoding: gzip Vary: Accept-Encoding Content-Length: 5381 Expires: Wed, 10 Nov 2010 21:35:34 GMT Content-Type: text/javascript; charset=UTF-8 X-Cache: HIT from sq72.wikimedia.org X-Cache-Lookup: HIT from sq72.wikimedia.org:3128 Age: 3 X-Cache: HIT from sq36.wikimedia.org X-Cache-Lookup: HIT from sq36.wikimedia.org:80 Connection: keep-alive )ƒ³LÒû  Ìà/Ÿì³³jûE ’úG@2Ô©ÐP˜ PÁ›öàŸÒ¼) €È; $*bn2¶ 9‹å\ësÛ6¶ÿî¿æî5)?$'ÛÍîÈQrÇiÝÓLì´wÆu=IŒ)B—¤,+­ÿ÷û;ß’ÝÌÎ~¹ši-‘ÀÁy¿¤·+&2–‰ŸÉ‘øâßùi„óLìö¶îüD¤·a,½“A¦÷H?ÌV‘œûÙ”ÞL³lÞïõ†a–v—ám8“£ÐïªdÒ£¹éÁ³îß1m«·+ÎéÍ/Ò?Q³™Š»_RZ¦×{™ªEHùñdàH8¯hÞ–Øo¥~ª¸/>N|R1NÔLô>§2éÓÿ>ø3É«d•ˆn¦"S"›J±À{7~-üH“5÷'’€Ÿûaœá?@'~° "zÜÛ ÇÂ[NŽ“,Ä“³‘ Ä¡ØÙˉ]¬#~ß‚Yù)±c9ù¨ô®Æ#yÿÓØs{nçÈ ‹U2«ŽJÃ4K¼Ã} ¢#öZÞêWÝL½WK™œø©ôr™L3’sÁåé½n"ç‘H¯'z“}áÞ¸ÞÕ,r-yOóãEÑ"Zc9Р1áKЉz}§a2JeëX°¼L?,Pz´­×éˆ%˜£–ÝH>É´;Mä˜øÒò¸ âW¸¨|I;½$õˆb–&ÖîÒ¬Þ<æìÒ"¾øüé=ž€+™L´âZ‹$‘qƯwóiÅ;ru%cV­þûÅ<Œ{þ"Sо v}Q4¡»…è3̘¾«1/–„lX¹Æ‹8 a}ÿHã~ö£…ô €ûb‘€Y[P2â`¶šK€õø!Xî. acèíÈâ?h0[ó/1RÁb«<…LHòÁlôI>ÉÉéýÜîÕÎëkâ`Ax:ð®~ÛùËõnÇ#Ñ뉋LÍ…Ÿ‰)TRƒ™ PWÞË€‘;ÒøÎÈXfÝHƸŠWâYG$2[$±É@äçOgps?ovõìš&šZw–a6ýñbPbIXÇQ¤–lêÉ 2M3ÈN{ ã$rß#Ò9”IÐ$‚ª™ †ñ¾˜Ë ô£þùŠ|C>J •ºµÒÖ.‘¥øã˜Û£u@1  >˜¯Ý™ŸSÏù­p†àïËWƒÿºÞýëüÕéíUBp&É.˜Ï̶Š-Îø¥˜©D‚ =ƒœ`,Ë@¦©fiëÈ´¾AA¢Ø!•©<…³™åÏ­ â7–/Ÿç‘òG@±×³‹å«“~FóRÒZQ#Ãi =cON´åne ¿÷¢0͇¥ýeIòšùL»p8ö@4­Çúña1Bðô #ŽT· ê8Œd—œe®¹ï…ÒUªæˆ<ñÑ'P‹8 é#š¦%óÈǸšjd¥‡~Û5rYüXÄqXêÕUì d}Þg€•OÅäÉÅEÖqe(Ûëën9Mú>Q P¯™H¨zì3&0ŸÃ#üyYgœÅ‘ØÛ›Œ¯C»š\k…%bœ|\."JOÒ©”ákʤá“é~ŠI£€‘{ºd¯hß6i¦þ0’ f]·^ë,Ë‹u…x0ß„yø øO®ÿ­ôVeóT›b²˜¤ª¬«4ø<ŒÃã ÙÆÓU³®¨‚ÿ«©jvks5_ÌE…Á-+Þ(ñ'b©’h$fþ¼«T>—SL4jøHè&Š(Ò"}RÉ(Œ‘ÇŠ(Œo9ñƒ¼;¬8WQЫYÓm]KÚ¥ØÊhLHs Eš ‰ä‹¡d40‚ÞâÛH WÀ>^‰y¢¾PŠÚûBJ¶£ÌïWº¾fa§Æø:Ó[hEššö1Ÿ³’)ƒ³Lfÿ  Ìà/Ÿì³³jûE ’úH@2Ô¨ÐP˜ PÁ›öà¥0¼) €6  $*bn2¶ 9·i0]ʘ¢SÉÓ_ÈäN{/‡²óéy*‘éÈj‚îXýá tÞ ±Lêѯ9ýêÑ®NkízP€Dj‹“,› ²ÏÎÜszËçÏÝùtþ: ³H ¦ÿÍÀ5Ÿ¸ËÚñÙn‰¿Ü (Kd˜½¢ØIgþ=âÉàù³‡‡;æÇ?_|wxïOõ¢%œÅÈ2b™ ¤G„’ä,Žý»pÂÖäÏçy:ƒD¥jœ5gbÍ2´&Üáb"Æáý7¶û§fuïÂ{ØÈÙ©˜ª$üª =)µŠ¢¡Ï‹æÓÚtëRÍ®¯_›1=þ›ËXE£_Â593EC%$|¦¬)‘“EÄ•ì†L×åI'Ú‰-C™Q=‡>’5ÅìV{eE 8'{~¢A"²oŸ~êŠ)••ž\|oªh.£A× w—»J¯œ’$òQñûƒV5Ó(†&ík¾-9ý1Ã=è*t ¯Ùò°ß:t€jz)L—Äñ^÷ý5ýã·Ž#öŠUñݾùkÇét:]ê‡YôºvÆ=CÞ L:ófû ì¨È\ÇHÖ‘{¡ÓíÇ''ä­•âp¹äÞOYËSI³:”ÿ»ï|hYÚ¡<—é e×ÃEÁÀ‡rLÙ+=©.Ô‡÷ Š”°fµªV®DZorÁ¿ÈwÇžîOR«‰´IÇ›ÕÙ†:? Ö2ÙjY=HÇrÖ¿gn ž¤ô*}³ºô¹m€QèëŸ9È«ÝPW»!"vuÁ¼Þ ÷öjåäcDU]…×ÝŠ6Œý:½ö³q&|­xwìÝ?Êp5°î8LÒìdF£îÈÏ|Ê·ê /¯Wu)ƒ³L6††Ìà/Ÿì³³jûE xúI@2ÔÁÐP˜ PÁ›ö઎¼) €: $*bn2¶ 9kÏ´[£u6:3@†¤‹Û˜°bË’¥V²»ª¼mû¬Ôƒø÷#ÉÏkÏÿÎ5† PRjÐɓІ¥^YAKúAñ$þA'©òFQZ«3–Ÿ†ÔòêZ¹&ÈU"Y¦5Ò*ak ÓÀÖ²“Ìæxž ÞîWTßz튳¿o4:ÎNÃ┘û™´ù[©½±vL"ÑÛ@K•ÜòþŽm\Øñ…L­a°Ì×±‚ú¬}Õ—ss"‡ÓF1 ­…"?%ÒäRQ © T¤l=òe¦ƒW©»«Z\«×¥R 7­º(‰I%2>ÑÌûi|Hä%mh‰W&¬¦ÅN6ž?^;eOÍäza’¨²C,Ê(* D+éeë¥j••\«,aŠøŸ;³N£Rnr¡œûY [pµªBQUË É—‹!7ì®^©-Üpäî—gmòîÁ¢2… ç:úmѨ} ³#·­j S›ÁÁV’E+ƒrŽ[E¶·[5»]q2•Á­ÞÄ£MX Ò>.ýˆ7Ý·êšM‘Rsêap/ƒ·ÞüàvéS2¨Ù Ã(ÌVýúB½œÌ6ø=óo©Uk±Nyk%tÂ5Gc¹Ë;óãÌB÷XØ; ãúÜk¬¥ØŒhIíqz…s²¹j Š.Â8 ýÐCK i«$ùG5„СqFš¹•mtÙÌç.ÔÍo{V—N6ê}_:@{­}}èuh"Á°máj¦„L+‘È IªõµÊ’57r{Ö¿öÅ—Ej-pG)hôä»5¨Õ–Ó7Ç*)ƒ³LVGGÌà/Ÿì³³jûE 9úJ@2ÔÿÐP˜ PÁ›öà¯Ò¼) €'— $*bn2¶ 9–¶KÊù§ã }šP-rˆjh©°ñgCÙÁ+¬ 56ð¯Í*˜%õ>šý<4ž®+Y,^%ÈmüçBüNôùSYØ·q·Xi»•åûº¥.ê·dÅëBB¹ÇRY¿îÙsß! X“¦Š>àÌ'™ø±Ž¼?-¼s²ò¡ñ]äx£PŸö´§<ÏÕW7…V@HñˆdM~f¨’[èXÝðY¹¾ %|A ’«VÑÈÉûç_ªCY_IA¹ôåZ§DŸÓšVùWí?¶C\ß,Ák›×*œ–&Ä&ÅÊA¯I$øå£yÄc=‹µYfѽ æ [¶C±GŸú7ï¿R–ìǤBzâGZM,b=”|¤Ú‰ oÛiÑX¿¿züÕ¿TÙt㡜ãÕÿÅLe‰º³±Í .¿¡'nózˆ{éG·ýbDG'×U¾7ø˜1ÃA"µU=WŸ± I¯=8Ì{ïÁ5¾É{?©»ßÔT÷¤Ì?›ŸJ9°¬µoNê¬..ìš/ñ!±nh?¸ÀcfàIi2ŸwãÉù-Â÷Fžƒ+1´f¾¦•ÈsJñ¨“£PS™­_Æ0N¾$ŒY§Ý†¥tŒÚëîa ©ðQ°oÒù­ö[oõõ r¯#>2‘UÖJ`dP`Ò}jËq¾†ÁÐy'ãžBG;Ø[kO,‚CV³þíy~>KoüˆÂäo0ù†}Õ{¦Ã4ã#|µi~Eâ}ƒd’î‹„“‰] û ¦’[„¾˜Ñýª‰NØTtÛ:†( ©BÏæû2EwRßžÊï ¶’ð¯$œÍ¥>Oéž`+‚Ƙ´Á¶Ü^úNkÚ¥>½2޹Á¥—î~Ý…rY¹€Ââ-*æ M¶ ÅŒÓ)l>2ßÒ`+O"¬ ìôüÒ —âdåb!¯x§Û)¬J¿k4sJ»×­—ŽÂz Ö|-]Ä ÍEœ2éNÝj5Í“Üt© Òd>z*‚>ºY~ÖìØØ¿ëP¨€]·vÏò²öÂPÕµ·jfq¸ñãÝ qŒÕt1äÞQ Hç#ùœ­=ùssÎï^,—Kzs3öé¾9Ý8<|“ÍBíq4üTpýŸêdØ_HI§È%lrt7Á‚}¦À­~ö±´ÊnqK#”ê°Î×<üÐ÷¡Ü+ìŸU¤pϹ–—Ër÷Ù"x( bstp„·Oà£ÎŒsáh‚N|~¯R)3¡Æcg$J÷R’WLc^~Öt–žÁŽÉ+cxæ¸Á³†±Ûû{À<ËÞ®ìA8xÒƒY\@!.²L\üq2ÿ¶ ñí·çY¶=·3¤W}à} Å©ùv·Ðë<¦ŠÇ^¸X5}=­®ªŽ@¸]>yqhý# Ñ*…šûTç#>Ú²Or&9ÆèVØ{ —uúøýúÀè¹¢ÆìVx>—¢çæ-£s*ÓuœTg½ 0ÙûËõZ'óMœVô‘þ¡·¤Ÿw•Z/Á»Ï6¨=l.„Ž<}ät,¸n6Ö¦$?Zþ¦Íñðc“#çQûã# »÷Ox~ ŠtCþ \>:çûé]ª:).¶®,¡f‹¾=VœšÀ†þ|GÁ>蛢Ã}K¿Á½RŒÕ ¬£s süJ/í#8û˜©¿uç6tm÷Ö5`¯žNn†½š(p$ªœòQ›L žælœþ'ú`ĸKœ4¡¿b²„¬çE8u…î_–uUÓzë‹ÒTÿuÁŸn”ª¶”¦¸¯º¾œ°% KÚ)ƒ³L U  Ìà/Ÿì³³jûE ’©9@2%DÐP˜v PÁ¡ÄèdâíZ`~€¹€ <þ2¶ :\é˜æÒkÑò<”TeÕµb9ª§©¯Ó°XäÕIBS#›ÊœÉ®+U£õ©]“õ5Y’ ÿ›|6§×Ô–VRÑ®ÏߎЂ:R@mæí |%8²JgÎd¡¨`^Ö‹Ä&ÿ‡„k˳ó7Ë;ÉÚ՘ɓã6ḠÃhÑ“ŒÜVÎúÓú¶:8ã$Zÿ+Â"j=íšî{ÖýúºÎ«J´‚‹Qžü`͘õÁÎò yZpÖJÝÏFަ¨zmcù2Òc’Öú¨¡&)Y­LiÀ2.ÏŽ~P¢rN&\{d(×K½ÖF(Ê—e¢ª8i½óæ,êè’)EÑR‘[km–Öñžq0m"òÉÀÚE0…°º@°FvÅ -Ó½Yn1£š«ޏ<–Ή é_3juüiÍP'Æm³zÇ2Sv¨ºU×8„;]g-#`Ë”S“gÉ·ôâ;SÈ¡ ö!gÌöyÚQt4ºÎúzHm«U§ø*—×ícJ.¦9îš`ù˜é—*i½Ý{-ó(•DbG…6Ÿ¤f0¬5Ǧà»h¢YÖ3A_ŽÖ‘K’s¤ȹBÐÎ÷¤ÀUå ᬯ ¿*g4X¾Ñ°ßsyÎib¯Ý>`ÿk’ïEž£”ãXܨ뎄 GcãË+šI‡U –Jð«I”Ajuõut2µ&4ŠáÌfvþr ñl7üèâǸ‡êžÅÕfð×™X²ÿÿëãU’®A½ö÷ÿŸiëŒ B‚Þ;ÀïèiŠ ³Ÿªé´ôÃo=ñC_>µq«ÑÀ/$Ê iéA %ù¡±Ø@TX$§ r  œðÐXÄb›mÎyèu—ôP ñp݃~·ÓCcf¾ÂÀßpë˜"‘„ë$!î(!©ÕH¢ò_}ìA戰Þ9ß¾mÓcÍo>çýù«]à„»:†”út8gË¿ ÂùõÅ×a8> çý‹F,x„N½}\½K4ÑxüಱÙA6ÞRÉ œ_wÙQ1,¬ï?½ÞAZÓ]½möâ[ˆÞ½  ÿƽHƒå ÆŸ^½é¥ü‰„³× 艴· ¤ŸwôsÃÅ ñË:øïbd5çûxI§àÏ\†Ô¿ û±:°úÉhVPö¹m±­‡Ç G6l{Ù‚¢ÍòÒ,Œ‹¦™Ü•>žû Õ½)×Ã'Õ½YL0×Ã8yLWž1Gê΃³õ“J ©±ÜÁ骣on×5(À¦ÚV£µžZ¬"áeö`É£lõ•8S@ëËÝð}€ßó‰–&»ºQðÅ ¸»î/süÂ_ïÿ=Þâ_¹e•ô‘ÄñI)ïyÈï14×­f¤Õ/m=‡Ý“Ö“¼·É>)1m Æ]=׳cb¯õÕ.¬¢BûÀŽ&Ë)ƒ³L6U¬¬Ìà/Ÿì³³jûE ž©:@2*7ÐP˜v PÁ¡Äèj@íZ`~€@÷ <þ2¶ :÷ÞÉ*î±ÚY´ÎÜ\Ť§éóy(ªŽOº©zøÕžõQçá—¶‚4´Å¦ºs\&êo.{PR&»'õe7­ ¯¾º¦e_£Ö¹ÿ«-\˜J§Rw϶›gòލ~ЛW)ƒ³L@\BB³³jûÌà/ŸìE4@@¾û ÐP˜vÁžPþÁ¨ÝÄÃa€€¦k 2¶ :<þ)ƒ³L´sBB³³jûÌà/ŸìE4Þ+@@çÏ ÐP˜vÁ P×.–7ÄY²:€€˜¹ 2¶ :<þ)ƒ³LHyBB³³jûÌà/ŸìE4ü@@Éæ ÐP˜vÁ¡PíZ`~Äèj@€xX 2¶ :<þ)ƒ³LayBB³³jûÌà/ŸìE4ñz@@Ô€ ÐP˜vÁ¡PíZ`~Äèjª€^ 2¶ :<þ)ƒ³Làâ  Ìà/Ÿì³³jûE ’£ì@2*‘ÐP˜v PÁŸÅ e棥€Ö‚ <þ2¶ :HTTP/1.1 200 OK Server: Apache Last-Modified: Thu, 04 Feb 2010 23:18:50 GMT ETag: "6ada-47ece8ebdaa80"-gzip Cache-Control: max-age=2592000 Expires: Fri, 05 Nov 2010 20:01:18 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Type: text/css Content-Length: 4937 Date: Mon, 11 Oct 2010 21:35:37 GMT X-Varnish: 3909036089 1406892892 Age: 437659 Via: 1.1 varnish Connection: keep-alive ‹Õ][Û8–~ϯàÎ …$ˆ\²]®Š+tz'@z{¶“æa€-Q6»dÑMÉuI#ÿ}y%ÞäéÊ[AWÛ¿ÃÃsã!)²Î_={~ûŸ#¢àÁûÏŸÁOîÑ=¡·ìÉ{rx¤x»ëÀ‹â%Xäùüð/ûå×ϳîîºîp}~þÛïœÀÏ ²?‡rì^2ðGXƒ¨iQ ŽM‰(èvüüñ xÁ~eŸ>¾ÿðߟ?pR/lJð_ÿ^°_Ã'ŠD;{öêüÙ³óWà|dM€ªˆ¶Ï²äÃÍŽ8“€l‡Ë5àPâöPÃÇkнßÜJ, Ô¶xS#Vÿ@ZÜaÒ\¸iI}ì¨FUw ²µú9<ŒèPÔ¢Ža÷n1CæoÁ–%n¶âó†P&ñ‘u©Æ ŸùFKþÌgË· C]V¢‚P(Y¥{2.)Ü«Ö7¤.ý±;¬¡ßœ¬T&'ç¥rø°ÇÚ©u‚=<±ä’’ù‹+N3Y³çXÃ(/^3Ø­ÿ‰È¸dÚ>j-0ù‹0±ãƒcBÒVYP‘âØ&@¢Î8«G9Êm¿«rDŸ‡ªQE×òÿO!|(R‚„ e¥ÿó°÷g¨ØHP—9¶m„M{ÔT@Ønúw&ÆÆæRŽ¡ë?<Ê‘9×X9"ÍKšùju#kŽ­œÍ6}Á[är# 6ÌÁÉÝDuMij5QÇ+™Ð"KW "¯Ìx^y³fµÆÂƒ¨Gº%‡÷¤,T-KAZ·Á)äDÅE½“ôú%³R4[®kEËÕËÁz‰ðÐYÊêò{Hƒí+ê<Η*˜º-sЦœDÖTtí*г+¾ æ Qß¾Çb•^Ò¹äKR&5ß\ñM™ShodNx³X]>,.¤2ɾէ¢¬2¶S ËÀë%x™3—3O¹~I>~âÉ:u°zë?u°¿[ߊ󹠿¶%/Њ}[>Í.âÛwdy™ûY^òƒ>†JC2SÂSeɆ…é'¨ †€Á·þ¬¾jä@0?¦e_ƒBë;¾Co•83q·ÆœsÃSBöQ‹?ÔJ3ïe2)œän|ÖΜÒÍG¢Lè(î'ãóÍÆ:f+´·~-f‹þøs¢=¾ƒØµCœªº©dÅï!±Å›Y X¨­Âœ½6,Ï{>û¸"üw@\äØ> ÷ªUõµ¬¢¿ö;òÖS‚Û^›c=pÓþv耋[D§Ûvi0 ?t5Ôä‚+‘ÿ2ÑÐB ¿ö>aÔËGSœJ‹/¦½ñ:j©Î´6ºÄFH^wkö†÷«¿ZêMo‘q&ìãÂqV2}’¶·…) 0€°êÅ€ê²f'!ú>è†&q6èlnzÚl&)WôtØómwWW Å‚$ÏîÄû9æ®2 –Ü>Fב ›'ua·¬bdÈŸÖ€¼X‚µÃ"ì®9ûv !T±ÀO™úœD’Qß3»ìQlÎÚ—5€~ &Õ•mhŸºX{ÚˆôÜOL Cš˜§ÇwÐ .¡²Æy£‡ŠØúm¥k ?òfváõùng³+ð–!M{ΈZWÙyˆ—fôÞçw&VÝë;¬Ü7Âôa%Ïà¹ò¸ÚäÝ&Œ“Ñ´zpâV»‹Y.ÆiŽr0KMÚ­333Mg&'ñÖ_Á20"ÃØJ^Rõnª6æ.•êÅ'=tÈÛ à)ƒ³LéÌà/Ÿì³³jûE ø£ï@2+(ÐP˜v PÁŸÅ v£¥€ʰ <þ2¶ :âÀú4Ê£çŒ*s;ÈÉÂ=fF¹?Öf³ ßÑ1s‡žÊØ—9Ä8¨ä|̧ª4*äú=8¼LG*7U-¯WÏ-Ïã|œO’Ì!v$¹Uþ<]Æ¡Ëål_ÄÁ‹Uêf5l»`Rd¹B&é{Œ=F}˲F߃þÀÝå…—àëèŠà­©(/Æ” š[™ ÿúåh>Ëpí6£b½¬Ä*“îj_s]H™T)Œ.s÷PI”„ ŠÚtœ‹ëaz$Cú¿ÃËõ =“tNæÈ£ÃÀ˜š@ƒjÈ&I„¼øƧS“S.MÏqÝÉ;d‡Ûœæ®S[·@|¸úõ‡Ÿ?€Ÿ>þ¼èà-j@EÉXãÐ|¶š-=.WH#{ØÏhþyþŠ‹ôQÜBûñÊa­Jç¯^›ŒÃ_Ó—¯Ÿ¿Ú™Ðwð©Z_Å}¨|Â÷X­÷°q£½}ñÒWCæôbß}¨f§*\ä¹ÿ¹Nò½ÄüÚlO˜[‹úƒU w2l]¯ºÌ­W¸ÿ(óèH˜­TU,ƒøˆÓû¶uGó7`Àì‚ùt®‚–b¬Ÿ“éì}ݯp+ÈÕÚ¢“›)×›)2Q,æ’º¹ùtR×ö”?UW_ fë4ÔLáÜù—WÍœ òÔ­[£¤Ñú¡ÛÔ`8°'Rå*ÎhÅôŠH&û+7Ù—IóܬùÙ©^Œ±Iéû…&›ŸœÀ¦ï““úžiŠØ<“ç¶r‡QËëb`¥Ö€½ ãj6³´lŽÂíV$É~¯Ö]Û“;Á 9§dËÚoY…éqçЃ€¹Ü™Úcº}Ïî`}dýî]Öê·Jöxª§…4M#W„ü6¬”í`S†®¢\ðÉ4㌸uÛ¹Ü}LÛÜAåkòõ¨”ΗÈ[®Öïë5–¦YŽzCº²,û;Ö³UŸXZƒ„ešÕvUmžIÂÈ"Œ aEëʲzII®˜\#ï§n=Ù{‹ì½—¬ÌO¢ÚÚܶ»ò¥CÂNûç¶Ïν¶Ynž×6éõ¸Cq;&a“nN$mÙ‡C×GãˆÃ¥ëªR|äþ¹f&BjEý@òŠC ÔŒz}ŸM.¬EþÅp‘a¯ú¨û½ÂÍQØl“­Í‡Ëb·dœrXƒ;KÜíÙ/Íh6í­·žOR9r‘r¸.ǽ ´t_õ&—ϵÒ2ùVœYÝ›Žƒý¼Ù“õ~’Òìh÷ÆÎ•ÇŸÀ´t\‰åÎ~O†>âZ‚þ¿“0 ®äç,~¦qB~ZyÜE¿0[î «=˜JO%•¢’þ5PìT9f%:¿ñlºTkˆƒIÊðE %ìáFv¿#šÌÔ.Š›™{y€ãiQ`íÜ“¯‡©š¯r D:U²ÁˆãïÞi¤Õe ¡Ê£+7'ÕfÉ øC@ÍV^"ªb)M\˜=qóHmÊ`Çûâ{µâ›˜yæAV$”ÿ‘¹8Ô"´oá!u,qc³‹þïìtDdû?T»9nû?­‡ú‘wÏË_÷Á6Ø4¢¨nÑýQ4›Í€íF†w>§©Çï¨i‡ˆ°ôìNù|Ò©ç(˽Ëñ¿Z“±ÙÚj)ƒ³L“ BB³³jûÌà/ŸìE4@@5á ÐP˜vÁŸP£¥Å v€~!›ê 2¶ ;<þ)ƒ³L¬ BB³³jûÌà/ŸìE4¨(@@Ó ÐP˜vÁŸP£¥Å zÄ€|ð˜W 2¶ ;<þ)ƒ³L¿Ð ¼¼³³jûÌà/ŸìE®@@Âq ÐP˜vÁ¡PíZ`~Äèjª€€ÐaY 2¶ ;<þGET /skins-1.5/common/wikibits.js?283z HTTP/1.1 Host: bits.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: */* Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³L!b ¾¾³³jûÌà/ŸìE°Š @@:v ÐP˜vÁ P×.–7ÄY²:€€ÐÊM 2¶ ;<þGET /skins-1.5/common/jquery.min.js?283z HTTP/1.1 Host: bits.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: */* Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³LDb ¸¸³³jûÌà/ŸìEªC@@t ÐP˜vÁŸP£¥Å zÄ€€Ðî  2¶ ;<þGET /skins-1.5/common/ajax.js?283z HTTP/1.1 Host: bits.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: */* Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³L‘ ½½³³jûÌà/ŸìE¯ñU@@Ó* ÐP˜vÁžPþÁ¨ÝÄÃa€€Ðt 2¶ ;<þGET /skins-1.5/common/mwsuggest.js?283z HTTP/1.1 Host: bits.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: */* Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³L=Ž   Ìà/Ÿì³³jûE ’©;@2%BÐP˜v PÁ¡ÄèjªíZaø€¡é <þ2¶ ;HTTP/1.1 200 OK Server: Apache Last-Modified: Sun, 03 Oct 2010 11:20:09 GMT ETag: "7a4e-491b49c48cc40"-gzip Cache-Control: max-age=2592000 Expires: Wed, 10 Nov 2010 07:46:24 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Type: application/x-javascript Content-Length: 10004 Date: Mon, 11 Oct 2010 21:35:37 GMT X-Varnish: 3909036820 3582196576 Age: 49753 Via: 1.1 varnish Connection: keep-alive ‹Å=iwÛF’Ÿ¥_ÑæzLÐâ¡#¶cɲׇœ(c;YK™ä-©è@“„¦˜Øÿ}ëè (k<»o3od¨®®î®®»›ƒx/ÃÈÿ-ºŽÄOþ'ÿ,È¢E!òr±H³BLÊ$(¢4É··?ù™âH&Å/¯Å±HüOÑÔ/Ò¬_æ2{9…çý"}—.eöÚÏ¥×9ƒøAª‘ˆ’IJH¢ür*ƒë èà_ȼð,öŽxð`{ëÞàzVÌãÏù"M'2ûœÈ"ü… žŒú»ª‘nÓ9"ÜK9¾ŽŠË¹_3À¯ßöé7ð‹X2ÌhàÂÎFá¹ ;â¯í-EiîOü,rQEI(o~žxmY»#î‹Þѽµª†`ÇvTC¹ŒèÂv÷àAC¦Ë\÷¥(Â?É,‡u, ?ËåiRT†4Ü»€~Ù†%y›f™ç×r•‰$-¤(f~!Þ¾=Ø"`¥‚¸ e(f2“÷ôšM&û¸b“(““ôf4î÷ž^|žG‰œD2GƒƒõuäE–—ãršWšï7Ayç3™Kág2iX‹©èŠq \™Î¥ʼHç"'FÍE&ã•€39wHµSŠtßm>Ö7{{_i ¶%rÐ:Hº™¯\¦¢€¿ÈJyT}z¹È`üŸ$Ïöˆ¸¦A9ÇÌ¢8ü†2¯7ßÔöMŸ>¢ϰ9žŽúÃG¸ÂÃ=ø;Ü…?¦%#Ôè±^äµ±¸POÖ ˜dŸCŠÛäé#Ã>uÉ!‰l¤s0²ñx%žÍŠbq8Ìó0éÏ£ Kót“‘Î2é•ù ŽÆ™Ÿ­àÑÁ“G»Oû~¾¸yÞElþ§4 £d*&~ ¬¹Hó¨ˆ>É\L2àÃyš¥IySÈ·`Λ ¤ô.Š9Sœžˆ__"²¼È•û{Oö:ÌvÒÌõÂ,%€œH fÿ¯½î—!>ü¸Ûý£—72¨HM`´¤Œãm˜K’oãÔ‡ùù(§'7‹þý=yv,÷wq£Ó)sâ—m$ñ‡8û1 (KàC:¾’ì4ÚŒ0—Å do¿þöà!ÉÂïÂàV±\øÅ >^Ãþ{8 „~ ?Á] ô„V§€ ad³4½HSPÀ©¸óg~ö`Sj‰R(x)nP-€0(³@òôAù3aÿPmÓìÝÓ{€^¼Å^s³ ݇0þá^“†$[|H°P˜ê‰‡Û×¥’Qm¹„ Ý/ýX&ÓbvÔ™îaW|¹›šÇ¨lQÛ"SÁ½?vc’Ↄv•ñaÓœTÛ"¶6JÉ~Æ2ó”8é6W§.š£åÀv„|8•fÒÎ~óó¡˜GÓY!–>Ø0_QRdiX°Ð¢,¢8*Vfâð=«òåä× æÂëàùñ^È’´órª —Ñ~QDE,ÛbæˆÛüúñôu t%8b$©ŸÉEìÒ€ Òm_¶;ûèoûo<´Ý‡/éá!tDÜ~àÇ™¿|«…<.`+ ®Àˆâ¹oÃje²(³êœ-QÍó†cÀE’á™b¢cñ×2ž´îöÊüàZfÍs­ðÆjo£ø¨à» ÅtŠ,ÈRÛ[ õ„TY’I¿'±œµÕpIäý\/ r °%¾Ì‚v—éjzïÛõ¹#hÓãTª»üÕêÜŸ" zí™ôÃvg¸{ÑgaûU›´vìÌç̉r*ŸIYaÐêZš× 5/|ç 牾͌7ï *0ƒ]1G[]!ß¶*q”\ó4Æ}¤`ÛšÐ6=Ó æ¦#~< žC‡G,¸œ^á5;æ§Ì=ß¶N±»NqMþ2àÙ™'f;äÛG¢ù°iÌyó˜i³kâÃ3|¨ë>êŠs$å˜(¢ zzR‘Çyu|52±1Ú]jDÀHmZzDtÆf?Ú·E4Óbœf×9šµ¤Ï¿}Žöv·AšÝ΂@n‹|ƒ÷i’ŽQ?2Z /—’ôÊÞwOöžtØ,Á©M'VÝ£áÑ.ÁÖš€7¶Ñ–#ýÎN{®Ðµ¹äš‹<Ó,oñÃd pWVüò3axÝȆ×\-…íâÉ¿ÝÅ“¯u¡mÓ£§·ôa\§oÃÿöí~9²¯ârú óúmæ#ÇiýkÒ5³kíÛ ½×[­2ªŠt«ÎßuöU?N¿`T=ÕOŽê¦H>K—çipžN§1*wÍ$¶ê )Íì7?¿Çl{¡¥n.³\Ûñûçïß¿‘—2߆¶$:ßLãPf®@±{ëÕê4Dõ”$Óyò¨¥¼‰òLªw€á+mqDV ó°î9=þ\ÅÆCñ½!#mI4xÑ,ŠeH„âMx¿èA¥ S³³…ŸÜ*$á½"ÈÀ÷ƒØÏs”$$1aÐÔ#ÈF…™¿×‡\Gí+¼ºëq\™ŠÚûJÇ` ’ËQR©ýôfåuׯ8µ]c:zà3WoÃÐJV’ð:Šã“O…:_˜îj¯wæiðcÒÖä•y½ŽöUÁæ¦Îüß¶¹‡‹¶¡Î2à] CÞ¦¶–ó:†gú‘ü%­ªlzhb$¢5ƒÉƒ9™Úú*ž²³ÝêŠÖ”%ga}ãc œ·F£vK¹u£QrGIËõ$\2ѸҤV¸MPÔ~о 5üùâhÃÚ­»¡ø'Pµdz»áˆ7cx~7 S‹æ•ÜÅxf(´L¾F€LD7bìc0æxœ¥ËLIàiI³Þ߯°+‹‘4.¢ÅKjûw¹ú…›ûqÑk«³IGвln“Ï¢Iу%Å–®V»WMc´©ä±jù©çâÑþã¯õYÜSDÞÞ•g;ƒÍ :m= 3÷ƒÙr&ÿ,e–f&×¹‰5òTºè+-q\<™Ø¼q¥€äÍó£¡G=u^xØþá¦ð—þéwF÷G†e^*ŸÌ3ФY–œf•‹°Ì„®W¢£êŠäq:¡Ghs¼ÿ³ ÁÄÃôà4­Þåð@1Ks†Ë1g'ÊE†Gˆ$Ù2ÊÓÁA3U~d ¶ –Žý1à™ùŸÂr1^!†PÙf$_ý'‘$^fH|Cg¯úþcE*-‹£æ¶´1Œpâgçµ™¡kYWô^õ‡}£ÿð‡ÈANFŠå,c~]Øa®@G0tYNƤIö4‰‚™~@H2Æ'Œ”ê¾8ÇtI„é-èoÅý„¥‹"šG²ß Ò`–DÀÕ}Çá}m»å„6r;HãržôP_vQW™è8Wð ý„àæË…˜º?‚¡/cü¼èÅé4mcË€üI3F3f #Iž Ô2X­we¡¯Ñu›½SE1Œ.Xÿ«Hw‹B¿µq+àÍ6{³ª/ì?à,:?-2ü#“´œÎ˜¥“Tä%,`e!`±)C ÎÃfznî¡c¼( CÎ7£‰ý1,›Fc?p×ëXìÁ?ÏÌVP©(x¸³£&—"!Üê>«¢Ã$@z ‚U¢þNL…­V€&;µIªD'ÂtŒsGèQ^i•ÚܶKŒ°%ÈÇÞÙ¤wDëþ£‹/¶¦¹ž© š»L†ëP:‚×W1š„€D)„{Cv1(r@ZéÀr3@2%?ÐP˜v PÁ¡ÄèzÄíZaø€H€ <þ2¶ ;~¦¤ ’Ï|k A³7B#…õÆf†Ä 0É ÿ5<Ð%–J˵Ë ô½ŽÞB@ö rLÑ'ŸÊÊ`kqÄ"FíàÌ`f+±90‰#,Ïpz¡`¿a[ƒ»5ÔVb‹É`g~iƒºî'd“2œ²°rôùqËjæU®Ø‡¦^k‹)<Ø*ïNµ–ëàZP®bi¿0ŸcÃÓLß%níÒÒ€&»z½ºv2»v¬×œ¦Åmv’ÞSؼG-6$þ#á?&Ä›,‡ÍŽPY‹xN ž– ÆY 1Ð(š\pPE­8¾Ø©|©>°óÀûã³èÈù¢X©ÙôÄçûì‚ûû-€Q‚øÎéüîáó‰îk£õ‰x-«9¿Ry üGc&¶º5«Ï¨®–N×ÉöEC2D@ÊÂD¡Z°V%ö‘ šÉc`Ú]žãf,[vÀ£dZY€L70{©$ÃnîÈØVÒimñZQ¡ÚìÃÁ%×PO‹Â¨PšMõçþkN9ÅxÌ­ê…Þ‚Š“YñЏÖS’ÜîÍjì’TÖ†VUiž€¼›/@ÑŒ¹ÚÉ{ÑaÚt Wi°)OuvÓŽkªBóXÕ@e (™ÛÕ)cw-*ðkaû¦&2î#ÿks´è¾£h'ÈXåñÕÛ-@0½dVÁYO¡XŒæŠìÃn9¢j´ý ãÆÐJ[ï¢ 'ßc½Ø‹?]Zw´Áí‰]G'…*ƃfàÝPæ+K”‚‚Ø;DBOÞ¼?ùp~ùáç7'äu U°? ¬ww0p¼×­1æà ªƒC*”;ù}%€ò@µæ_Üü´PaDñ¦œÏWd»„¬ˆƒ(Ö ¯è)ØcERð”…‡Šy3\ƒE“HsècNŠŸ¹‰|è{¡_œa˜ŠÒ´œQ±HTÔ|ËE#޵ú ¥@o7oÖqnñ+jdnrdÂÖY+ð¼‹Yý¬rlñgäÞºTæ%QާøåŽØ´«Å±z÷\aW ¨™†•—Ž9¡f.åVuŸ<<Êgâƒ1Daü“?VOkPO/RÁ8ﻃàV?ïp2ØæoÛ°ß)$™ƒ”)61TÞ!°W£„ùõ‹Ž$¨,OØ!;Œ2(,C Æô|ÌâÆNBõ$ÿÏÁå.¦+òÕ?k\àÜóh.Áìõl"ÿ댢PsL +öwwm¥“l^Çb°A’7 fi+i(©êÈç{²O+ª×­º¯ŽygiÝ[Ýshžó¬Úx®úT’æú¬@S^AÓ80À«ä.°£žÍë+ÊR·ÇêÞqàvÄÞ‘»ª"¦Rc§× lSk°~Ù¼‡ŽÍ&ÚÙ‰L"ÔðH[5\f:šÞR°ú°™™4Kxíªm9)‰I ª¡m¶E#¬J’ã)Xˆh:N3Âý¶Õ«,–x noý–EEÆöJüÎ4«ÏpXÁ÷àóË岟ã“~à®ÌöÖK*kÇ0¼ø˜ŽÁðVs?©4ËèE‚Ïñ4¢  8T«\´Î1¼“ÉÔ?VÈ À 9<)@ÕÀÆIR°Î –U_ü¸ÿçŠCQqï°×imo½Å´Í`³=ìí vŸ À1ë•`‚ /{ 0t`¼"ñ•€øl»ú®¢T^kç‰ô$F7½È”¢éŠÔ¼Í­ægÙGštDåÙî4†8³cí7wÉu+k,ÊûW 5 X• Ÿh¾à¶X^â¹(<’GX ñöíAKVúû]Au)ƒ³L‘   Ìà/Ÿì³³jûE ’©?@2%>ÐP˜v PÁ¡Äè€"íZaø€pM <þ2¶ ;…âiÿ*ø-MîÂÃD±·PäU‡lÔˆ¢ø¡áfÅ~µN´È·ûoÆV ⬉1ÏŒ>£}VÎ.ú“PS`ÇÇyµw:!°¶fõ'α‹õ®+É;æ*+<á•ÃMÓ²ƒ–Á'ýÂ~9lXcø8xtñ QÉggÝÖùÑhwy‘>㣗ÖkÍ(vZ4¤¶ú6<³³KëáäÌ[àßFy§ÊÀé …£)™õSªFèµ:³÷ Áçû– Ç[=ñMô|œ»Ñ¢–?UK§–hü²Èü%ºfޝxޝxKÔØž›9Öè˜3 _W:ÈíÉ ÛÉ5wrÍl˜x_Ý{÷šfñúB»Óô8æ¡ÝiUzÔ™¶ª¿£÷öä‚»uç½êÌuÕòuÍ@5žQqž¾Íü)Z&ê“•÷úLqÓÁgu¼ø%žþMŽÿ^9^Ì¢“›[C}I`ÿX?¶+ô]GîVŸ‰ïöwbá’NÎ…¦bq ˜ñÝÞ÷ý§ý=ë†ÅÒåB€†Î@_¬TÓ˜ð‰#xB°îp*åÚÊt;¡ºÆo›LøûôÏ(Ž}òù)Û¾ô¡çŒþXPBŽ!um9gǹp\{öy¥xÐa«zð®nŒ»躠¼?óÑð;æóÌ}Í fQ-ûÕ"7wÄô69HY0Utžf”SQGóL †Æ½ #öž>}Ò‹æ±8+J´,ßI˜Eá”s?¥)E©Á‘ÿðãk̺¶Ñ¾å'xÕOâž?`—Øwþj-®³U üÝôÓlÊ T=54m(.^¤aªgÒFʃ4ƈf>ÀVø¶~¿»ÿ}Ç6Ša¥?•½ÏL¢@„Ñxdš¥å&dÂã¹›ÖœÖú*ÔŠ \`ã~Ô€½¢[íï?îPàKjòK@9•—t0â¸vH" Ò»AäƒöQµI¹ ‚'è>ö§Ñ¤bÚTƒà—& ¬A4@ø¥ $Ë,]HXWv®–SÓz§&‹r¬>|(¬å¤÷r.³(ð“&Ž)ˆÅ$ÊÍ€­×BÁßÒ]ø1•Óò–çÖ*ÍœÆ ()ç`R_¬Nè%­º ÈT¡2Ì©›wNèG±Œ=‰ [C…ÐP…IðêÓ®X DÀlë“ö0ˆÓçàÐ~óXÆr³ã¦»áB„Å‚ãDÖ-”qS uØuTMÈ>6 0GLh}ËyX hG¡Û5Ïée^b@…'…Ãàwâ7m(ÃLãØÏT;OØb ÍÐVcQ²ücº4®¾îãV%ŸÕ|ÓÃ~.vÝ13@ñ£ôC O_7´ÚÒ¢RƒnhÞÛ#óÅ‘ÁëX¨ýîEMÝ3pnüøÈd ~“ªªL –Cœ þe›SíXÓ„éHÃuÈUJ‘ .ÑœRùÕ†p±¦£È8n2Ž).'ÙªÀº:OEÛày=ÞfÃmmЫf§èÛDLD›RìœÎ;afæ™OÉ¥ãÖ´xŸ·°9º%Ú¤,¡G;nKeAHcybèUŠê[ÏM«g”Írð‚¥•.]€hÚ. Ž[úQE,ן¡ÔM[ 'ŠãÖƒpµÏŸ °3øÇÞ®1Â&IÇÓâ¾5;¤i+5'YÔØ×_ÕÛ»ó&b}š qªŠxq•%m8@IJη*É*x›¥R^e>ŠpýWöñKdSŽ9’”…jÃå,‚çzžðN#”Ãi%Á&/¼­Å­^Ý5«tgö²#¹ª¹&¸´ÐyfÏùÔ)ƒ³Lžž   Ìà/Ÿì³³jûE ’©@@2%=ÐP˜v PÁ¡Äè…€íZaø€ú7 <þ2¶ ;÷ýÖ‰‹@i’ÞF»©Q:‹XÒ‚îŽf“&\YŽÚ¤«ñÔ‚Þ¹†âÕï8BQ9yÞNå.3ºŽNmŒÉâŸv®‚¨2:E4¾¶²áª"®šeÃUÅþÉêöÜՅΤ(Ë'C«è®†Ï3ktRxK®ôÝ uEžcK S6îÙf0I&ãfD‚E ¢QhÑÀ‘½8’ͨ©QÝð±`Ú>õ;kÔö¹.ízyÏ·ÐU.\ªJ—ª¯`öîæ2ýµ…ª;¼ùœ¥e¿Ã¬ÎÓp´ Ãý‹®ØíR ׌‘©gäBò-gl7q½°®….Æi¸êÂrc®ož~¢#?àÌgΙªkÃ`2X`9õÃá% úÀŒÓËÁ±³Mç*l¿fŽè ½K¢ ¼åãôZw®”Aõ* #™¯]³RéÁÙ<¦úhèèÔÿËîýûC¢1½‘±,øj6®¨¥=AËœáy„VÛb­1]=¦]žÛ"7EÖUµ™:n‚ë1—éaÃ4Ñs´­'|÷mJ1» â㋪uñ:ì×mò*ê•"Ëé™ÄRé"ͪ µ \kªçÙØW˜Üx`sú£³5ˆý { ÇB1\ZA˜ˆ^QØí_ð™ê[¢Š:äÈÓÛÀÿú¢ì¾_“…\³x©:süÞŒ Ë%ü<ˆÔ­pLR¯ðZ£‚Ó‡Ö°¿­ÝÞZ»Fæ$šÒ¤Ç:4ýïRòQ(A­ŽžÑºTÇ×´T_›ÿ¯qñÀ^§I^deÞ/˜'TGOž{‚¨ÀœŸ2RlGE„í]”{øgÿàŸïðÏ#üóÿ<Á?ß㟧ø§‹F£~›ºŸû74ïØE=VEHfàœ¥ˆ’[â6 wB‡ÝÕæ²ðÍa\1EvQæ3¬Kzà”·GðßýÑÃÑÎèŨ?òFÑçÑ_£/£áèbÔ»¨ƒlö~’)úB]üDWÙ ¤ãìrOƯZ[»k“á6«åk)Yn¯]©È>u§•F@wÖ@-bÇ”ŠWlÐ*oÃçŠN»ªžÐ\¡ ?|QZÈ ½Aò»êÜÈRª#¹`y-ðÈWYÒÕk(: ŒV5Í)J \¢·É ‘뛊Ç;™G7x~l«XϘØÒ µõ‡×¢[$·ZÃÞŽòE_Ð5¯$H/zÀ¥êcç…w²ªóëøR)ƒ³LBÄ BB³³jûÌà/ŸìE4º@@ å ÐP˜vÁ¡PíZaøÄèzÄ€~!ïŸ 2¶ <<þ)ƒ³LRÇ BB³³jûÌà/ŸìE4Šk@@; ÐP˜vÁ¡PíZaøÄèŠÞ€€ÐÜÖ 2¶ <<þ)ƒ³Lñ[   Ìà/Ÿì³³jûE ’“b@2;ÐP˜v PÁžÄÃaþÁªX€¢Þ <þ2¶ ;HTTP/1.1 200 OK Server: Apache Last-Modified: Fri, 09 Apr 2010 05:35:47 GMT ETag: "7254-483c72ad252c0"-gzip Cache-Control: max-age=2592000 Expires: Wed, 10 Nov 2010 07:46:24 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Type: application/x-javascript Content-Length: 8422 Date: Mon, 11 Oct 2010 21:35:37 GMT X-Varnish: 3909037062 3582196712 Age: 49753 Via: 1.1 varnish Connection: keep-alive ‹Í=kwÛÆ•Ÿ¥_1Ö9[’EINÚ´¢¨¬ã8µOb»k«u{²>: 0$E©±þûÞ×¼P4Ín>ÄæÎ™;wî{F‡OwÕSõn¥ó:*ã…Š~Š®UµžÏuU§E®t>Os­fE©Þè$>¦—)tÁ^ëJW*.JíZT˜TŨªõjU”µª 5Ó5}0h+ì剪ÅFÕ ½TSÁÒuZ\n( ±Ti¾ZוŒ;½Qï‹©Ìêâ§WZÙ™¨Ú?în‚ƒÿ”â)Ê«,­ê3•Â1"Þzuþæ‡ß+é%N³^ÛÝŠM¥nŠ5nÔ2Ê×ðå†Ätvƒx¼Ã‡ØøD."˜Ih˜j¢KÈ(¿ö[¥ûû²xäÒ†mèÓOc Õò8ÄØƒÛYÇ@¡2àOXšÉLvб€Å¼«,ç„•73´=Å-nÇ­£xà″yI~*HxFÕ$^8L¨½ÁpZ¸úR«»T:L 84vW´(ŠË—Wdþ^p·À@\¯Àï2sêKG¡_¾GÛ0V·4ÆÑE¿'B=+²÷£%°^’}õ¤içñvµÎÉÅŽÀºÍµF'ÚèyTÑ 0…QŒ.R0a“Ó™3¸§Ùº¬F»;['Ž÷LúiMx+B’ó÷`üaÚ(a¡µ¨MMÖ7£tà¯@%‚Ÿé2Õ‹u‰´‚sP3&ìh–ƒfY®šS”D9K`ñ TLƒL£¥Ê–Ü Fr|4:>ŒÜÁk¡~^×e ãh°ÓýQ0<º‚¬vU8" Ä€Œ Dê®t êÔ@¥OÐûáŒL v—Á¿NsÏåÀ>(¢j–Îìp±µKC¯¨ ‹ðJy#¹ãù¦HnîÝ=æwž¥%9m®uf.ôz NëˆZ_¹’Qöü0²€cF8¥yBßû5Ks8e Ìê=‹@Â)ƒ³L_   Ìà/Ÿì³³jûE ’“d@2;ÐP˜v PÁžÄÊþÁªX€éÿ <þ2¶ ;š…7÷Ahàñ‹?ôþ€‘¡¯9l÷ýÆ·WdxÚn™žÕ­~?àÇfGc_•ÆåM¦G«¢JIDÓªÈàÈõžTMÓè­®ÃF:ãÁl³ÕÛŸÔJT'R˜%9P•­NØm dñ:êÆ­)ඦ‘`>[W´eJ¦™,ì4Kkd²žØÛ=ÞzÐË SP™ûê¹Kã··¤sñ§ïšÏ é³ü(I¨ã 5ZÖ|¬¶5÷»ÐÙðgyÇÌIclÒ”ç(ªë(^¼4’ÊÇîZàЀ¼jtN{ì ˜nÓQ}/1ooï0­ùøÒ·9Z!ãµ_¯š¦P`k8“Í[>UÀçdëRûØYD"zr”&ŸÄþ/r”9»’EM†¤}'qçEŸ@À’šœãæ ïäå4PÀF%ÀáÇ ­d\^Z󰉎‰5ñ¡YœuX*ɆVÒ„½+£åp‘Æé§^EÙZ³Â!ÂZCÐD—†Ù„ ñliþØö‡h†±¡ZÅÑJ[C'Œ9¶ ׯ"Ú³·'ÂÏMÔ—Gèû<)­K ¿¹|OSñ½öL­EZs”„gŒ 6X+].1QWk+)®s-Æ hÈ(© úÔ(Hô ÙQÚ€J¯'VW‹¨ŽêCÜFk|¼3Ð!ç)zh>A‹ÄØ@CTÒhUeél¨*.‹ µ^xOaX“)Öm¦ ÿŠ“ÙEX4W×sâÍoJäå(´- µƒÃé®W \3°´ÒÒküŸAx)[æ¼O…Óøâá4þºú•&q°}Í9<ûÊÌá%ñ4€ßav¹ æ€w­7çL~GGÅñJ(©9w|r‡MÓ5Ëÿ]#¸0ÅŠ, òÎÎ#ý¸àäc…Ñ¥Fºèä`J3’`6°$H0ûàÍAíŠHlö¦sõ›‹gĤ•[Rs¼K"±){÷÷YTÞ+¯¬€|™€>qÞ£ÿ]ZêlÐt=l£ø³žä{bvYJ”6A;Éþ‘o[®šZZ){˜Á>¼À¥Ã(ëlÕ4‡¦úš8|{â€Æ”çô>Œî˜‰J ú’…'›Ô ¦Ïn0š>G…šÇO u5:IîybaGšc.FaÂ^Ú%Z)x"8pd+ ÜŠ2çƒbDž¶ÂÔM7ŠÁÅ-%[ÔàŒGf7E¼Âõ£‡ã_Cóx¦3’öÉ¿ÊfØ {Oïò¿J?MÄf<"šúä™"Ë8@c ‰ÉðÒOEš”|¡Lî„x™©ÐL„zß\Šñ>{Žò30+))^$…ÓÓG›ÆÝW½AOŒ´ŠŠ¨¼ŽÓ®°àbMf`U4Ãl&y(4ï•ÈsõÏÔçÏjõãñ'óÉs »×³eE[žçNˆd¼C¤ëÕ·Ò@[‰l~ȩ̀W-8е jÕ6)ƒ³Lã`   Ìà/Ÿì³³jûE ’“e@2;ÐP˜v PÁžÄÃ{þÁªX€ah <þ2¶ ;)ˆi„ª·¶Æ$;rz!°Ô0^Ü!»»ùÆÆKÑ ~A‘9bãU±¢@ì…«/I æ†EK‚ÿ³ùS[éÈ^P­›IcŽÆ4€J+5Çõ5Œò¶½Úm–6… kÞTV|b@>Jt‹ä ËC³ŒÆÐM"™qS­¤IoØÖÝCµAt0n¹x”æÐ«½Œ“[ZmÑ_¡vób+ãÝÖy8cT…ªHLEŒüFY£Sã" ¶Æ%½ÀczP Òª¾‹ÐМb ÉUm=U×h„Öû‡Æqü°ŸúŽÌ-LT+àQ1q¨*‹‹” ½Cå•©—P8¥EwñHÄEoÍÍœkGß:üRNÜ`~àMcí¤Œ75aü*¡Îà@p"Ø7R? ܸmQ›¦-»ÇÙ dQ“XÏXj‡Å‘¶NÏzI=´‚ñ³Þg ÏåÓGŸH5儲‹>óÇŠzöI†öƒqq,1ÛB>5‡öùó]Äàjvn€cà1D€ÿñlRE² O<ÕÊ †}høÜs%l"Š€ÇVÕ˜UìM<Ë»1„¯½ƒío³Óè§"Íû0nì±Ö¸ù+Ù".V8“°bT¡óa¢ƒH©„BÁ䌲 ê´j^ÏÞ ¯¢¼¾Ï°1™¡Knâ/ß©ªÝÙB41hÛq)Vw¢g]§T€Ä“c»æÁ†˜PqKíáwA¸5šai&…ÍMœ¹A)*7Ö uë‹¥Ûßïõœž#ËN´©-2ó² Æôk{×d¤ET¼™Û*•s½Ä:^=¥ÜW{?;n¹Ýn‘Ft*ø?¿k2ÅÎØm3ÿöN)wCš²yQ2Jà ˜}%µ…™cö†±Æ‡%2nÑ…l-N2GšñF‹h{¾Ý1±—8~Äõ›‘´zlå¾ø1žŸ}–éærî8dòvxŒ×ËlnædqvTærÁ¦Sßß %Ö¸Þ‘†ÞµÝ÷ç—ç=Ê{`9ݪ†éÊ%މKåAÅÖéC=>`ŠÓcÞ±r’G¡}÷RÉ Æ‡óœÎš¥ÙŽ”;·á‚*o|2↓g3ïø™À¬ˆ¹.zQTµÍêã× ¿xSŽ2]Â÷þBSþ1È˪áë!óy(†ÄÂp °Ò F%úJgÅ eÚa­ÉÊí™eò*ë&\0¦U=Å8¦¨ºJ#O‚°ðî·‚¯Û2`6ïedŽÈÀ-l¥~ºÜ '•\\ß"38:b°rŸÈÆ_;nªP%at‰^t©%T®óhÇ2@¡Q~£Ð„CÚÓ‚õ¿!<)5x®×™VBw\¯˜ô“PøIÛ´"˜‹Ô¤`k̸{-µ°çm—_#Š•­Èq…n;­1$k‚å[y±yâÛ¿©-Ò“’ʶeê’ÜçˆÎȯ“µá˜‘)Ù òh`•ñK¿âÏup-!Q‚ Ž[Ó c\ó}0Ò„Šºæ@Àf bõ–*«A8ºãr-GåógÀð6zËÁ¬LxîV,kªßtÖõõ³ýÉk°W£òyæ¸UOÐû;ƒQÈ<Õ)üü§ž¶9î– -§p0ž/5P\Lä²aákUý4™ÐO¯`=øq~¢rm‚?¢ÐNùÊã;ÐS‚‡K1ßÚÛíZÒ&ÜðŽZU†e³ kq¦&Ì®Î[Z“þ[Æ÷í^OÞË%Èw—zÒLÖ³´:\xñòάÇ6I‹FnePYS}rWTÛN÷ÞÊAã=Ã0¥Æ<ȸ*.ÓU]”<)™~’†$ã{)ƒ³Lÿc   Ìà/Ÿì³³jûE ’“f@2;ÐP˜v PÁžÄÔÙþÁªX€¿‹ <þ2¶ ;¯)˵{?ÏòK¢›Š-2 úº³¦yDMïfÞL†;‚µ•ÇA˜OݕЦI¢%Ûê{îú\ߦWT¢e˜ï–Ư =ÝuAwýç× àºGÕ­ö–k×U&¿dö7NC³˜*š·ímaj T¬ñt\E|µŽn$¤BfHpÕC"M÷iÿ_ þïKOÞnIQÞÅÔg{”¸ƒoî±iÓ7åÈ¿õv•]·h N¯ÎH:c8ëÀņ便w«³ú¿K½*þu"¿¶˜õ…·i‘ÝFlÖ‚¾wõ©I¢6ônñ}<¼\\=(Râ_ä8në¢V«V¶lÞ !Ô¡ ¢ÁM˜¥ukÑx>Êténz Xž~£°™ÍZ7a£§š«‹Û—Ð(‘ÜØð{Èû‹v;˜;Û±_X«pH¼jÑïߥ×ý„鿨—HöÞ)¯‹î¥Nö¼’g™âžkdseá6î«Þž¢ôðdær¢ˆ§Eu¼ã½³Þø_Šæ7ƒ¿¿Nä~[Ð(²O$)ÏNëd+M¶“$%²œâMÓ6熲4cøõô{œÖ þ¯<“”‰›Ò!m”gl³ìú«Ê ;¸°Éç^TÏóq»j)Ðé$rdË©{4S·*8þÕô‡G\‡yNUîGœ,¹¯R¼#+tÛÌò7¸U ú¾+JW`LõÑ\ȇѷ(ƒÏÁ\ér–›ƒë¡B«œ.nò<§æ¨îú ˆ0™ÆÓ7HþNÁzޏ÷Bï €ðܧ#»ýß”ø ÇA¢Ñæ +×ZXœCo·«Hø“äæºž%š7õ:¬˜]ÄY ¸ˆ&‘3ÎlxVƒX†‚ Š/MØYÎ|­ÚßNÔÑÐ÷ ÌÆþZmkysi¡A"ú}‰¨»;ƒ°°Ã,µÉcÖ'ú'\ |ü—W¸ÏKt=:ÖÈÛ‹wK¸B¼3ú÷w¤/Ü ýÿ Ýd¶¾~ëê@8ŠZÛ[ë¡O7(òJà4¯] ^oZññ=ªèÀéjÿšn§ÎE±LÕv\IpˆE,鬒v)e]Ð9‰O¼íïþþ{WLéA¶ hïéï¿ë‹Æà™ÞxædSùMy96ñÄAWˆNs}Up·¯Àˆ9¤=EeiBÛ©½»G\ºVñÝžÈq#üþø¹Ÿ5Âl€÷ÍðßmÄ¿j„´þªlïãðq#ü“Mô—ÓFøï7ÀçrÑÿt|Mð{»à“ôS#ü¦õ eп¾¾è-ð‰ÓCQ¥}WK8½¯*<ù¤+¾#IÈ vªoÁÛ_»X°ÎôÕÌ_==­ì¶Zµ_¥—Çš††¾ëO4E±w¬Xw-Ö[Çú½ÆŠ®¨õ¶ïTÝØ’œÞ)ð ňšjÛÞßEÝ´Êê#á·{O··L-æìk3 þÕ!¯Oä:’¯®†[8LÇÿµ×„¶{¹x^9"Q=Ëç#¾–S¹Wå.¡üPrR¢+ŠuY³lÁöè@c‹.¬-Š·p忆¸…{MDp'knKuÏgw6ص*uæÝiT,&Ký@‰~xÀE•Ytb}]q¥…n°Åj4p»ÇÑ?[ÞýÁTS€1ÈÓ‹Ú‹•8ªÎ ¶zkQêºÎ®®°KÚ*nÖG¿‹T‘븹Oø]1® ÷±¶í™ã?/0qÈžëGü<Î<Ù¿XÿîB+ƒá3ø\Ê*l5 æ_¹ð“þc wô4(@LtzÃY# jq<zz—¦˜´ËÔåx%ˆÂ¼!\áôÔà?iÚèÙå³d«½ƒ£›¨ÏÔmÍ´+ÜèGS ×/`Æ2ðKx V²¾¬=–úpºJGR °LŠ´ fd'V“»Nvàcsr€ü?<Ô€²ú  Hº^ˆnhX,âH¾5bœ‚ 75ï™ÌAW’¥¢ò¯ì±ísxåÈ”—‹A2¤‡iKñUÔˆS;k{h*™U—˜áõ…Ê2b™÷Úcç†WiÚÔäV…@.Ux ù±%ñE ­æÑ³rp¹Wâo þA abXÑt¨)0JÁT2ž¨{.*X9È¥wÕËP‚²ÀÒ™¢X<³âÜ4¢NÒçA&e¿À!xˆuµêî º{}tK!ºx ¡{ÐÌXÝŠW«7^?ÑK³žx“ÎÅÏ,° ô;–bÇT“Ï«ÓKt J}ZGfgRàÙ ºÐÏùŽ~yä\7F“‰Äjb]é3Ä(è¾bºü€|Ô×ggƒŸÎð;˜·ødœàz<‘¬Jåðw8úîU¯Ò6f"ø¿s4'°&¯¤Ñ*EƒO&à —Yí¬«ü}>õô´t…[Ìmôú†ËªÚÞ„ö´žó5ã=2ƒéNjŽò ¹ºEÿ¢òÒ¤X‚“>PÎ/¦`–â%c8ac X0›‘Oa¡¤1ù7Y‰´ÌTFžÙR_¹Å‘PBæËÞUÞÓ|ëLcÜÂD¥Ôû7ðú¶K8+ÈÚÎ¥ N{ž¥f„õóý@Ž{/ÒæŽÕÅ]ªV­MQ÷¢Ü†Ò‘¼xƒÉ+:†¿ÕSÎ}U~4Õ3ñD2cäpÕÐØKnMàªb½ßÇׯknMÕ¾§IÏ\wF?/UàM0xðÖŸ$á<µTéÜ>-º‡oV,·ÌŠk㛃*øe»j®Hm`W·ÉÆ{]1[^“ ·ôEkÝõ¨¾Ñ")ƒ³Lð… iiÌà/Ÿì³³jûE [©B@2'rÐP˜v PÁ¡Äè<íZaø€îÈ <þ2¶ <9r+¼8¥¡7åñú™$]™æô:óó׿€?Ga‡Àœ#jI]ɹ]Y°g@幜çÎåÌZó¹Í*é1M)Ÿ×|É?ö„A>Ó¥³Z7{¤¹^—ý!&V¤§ i­ª.Ù9Í0–/Ÿ:gÁE†TbrU¬*E}e›>JDŠ—{@dŠS{—™ùÙ*Tddbå6ÏãÓàuÀΗ Ð:UýÂè5& k.(áä ã¹ͧúÖ‚U˃©=.­v ò,øJῆäÂ|Óü l¨¾ÑÝ$ØW¿ß×[A_ç^‚¥Îi«7¶Ì±vuˆBÛmÆQÍŒ5 «Ý&ÃófRˆŠiÔð…î,ã3¶•…éTù¤iõ«ëZ]ü¯-g“Þ¬.œÐ'Í T:—WÁ™‚Êö]›K`™8'‰´‹Èð­H²,™kùª*J© <þ2¶ <=ÅEûb-.V*=•6Ña áL›RœešŸ¨zSx©zÏ"Øëlû „,Û‚>Ý èãd[Á0ëéÒ!’-š¨…w=ºl?¸äèâ?ÁãæÝªÑl oMãÎÑš±7W0ãâ"à‚2ÅçRK­²"Ÿóåb˜§šx)•`Ó{{£Ñh¯Éz¡;qÌÉ­µ!åEJky’ë¶éý¤¤¡ã„ßñú/r ù(&IWV4\k#ê¤ù4¡÷ˆM Ïx ó—éèæ•ù[[eµy¸ âà—®e±Ýiìmc½2)îôŒŸÓšã«ÏŽÀx¥‡ìL #à/îЬlü‹tª¾ Æø’†˜FUO'˜B!x¢ Ø@%ºf‰Ï[¶¶u‰¯ÿÒu`¯¬‰£T”Ë¿‰Ô¦Þª$eH³9dtÆìÇ–³m¯kò¥w7ÌxׯW!ÐS–U®çñØ2A®7¸ÿ´óêžr_ãŽl(„†ÀŒiÃØ†‹öSž]I¨×ø¼ ]hwhæ£:žåòŽWÉ6¶ú£)¾R»‘÷,”~AªL‚S\š×|1•ðnðõ äz3ðË5Þü§— ñºBb³Å(jÂz™ n€ñäü ço!&(©&B’7ž Xð;[â¯{°ÿÊHÞ92Yó'òb¢-Ç ¬-6ì͇ŸOeh,/±Cà½[ìb²¢;3¦ZµØ¤}×A’*k8Í™)Ò>°ô ¶õÁ•Ìvzt‘wÎP‘… Ë—˜¢ÅŠ?y'Lgo-Þë:Øu‘J&fé=ÌxçE¾f¦ Uü@XÈohf,¢»«â’^fu×ÁÍ[bÞùO+v?Øu†ŒI'yÜæa´ï>:QÕLR%IŒ~x óçûzïм!“ϤºuÝ eëÀh¸º î§µ?ûФ73 ýlâ^¤ =8±í§^»-ËÛ&­¨Ì×3ÕŒ;%àÎ>{¸|î–ÍR5à”7e|@‹Ì±\¢c ùÆ>x"«MRJÿ÷Ê:³%­ ç±/[¹/<±ï? # 8­Ù½øÆ™ÍmPSG‚Šæ½ ¼/‡¸ŸŽôÈ+0 ¹4ÈFÍâ5-|~ªëèxÀ‡<”bØò°•-ÐÃu"²³I§…•³Ô ›ŒÂwÝO1ît9˜ ƒ–óL.Xs †“ea ÆB^ÍNŠ+C€ÐÉ+g’7B9ÿ`1‡H¬Í+Ý›Æ}Ý^‘”«wÛXLŸs³>GUªøí‘seò˜ÉÙÊç`ºÀ–^à÷¾µ…d¢Þ¾V?"ŠOáyóÁ¼ÇJÄ.‰’Ÿð©>ŠÂÙ¤"l,h°GÙð¿Ž=®>à& !î’‡mßœ_æÈ|Òg¿53Ÿº0KsbÁËíòÁëdz‘ÍÎÓ°Xæ M£}’XÊKY»q5Þ] ÞÉæGôèºyסw— ¸A®¤à·×ú|ùÒä&£š—TÀ5é OS[ÿðùj•ézú}Zÿ÷aÿ¿“ýÁ¡­âîŽ6ö7]Vl,ºAÚÀ|k!>U¿ö…g½øðAU7U­—NÐɲÌ«i KŽ Æ’?D³¨L¥Þœ¨N§ëy5‚.Óø~ˆfÖ|Åóôë4™üáøÙŸ¤ ÷W_ŒŽF_áŸcu™c®¸ôÊÛä`‘ðþÃw@÷Zïܳ‘H‹G¾XäĘ»×`¿É#,[žx{ãâ¦w¿ïÆ€G c ]E^,µ*c¬wþEõÔ·]ýÖ+ÄäGmPHÒ|½´#sáû‡õl†á)ƒ³LÈ¢ ˜˜Ìà/Ÿì³³jûE Š“h@2>ÐP˜v PÁžÄß•þÁªX€. <þ2¶ <)5´Î.B†E¸÷=W=‚7ûØv ”Ú úû TAL¡Õ"…3€Ï›¥í ÊÖ4ÓÄËÕÒbÒÄ÷jà7ëÓ<³‹yBë±u÷¸(WkßliTÞó(ä sì_‚kÞ¸+àÄ5†K`Äô0UHøW98¢Oqö¨â—îåÑò­ÇÁöãŠæëGÁeæjpœjÀeŸÉ âg¤¼WüÄY_nšãñÿfÿ59Û£†{ðIÜën¦÷ÿxü¼k^&ëbžq²^~ò®]j½’ ¨Æ;¼EŽWË,ôCŸ/øû—Bè”ò„K|ð¼k£±Œ=¢ç¿ø-ú༿…ü<±[÷“%ÿïw:ØO® ÷6s"õNÛ¢c7·Uº?ðÕ¨‘¼Ú%ŒÑÁ&¢ôoâó'øµåªʹ¿d3Å[!QBϾ}­Œâ{/wŒä„uHÔ`ð<ð½ç÷(°³û»o‰7³Û84§·ëÀg°?SKwúؼ--œHó»c¨ˆÇA°&ÂE©gxŸæ§è*âë3'WEšôc¯S‘óa /âRÆÀO56£Œ#Y©Õ¼=M´ið]á¾­û pO?à vAbq1ñ‚ÏD *•M/ZÑíz(€TYñ ¶»·á­:³Ô-7ú/W¹eÓõ.ùðˆhx0»ÇÙáAºIh´ wçU±æxÛ²Ú@â‹KnêæÊíO¤{z›½–°«ìêV–!.ÒP©òž{îá…ªå‚?pÿ 1Ì‹ÂTr)ƒ³L-½ BB³³jûÌà/ŸìE4&}@@Ÿ~ ÐP˜vÁžPþÁªXÄá뀀:l² 2¶ =<þ)ƒ³L}Ý ÛÛ³³jûÌà/ŸìEÍð@@ÔB ÐP˜vÁžPþÁªXÄá뀀Р2¶ =<þGET /w/extensions/UsabilityInitiative/js/plugins.combined.min.js?283z HTTP/1.1 Host: bits.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: */* Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³LñN ¹¹Ìà/Ÿì³³jûE «©C@2&!ÐP˜v PÁ¡Äè“cíZcƒ€ª <þ$2¶ =HTTP/1.1 200 OK Server: Apache Last-Modified: Tue, 31 Aug 2010 17:35:00 GMT ETag: "586-48f220016d900"-gzip Cache-Control: max-age=2592000 Expires: Fri, 05 Nov 2010 20:01:18 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Type: application/x-javascript Content-Length: 724 Date: Mon, 11 Oct 2010 21:35:37 GMT X-Varnish: 3909037840 1406892842 Age: 437659 Via: 1.1 varnish Connection: keep-alive ‹}TïOÛ0ýÜü7¤‘„v Û¾QÊlˆIk©(MMnrM-;²fhéÿ¾ËOÊ6&UŠ|¾{ïÞÝsت%×s‘…Kjè}Ø€UÀ à<¥{—6e\Ë„`–+ +¥añ@m€Ž|¾VGôU1Ôh7*Ö#˜3‘Â\Ó“1œÊX+CŒ¡ :êï*‡ˆI°¹– V+°kݵ¹|ƒÖr™ÔñH©Gްg¬ÊE]ç«sÜ#ÄÐá+ð ôZ²鯬Ú+ \^-ÊÚ ­¤-¯h ¦\òrñezþîL«Â .ç‚=-l£v®´eKåŒK‹2VpÇyy&Xôx†Z?ù¡3,ëdž0«tÊi‚Ò‚¾óËx«\F5žçýyÍ6¸ 9çµ´öv ±ž‡«(O 'h”\Æøójå½:N&pè dëìò$h›ü[-:– Ó2.ç,A˜@‘LÛà ·ÉD/„0ûíaëª\‹ºà®sJ CpC·N¬Q$ÞŒ¥D0éÉZþA3œ€{tt©Rtdž°È0âL) VI[@aðeÊHÅx{ýõ\¥mWÚ"¿oÜ}ûáÂQ;»¡§:jµl.>ÌtÓĸžg#¤Ýåõs¥F?+éÚg«’ÚëuÖV­ÔúÕiFñç¦}hpÇÿÆ3í2’eœnš•@“‘’Yž.QÃ1-ûÿ8·×ßèY¯™¦±º1<ÍèMW¸õ;îÀ{¯ ÕÞ 2­a^» ÊÄ®á¤j£÷TÆ4K äÕ2“/ÕÞ{?0™àÖs÷Û…T.^…Á©üpLŸã®¥¢ÐpØù§'›3m+Â&õž?t¸“·VøœÚõMÒžƒ÷‡ð†|`+÷»Ç ›î ó˶3Á_ò¨ƒ—¶~õÙ:¿­¦Ü6†)ƒ³Lbc BB³³jûÌà/ŸìE4-@@ÁÎ ÐP˜vÁ¡PíZcƒÄè—Ú€²ÏZ 2¶ =<þ$)ƒ³L=” ÞÞ³³jûÌà/ŸìEУH@@! ÐP˜vÁ¡PíZcƒÄè—Ú€€ÐDÜ 2¶ ><þ$GET /w/extensions/UsabilityInitiative/Vector/Vector.combined.min.js?283z HTTP/1.1 Host: bits.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: */* Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive )ƒ³L,¤   Ìà/Ÿì³³jûE ’“i@2;ÐP˜v PÁžÄáëþÁ«ñ€Îî <þ&2¶ =HTTP/1.1 200 OK Server: Apache Last-Modified: Thu, 22 Jul 2010 14:18:54 GMT ETag: "153e9-48bfa9920ef80"-gzip Cache-Control: max-age=2592000 Expires: Wed, 10 Nov 2010 07:46:24 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Type: application/x-javascript Content-Length: 20863 Date: Mon, 11 Oct 2010 21:35:37 GMT X-Varnish: 3909037988 3582196872 Age: 49753 Via: 1.1 varnish Connection: keep-alive ‹í½kwÛFÒ ü]¿BÒh"„¨‹s% é8ŽóŒßIboä™Ù=Ÿ= I°)’@ËRûÛߺõ h”âÌ̳»g&Ñ—êêêêîêêꪭìªUÞÏÒéÕöí]óÉ(½Ê&é(°xè=lÝÞuæEr™³ò>^·iQ$×itnfg¦‡ï øÿIQNg×Éìðý<ë §·—·s›M:ï‹Àt·÷Bê» =‡XÉhô³ÒÐL7\(â|HﷳɶÉ(o²¢£>û=ˆ¯ZCÐÝŸ‹kÓŠ’üº ºî´¤l.ò´œç“ ´¡@;À ˆÏ-€ª£Ð3|„ æÓË÷é° –K79Éóä>0݃ä¿0Œ‚‡ÿ:y:'ô\ìíÖ,É‹ôõ¤lqñ°}Rúü=@ê"½·khežM®khLæ·—ixÚÛ;˜:Ð_¦v¹W¡i™å÷ùô®Hskð’³ù¥ä@Bï}+¸œŽ Ï¬h¼áY€ºÁ¸ÌƒéHÎ$¹Mmb*H1À˜ŽÓd¨‘QY=â|·øŽ¡¿.ÎÓdKÑ}8Œ2ÄI/Õùé,–ï¾.4è z˜ù1ûr gÌŒynëfy¦W‡Jª±>L!±X´ø˜æ8ƒötÖvƒ6äãß0¬÷C×C¼ú/\ ۀؚ ˜€õ©•|z—\¾†æ“á¦ä-d½†µ Y _B,4FH“áM«R¸ÌbÍåP§XØIÊ2oª*tX#;%ÈÀ¼Ô@™šaO1+¦žþ,z»›lœ¾(î'CƒåtVáµ>JÇÉ}ü3,ƒä² œ¥…ËåñQt9ˆ³â—äÎÂïðì«££®[…Ò#œ1}ã¯åÒê©CËh<f£‚øË)ø¥“çÁ7«W£3]t™^g“x’Þmÿ”)¬¹ÔëV#­úŠí´ˆŠÔ¥8>Z.[¦ÂAO©[‹ËÈÞRÂw‘–ï²Ût:§…h~›N=\âÓ4bjÁ CfÜZÒ´æ‡øïÖ y…)ƒ³Lf¥   Ìà/Ÿì³³jûE ’“j@2;ÐP˜v PÁžÄçIþÁ«ñ€Lù <þ&2¶ =ü´FÖ À>cJ–p%…zö¨¶  ܽF4Ñ{Ü­>{>º[™Ü:Îj¶YÅLX:ˆs;‚½8ÂI‚Ýâ^]M|“.Y&væ®*ИBôyÿßçi”s––(¨¢Âs©Þ¼ƒ.¾T©Ôz2/§¯ÆãlVd…ƒnâáB~Äš8‹`6-hÑ‚Õwãs? JX[Ëlt™‚ˆ7ÍSlN§Ý$Åù Ö_õ­ º“ùxü©F{{2y}³|³b)l(µ:V“¼bQÉÎ()“V`÷²3Í3àÑdLmÃzµYÁˆ‹•ð»*éÄJÛ´9œ ÔXýËdŸ<¦ª=î]žÝÞ&—cêGŒtáôY>-a7JG&Ýê»»âÔgœ†Àã£<Õ£Ú)Ò1Àšæ¦n­Vð¼pÛ‡§°Ô Øtaš”)41La°'Ó»<™A–ÕoEþJogå} VßÙ yÆ…ŠTR[š ‚º[í…ýi—»³ëße£òF2fãìÌýT…»G=ÚÜ&îã4c€%èoS,Â[ÄÖ| B¶®èήw;aPµÄ:\Ó½_`Üñ´x§;,`1oÊÛqËÊìß œÙ&>ܲêÈ^›•cà’’Fš—ªÆNoÜeÁvÃn×{²aÅÏÐË ³ Ÿµgw§wᢸˠ) ^­¤ÈoEÀ:q‹!òï6²…ãfË×yèc´¾ ÚE6Jãc`*h‚ü‘æ·z¹¿Ÿ€~zT]AWv«HŸÚÞ"ˆõ,q21€Ç:=AމŠÅÚmN;ÂíÁ¢Ï8½–È!oÓÎäÏ}¤ñwnþ9 Ÿf £g«É±X=9üsߢÀøcd~Ìñ”ím>}ãêÌ7z{-󃬖 âÔž:ö¼CÑÜH Ñ?X,™£Žä쌓 úÿ#ˆnM©<º1çuÖÕܨéœÅœÅa’åú}ò#°IDÖ9Ϊ‘%&fQ]FCÆ xöíÞ¶Z ké°•ÁÑ£?惠D—áC/ïË™u>ú ·†V•Oýª=£S)×a:·‹ä*ɳøLU?ýòXÛ@ N:G<×…cB0#-°Ëµöª‡ÉÓï:'ßÀáþj^Þ$ù<àÃ%ùÿº¬Á›ÎÒ< ö÷ë0âï:ßÚÍd uI¸8lõ¾»è ¾3$ÑÊî™–“?ާIÙÒYÑñÐèÈÐîÄ&s'Ž?…g滀”¤×‹ã°û ê ÇIAèw¦m@õÌ8÷’ÆQƒ}]þ’|̮ۖ?Q®²t§Á™¿)‹@’®D©%È‘ö(]# 鿤e1Lf ÆA2ßž? ƒ°›€\9ýiz—æ/a„‰©ØBZ;ÿÏtzκCèê!,·Ùdº29®¤ÛivùAa¼ßO>-o‹,]-™©—Ùl:‚n¦“ty sñpA~¿œÏ–£épz;úôëR?¾ð2¾^¤ih#l]./zgÅ2lõ“ƒ“^´_œAVo9J?.ót¼¼—Pd/Ò?îØQz•ÌÇeØ=>Û­=”×e“¢L&ôÀ%¿1SP9éŒvW•…!㣧>tòÑ»Rã\z ÇwÕqU^‹uŽÝ\]ûPÇpø•ŽãèáÿIùP+|‰"ë«8ÊÀyÀó£é]È*Âtô=|¶‚¯ŽŽÒdÿ€‰¸²é›d2§¿RÑ7¼µ¶”£8ªS¼ÐäíÂ*g&ýL¤8¢»H?Íp:z©d¨nð§ÙÁÇ,½+¶çã ¸Õ ‚#Ùe°mÜäm\‚¨¸É®pDDUÄí½TÚr£xKÇ) ¾J;#ü Eæ™\¨¦ õ9«v0³í/%§žð9A¡ÃØJ0ºu”ʤË$?+r§›á«M$ÜiÙ³Ù{QY ¬¼È=0êjõ”‚‰d×Z3ÿAm‚®™zµÌ(¨³‘]¡žéhX °žPö²¯Æ)êž+E0§â\Šð†SZz×ÑÍÜ´•KֿůF¢÷Dô‰Bׇ>Û«…5Ç|Șuxív!.q„EaYÈ‘,X¸£¦¿l^¬¡p–l*æ¬Ö¼wœíïÛyf>¶´¢ä›ëë4oí^‚Ж#2/¥ð®oïº~LßMU‘Ñ:LÚA¶Vô’>È)aqkÄ‚öÚ~T–>Ïöéб©±p»]_‹r7 ;ÎüYA°WTn¹^  ÆÎïnïÖ:¤#L9ŒGÒ;ë¾pž¯a 8›°×2åÝ5U¬Á°ÉÚ“Úšeù`- €Š]€…VÔ„¿›6Кå³=Íñ%ëzù rÇå¿0)aéIóòÅU I ¬õü¦bƒ~HRü——Ä~€V+פ¨¦£Öå4¥ù÷Ó²œÞºi?Áží¦üŠ{¼›ôn:S Cù Ç Tpò ²5Ce™kŒ®>uŠ2õ1q`Ž WŸè¼@¹IÉ JþȈŒÀb6pÄ-Cìá×d„¹¿þÇ÷-þÂ¥NJAåûq* íæ×—­Ý6kuo“O-þG"}Q@vùB ¡vTa€ÚÕ°mE'_}FG¢Þ à±ðØxü4€'Àà‰('¿Ýh7l´ž)²o íh Ew— Yã>G‰ûûôضÙ|ŽWuqüo–UŽ:)= ÕFN餭#Xñ!Ðþ¢ux£®k°8Žž=„ðm”t¡NÜŒ¤j¥¯©Â­ «i'ž´gƒpÐŒ\»uÖ½èðÏð,¼øoRÏ]‰½èó4þ_œt¾ú*ªg4g=“,§KB}ÇÕ‹ƒ‰'áºïM)í#²7ù%7ã6lŠN{bíu(¶+ÈÚ\ôeÉ AÆÕñ p±±¦/Rf…bËš £é‚~Äs8Ï_žŸ[eõŒÛ‰ƒ@æü,ódRð!(X.¥òd:JQ©ÃÕwÑ" D&¹AhñneŇiÏ6X#¦Õ‘þ ôiÜY zl«Á¤ˆÉoó¤Û?ÂUÿDÉ?æyÚíŸ|i¥]¦Ù5¥Á7þwri¨¼Äšð?üš)ƒ³L©   Ìà/Ÿì³³jûE ’“l@2;ÐP˜v PÁžÄòþÁ«ñ€ñ <þ&2¶ =§üÁòéݤÛ?þú«èËøÿ Þ'§Q’0µŽŸ}ÇIª$˜Äë<½GhÄÿéä” ˜öá&ùAÙo¡Ü·Ï çN¿MPû]EÀV{Óqö1@ß~…å£/¥Êƈº (©[˜æ èŽÐWÏ¢¯ CG_rzžŽt)Y$ã[8¦÷Ož"Pôøä„3>fÓqZBé/¿EŠã¾:¼)²„[*^OÇ#N89þ šŸ|‹ßÈì×Ónÿ›¯¨K"ݧÑ{v„h"º÷bRó `}y’Îô>9ùÒŒ ¥KSÇ_BƳoЗ&ÆpŽä?IŸe“B«oO¢ãïžIú}:Oï¤øß AºM7&zp¬Îß&ù‰G]ÅB“äã½0ËÉ·ƒˆ޳…Îx}M€-¤¾;¡¤fó|6N\¥‡Ã$Ñ`26¦ÈÆÓ |wɃˆ V¬~!ÒÕÎ yN-Óé‡,5Bév?&0B‘­d5–’ótÇ=»+›)ù»\.ĸsŽ7W¨LÃU ¿‚ §®1A"Î`aŒñ®ìcT”±nP%u_aP­¯í6—ËJ¬£}÷òœlFC^'AN-mD#¬p%mÃ@üîˆ9_‹>®å#lW‘ýâäË/¾>ÂÿÃZp¤§d¥(šÿ©~÷ ÚÔ‚…KYÍ@`Ó@ðã êQb`ðÀï° „¤>OoáÄ¡ëð'Ö’ «§èšE ;ˆA™?±&ÿ °Üh:$³FÅG}⟠¢t2„uÿ¯¿¾~9½M'¨a#&#éf„hFÜfÄ Õ B hÆ»Bþ1²«4»¿_IÀ .´jq¥@§˜³²ô )÷ªZ*è k|O`Åî~MEûÙ@¶V†L 8hGÝ$3¤öqÇ4½Ú@4º²ú5JkĪAsa)³ËàØˆg7çBE‹<,¤çn¥¬ž—êô¥/’¯£àà MÒ6%Æ”S.T,­¾9i—løX:‰VÞv&„F\GÉVÝûŸo’’^°=›² äãðÿ²ðùÅ“ƒ ­kþmA ·ŸV3³º1ÜDkkÆ<ªâ åó×?ÄÍͼãM(Z«•ÀrWß­á8Mred,Ežj×2@¶ïWZH¿Pkº„1yˆôϧv'Òò ŽM¿M¨°A‰¬j/QI;nàÁÏÀuÿ¢Ñ¬vó¯“ËSíóÌ2ÕÇùdóÑqæaÕõ®c/h5~1ýY%›ÎáA· îü Í@ ?d ßÝÞ­®áª”³ˆíU:¬Øæö5DÛ¨l‚Ê7­N6™¤¹FIc¢@X÷ ˜cäVðõÁ¯Þ' Nƒ;6-bÊá+`@~M¯_}šµv/..wÛüÑIÉÜ»F»Ù.Ý„STiÑÖ=K&ÍÚö`·(SQ¶, ¹*gYéš,Üf£Ñ8½ÌJFhN†kÐ^ØÓ¹vF¢Mð,Ã1ìk±)Oßx4lñbªQa+ê—¨ÀoYUí¶Ì¹RmN\\ÁˆtQû¡W…ðÇûûÜu¬Š°@ÊÜ9lôÀoIнð0£')\µL®‘B!Z/Û îß)!qtEXeÜtq© |ˆ;˹Œ·ÛYmÖøØÓª J,‡‚<~p'õ 9Y ›¿I°­œ‚ha¿èÚ–óam²Õ–~b#×[c³XÌa;+ø4²Vöœå걄ü湦Wb>©8K°¯`è¼ S%àïUvÝáVT» zž"üJÆ¿‡?/§ŸpÈ"yßáÁß[§ƒÏÕœ¼'÷)ƒ³LѪ   Ìà/Ÿì³³jûE ’“m@2;ÐP˜v PÁžÄ÷cþÁ«ñ€Ø) <þ&2¶ =Ñ|†Š,µ§Xâámr™þ˜"§Ö)å4îı¿Á…79^ª×HÏ+De%9©Ä jF+ڥɱõ™BÓWÆ–Ä £J_Ô›0:ûØCA·ÅÞ0[Òaf†Y’üï§®TEdÜ%sƒè(U*£iÌ‹¯HZ°q=*°Ý¬lžÇP5°fØ¢cš% hî™'Ñ,Gk¾òž•ú1‚J–GÄ=A—óibʇBš¿X…+{yzMÂÜîôèALMÚvÿ9ÖV«’`§b1±znZÒÍ¢i¤n²QjìÅ 7Ó;ydÂÈËóóx”ÓYµ¡IgzuŒÓB%ö¬ÝT-øÿœÒâm^]zFDÁ[³¬ªüweÜr“ò#®ëLe©§,…~̧·xíˆ~°}~k0ˆ×u„ì‹T~³2ˆ¹=¡] äU«ìégÝbšsPEÕÛôJ" pyh@|ÏÆ¨ð(î1+X[N¸“Xª¡”üTÏÞz¢½#dPŸG͘7éÏ)t¾?Í»Lû]_Uûâ®Ö’WUÈ”ö¦R/¯R­Ó3¿Qö‘_ùi Ø ÞÇ@=£Îa1ˆ2uÌ+I¤YÙ^عΠ¾¹· ŠRókD4:)o~ÆârñïôU‹Fz9SÈÂJ¤ÞÑÙ†aÄ/êAPYúÝ´¥mÅVË%¼{Áª’²lsÚú¨@µYªûûz2ƒsòÂæ¯4¢ ¡^]>ê'mŒ2#°V¬ ö—#5áOgƪâ2—÷÷=eÔœzvÔKµ[MQ-\G)Þ™9_dÎ'› 3š¡¼eRxœ®iS»#`¬+ƒélXóc‚wõ_ø÷!õ>uuSÚA¡©V==t^o·ò ¸‹ó'’çYü¡ßHu-F"„ýØ Zúuz·jCÖvÇ‘Fï÷X¤p^ö‘è¶ ¨# Ô‰V…À›!Èp\¡ãò6+ßL^޳á‘]ªÛ¡$»óoˆr†Dfce­…Ž4ˆº(&kŸBÞÉ!‡õ²>FœdhÃyN7Öl€.Óñ:-—K¿ZGpN1™ðI¢“ì ôLë#KSºy]ñʯx:¦zÆVŒ$yù ºA¶ÃíÙ8Xâ[MÐÛLÖ–w~;ñîîSÐ62»ƒó£;N[’ôž4J£G`‚ûª;Vï_»Ê¾R·g@£ùÿ’ª~V˜v¤÷HvdéªBÚ£®>léÞ°]c£ìeÍjµ»¯Ô¬Ò´½U)–KIYEUWEŒuÒö˜ì×´`IauTŇ7h%ЪË婢¾¡á’DÍèCzÔ,KýTÉ]˜Ç+ë]Rü-#ÓÎÆQCt?r¡@Iät5ð¿}CQ99hÜ-¶¿<êmM U’Õ¥Wžårm¶F¶<@Uàòøj JÌݪ`Mò´Ù·Ÿ}ûhti[xºU$Ls6*'ßt›FCŽãk˜ÏÍf…ÉÝ”‰6ÂõøÙ:\›Á|®}]¯l’L3xõxT·‰D•ã´>Vá+K~Å ²SËZU7Z×jÚÊÊÓ•[”Wªq¿VLo'ëÎv¾Ö×ÍÝ´;|€7ÄÕ3³×6«%wy–×]¹2pMqgp9d7:í £Æ×··é(XoAäMø½™ÂËŠ}ÅP¹á›ËNEܱöýµÒÕ“ _¹]¶MJžC¼£ÔsDY_©ÏZw¡ôžŽ5­uSµ&?”"k=¨zúäª9ûƒÈ±¾‰Ô =Qõh¢]dUÎ=Ï"Ï…Nxµ xÿ?Huý´Èž•äòh`»;¬øÍ”)ƒ³L‘¬   Ìà/Ÿì³³jûE ’“n@2;ÐP˜v PÁžÄüÁþÁ«ñ€Xî <þ&2¶ =µeD)š5)¯˜P˜R€†RF+ðX±Ú=¤ë²œ>Wh>]ÕÅ“äùP÷`R%Úí /hFÓD£7X™öÕ.VI*ÐßÑ$´y9žçöI£Ú¢µXó¦ó}õYÛ1òm>ÎDvå̲;,ÜžYIJ,\i §5„zN“Rcë^âöNæ .¢W“xAïë8ªy|!“ýÛ+‰Ç Ü­œäRvxÏ‹gOΆè.™ß¶ÀzÁ¾Ý»@ÅQ:AÖB½6Ø,tëqƒNsÎ_QŸƒÜ¯Ö9j ãÕuØ;¢D¥‰Pæ`‘šJçøÔw¹¬¦À~Ä®âFÚ¡k!ë­Bµ|d%¼âÔf ¡rÝw“lö€¢‡°z¨VÙ,k+¶áM:üp.«ù;Ò©“§(À¿Ð¸‰~˜—4ižõ²â<ÁÅV"D(jËdiÚPÙÖ½£Ýì&É_”ú“çÖ>AYˆÊ·_Ôêô,ªe(·ÊgVCâþ‹”!ëÕŽDð’"—q¡Ê {eœÕ¶ÙLu@å9s­ØóCÄz6þvZÄž†Øˆd2ªg»pía>ßMg’¯>{žÁ¶_ÁÒ†>ø†I0ØÁK5ç©+ÉŠïÄ»“]ý¸ ·Ji[ bZÃݨƒ ±Ã4Šé?®\9­] h¥-¾÷رٚ»¢‰²¦/šúÜ{zؽÑàVuLj8V£Å’jê ª.YS’»¤ÇpM—T9é’=µí.9œÛÔ%‡oâX1wI>ª]ª7ø ¢28<·\:㆟vŸÃž^í CØÒ¦› j*9LÖDU¯mÑ}uÅÇŸ¥5nÕ|…„{„6'h½kbá“džõ4YÕ]•`êé­ÀRVÐ;"¯fc£8)7xlÒo<òäiI{Ô¿Óšd\•ù_q0ªïù`; Wˆñn¹Õíx„qßoÛ½¢RjÝ~`v¶ú~À:0  Ânµ£žºý ćÂÎVQqI(TeB$²“JVà\lê˜C°*ò5qKN@A¸Ê連–¹†„0ïe*©ë1’vå'j³eÒeñÕxŠ^µDª£ ÌÖv޼HÎÚƒ³oºßÒ½fMž:§Š %]ѧ´cÖz«Å.͢T‚õó“Ó99Cu'âj—X„šÞ G Ô¯'XBÐ —žCèT4~‡7Ø?®1õÚmÒ(Yê¬ ö|p¿¨Â2•¬àÕŠ¤©cá øS <ŽêôSÓkZ*0Pem1?*{õÆ¥=ѧ¡"å qÞóÚß{Ïj^?þª{üu~ÕͦñOZö² n˜aµ€x0ZÃt¹äZÏ>úpÖ UÞ©'¯­Òn”ÅÇV½ÿ² pž¢uñh:V~¢Aò1mvÖQçŒêßr2Λ´2yÃ9„iŸ‹èèªM¨¸³ÌNíc•«tͪµØF%ÜrsÛrQÁV(ˆ\U=Oão«jZ› [†ºvjí ¯°(Go‰Ìµ(]'É‹bë ,É.´¢eVùâ*ÿ’#¿a’6ýmT$lg…“´^կ܇‡%7*›*/0[.ltõEs´9ßT⥺D¬õeX¨Xc …cûF{ËÎp…6·–n¢©¶)à€ÑÉA|"ˆ—2Ä›MÄåÇoýy—}È^²rš[ÆŸXü&)^_å¸^KúŽÕ#óàc/£Bv¦ˆ„éè¸ß\i€¦2M=ä;cR[7¬W™°§!Küh¹"4ðÏLýîÕ$ìËì°¡‡Šûª‡ÜÂKvP@$íök‹+nˆ u1Lýt4s”ú(ÐÿÙŒU”a˜I!¸áEêöûÁiDß  „EÒ‰'˜È…TÒw¯1‘c éÔg˜Æ±•Ü4WÉÔÇT©I¯ÈÉúÀBšÛ8rxáoÿ}Fêß^¿MÐÚòîúœ¼ñàW;8¤ù„‘¥ŠÃ¿ªÚ¯'0í’2û˜f躳84£z iVœÏg³i^¦#˰™›$þ¹¿/vKüI¢ã›k¿ee˜RN‡Áré¦×I¡xwýk œ}ÿ€âÏé»7/+´* 7*²ú] ½ÄŽb…§aÆLÕ:ã?]›£-S,È5p«~$Ló¦ŒÉÞNŽ›"Ú#e”Â2꿦¿Í¿êDrÎ!ö KÈíÃN÷[0¨b‰¢8dlë.K9k%¥ÿâØiÄ "nü% …#²³ú¹¸¶PeëðÈ8 1xª4Ÿ y†:•ÔG?C;l®°\Z©í[Öy¨þøV!Ë×£sÛª¥tAôiÞëYU%ÕÚ3=«Tæ’Ž­¼âŠjH)ƒ³L]°   Ìà/Ÿì³³jûE ’“p@2; ÐP˜v PÁžÄÃÇ}þÁ«ñ€ѳ <þ&2¶ =ûâ­ÙÆ÷-;'òÃ3/J›`µ+Ú5´à±û D¸úàËŸ•€Ä´åòîú¯À©Xk+Æ`¹”Ü@—:IqÇë!îì&Þ|²ûRn„Dõ|Û°£0ãÒT°GžZñŸåÒ)++=yʇ&†â7!,B7e9ëÂää}«ò Ù?‚™¢y `ƒí´á‡™ÎðÑ΂öÝõßuÛØµ¿qÀ>»·oò7$jW{͸Ýyü7öÖö´Kµ +íïcb`Ê1ãDŸ4Nó DÀÓç²ê`ow#nòh8Œè;é®”W¯€,ÁÁ=ïì½w†Õl>­°ê[íñ‚6 _pxn~ÿc=øá§  &Ö[ ]Æ‚Ž#õ`Ó®üt]6ÕqfóâF‚;8&ãT T¡zàãáwS<-þœÌ&ï(”¦”€ÏØc–?õ_"q¢+ˆê&2>ïYB“#…N¦‰zöƒ6zMf*~&b?iGe!;1Ò+f×2ò,F?ò‘B}Lç äF– z]UP1µ‹²p²ÙôŠú~išÅа ¬çd(äøï€-@ÜV–ÔÛJêÛkJ#UyJ´Tq‹Þ¡‘áá«%ñ:p\Lí‚ÁÕdÆ ,±Šd]A˜Ó¡JŽßšº¢ˆÑìR%ÝW~K?âÄ;n‹ÛÄK­hØ3j‹õwhÍÉÃ2ÿ%½_.ù3—ÖÅùù ¾ÖvíP{¯LЧkúé'˜ñÞûVÐW)cTÝ)€yÌ)‰.5¼¤å_cùƒKýu"®/'§ª+V73ý­•)«÷ 0ãZPN°VÆé²ëâ͕ֆLZ‹êÊy–ë—ío¿®ÑÒ­ÌFÖxufI,~su€ð-‡À‘z`]Rnˆß A¨‰ƒQ†„†•HÝÐà"h:=d+d¬Û2Ú–Ut'–:Îax6ϯSÞ· ËõŽÔQUzut ;cA¾ç¼WÓ˜h¿H^ßrº˜¼¶ žÏNŸÎNíØ{ŠHâ'ñå?…VÖã!™[`CúÐ 8ÏazÐÕ°¡~UÛ&:Ù²R†Ç§¥AàkS ¢jó áÿí´ö>bþ‰dcyÂU…jîhùq ÚûQ™°ƒŽ°Z»2D»†Oš9-–ú¯µ ­X×îÞ4[ Çö·dAàGÚ²·jDv¨lœS«©5/=K¥×Ge3ØÙÀeÔ^[WÚÃÞaȃm$I$Û³øZí;>:ªáJ‹EÛÇ2ŽÍGJO/·~•Šò^AÏË^C÷¿pÞ½™ýL\œÙ±ñôͯß×@°Ÿ$ñ .ý1CÁ>–#²Ràìeøˆ[ÞüGJbnòèr^–xzÊ&¢ÛÄÓP‡ÆSñÕMzC[ÝÉ´lYûw(Tr=…韖iÜg_ä/è‡ Îœ8£øaœ¾m±–=·Üó»ÃÂi ®T¶Z€]ð£y9ÙºÅ-ªÒúò| ¿óÃÿ„Åbg¯¹xعI WÔzÙ¡]z’•MçÅ9À&Œ¾·`3F4[7¯ü'Ô-“/œÈn=‹¼Ã²ºõübïZ­±¬6›Å0¾M>¤2S1¾gŠî Œ‘eDãÚksÑš‰4Ò¥´!-Ö‚0)²«û_€kÉ{¥·t÷,ôìÑj6X1Ô³±o9ù2KžÇÇË¥“Ñ÷;8FMßîn¸¿¿ƒ…=UùäYíÑêÁ³€õ>7u¶>'v¢þ€D@äŠl×Ôåne °Po ) оäü«‚Í‚·•vY鯨ì#l…`wμ¬ñ½]®)ƒ³L¼ BB³³jûÌà/ŸìE40\@@•Ÿ ÐP˜vÁžPþÁ«ñÄÀ€ÐJG 2¶ ><þ&)ƒ³L·Ê BB³³jûÌà/ŸìE4£ @@"ï ÐP˜vÁžPþÁ«ñÄÃÌÛ€€Ð?‹ 2¶ ><þ&)ƒ³L±U  Ìà/Ÿì³³jûE ’©D@2%9ÐP˜v PÁ¡Äè—ÚíZe€w* <þ*2¶ >HTTP/1.1 200 OK Server: Apache Last-Modified: Thu, 22 Jul 2010 14:18:49 GMT ETag: "2c78-48bfa98d4a440"-gzip Cache-Control: max-age=2592000 Expires: Wed, 10 Nov 2010 07:46:24 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Type: application/x-javascript Content-Length: 3724 Date: Mon, 11 Oct 2010 21:35:37 GMT X-Varnish: 3909038390 3582197096 Age: 49753 Via: 1.1 varnish Connection: keep-alive ‹ÝZmoãÆþ~¿B§&YKŒ}פˆl^\/h‹$ znóápVäJ\‹oá.%Û²ÿ{ç™%)’’_®MP €A“»ó>³3³»zqtåFyX¥23ž_Jݸ‹* Ê3×Ûª…ûr³ü— M^¾ËÄ<‘ÑyT%Rûaž$¢ÐŠÆ2±ö¶¥4U™LYÉóûkQŽRQ['1¥3Û:©VÒ™}øà¼ œÉŸ>~œ8y!KÑ}å‰ÁUžýZÉ2/Û‰?ú§˜˜'"\ÍeYÞ8³…H´œ8ªÈ£ÎGœg²ý,ôëúý~â”&ùߊpC¦¿Òb®en|#µù¶Ì7Z–.Ê;dÀµ,5ù!8úfùvgñÅú»¼ åró/ ämèWç÷’˜nà|[…+i.‰õüèŠ\™¯”t5ûyJ\LkÇÿ>Ȫ$Ù¡ÿ Lì—y•E®}Y”§®wræ?ƒô¤~™ly]¨Rjgöú”ŒG´œ™ó¹sïßßß¿è ðŠ¸“u•*|qŽwfœ'Q𚸺ÎgÅ4ÙrT%Žç‹(z›­]GË0Ï"Aôü¹\ä%IvQ%£ÓÁ¸(UJ“ã7ŸWÉR›ÙJ,¥>8’v%="I–$5ôPx”=®=²xÜÆôÐkz <ª¨(ÀåôQâ-•ŠŠð &!˜¬½Œ…P"<$ Z9Ö›/1b`Ä 1›X«´H@=“ŒGå–Àü`aÀÃàsŽÙФü  @Ä-ˆB‚ ë9ÇC&åO9½ž’wô+tºâ$iÊP¡mVW`Cà<…(¡NUZœ› ü ^‡óaSŠiYôö+T LCË,ä‚y§9Ë cPãí†R˜Í½dí4äÈhR c !Dœ 3Õ)Œ½‚Õ­•-U{Ʀ…Än@6QL6ã`³ ØÍ&Õ–°“a’ðU!RH¨çµnF”cŒ–‚Κ©/Ù9Ì  @aÎ>†Ú¹µÀ”cs™€rjØÚà´© Q«”íÉA˜µKa¡HÁ{†#èSÕ’C¹š®9€5lS?ãgÁqÅžTpÜ$+é :Qö›ÎÙ‰‰ˆØ@W¼„z öõ Þ39Û¡ÁdæxU ¯ ¶Í¯×A«‚P²fȘؕ ¦·‡DËYa<$‡õS+¨ZD ÁäcÁk„×QĬ´a;)ƒ³LW  Ìà/Ÿì³³jûE ’©E@2%8ÐP˜v PÁ¡Äè8íZe€h <þ*2¶ >llæ E±j,¤—×¼à6 ¬¡š²–ät&ªbGB¼1½ ] 'Àp™ƒ’N9A<$¦o%G(“dVà1d±qæ«é-GÄŠIå<ÅÊÑUÄ“ {[±ÿx©• ÆÊBRŽ—hÁd˜# xJ—0šáä’3ÙŒc™cCsžà<F¬"HÞY³_XÚk ]c†Íczc¬¡‘aßu„õbØJœ>!h¹aAñjðªYšŠƒÄYº”sªbHvé-G Þð™Vpuå|ä”/ÂPæ{Zo¹|uk¤›6UÁÖÆ!Â˺Hœro»+*Ãy_Ô¸$ŽG<³P·F)äÒNò,¥ùÛû¿ÿH%þ}XªÂüDóÄù\Ê/ââkÁ\€Fææ8•Fu*[äÇ•*ʼ¨ƒö1ÂT˜àJ£ ·Ý_$Œ¨+-QùûUÍM!óÅ“>S'…¨øË…ÊdäïÍû ãgú;Ñz8Þ–u!ÐUpz~uñ8ªO}éÒÄçW''ìˆÇ¡?\}ô}œZ×h¿¨tü4ÊçÎGÛ <"Kò*Wû•z¶½™tÛô:^ÝûÕÍHÐogüz¸nNŽÚŽf×iuà¶ Æ*‰JIí}m¢ î¤NÚŠlÀA;RËR›gÈô½«‹6<‹+Xœ¥KT¶ :¬É‘ëø*3²Ü¨•š:'-öõÑJ ¤š;޹žœX)½­E!³è2w;yu×;§=̪iµE_Ú:-Xº™"“Éè ±ÚΪ¤âÔÅå‘QB¿ÜQ“!lŸW–×ßöœaè(óä ]ÀC~£VÞ.Vm„‘ì·œqø[ ÀÁ6й»k¾QOŽÕÅ™7k·Eg4fcÒnä¶:S¶¡ ’i½w>ñi©oº!8Ä­ídá,GSëÒë€5&Œøø–Ï;o,;2ùr™H÷H&’)fUCø… ÅfÜÏýIE:ù¥hÛJµoÖÞx‡ú{'*’—V9ÚÒiïœ8c)"…¢û I³XÂv?,æ%y®ƒ½¥,®/ë9ìÑmÄkIMlü׬¨x5±Íˆ‚”3ihQV?oÛË›7F¿ïRXÉ›(ßd;"rÍÞ¥Àâ7«2åÙë»»ÞÀëWÞ¶‰‰š+GŒŸæT¦û4@¶’Γª¤xïgo+äop(FzëC‡:¥IØ«up‪>.iñÉMÚGU¸Ìß6Qìl•ȺÆ™$1vˆ¹ý½4F‡ž‚°)½Õ1ý6ÏŒ ¬ô"Ô`+þè‘‚g’¬C³¤¹€{«vy´<ÎkX?¤åCUM+¨;žŒK™£Örìñ”K&ûÚIäÂÐ -Õ2¦ÈœRôeT™t·™xæœ×Îýdœ¡ÃMÆ“CÓ*tmî¿Ð¤r[RÚP¡û‘å˜r÷M"ƒq¤¨=7´ö2yŽ’ „7pcF ¢ù†+5“Ý…YSÛ©u“ue´6ð|¡W‡`ºÆl΄;ðóÁÊbI°ªEIhùO•‘éùáúDïÛ0zÂûv­ N"ÿ!µºån†þëw5‹ÿ‡¨>ªÃ™‘½Ï¦Îÿ¿ZMÃT¬Ÿ¼A}Ú)ƒ³L[Z  Ìà/Ÿì³³jûE ’©F@2%7ÐP˜v PÁ¡Ä袖íZe€[ˆ <þ*2¶ >ê°ËbfW ¯Ì9¼2(€°4ȲVpŠRêgeâF³]äîã=+t‡«±§Ëɸ¸?±4Gü<ÉÃÕoíÏŠŠçG» wnk×Jn´=F%tÇö¼™ðšlÞSû‹Ú­»vj³×Z;µvH;އ–xÜwš´ñB%T~¢JиÉ>õ¤L s³›³É}ÿ·Î«ÇgΫ/9›¾þêÊõ²Ëù ­F‰rv› ³=]¨…bmóøë?>#NˆÁ®l 3нg—Ñl0t·»µQB1ñº›uóÇ4kLDšºoµçuˆU-…áû¿Yº¼!\˜“‡àX}¾L¹°´ý(©i+KosúLì“ÀöäxZ§® ÷“¦Ò0Þïe4ïÍótþìT³~ZTüw§$snD™Q¢º»c®›â’6ñóüú { NM|ÜÐoE “}¼¯R{¶ôpwoÓ~Nš>Ýn'Ö"q=V…ŒRf2áêgJùæïÙ·œ$þ™%¹ˆ‚ úyfSGÅ£Œ–WåAŒŽ$]ê”y«Äí !Ó 5I–Á düŽˆTìØÈÔª)±å~LXo;`ö°[ï‹û(/ƒ0ìˆ×éÞØ~cOnGWóTçW^ð^û0ìyçÚqw Ö—¨u¢oZÿÇ&öþÅAóI,n)÷ £¥¹T©Ì+Ó ¼Ãtw"Üê°¶$‰5û»Kù>Î7á ]OR| ò¨žH¹|JS¡êò;Óïy N]Ãö ×P8KÝ8“Á ·u¶uhC‹ðÝï=B±95ñ>RÇÑÓF},²ë}ñ“K»qðÉÊ^;Ûã†ãc½RˆsJ»\ÿ"*“ƒÞ/ gš¥wuÐ…€’o»O·{hdSýg©·«ÍÝ]ôS)’ºpáS#t]-Éoæîê¿lÕ?øš< ¶ÎÜþJDã',õiþn…”ÈÓ¼ýùÉ'ýZe÷#™ßžtýëêŸqäÿŽ2F^úJ¿¯ dÉÈ%5÷~þBNg—ä¨lÔ8ÉÉIF¾³r®£ì¹)¯}f­þž­>z3âùƒg\]“ÇÒ\×SûϰÛÃúg²–UÞ92`{h|n¿msíàˆÊvÔ€“tï:a7þéºtÏß;V±çjV–Ù_? L,ô!ìžPèË»]÷F¶m×m게ëBØëü-YCUl‰ìjeã5°PÀ÷­Cx¶«WßÕ Ï@©ê|½¢Ï"ßÈÒz¶¸ä ê×Kûw»&ŒwÝ-_Öž†ƒwŽ¶Í ÍkxßWâÚÝVe2;|¥k÷Ô´BíN‰öD´T³ÚøU¿Ì˜~TJ]à³Sü²…$ÚDÌ%¥Ú™c/|uR®Ò³ÁÅ/KÛSÍé|Xi>œ}´Fô‡µZΤ~! I((%&³Aôï p€g»þh Dýí‹9åòoC’shgÊÝ;„ûó€8mLJnÀfÔ~$´>vâÛJÁöÍ“\Þ°°2™HâdâìÕé¤éð¿+óô{jñg{'1í ì8ÈfH{íJ+u £°êƼì4ám¯äMA Ô‘à,¿™¿‘ªº¡ÉŒèe|€5u»é·’v.>;;‘vÚÞ8½8JÄ\ÚSq¾¶üüMÿW{–ᔡžsGÙKq¡=ÒáÎÔë]N6÷,÷“ܪánU}˜šFã]’¨B“Ï÷îÔê{ð!i>¢p,„ÈþŸî>+'ïm/8ÖJ¢ n,+J ±Š"þ#r}/¨—³›<‡2iECg8ázVŒ•)ƒ³Lø[XXÌà/Ÿì³³jûE J©G@2*~ÐP˜v PÁ¡Äè§ôíZe€¨÷ <þ*2¶ >r‰M¾ ÉNat<ÛIþPwanx,)ƒ³L©wBB³³jûÌà/ŸìE4ÉZ@@ü  ÐP˜vÁ¡PíZeÄè¨ €~¿ 2¶ ><þ*)ƒ³L%†  Ìà/Ÿì³³jûE ’“q@2; ÐP˜v PÁžÄÃÌÛþÁ«ñ€“à <þ+2¶ >ï©t@ž+¶Ø(¦(ÿÆáÔÏJ}\0«ßoaƒ,ï±V5ÖC½ß|Êpê¹Ì˜ Œ9Î>FµÙOng=;ÖÍsJ—Nâ)%^»‰ê•JpqWÃdYUoN ®þ³Q Úýÿ„iúPºšåôa;.ÁCNL©@Õ¹qšŒ€YØhDgj|°ÂsrY`ŸzìÊm;Çz8DÍFN¦1†ß)YŒÈÃl›BÄ»fÚÝV¿æKŒcj³À.N[ Æv¼mC9 ÛÁóC,{ªz€]ætøb—¶£êº¼öÔüðô¿Wå{Ro‚M3ÆÍ˜¡Õ‰½m=M’ÙTD!‡D›ËFn¯àб÷×›Ÿ#RJ˜W¼~7ícA›é»îh¡+Ó¹B‘Ì]—¸AZÝ×%nÕ†hyu^rÒ¸r© ɶÂäzÅó‡ VoÐ [ŽXøPT4Aʨð(¡¢¹å4€qרpì)Ð9úƒsÂ|•ÅTÁ–må[ú‘Qر(hÛ@ˆ¦µ<¢6‘GI”†îj~]¥ã¼Ûh*+Z4ë‚®Ic¸¿ëuyª'+•qÔ=AxµBÑô[©íD»Ãž•”°­ý,Ù}w¼-Ùh*hß*TòÜ”ý}*.úÌZöŽÓJ}Üë aÄõØßÓ¡)ðXÃ:<ŸOÇ…rð¯3øÀ¥Óõ•,­”ÃThw®Ý˜ÐÝ7…ÎÄfl,…N1²ám†“N–ÿ‹jÛtƒ Ýø[–Þù:¡o¡Ì»äò1½+1Ìy½k£ì#ìXø¯ëüݾ†™gxorh{eäëL­ÁRql: ”SCººp|Ò$Ðpbš½ÉÓ+h÷O~'4Õ¹©HÛ´îíͳúº­z‚.^Ù‹ƒ§xЮ©E ]`H½„åºäÊÈÝŒOÇ:T­M¨"ß4!auÈh‰²jë EfÌw½ÊØ9–KŠ-^#kîBª„Ý€Ãˬ$ï#>VFzȃå—H–"•Z† áãE€Ì‹>6Jj>iƒl(5åTb@^6*S¡™¹= ÅÛp;sŒ§Ã󌦭¶€ù‰­µ½UÊbÞ¤rUš*a UItFO•\©²´;‹p:{P‰?ӿŋ—/ü›ù£×¨úÉ$»Å›E H—£èøp<½ ´Žo ÄŒ˜9bé«Q‹>˜HdÁö>ê\¤êùïÍíã×@NYz‹”Ú˜ØÃè—çqý®u–á3¦nÛÉ WÙåtðÅÅéÅó‹ÃÙœ„²(`)ß.Gy“þùLUÀ’ü6Ê Ï›M`Z“/Â* ½ãjYï–DU­·öò~†NEL"uTƒn’8L§Ö<ÉÆÕ"Pb‹‹}†@‘<¢,9 »Y ²3oˆÓñ*Oá„ÕñüC_°@¢;úÂ>™f“áx>J=Šnµ¦šG#\Tšи{QîVAxõë¦Yô¬ÕÚegNå™§®~Aã4­.U06¢mŠšÜ½Ë“iŽöhd;NçŠ H.0"jŸ¹±K;åxŸÏmõÛ–Úm‹­YýÕ›üvž2.h–Ú! »Aïýé¹ìÃÖøãQs%úâ,þ@_@3úûû;xb~»Áuþó7Û ú’ .&kK`ÌíRž~âÃÏ-gÌeï¶})ù^©‹­±™6D3>Ö™Ù£Ô\î{¬€”7Z¤&8X»T”X¹òªÕv ô+m†ÑV“þËôÊ6–¶íLpK¦3"j`\«ª²¹õ —I‘²[Ž2il2¡"=½ )ƒ³L„ˆ  Ìà/Ÿì³³jûE ’“r@2; ÐP˜v PÁžÄÃÒ9þÁ«ñ€Qm <þ+2¶ >¨ZÙKV–æ{÷Äj"Þà­Gßy„ãòYBïïÝ1o_Ù°‡nk,ä¥5£û.¹ù=Ъ{^‰×“ÇuÜóúßaŠ÷ÛÓ@`œQÎ^ÔÛÌO¡gŠ4ýP¹î4SGyQ¡œãö³U¡·÷rM †½4æbgü‡–:d)r³ùOWMÔ7–ž%”Ç µ}qjm,U4C?ÀÀ²P’•ÐTÿ©èùEY\Ú,÷vˆJZ.•Q8-çeŽîÀÚz5h£s0.r6/)ûûpQ…–ËV²¢Óbµ°CŠß7W-–æƒcÛp1UJ|ìL\¿S½úTb¯ð•£Ý+ ùæ$J¯>Ñ«xëB‘QÖ&ðºy sö^i+Ù0ò/ìS™(‚$²Ù/J(’‡â™®céÊÇ𨊱ú!o¾m0±óŨkÉE^ÓQKŠb¯¡1ÕªÐj»ë̽îšÅ3›¨Cc?,#s s÷÷gÖž¼ûv—‰­)¶˜gN3z¬ª.mصGêê3Íš˜)Øö‰¨P‚˜‹zëL Ó'3Ѹ˜5ñ°È ¬•{ˆ*u.žÁajÝ»¾ ºR9 ƒ®Cr8Ú½—\'M¢œt5KHNÀŸLõ‡žNYÇ5X¦‘kªWߟ…sT‹.çTšZÉ= Â?‹{ò ŽO‘Zvh,/av„2kèVÞEÈ• ”éóð6ÀA¾…z>c¿Þí[f©¢ùçéóCù¡îú}?ÍG(ÅÃ~si~ªNAVù">ÖÂûâp6ž_gÍ¢¿}“c|´õ+Ï8Ð4SIí`¤ ªíÈjˆó ¯@Q™¾Ÿ‰Jo‚·ÔÙHî§E¼çžÔÁ>p´§ækWh+8>:úoðÉ™,k-½)WMµ€[°…‚|t²Ý¦±›;¨ˆª‡Ð±¬µvÆÓdTy1²Ã§ñâ<…ò£_ç)ƒ³Lƒ‰  Ìà/Ÿì³³jûE ’“s@2; ÐP˜v PÁžÄÃ×—þÁ«ñ€2 <þ+2¶ >“ –T½3ŒÒ"»žüŒ[k€oš<÷UðìKE-óuÛ<`³Çé{ù¥Þ £­Ú:ëµÚâGC$Aº­…̰î˜ÓbØ#Uüÿ¹×´t=+¹h€;«ܪ;\«Ð¡§”1,µ­Añzs—¯±±@&ñ%8WÜÿm>-{nmNÃö¨eªRi\ߣ d´.V渞÷]Ï—X{UN9¬ò#?æÿe~{™æÏão¼à·ñŽŸ±ÜUû¼§Xë?—“ ï›â[TÖ‰©EetéÞöÐ};]Ê·•áïÞÙ4lf+_±sï÷1ïâÐäÖ³‘\­í%à ™ª­Ý%gè’פ«¾Ð#½ùÈXöä32=8ÌŸ_æ§5±÷š]\RX ÔThƒ?CïÜ©UA’U*ÕçR­QBã$S¿}ÓE§«†LÛŽÕü Âև‹¥^`TB`Yª9’#™ÝpL‘Âû¢Ï¤på2H%Ä&n”¡©¥X‚…YU)Ø§Ç €WêY;ZÅOž>WlíH ®éØî¹þÒ×#ܬŸ±„K2ØPÏ×#ÿû]ö¸EHW sùåK² 7–w¾îéFÔÃk«õùìo›ð´LñµþðÆ¥•jûü¶´Öø XR£ Ô> •÷Ž?ÐÙ–°†ÛPpÛöà1­ñ3`«Ay6þ=¶{òˆÈ¿¯m_£îËtÓ6þ¿>[B†ûN+ÄìðËLõTüQqéÉ“´ ÉÖ‘ŒÇ(bóä}3ùžLOþ:Aa6V~&l2§Ôž75^Ù›§ iW!YgŽ…é€)ê÷Ê4«êVþuÆ0dê`¢ú¹wÚl*1ÜÔ<í;ÒÜí†ahßêVŠ¡å·öɆ* Å&ñç5]€—¤Â<¦šªöȶÕ#O“åÐ>© ¯¾pîNÈ4©E{1ì€Ã†ˆ–“Þ0ã8ü¶¶ã ˜,&Õ>kÉÙM[qÍÐÌ5˜a…ÉâW º&räw±|{£Wì¦ÔÀfq¾„–´›p»'¦{¥—_IwBÐ*¾@Ý“¯bÁG>â~ÛoJ‘õš_K=+]Bˆ;5wŒÍÔ‘jÚZªæWJÁžÓCN?ìJ!ŸÏÔ¨Á‹qý-Îã€qyÎäŇ4ű¢1)I3ã¤x怜JS ;ÞTT ,G_ÅÊv‹þ(X,öD·+Ú{‡Q€‡†¢1ž*Ós;L ­où_ÒŠ;¹e¡„šé’^ k€0¦&fS‰°âUhóÝwCÛHwAr ^-ŠóâD~¿m—ÏöUÝy*‡áhþÈò†§– VÄæJ‡¡ÄN%%;»g¸Ié²½k¹êî\:€›mK…‚é2UVcÌ­r±B¿›Mkm‘u£˜6Ʊd×YÇmÁ–W‹XÑVwJE« ]!Ëõ×r¹f(ÕUq þ*àê1ÆZèoƒ° “q„…ìŽb‹îP%¹dbî±y*­iïîö¦¤Ê÷0” ª¬l9‚…d~¶­€}P¡ÿ~ÐV+èû¸ o­¬Ê Si«; Á³;Ã1jLiY>øµˆøS‰ý;o¼öh32|0F²œ¿äLøùÊü<cRß8ÆóGÖ<°ÐÓýíe§8?䥽sà_/${kB­úÙ@õ–SvO »§~,—:W݃¾±mŸÛ.tí"ƒ7ÃW/÷÷­p‡Ïc]–t –Îd¢ÔÚL9hÙ1Åæ‰¹XZÙ¡a€Öt(ÔS{´MÄ!«ùóJó0`¦úAkUuh[=„)ƒ³L0‹  Ìà/Ÿì³³jûE ’“t@2; ÐP˜v PÁžÄÃÜõþÁ«ñ€Þý <þ+2¶ >Pimòôè÷ ™:œÐk§•ãT†ã§“üø¿uy7$pÜôK¬Œ£²gÊØ~¨L” DÞlYoánd]êCd/¼]"›æQöòAd´ü°ª¹³¶UÐmD§r;ê³6)¨íÆÜϵø£Î&k+ÕÃÂÿþsL]¦Y÷3h þ™zõf\ Èû™:òÏ‹ØëJ u!¸Ijý?J¾àN’–¯@ìEͺ*~¼³'ô4tx*MgÍZ ø‰‰€ÄÕ8F²lÚ똻öÚg£J9ziùˆËŸuk7 d\Qzim²¨º*!vôt9‰šù¯éUüö¢£Ácõ¾QÚ\ÒÞŸXènò|2J›‹é£RMßÌ~%Õ ²6Ÿ‹éÊ#t}ÒLxïO›IW4’®n$ÅFRn„-ØŒAVú Ê¥n9”Vʹw|ò:ñHü·š~S{¤¨b×X¼¿U õ§~¬È… ]úÿïi¨ê),޵x9â;k§\æ ‚NWÖaH~÷MÂhóíte<ñnôq|«š•¨|O=¾6æø¢Š¯'þo/¼’úIÛRÿ!Ã}Á¨ÿ_ÈðÿZ!íܵ1ÃõÂûȘáªÞ#b†ëǺMud¢ôUžŠì-æÈëoi† ! QªðE@ìѶ¸¿[£z=ˆ†ºh`…áþ~ªsRÊI‡O•´êѶ£´_›”'Cܰ¨Rƒk=Íþ0¼%(Î4vü`ŸÎR+‘ÂB¶×D ËU< CåÃÕ””ò™ƒ—Kž£a^H;õ,2Ó'©HÁN½°¥ÓÔ™põÃåù­éÙ,~‹‡Çß {$-‡8–o…Íä/§ûVmTö}‡ç¨N'':ÃÃHøÊ¾ü"f¦t,Ž•^ŒÇ¢àÐíh0È ÅWÆÆ*›'ˆXÍáæK‹a‚øÜ>àºaÉÆ¤z¶êX[‰ÿ9ݗд •“:®©ÁµI³Ô„-89=Åå:-¢!ží`Ÿ9ž—t¹_R·õÚg˜rnfù@ Ûböž±“{ ÄÒB(qgš)êVDv£ŠíØÍ0]÷Q­ùºsò‡õÇË£;ä8«1"‰vV£‹éxÏ«T !~›«VTÝkL@ÍÃq«’Ïk¢·®?²P·ÃÚ‘Þo…‘ÿY—b[爵ï[~©Ê‰ß#mMü~oü2òî§œr:óÆ®q½;ªh*è†]µh‡_?=:»çWVâ¿l÷¾§À Ž50—•ÄY#îè§3~¹^mÿ´ é¬Z¢[-d/Ëé-ÃS€Û•ÅL?\BÂIÔúûçª4ü>µ ðã «û°WiõÞñŒY‹ZŽÅ,†ovËùÕÕÓüõ« Ö¡Ìâ„׆åöõ«x¡[™ù^hÙ”ÁØæ¾2ø£b-ê̵haÅ'çPçáƒÇ`–Ã& bA$?Ø]¼·ý¼}_‡ÇtRx(«ˆ$eMŠÏ0¸B/GòZu ™ Ìd'Qh¦µä˜$>Zc0$tZ›z—E‡Á­Óè‘V;Ç} Ðqzõ´Š<%ŸTUµ½,{˜G;DÞà‡¥ˆñ4€u86þÞ¼s=mŽSëÍè’\Úõã«‹³pò¿ìb½Mq¥âÝá8MrX£A<ØÕð*/÷Ø¿»lÝV퉎ä<„ë3{}E&“ã£;á¸ë­âÇ:§¸^P^„yŽ¡Ó#ù7*Ó ¹Q7®°{{-~¡€—qä8{“\ÔyÊA›~’_ñ^Ã2½Èóä¾ tž(B+®keˆc7 <õRMìX혜21)ƒ³L匠 Ìà/Ÿì³³jûE ’“u@2;ÐP˜v PÁžÄÃâSþÁ«ñ€í1 <þ+2¶ >¼‘c‚k‡•n vvü¿Ë‘awMdØÅCO0zöûé>ä}LÔ…§…‹­ÕSÞWV‹&¡ý¨Žo&Õ3z+n'é&°—Vøv–¨¦Ý àñØ\¶[VÇx°G‡†ÎŒÎÙâ¡+é¡=tm\æH~„è˜+lñ°°÷kzýêÓ¬“Ãd–šw4ÆoSa=³íw¾hŸýçÞâ¡.//.úƒAÈ1…öŽQ|ëvß >RwFY2ž[/f0ªs0.süƒrMÐí÷ƒÓ8ˆ¾À€\Á ]M?éÄ“AÔ€]£à¤sØð¿ãjÂI5áY5áË[¡Çºï:_cb‘\%y¦SŸaÚð&ŸÞ¦vÚ?©ü/ŠüCÌ×E×þ?и4•^5”žÐÂTé!Ì&MpåMþâö®3Wž!Ø‹A?Ø{ßq,â¿ÒŒùÌ“ëk|˜¦Shù¤”AäŠÌ«Ý½ÉÂç ÉR-­ v„Ιxýùèd#~pÂvÌ£u´Dßdãû—µ`ÍaÏß «¤}pªÙBµý養Öp™ÀÚ€å«Q0 Èçez@:¾@·*(¶ß& ,J ÖñF‚»ø˜q@Zh¥g¸LGW“î‚ù³Ž!ü½Ê®ÙFàÈMIfŒ9 R8Ç ÚèKÛêÖØáü¢²«ºÖnÑZÜé–›ö¶nÜ,Á€nœ-iGå­Ø;e` „â$l ÈÁ>Öó©EüAÌ«DG"iÚšÌF›°ïýº§¬ÝOÐ= Úì „™ÂždÍŒËÏ~pðçyB66B*†Ûsò:—×Ò]7ò¼‰#,ãfÐdì«E35öÆwQÄ’ð.•Š“ôî{‘ùA&#î.® wkŒ%”ÑVSí¾³<_§%5]\‡ƒØ ©yƒ*YÌáÃÛM)&èÙG×]‡Ž§Y× åå2+‰(!r™FnOtzž5ætz¦þÏIyGâO­æ&#]Útˆ1õdT[³+[làCÞΪáïfB@ºŠ’ž^ØžKr7oEËQCI^óÊ‘Ye@L{Ä ¤-‰´¿Ýz^T™â@M‹ðð$´b¥ÔY‹¸rî·¹×/«DÚ‡åî5‡¯­ntɧw’× ÛÇ=]¯ŽÜ{;í/R°A¦#”d+º‹‡džá‡ªàŒ{"ŽñêY®x®¢'‘ÞmMt_Ÿ¡Bk¡¤ºˆHÄà‹ Ó@X—émÝÀúÃ|9Žá /Ô)/r(©é ‰¢ ‰(‹pJq—á -&ÂBŸÀÊ_ðÊ^ÀʈG+õ©••ÖaÑ—:²_Gƒ8UŽsƒú¢ÎDl”B¸ˆØ4Vy8 n“lby,ml@kW7¹Ëy6§.¥¹È`Ñ—¤Aè¸;ÖÓJÔÏßG | | ü·!lEXÓVäÛÚ13Š,,î\%P¡Õ@O9hÔ…§s8$ýYî8¢à*)JšrÛOœˆ¾)ƒ³L¹Ž  Ìà/Ÿì³³jûE ’“v@2;ÐP˜v PÁžÄÃç±þÁ«ñ€OI <þ+2¶ >gÀ‡,›IÕ@±.¸åcZ#¾9§õótm„§z×ê§° ¡Qe@Ý“Ç Â $= ×JÐ7‹ ¤‰ûûL¤D¡üÏF’í ]-D `Æ„i†`k$£ãZø6jYø°É…ßõ"P€[3•›äˆæv–\§à/*þùHÙáæeä0îŸ8ï‚<ØPm4¨õGÆ[¨¡G«Û£ß´|PÂûýtúá6É?¬… ‹ëxì+ŽmKC0÷ŒÄZüÜFç¡ <‡±O9âF’ÃY%Þ@’ â¼+kp#αðaÈèMgõn[„ƒgÃaÀ ­×kQÇào`=8·!ã4ªRŒ÷,KPy۩—©¸ðþ×P–þÖº§'‹ŸV‰ H—¥–½}‚µ MÈ ²ˆVÏí2¨{“À½aØMk p¨Ù ü`õ*Æû ®û;÷2zÀºYËܱpÃÒŒ§òÇ¿aç€bvÜà­G!f*ÂË*±mà ‚ëôVÈ|§Â™bŸƒ¯}¢ôcÙ]TUŠÆ«ËþÆq•©æŠBÛê×>:¹' Ô˜”ÓáK±1oDd%Ë@O”Ù‹[¿ú+Ú賃Þì†F&PCÔÉ«†¬8%ë¾rSÑh/ÄMÚwMEÖNHÚÄ«]ëyÆÝc³¤D…uÝÂÁRÛnœ¼ŸFÅtN¦ÞäR½}à ;±¾èÛßçB–Þ¼‰2êàÎN!Ç:žTQ¦³˜¡ôÔÍ)[ûï`V–ÅÕ4'³Ó“¯Â…lÚ[Y»-ñ™Ç1±ä"F±jƇ©Á•…Ñ m¢ˆv8c4•¡W¢lÏ0Τ¾Ÿfè=¯E«_Þ‹þ‹ Û±Ô`bwtéËòdÀz1h»D3_‚®÷ŠP@Šõ?Åé ÐÄ9EÃÍj`Q¶Š.7­‚Eá1õ ¶ú»êR>®áóÑ…â;åü*ek}¬0Ù¶ý;Ú¾vâß¾éÒüdÄm¯CèCÙÙ¿¢åMªˆ€štßLiorlÀßì›\Þ;›æé×\ŠYAœ¶â€“Ѷ Š“¢vس/—‘ȧLiԗ̾HOP;Ê·PÌò¬)ƒ³L‰  Ìà/Ÿì³³jûE ’“w@2;ÐP˜v PÁžÄÃíþÁ«ñ€3 <þ+2¶ >LGlÈ‚Qšè’Ž's§‰ eÞ ÙˆÂŠÙfŸ¶ƒ¶“zL©r›´#}p;äpúB¸àêäÄD¦Âßè,ÍnüGž¢æŠfÁÈÑ·<†üÑlžóïªdjÒ-9]ÔÉ›`¥V±Ž+ Éžµ¿¿ãä>ÒXÒŒAõ݇ÞçØ¼f…a\½ùhÁ@»ü¡!”i#¤}¾â0:8uåáXªsÙž\õâî¬/zñûI®àO!»äžˆ7M‡3Éæ…#gEé.Þœ¯o, +eü´z%¦ò}.:0˲BÊ~Ô’0fžYcÃø¿f eWu/¾É5W½Æ D0×»ÓY2ÌÊ{bŒëk(nÝènmÐcZ·­!®³L…9–×<½‚Vÿ¢˜îÞ‘+Ï—ª\x›NæÖ[4u¦¡«ïjõ¤ZY¸ÊÙkÄF˜;ÒåèJXF€eÃ<)\5³6–MïjÅ`¢hùÛ‘"çÏ+°¡&—gñ IŠnæô”ÕÏjª8Bp£ˆÈîüQÓó ÔYuè¢÷!µ~ÿ·QqXü=W#zíVy;ª+Z•çÃyž“ù§.i8Õäña]¬:±²U1{pœ~ÈÒJ(džõÅŠzpÉúj(¬¯Aˆ.‘§ŸÑ"ý4Ëò´è>;>)oºÁað ±BüŠ-\ m5Žn¥ã§$®@´S®tae¼ä^ÃÆt¼ò4IwŽ2¼îYRΘ×sÓt^Ê)/t»ÛD¢.{µk‡à9ßP Óñx…5â#úB›>þ Ú+~“Dïb¸Ô]u•;ü—°lp¥}ù&M"¬¸×Øh{³S培²såÞQCbéž]·®°©0æ>ªIûæZCà‹kÜɯá"ÛKy«Æÿ1×Îè7­?î%h´xØü šä£dr=—kt&•s÷LLŽe‚H؉‹«£Â&–>-4Õ§°„T]Wõ­¾k†ƒŠM‚a·ŸÔ'`A¥‹‘9]_õ¼^ØKS~ÊÌ!¹8±MAæ(usZya¦DU¶/?ðÙ%¹c3Rj@±a±¾A—‚| ¶°Ô1…ÕÀ$.šˆ!ÐÈÔ*IÙøª†?°JnLÆÙõVÐél÷ô9GqmoyûPûXÍߪ ]QWT㇄›§cznXÝSIznXÆÞÛr“¸q«k€¨£Aw ØÉ”~:Ò&äñ†UEÄ·”LÜöð`9Ò?¢§Oªôþþ±ó½%ôMò4¬úǃ&Ä*š 5ißÅOHkLu:Tj›."ƒ&Š.¼ãÚ®qkÑ6[OTÑ€µHý.¹ôŠ!EÝûtŠOf½òšZí,ùL+Ïê—1éˆ}â¢öTp‘Õ$ÚYoæ= A­`H.Q4©ŠO«Nfšq6:ÓÂ/9_ôÄè4á²Ê:ZFÖ/æ3ï©ìr<ÏI÷ò9|®A~“0îµRè9Ò›Wµ„~ßAAÎpXÑæâ÷Øá ˆq®; jTF5k‰zene¦µºArYLÇóÒ_Ø93mý*¥oæ·ÏËÞÇx•öI™}¤gÏëÏ~IõÝ·u+œ.B‘üjŒ/ƒzžƒö‰‚ζ:ëïQk‹JU5Qp9ž?8ºuùþô/NIaáiŒ\(Gš‚!‚4Ũ&,ò0W¤Ü•½Ë=£§ á ½ž´”ŽÃ~œ`lðõ!í„2° j>ôè«~„ÞÖ•zø®)»M*Î#$ÕŽîÖ8×K¬'%¬qC)ƒ³L‘ååÌà/Ÿì³³jûE דx@2=ÀÐP˜v PÁžÄÃòmþÁ«ñ€ëC <þ,2¶ >˜6"8¨©0•õº+Núb³Ua5þAõ±òê‹Ë Ã]ÍæäèaÃáßôôoĬI¤ : è-­ôF ÈŸªØ¨ïtØ‚Úsšö¿L^#ûMÐz1ÀZ×ušCA‚jJ´m–ùú÷g‘.ôþ`ïÏÖ½¡Â 8Í‚9°ãº+¨åïïg£õê cZ5­zB­Q³l2APk)á{;¿æÌÇî ¾÷½ë2C§ç–ÕlÓ‚ Ö‚ÏÝ0Í5‹œÝ„go#]ÞÐYpDâom´LÁOòzÊÄ÷2»AÜgÜ÷â\q£=›p²{ældžÀ)=c”’NLÛÐrF=OËô$bU–~.¦ês¹ÏødÌl=s,rD+·{üv©ax"5”T¯Š°ÿ\«Ú}õÖÈÈv×äQæs<7r`~þG~ð[µ‘SnõÉ}ü½ÝÀèÞ§Ip"ô×ô΄øPÁÅ;^»xÕ=jƒYkß°ðŸÕgGþ³Áк~NGü\ÆT|5ˆY¿*‚ýJ¼³*Ùv<cdéÓßð¥¿÷²ccŒ…›-¨ê·3Và­ovjˆ5ŸìNz¥>–šÍ¯Í+ì†y-NHôÓöõfÊÕ³¨k5Vò½Öæß·ŸÓ~Eþ-ñ¼3E¯ÎÅן§óM›+¯Ê- õÑ‹rÆÀ~‚Í›½8›C/Mqsr+"-¯*ëËíÜ•ÄGÙÐåÚ =|®wäž  ž^÷“aËîI´.çc"Ž0€ü(¨ú}™ŽGY{W¨µñäωt– WQàÉéóxêxRÏ" QÞù}ø‹Ž&OE—Ž0XEc7ó‡?¯ßä·öXöÀÿØ.*þ!e 7éS)ƒ³L µBB³³jûÌà/ŸìE4Ya@@lš ÐP˜vÁžPþÁ«ñÄÃ×—€x6" 2¶ ><þ+)ƒ³LDÅBB³³jûÌà/ŸìE4Ís@@ø‡ ÐP˜vÁžPþÁ«ñÄÃ퀀ÐR 2¶ ><þ+)ƒ³L\ÅBB³³jûÌà/ŸìE4y@@Lø ÐP˜vÁžPþÁ«ñÄÃõ€~ÏR 2¶ ><þ+*ƒ³L%ú¾¾³³jûÌà/ŸìE°ÚB@@ê< ÐP˜vÁ P×.–7ÄY²:€€ÐÊD 2¶ D<þGET /skins-1.5/common/jquery.min.js?283z HTTP/1.1 Host: bits.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: */* Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive *ƒ³L ¸¸³³jûÌà/ŸìEª¾@@l ÐP˜vÁŸP£¥Å zÄ€€Ðî 2¶ D<þGET /skins-1.5/common/ajax.js?283z HTTP/1.1 Host: bits.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: */* Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive *ƒ³LoÜ   Ìà/Ÿì³³jûE ’b§@2kÖÐP˜v PÁ ÄY²:×.—³€ý— <þp2¶ DHTTP/1.1 200 OK Server: Apache Last-Modified: Mon, 11 Oct 2010 07:45:46 GMT ETag: "18795-492528c51fe80"-gzip Cache-Control: max-age=2592000 Expires: Wed, 10 Nov 2010 07:46:24 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Type: application/x-javascript Content-Length: 28064 Date: Mon, 11 Oct 2010 21:35:38 GMT X-Varnish: 3909044138 3582195980 Age: 49754 Via: 1.1 varnish Connection: keep-alive ‹å½kwG’ ú]¿‚¬ö@(¡€r÷ž@%\[míµ-OS=Ý}AÈ E²$€P¢šàüöÏÌȬH¹{gï=ës,¢ò‘‘‘‘‘šç×óɦ\Ì›ŸËùtñ9»žO‹ór^LÓÛOãÕÁ‡¿.V_rWj]ÌŠÉf±Ê&‹ù¦¸Ù¤·«bs½šÌ‹ÏR¸}>o—órS-Û¿Ë~‘¹·6e¿|£ ßdÓÅäúª˜o4E¿³Õb±‘ò¿^—“¯n–«¼ó~øþÙèIóÙðôóé_F­çéðýóÑ“o¶ïׄ¤£Q+ý¦“•ë“òj9+ x{ø¾÷»Óái;ƒRl5_l>_–È:=Ïͪ¼‚RÍÓõöôºÛý®›¶¶öã›ÎE¶Z—ó‹Yñn|%Ÿ5O?·ÒÓõ“ÓÎàysÐ{vÚ9=~ž íëu±úî§2*/ÆŠ¶KËÎV‹Ïðñãx3¹ÌVÅxúåû??ÏÖ'üP®7ùp”½|ûã á|óÃb<-¦Ùfq_äoÏ>ˆÛËÕb³Ø|YmÍÉ.Çë·Ÿç?¯ËbµùR-ægËëõeþÝj5þbÊ`b¶ž•“¢’E©¬Pqóö¼’+é}‡¹ürEò[D‘Þ¼Bì»"à@Ödƒ¨Ñ/Ï›‡ZØ!ßæ²\÷ïAžfµç‹iñ:Jo1³-Íæø1ìŽr-×§ÜY1¿Ø\æÇýíåyžœ-¦_’FãÐ 1hYñ´¯]hBëq?®5në¾ÎP‹ó;†5­n’Þhr·ÚÅM1q£MLT¢Ñà¿ÃãÑvëFžÞj>¤§·0Ò¼)yùÛ^|ž«—2‡íV’{:«‡›û­P3(@ÉÚ—ëŸgãrΘØôCqÓ:ˆMý7Å+XwøÂvp˜#Níñf³jOƳYq²ÍêºJSÀ. ›ÞÕê—Åéœ]—³éëÕø‚J B£ ëÒ¾kkCÿ“Ëb|6+øu.ÕÚ“Ùb^üèפ¡ôlfÚž\B˜‹k,+.óº*VP –?ópäÁáðuQldßy3•…|:" cI‚:þh—Óé,)6Ù/—³/HZ2NÜ pÕæâÀ‘Z|bšJ‡[Ÿ(“9íÜŠAç8>5M< Á€jäÔ×ò @œWë4Ü?m,Ê ƒVh'øfÎç©Âï &ý'Ú'áBPZz § áã7e?û©:ž ‡#?‰GÂ^ül˜àeů~¥›@ à?:¶V¦=û•µÊÖ1Nä¼\­7»¶Dñk“P|6Þ[æˆZ¢–w•r¸Üä=Ä8H°$Öi–Pf’™}æsÛå¼™dIн]—ÕUÜÕ§#Kî2ØO™›¶Ã]s&mè‘z-æÓ3td»•ˆ{_7r¹ÜÅjÓŽÚø7[/ bøI¿îú¡dcØX—¡E`§ÁX|º&˜Á!YØø€28 Ùnoï²2?¢èó„fÓ¢XŠx°Xb[JpVà~–_úže”æ‰i]ÌŠñv;UçŒ~¥ûcê¾_æOÖ“ËÁ¹‘,‚ÈþV&.…G77 Q#2‘(çRÈÕDæ5ļQ‘K¶$á”&˜Þ"Y,ç×Óh`pÌ;V¨¥äè7¥¦¼¦Äøå0š]M@VµLLðo¯®éÁpÔpÚéå¦ÑÈ3êšÀÐ+üŒŽ|Û ¡ÌüçãÆ]ˆÊÍÛù¤Ïs؆Ô`¯é­ íù/ßôˆ.Q}øc~6ŸPÞžxíFþ+¦Ñ˜ˆUž(6ïÊ«bq½iZ–(;þ)sØNŽ|y?$è¸~çsØ~ÝþgàЋ&ÐôÜå;Gé¾3â‘ØS©<©íâ¢Xýq<ŸÎŠ•I®4*ÐL¨¹9»Ì\x¼Ò@Á ã`M‚NÓAŒò€ðnˆ ˜,P%²)’øt]É!ÉC+§ÓWŸPs,æ8‰YÍ$ÖX$U-{Úl©61ƒbI,¦Tqî°Óä’°Ãò©Íd1§6Ö8ûÉåx~QTÇäGÖ¬%í_?3&ÊýÍêË­K’–@ð»R‘3Ô˜ <Ö®)°þÒð}2Y-f³FCŹqÚ‹ËNOFOˆ=~µö‡ ¨„u1WÈý@ëŽÚ’ƒýðv¨¢4bh^Ôn`ø±ÝV;4qÝQ²ÝB‚Såðìô7°f«Oã™ßÀ‰E€´¯ù‘Ñ„ó*Ôt¹³ÄKÒÝmsþäϘ§~¼=OÒÊ`C>_úxfÁ_:²ŽBbnÈóv»k¤P0%À¾ºZn¾Ô;ÁÝáhN¤ëˆd8¦Õ D2×ÊÕúEÂÕâóüDÞh¼ZÿãäíO†è7cZCáðûÐ+¥¶ÛC.áÄ,"„˜¦gªW¹$L÷ÃÓQçÛ镱¬ À\ØdËÙØáÎéisÐ&§§§³óùj3Ú^»Gÿ6>:ÿîèõèö÷wiç"Kþ¯$õU’á{,??]ž$[œí– °Åñl§Ó´yÚ>>IØzñj4l0'`{#Ûy¿ím³k­ŸœÓ–IR¿ä²Ù*ƒ³LBá   Ìà/Ÿì³³jûE ’b©@2kÔÐP˜v PÁ ÄY¼ö×.—³€f <þp2¶ DZ†ùh•ˆ›Åg·‘æScI‹rÓf$ÿÑ‚5“7sÀürz@K£…dóÅbiO€g‹³ñ씯YCüÑh8ý·¾p3—@çîѪ$X&I‰wÝEƲõdU.½Æ&ÒÂ%œ 'ÿhW ÀÚù0þ4–l#°­¯—K`ÒÛœóŠÈ€ÔÙ–¨akFý½ƒI'Ç3Tý ôI*%ÈlÅ)“¿†ø}»ªhr¡Œ2H(£Ò>%¬Š«Å§‚»ä‚²ÓA*2',ã:“‚N 6Ág{³ø3Lfõb È‚tv^I¬HÌL;#‰øV‰²6*YpI+Ê5P”Üñê†U9}®I›—›‡T?b͹æ:ÉKÎa”G]ò¹~{+õ4Z›P<ØÓòf;›â¶>J¥¹~<›²wÄn@ÉëB€ {ÃMä‹ *r,ýÅó uP½ÕéçÖ0霎Ê0 ¥~ñí]\“u’‰!bt¯…4‹tÑÔùÚcü|}=Û¬½ÞJ¶ÛáˆWJ©$¦ßª+¦d8×ùd ¬Ü U\¢2 5mHÐ>aH¥G}®äÆ s”Q«^¢œ4h’ªm‘p(-¡ê—KTƒx…誌”ž}Ñb¹vÚ>˜Xðw»õyŽÊáG«åYnî]v=¦ë~úkàÅ®ÇùõÎöŸÝÙî.¿óNósqö±Ü¤ÃƒÓÎmÚ£VÚáëV¨¾Ývš(/Œ‘=m?ùT¬ÖÐp:ØSüj]éA]Þa•ãMy6+„‡ôFê,þ^ÎfÒÉà`õ©§õc6-Àå9ߊ}CÏ_?'I&Ãëé•$$v€³ZC€,p—ö­i„Jº¦3  aK¶åÃ+üù{XWhÄÚ‘°d[†—5$1PéhY›¨Çöz|>^•ÜUsG‰b7@yí¤ç×Qm;žÐræ b¹»¿<Ö%õ÷kmb¥‡ÝFS„líoVêÄŠ¤ûT6ûÆô –—>НÖùăEðjÿ‘Â%0g¥¤S½¡þç^mN3™ç(逸:4‚púË ËìX¯¬½ÓëçÜ0 8NHühʽˆ3@ý²¢ÝøÃø¦y{½šõ4+¯¿Ì'¢ƒE-=•Êî"ÆÊ ”Ü63šî§VRÊ9`Íßýø±¢¼(D`(…ÒXz%ò”`»™æx2)Ök9ƒ?_ø¸ÍüdxŠ×½ÖºîàbÅ‹^ixŽè#J¨l¹ ;®†G®fØ=y§b~Ö?VΗכÒs<žà?[Ü<î2F“Y9ù˜8{‹ú®ê¶]6 6qYÒýAƒ *™AúñøxNÜK¿c¢ÐÏP­ÅcRpÊÂöñ!$ð‘凣¯jˆ÷©†®Îøc5è 0. ŠŽyTxùï²­|£ ÓX¬4jOPúà Åtês9öÇ/AòþœIyr¼¼£Î^£ÇStóÒMšGótéØÅâüØ×¿P—yþ4j:">itò>Æ“÷1]nGYø-SN¸7+PúO¤F§b³{@âÊñm¹Oê¤\û|ËÈ3ÚX‡¦òª¨‰ô§Š«‘ÉÕ ™¾mSØÍb6tEG¹Upþà hÞ*ôùêÞÃQ›ë³«róýõð ë<”›Ôà$J>»j‰\R²cÊuÁj '2Ö5iºV—«Årß&@4“^‚ûkø•%@ã5¤Ð_œiB&‹ùìK¬Þ¯$»߈Íg? Ÿ@9ŠÙ ¹@Qh>NøÚ!4±ø ‰p~ŸÅ)ðƒS€'#Y¹—À¯7ø+Aß TÛ%ð÷ÇñÞß-VÓbÕKèã{úH˜-„Ú&"35(ÃÓ7T¤ú¥„‚ÖŠwQéî¿[Ç=éį2ðçç:ÿY>LøËÍAV…pnŠ`bùzsCæϘ…nUb8àL†«aªùfÞ"õö¡ÁÛÛyèU^þSÛtûO1ð"¨çWÕÑæO‹Œç9ŸÍçuÀÖ.†ï’”Ðç»Hÿë)?¢‰ð€1s~H,¤S¸‹ƒvHË“ï8$h‘Ò@Ãþ‰Ï/g"ß-:8••ˆh„ßhTÖˆ5^¸FI®`C‹Ç¦Î-}žw½z2ÞPLó %û¦¢ÚÁÆôâTw:G ©q&>Eu|ú~œÐ%•UT‚ʪU ¤í£?³#”É»þej]Õ°!z=ï!äŤH9ýÀ+6þEñ—èé‹é]ôJÁ¢¼¸”|%+×J¡Ô鯕ŒY˜EÄvÏZûT“þÕí6» І›ŒÜÔ¿Æš¯ç‘²‡i5kû5 4_ln®fyÐ'âúvëMÃÿú*ƒ³LOæ   Ìà/Ÿì³³jûE ’£ð@2*ÐP˜v PÁŸÅ zÄ¥€ï <þp2¶ DHTTP/1.1 200 OK Server: Apache Last-Modified: Tue, 14 Jul 2009 00:00:52 GMT ETag: "12a9-46e9f21c11500"-gzip Cache-Control: max-age=2592000 Expires: Wed, 10 Nov 2010 07:46:24 GMT Vary: Accept-Encoding Content-Encoding: gzip Content-Type: application/x-javascript Content-Length: 1895 Date: Mon, 11 Oct 2010 21:35:38 GMT X-Varnish: 3909044153 3582196314 Age: 49754 Via: 1.1 varnish Connection: keep-alive ‹­XmoÛÈþlýŠ QT”#QIÚ¢€ëøÜ‹qb\thŠ 0VâJÚ;ŠË.—¦„Cþ{ŸÙ]R”,×âÇ wgžy¡Çc2r­­¤rnTaU¾¤LÍŒ0ÛÞxLñ|@s]lZ®,½zñâo´Ö©4ùZÚ•N‡¤òyïA*Å/bsŸÊYµ¼g šÐBd¥<ïÜùŸJ–öÞn ¾~¸žFç½Þøô´wJjñC•dM%‡dWx\TùÜ*“®lQÙ’–êA渓´–e)–`È­&€ñ™ÌäZæ–jeW¤RìàŸ³¼\SYÍW-¥Ü¨°Êc¦z^ññ•eeTþ‹œ[™&½Óq¯U§[¹±ú­wøøÙ¡AøÚV&o\Ó;açÈI++YJ{íµy³½Iã~¡?`‡+ˆ“.ãÜHaeà£"5(’y&Êò½XƒvÌߪôÑ1ÎY©ÙQ¥Ê7Û©X2\ÍtºŸ_|q<¬×,Y(SÚ«•ÊÒÍ•—ÒØ7r¡ŒŽ{§¼€SQ2OÝq,ùâkðÌúiSõàL\ïq’OŽ÷p|Ló¡ÜçYûÓN¸óÞ×&-çz]«f*SvKµaNC°ˆœ.A¹¬éÓí»·Ö?ù'=ãT9–(*WöÞ_Ç.ŽÝü‰ŽÑÌE–!é’hàÝr »­Ùº@NñÈ ËZ”v›Á¥Îåt ±ò•šjÎç¼o=G•çrÎ%cT^÷FÕÂä°ÇÀÍ5ýê•Ì=C)-¡² oX3T`‹^qåìöر‹'L°(´8$n£üÉå„9Òoot[nÖÙ«„q¦Ó;ŸÈ‡;ˆ'0ÔÜèR/ì>ÌGÏ;þ*ËümÏýÿÊìþÞΕ®²}ÃúèK¤»Òw%ñ¨›L—Lº“QY“ȉ!]TÙ©k™*Q«_UBW8*I t+‘§hK)Ͷt êïUY°âÒ$Ū¹vxŸ£iäÃÏzážÛ”>ËIè¶BRÎ$ÐMN@#̪—Œ~½)´±ïpá…AŒœ¢Æˆ-ƒâÈÕUɈv%l+ÂqXÜ#E¼"áÅQÕ F²1ÈJ¾3²¬2Û¨éU»YøþŽÑÂnûñpP3ªÁ·u9(<Á(…0ðÌt}^Ù~ÉÖ¨cc7´~Ì1˜ö ²J¶rBÎï´æfÒÅÓ¸2䆙^|V!EÌÛéí»oC£Wäz#ÖE&Ï<^H>}ÏFÇýTÿSëþ>¿*ƒ³L]ç ïïÌà/Ÿì³³jûE á£ñ@2,=ÐP˜v PÁŸÅ €"¥€Vº <þp2¶ DÒ«!ýåËðÉÉ•+]ƒ: xÊ.v øÄs»\yP‚n9ÿ…d„…ûy7tP„ØÕ Ó:‹C ›m/ˆUèF= Öà@uF³×öØ\ Æ·é>tù9 i檘›¢ÒfHù¹«Œ O…ÆÆ‘ +ðŽSȪ—¥y€ºÏQÞqŒW·ùÐý `@ÔÞ høœ¢±B=n¸ö¢Qs=pÑ…pOXal4®{[yÂÎã;A¡Ä!XÄÑ.@2zÉm'èÊ¿!þ”“2ŸcšýüÓͱÎy¶~i'ê#î?ÿ^nk13¾@žÓkçè$“ùÒ®pðüùcÅÍDŸ¿<%Àݪ/~<>ä5y깃~8§ û…ãhƒG>6n–¸­á·ƒÛèµ±‹¼{þíÅÙ´[çÞD)òlã3AdX“âèòÇËOn¶”UÁýX¦~híïŒn9j¦ß&ÑXdŽäÚë°ÅŽà% MŒƒF‡"•2Ó7„±;è’0òyQXAy«¿UUw>6eµIÐ]ƒ.o¥À· ¶÷± =!qèBïã—ÉK/óó•Î-´M!Œ!°fÊûl¼Õu=â±>ªLæÓÁGƒìΈåZ0Ì\ «N¶²täG3ňÅ1K®GÖˆ¼dyKçpiº--ŠgŽ9»t^¡ƒÆ»`oG÷‘éèÙ„þêÒÜg–Ûß÷ÖƒíÛTJ1» º­*¿º<µøpNÑæQ¥ÛºÝ„Š÷Âãrà.šŒº6F›3ú]‚ÎŽ b8×ø‚±n&ëEÜl"®­ö¯ô©Y!ÝmLjó͵–§!|ý¶žÐ$Ö9²›÷w?O[ª“=L¼ 6·rLLr»h°‰þ75aëbº85K0ÿj»è·Ü-/ǵt0‡´¨È×ø@#÷ñ9éKÖ½ÿÝbÂë1€¿‹ºëzǔଙH›ÀqÙ[$Î\‹¿&˜°º{ÕÂZá3¢·«÷Ö­’ÝþÍúúÉÖí,c79Âa;DšbÏÓxïìiäZ(×}[䯔ðæ©/V:¥„ó™Ö™ÄÚ‹Ï8¿©b÷jZw1‡Íì¬^| d¼ ÆíªÚÍýŧà †åÂi‹ ª™fÁžpÞÕåwÆýE?½)©*ƒ³L1 BB³³jûÌà/ŸìE4ã @@âð ÐP˜vÁ P×.—³ÄYÂT€~!ˆ© 2¶ E<þp*ƒ³L01 BB³³jûÌà/ŸìE4Ó@@òæ ÐP˜vÁ P×.—³ÄYÍ€{r€œ 2¶ E<þp*ƒ³L>1 BB³³jûÌà/ŸìE4â @@ãñ ÐP˜vÁŸP¥Å ƒÏ€äŠn 2¶ E<þp*ƒ³Lnñ   Ìà/Ÿì³³jûE ’b¬@2kÑÐP˜v PÁ ÄYÍ×.—³€V^ <þx2¶ Eã/n%ž¼bv×§ûnË݇ÐÝ%÷¹ÝâŸrmEV-äFÇÀˆÎ’¯ ¦¢ ŸT‰“±õáVÙš&¬ûºÙjðß›|~`;YIŠjݱ=¼.v ‹# 9”yÑÒ¯%R—N ÷1LgÅ!å Ö™Š$a:)bE´z'GÖƒÉxþxspVðeóÔ±ôrA¦txç™ ÇÚU¢½ZâNf´"»_†šýß™›®^ó"mͼ¾=SGÉzP­Ñ> ?¦3cáuRuÐÞn½þiÏj lÐ 6 Häb5é±]jÌx%ê=1*bc¤¼ØRBÖ•ÇòöìÛyæ~#q“A¶/5>†)™Kb_þæ&O+Zk3è~£mð—žòÎ1GŇ—ñ… ß!ëqøÒÜEi-„7së˜Û®ÿ¦`>ô“ï/}>Ëæqoþ›Ag ç¶¡š(GÌÄñ,£KâC‹&z% d(HænÄ%ÊtÖ&Dò.Q–¸ Jr˜@Â;R¬õR•8ªL!ýß(ª pz§pëlW|ñMw™ÉL{ºè=‹öt?{§÷?^£ÙNX$5»–c›ú›l•Ïwws®Ó¶Ë ŠQ,¯nJᤚ džÐô8Õ6FÌ·ÏpÐ1… ¯-’÷ý[‰¡×zˆ•F™r3ÁªK"áðO~­Ý ›ÊÙXÙ¤ ×Ëí6ø4z³Úíµ™ª·Rm2_a™¦*‘aT²÷.FqJ“ìã†Rešt>Ðuzk>ÌÔÜJ¤n¸0ud(NîN×z%ò±i;X2vÀ‘•÷2Úy,ÿKÄ´FcÕ×Þ#a¹Xÿ–A¼]ùj•c&e»Êî§"Ãó`Ë@Œ(i7!Î"êÊ¬Ž¡³¥SÃó‹fÍÊyQµ…Jé)b)m6>V(Á¹¶s!kÝÆ€·]}·Myí„-¤5ÒÓ¡n†øbäÅe˜Áâò’ù•"ì4.;bVQC[wÒPqD;]гBŸuû!ug’ßD& q,>ü©¸xu³l&Í÷ÛÓÓvš´9)~ÙÜM=¥t*“*62@Ë’&üÚ~“&©I4cK´ü ûŽ–?Œý¦$Ï;‚¡+ý‡g®‚óG™¢ËGÿxô—F—7æÔkh{ºgÙÝ–¨Pìƒ3¿SØŒ>¡ƒ 3£Òz?W Ûío™p@Ðò<<šØ…üÁ Aw±ÎÅÇ}çL-mfÀyòÌßõš©:ô ^ô.tq¸ÑÄa2ÝíÖ•ªS- ÷·Úù¦¯€Óû£PSÌ€<’›ÃÏøÚÛ¥ˆ*ÀW -†ß…º:k4)ÄFÂúÔ²£~5u½ÛæXyd,%-í“}[õãP†z¯íf&<ª9º°7æ$¼ÁÏÆíñ6[’p©34sÇÈø>|ä·¼ý5GËçÓ‡·†P‚3oåÏ^ÈuÊ/yQ±´WÍ©²‡ ªež³¢Ê´/ÃÈ­\ ¸™Ì®×å§Â¸“‹µlíÍb‰1ÃÆc– ÌT¹O|P+˜íF·€¤¥¦…#J‹o SSG³TTÅà’X‹øñÿªF%œžÆèüd,ç“dkï*ƒ³L õ   Ìà/Ÿì³³jûE ’b­@2kÐÐP˜v PÁ ÄYÒn×.—³€'I <þx2¶ E™Rž³¢ãõsMO®W¨Úzgš2›§bm˜p›ÐDûH„*e†ál&PÄÞ'ç7Z“5xòç«l½·7tÌïˆÛ3 •{J€]®ìî¢p†|̶)8ž¢ä `貘6S²£%vü>ìár6˜ÿmüeq>†Aü¼¢l:«k![̦Y¹~´Žâ °;ÛÃe& ü2åùS@SÌ)À¸æÀ 2º ~Ɉ`0ôwç:GÙÕ•¤‘ˆ¯²g)×/8Ý×Í|tXŸ£ä¿^…ÀôÈv@ÑBtØÑ0$ïn×a–àÑI JZ8Tfª=äbo-‡+z^Þp»Û­x -¨£d=‚|³'Þ÷ŒÊ°n×rЦ¾á£Í‘ðõÜô½ú‡Ý|s¨ÚªšpF’:ˆ+wíÌðr\Ôèœ|«c3 (š¸ü8U 8tžšå¶Š.£Ct²çÓyá3ɰßÖ ´Q}ûTñk£¨Ë›(QtKS1ÞЉî’)н¦¢Jõì7 -ÐÉ7WWÅ´oŠ:jlÃä9õ½Å³^2žmþïâ iÊ_Ðý$gÉ3ö+<`KZ¼ê™3¼©ÀËžÕ  Oè[ þUþþí`²YͰ¹`k‘ÏÅ:—3ÅÏ—@ÌÎW‹+Ñ)«n ýW¨áÙøK±ú+ÿùÛÁÔÅfasÐÏ_‚þUþþí…«r>žI‡â¯ôïß¼\i£‡cý-åדUQÌÿ*ÿv@Û;\¯&:B¦t›…&|*a«~¾,ŠÙËbI}r™Ù=úS!pº‚Ž õ·[˜,ÛUçÃÞÙœÃÔ.`CƒbÖšP¢ãà k¼üè—}Šwµ4ùã£rÄmc¯%pÛ(§õíù/!áoí—=.5´o°ÖmÊÖ¶#åÌ5ª@°v"Àµ 2ùgÊå•b¤Ïô6]ß^¥‚ aXnEȶì•BÉãi1Ù]¨£—¤lÛA£-Œ‡ÐhàSGkŠ „îÞÛ-Vj4ÈÛ&wÓ#_ž[¨”·ÉÝÔôü· ç¿Uz~·XÖtL©5ýÆ¥Mj7 V•¶O£Ñ+‰éÏ}£üžÂ4Y*¡îD óúæ¤l0¡2n=™–ik’›™u3à&šu«i‹5Žǽ0åéàÛ(å÷ƒ§½.™&? )†Äþ{õ¯ýÏ›DÜ|QV·ÇïšônI‹¯E\øùL5=Ç‹.–wÙ xœ^xÿè/!£…øPô'¦Óxí¾ØÉÜ­v%þ€üìG¬å6óáŒÙ9[Ï -©öë­¼ ™x/z+&×pDmú¨ÅÒ3S."¡÷u¥* a|C“È;aXÕU§8ÜP,yG€"\S8{]ã .ô®‹§b¯óÜæ¶U{QÙ¯w:ô üUöõµžçA©º",±à}|@î n7¨ñmT9žD꺀x¦”»€ªs’ ŠB§È”SòõíÑmžÝÄ nt¡/Úxf°î Nnk‰Ê%äúá¥g ³ïlør-Ú76lš¡†Ìè÷u²_-sŽªE†¸Îž•U}`†ÇøÁdÂpJp›¨Ô;¨ÛŒL…Ù™Ùw$C`ôb;¿ª® ÷p쇼 ¾0ˆÌ *pSÈi·9V"vReÙ,bÔk†YåÐû@£Þp¤5’Â#Ô•#»Î±AdÉh¨urC͘÷ˆvðL;ªȪ‹Ó3x’Õ%*°g¶$SƒÏ%Œd®œ]VAµrUÖ´p|ÏÆ…T—uÈT^ÍñòŠUžšF…¤ï%Ïð®7ÐV*ƒ³Lö   Ìà/Ÿì³³jûE ’b®@2kÏÐP˜v PÁ ÄY×Ì×.—³€¥ <þx2¶ EbÓ= ùè.Ïéî&8o¯×ë×iÕKè7ÐÄU’ÑÏY1†“X’¯7É?cQΉÎ/Õ¥aö(¯;v±ÐVÆï×=S§pè+M·jiíTÓ‰=U¿®ŽÊÖû"÷ÔƒAÊÔÂÁ^¹Ã±^÷GÔÉ\rìX½©½žpÐ óðšq­(T…ʤVø¤òt~ Ü€wš)¯ÆOH–|±ƒA¯Ö¨œ‘±Åa+|¨Oß#K?àÒ—è¹ýO›ÚY› ¡QóçÅjúÀ9o¯‚Þ~ûus ¢H( ¸—sÚƒ¾I n[ƒŸAŒ(y &…ˆ½Î;ê -~Ò¼ :eƵ^—³ *aªè0@ö®NaM> …÷¿0NXäT`@¯¾Ôì’ .­$­âÁ%2Wpœ”K2\uu»èçGÇjE††…u»‰Ø´J°ÃEŸz”¤Ë$4:ªß•~|;‡Õ·¾0D¬0,ØôÀ§Õ#5Ñ ¬ŽKì°Þ¦XØZÌeˆJˆ¾áú…ûL"k¾YÎ î-& Z^&@“ë5XÒy}Cß¹šæÉ3¤>fyÉA‚ âKÊ+$ŸLR"œE/ÿF7O~Gg;´±u„šÌoÏñ{·:Ýž_†ØûZtïF07¤÷`™R7$ã Dvnð%$*%”!«>]GJ>Ð_1¨ûíÓF£Y3Å iêSª{üþi²|8†)~Â#{ïlû÷a¦Åyjý¡§µÎÆ Û @¢”Uû°€²î:ÉÉFÌÑøà<¨*F‰BÀHÔ³H_wÒ¼páÔß]?ní]«ì·¶l7+.êöu3òèþ‹w½ÙlÝæ¯^ÐË#Â÷¼{°Ä´÷{LñÊy’Í®W=OÎCN• I«bKm©e˜\’׬]¼ãþŒ¸.9¸IŠšûÒ´/Ô¾öÁ6Ú‹©¹ôEè T.&Y‚n­F…VJd;AE…ª‘ˆ2 IŒ3ëC»ó|^ý!®gQ‹ÍUЬ ¾FYÍcÎiÕë@x ÀM$UÑQ»…ê…£úÔàD•û Ý+¾¾Kmâõa$¶j©è¶×|—à–öÎçöDaýXÂÞ=‡2§C+Bˆöíö8†×R&ŒSÀÖ“¿w|DÐu r íIÝA Í8>Ø\¢ZʉÇ ÁE›£ˆžË%‚ìD§MòƇ¬ÌfbÙNÊ{lïœ}q¯K´”äÛçöä~È­t`Ð0wÎÈÕ†ŽÚ&X(!ÌM»¡»ÊPz½Ófþ"¹}÷f7Ä´9GÞqmÃ~ÐÂóøbç˜+ó\`däu¸®‡LL7¬mÏ”ùAj«Â~-$˜ò”#7À}ÆGn"å„+Lvè‚P|ÓU鬮¡Fø¬ø®L— ¸ÍDÁõ—‡TÍ0‘„²ZYêl·òãPß8¥½Â«G¿É)ßo‡žûu'Á=Ĺj q^SʪmZd¬ËKE@ó—_’zgTÈ-Y;Dá?æž¾¿ø9b$r¬&—Jr0˪4vÓ*@–´(—ÖQœ{’ D”ô`¹_æ)õ6>[þ?íÓæ˜ÒHb±¼IGÍ?Â÷(Ãs€räðµåßéA›ÅlvÀÂ%?"s0=›ñ¤ÅX†:‰úu½ä¿(08^é@Ù£¶?±Vð¤øå@ô—z„?  Að_ÁYéë|ÎÁ¾é¡pÙcež°ÿGâÎp>ì&ø”N$æ™yS(|µçP+§ji´‘ÞZ9ÙujðL8Ô¾¤‹G¯Îeä-P'Ô=æš•;ñ›5“ËëùÇb•wšÍAï”ÿ¾o¦£Öiºå)þ<bÖpø~x:=9m‡“Ñð=üóm)~`éÚ»CÊÁóÖfÍÓáé)&o‡ð9J›§ë'üŸ°³öötµ=§OR@ô)ÆTë‚vBŽ»9{¥yS’¶æ`,½—×xˆÐ•:Yœ×À˜dZÌa7ëŽØÈÞL¼R6°ëêê7'åßÿnã9Äl·¾Ç €ceÓWð(·Z¿F}þ5öµ°øÊÙ JFMê¿ép‘×uhÎ Z‚Àß2A`ð@ðEW¨*ç—ÂNàô¹w=û<È_ü!§O:Þ4[/^W¹vébG2j1Ë/»Êƒ$ª•â ÜʺҘø0ºóÃWçøŽŠ 9BÍÆNmò€†0ÿùí‰t¤šXMQ| ©Ñxu³\ñaŠç¿®u½è{ûójAAŸ5ǽ9ÉŠ™,¿£±ÁPÊŽzŒV2qñ-9 –×,8$¨ƒ@ {Ór#_¥Õ¹{MÊ!õš^ öOs"VË» ²1:ÿ (£G'Ÿµo^òµ‚{ŠŠî̶]Rÿn7ƒ¬}Ž„¾n9YrÃM5ñ­ÕÀUÇû‰¦&ã›Ûh0‰ÜQO~;FI×à ¡1¸Åz=ÁÎŲI±ÍzÞo‘Á]¯:\.¡@Ó9¾ÿVÐ~·Ð Aáí͕դ^p¡ ?ÞK]*…"ävžç™@è5YöÒ1s­È+v Òè<ÄaHôÅòzs‹…Me1ׂD!ÔOòªÍ5Mƒ’ˆÛÝ •ª¬f âL.‡Vƒ·[#ö^B.¾nqq‘‡¬#? ÀŽ8˜×!Õ(D……Õ#ǵá­dbµ[ô8µZó¾ÖÆüPä+îs;Íв+ ¼iÒ¢àÕØï¸œ¯›}Ñ4 §ƒ(„ÉŽâü†áíÉ+Ç1¤‚,2º¬ü•™S<<÷û²ú×óò×ëâY ÓZ|äVK{þB«Q<7Èy‹ïŸ¡|j8•˜uéëT‰ÇñµXðôåìúƒ¦ÕìÆdÆNɼÞ*ƒ³L¬û   Ìà/Ÿì³³jûE ’b°@2kÍÐP˜v PÁ ÄYâˆ×.—³€_ô <þx2¶ Eƒ©ï¥ ïw»'ID¾X‹#¤9hNª8C:ÝXÐ?L^ú†ŒFM(‚¢‘Y7¬Âaƒ[(0IáÑz^®6P;©`|¼4rM³ɹø‚0=AÏJ:æ6¨ëT_¹>)¸…>Ÿy¿c„´‡Eв˜4þ­çYfœž&"IãkMMý†¿íœž¢˜˜0ɧ‘!ÌÄå—õZ!İã5::J0¨’L7¹IFK|*lÝ8#2°aIéÍÎ'‘Ý>Àâ½51—pŽâ?wvñlª"KVÎiPÙ|!ç1zIËñE^™À¼Õýaç€Cƒl<ÿòzq=Ÿò”Ù~³ >ç æbùK/l–J¸ã+¶üøbsvûa¡J¨OåîKælÚxŸóÐ7ÅU"‘NKŽÜ¯Ä©\q* °£ÐÓ=¯»=Wƒ2ük3FUñÔå)Öq»n¹U\H»*l+Ú??ú—Er=â¸C>‰ìhŒÒ€=HšÀ\F‡@tœ`6Ö þ˜5"óèK?‹ƒhfŠkßR ŽòMk4(E÷SÉvÍdü4nýhœ½N+1øì¢ö£fdJ—Ö5 á(CJµ£\o8=p›“7¼ôÐÐ0"6–ç>ï®uˆ‚€%¢ ÓwR›nbHÊ€=E Úž \­/Ð<`µøœœ|Vã†5IÙÁõ|ULsŒ;Š/…¢® ý!’Ôé³oÎU pË/Ž“7/“,ùé»_ÁŸwßý÷DH~ïöÍË^çw¨«ž~>½îv'Ý£Óë×ðßé9ÒVÚÉ^üðÝÉI#Šî/‡íC1R7å¨7y²·•8u²ïÞ½ûÖ;]﯀ùƒ^óôdÓoj m¶Ÿ ÒÓo·˜„­Áôz÷u >±“úã›`î½&>»o.·xý»¥Ç•Ó£ ½L:#THmÓévx:·Ž ÇÓ4t2À±:Ö,~Ý^l¶3©Í iµ”[9r½æ ¾‡a|CøùäÕŸ_¾ÅFöÍšëã\©j°NUƒuÚ„ŸO6OiTw™#Ò…õ?Ž—½Ûº÷q£7t¹4«”{·î6t&Ûâžß·çY4.[‰oÀË( ƒÈÓëŸá7H ³L`; ¡pÊæ®ÈÖÓ¿t¼Hf.ï§Å&.Kµ‰ˆára (4­0O:RõI'ý}ð]ŠÌ¿8æpí ÊÅõú¤ä OÆHUu_¡ÄJ ÑdØÒv¯q+ 'D¡‡Å4î5$]ލ]G¼äDÀ’^-¦–xYòü[½¾í¹ºt»×cïjÔ¼8d@èßàØëÜ‚\|¥öC— õ\T˜#­ß8ÊÚÕDîEß;÷aË ëºkY­´ªjz«´ZÜÎëy>-W/ð§Z T—½n¥9ªþ´ ªù®u7}ü¤…û²C^Ï›‰‡@ÂãÕAúYºNT€éþçÿoçR¯˜ô]†òíž¹¨“ŒEcUÆùþË›i%–³ÙU\„uœçL«®ëQ´NÌ!Ôjÿp@äúI Gýˆ¼úD$½ŸØY׌,ܽ±²ÀÐz¯0ˆ.‚'³Xa5<‰ÅG¯˜cP²é>‘jZÒ,SµÛÞ_-l.Ëé¶&òKÁ6&qÄqu_%}3ËÕQѸRÄ“Fž¤un«¾Må§ë†q(/y ýEp(_`ßÅ«¥/Çë°lVfe><ŒÑ™ZÔÓZ(ÆÓbUßaçòtÚ)ëZÉÿéfÇ´Ø¥;Ï#HÊè]¸£<{FÔCqGçÀUC¿UÈ0*®îæ;ª8oô¨ÛDí¨$çQòÔßQƒ½øcˆ¨`ß1Ì‹+°é鎜T¹×»UêààÑ}’X7u÷Ž÷–ëîÂòä|í>P^ଷ’UæD©ì¾'Ù*ˆ|ÜÊ¿“a'07Ú z(a$^BÔ)“Å5´Ù%$$ˆHæèÇä~=´vË%ñ“™­õ‚`‹膧“.ÏÏópœG$ 7-*ëNÓ-Œ©ÿâ 7øÝ¡o”WIU÷fb[öªæ}õPQQN½š"–<«º+ÈäI©¬ f÷ÚM¤y¨é¥ HЗÆÃñëc÷­:ɞαPŒ)@H¢åÞ× m|ÛÁTzP›Ê';)a95Ÿ°ë}?~O´K­$É 1‚GìZ®‚ òÌ2@îC©Æažôôwž ô5jjÁe<Ñÿò5æ#we@ä©`R_šM¿¸±FƒGt(2IÏŒi ¯ž†y¿c ˆç®Ð7®\äó‡°'ü®¯˜(Tfºa O—kSÝÌÖo»ZÉQ¢züP¢{Àÿ4<à=·ö›Îx )–¼y(¼ök­2«ã[m=Îk¯׫IÑê4‡Ã÷§C¼oMùw~§iGJ¤ý: Ût§ùÞZ´\ÕÖŽN­R¥y:m¥öMIz°ëÚ3ãø°dŽºè«KþµDj1›¿'':“¶[úÌ©Œ±¥'1¶Gäò]‰c*µöØÊU¬É§0d÷ï(ßž^wETnÓÍ2‰k QkÜjZ¬5~Å“gRk†<€Ã&`E^Þʹ}°;dm1Ï:ý8e‹v¼b©™{êX•:½IrjØ·ÁS*À_\áÙ®O›ü¼X— ÒU7*ƒ³LµÖ   Ìà/Ÿì³³jûE ’b²@2kËÐP˜v PÁ ÄYíD×.—³€í- <þ~2¶ FÏÎXm<ÞU ¸•³ÝM¢ÙHžŸEŽ¡zigÓƒ£ãÞ±ì.ßY°y–6~¥1LÕÙ  µJàßÝÛ·@OÙÿ„w-?* $g i†àc¾ S¥ “y´þçíæ9!}Sü ½î›cð>Í2Hyè<ƒJv¦cE•°#l¦Ù:ÛW¨Ï-áiu²¯60‰®M|5ŸrÒYTî,LÄr”äÖ³)¿GÛ¨ñêËÏ‹r¾Y79ïäÝwz÷Ë»·¿¼úé¥ 6ýÊ5òn‰*ÏâajÈpU$7Y R¨O&Qg’±6Wï÷<úô{"<-Ïâ˛ݕ@{bÊñ¯RÞÒÐùè°ÆM £Tå"Êvk&ÓòS’få4OÖ“U¹ÜàA ÇòK4{F¶ó]y%v¢øã»È“gcæ^'­rÚJwž'¼z‹Åfg¼ÿ>æB+ëbµùžâ–5±ÝŒ’½°•D6º.§©0)x Ý~óÒ˜¸ýï¼…èLÍ…­ó%«¾®÷X÷þ:ÊU7L»tÛíßñ¦{ï¾Ñ ©H+(¿Ê¸*bEÝÐj ñè5|('Îé…x'ÿS }GëÍ>˜´à„)aGNÈÊqÎSÀ»—]÷£rþEV£˜O¹í¨ô‹Å—©ð Šï´½6Ž<å@ÈÝsJ9ö˜ T/գ˵'z³zµDbKzüÍA¨}€ê;Ìxp_ç`q÷áîs´¾ËÿîñógñóDaæ·+{iJ…ÉÞĈµ§¨šûa•ß%x/7·i8_g:˜=Munµ,‘ù5Ìwhƒ#Þb6—Vþ“= -(—¤nÈ¿{uòÁ¹ôàŒÀ ŠS›Ië:Ä´š ˜_ìsKÕAdWv·ÝëJ+΋;œC÷Uv®v*oç$u+ „”ǺX+2:@ï~ß¿ïŠoó ëj©¥š¾ä£éîŸ ª§åׯ+|ëÊâåËAk ‰ÏãM§U?¬Pž^Uµ;¯™»–+¡¢÷”S|åP£–ÒíjóØ´iœ}œŸD7KH—¤}O)å8‹íxvÉû¬•üd¬½R?\mÇðY³8Ì `ýöÏ1ÌtLãzf7wVŒ²òH|iÔf‰ï¹UWì•ÙjIåºÐ‚ÀP;ÿîG5,é±hضÓC›–ðæ*h¤V1 г1K\ïÑLC‹dµb0|¸ZDþ·$bAöµ«¢»é: U =„ C":¨¬šÒ ÄåJÏp>Õu}ðÂòå ß/¢ºC)ÊÂjOÑÜ«œ8þoÁ³4¦æÁ`rÖhP}ÂÀÿ„º=1[î³Á9†f¨‰î‰09e±u$§cZ¯›V…¹¨ “±òH7®$,N—ÌþS.èÀîŽqÔMhõ—«AãŸ&šcº¶Ž£B¤·ÔMˇ›s*Az*Ið9WcGD† Èì± ¥ÛÙ.j.…“pÂBÆ”€d̽Â@Sò…\Wt¦å’.Òac”Í&½Ä¿Éj.ïµ;3kÞµYó‰OÙ¿ï"¶æq,Mu;Mêõ%ÀNÀ¿òHòÊõ|SÎòΟñÏ7lÅ÷“k¼Î;¨–—„-¦P)ú…l2”¦hån;Y'#=u½Î\ª™ÏŸÃÍFÑä~½ÏÊó@ÿ±(–6¦ ¹è y£:)txæÛaUrxè0—l¦{v¡öDúâºg~S¿J‘ýðë:‚î å–¬{ŸWÌl_ß»¯rå—r}R^-gò°ìn¸Ê¦ð«£ƒÈiD‘ï*ƒ³Li BB³³jûÌà/ŸìE4¼p@@ ‹ ÐP˜vÁ P×.—³ÄYò¢€€ÐUœ 2¶ G<þ~*ƒ³L¾9   Ìà/Ÿì³³jûE ’b³@2kÊÐP˜v PÁ ÄYò¢×.—³€¨ <þ2¶ F}_=«²ú**6ÌYÊ \?n¼Ú¶@­ ¿|_öÁÇTãÇÜ|²’ Åðö1…MîFä§6’²”õÆù–’˜@Æ\™,PqaðØÕæç¹T?3íÌ5.•Ï$gåT›áŠ#l†sñ ~Îñ¼Oz¨A Íõ±S:\è·rÔ,=â²êua»PÜD}ODÇä.Ïžp‰åB 庵Cò ʤ‡vàç0v™&ѧÅ`ëk¸ D#l+l¿\ïnûÐ…¥r£ d´ñŒšprÃj£ëÀ ÆÑTG#…ÒÀã£ÈHÔga èßbßÞ¹YôÙÿþ5†eìúÏ«çûu¯° ªJ?”þld¦JRp²FæÙ¤’¾Â0ID`…ç,î4Í þ y=JBË*ÎU+£6B†©¼seÔ>ââRr øƒ,°O´=Ñ(Äø k%F)æÒÒAΗ%*ÀÆÀ¸é›â Ú5Ì —'e_q‹î„ç|x×ø®w˜$q»wð‰"¾Ä•¯‚<3ZàÿýгH®j„ktŸ¯ƒ…‚Bd mÇö¸+e†Î±F§œØá§Ç–î*’$ì›[~‘GÒLùŽ~7탷5G "Éc]¶Ò°òYðrm½Ä€eùÎÌâ¡›Ç=:åã\é‘ l–"ÒUÔœ#kUç`áùáÉi¹~Y®¡ý9™øk¬‘í6J‡Ö1}{O9J}<Ÿž3ãppéL&˜71 ã$G="/åèôœžT>dN‡DÛm”0`ÇQHÒÛz¯…=~Æ2þð±ÆÀüX]‹‹Årr]oT®hÒ¼< dbS_›¸ÿŠá3 jJŠâ±½ÓA˜oØ}.{ G³··äáÀJ=¼vììªýƒóPpÔ à+ªïÁo‚§‹¨ξzybW`×äšSîÁ)ÕŒPÔÜïè‹c™R´¯hÐ^ ß1í¹‹U•",ÏWäOËZi"ÔÛhê_XRVÝL•¨ÕËw/­hÝÝx ´&è±ò[æÅ>~šs®«€‡ Kè|ê’ñ§áš(KžAv ãnjN Êw0”+§±âÌs÷  Õ•Ä<äg%mÁí6TD|XÚhXåB0¡•\Ä4V:£þX@ 2‚t`…§hÈë…^ïÚ7x¼òô Wuí|é/)v’ün&-üh%iR9†éêCx,ÓTJnt‘—¦è^t fä…×öÚÔˆ²±k F¡n¯ŠÍ#¢Ž¯Òo:e¶Ú°åAÞq@ß›³ÅFþŒþb) |o¿œ~nõ¡È|Á÷gl ´}ÆÖžÛgÜó3~]tûl½ù2+° õóìȬ4|Ÿ¶9üV?Ðv …ÏIfÅÙÆ»ç+ Ç ú_ø¸ËòÚäÓG…[Éóg¤‰ð ]è>¯ÆKzá†Ç×gÉ3 ±®/,æõ×ãç@2žu8ÿy2ÊfÅÐ ®u^³)°Ÿ*ƒ³L:   Ìà/Ÿì³³jûE ’b´@2kÉÐP˜v PÁ ÄYø×.—³€£5 <þ2¶ F\ƀˆeåBtˆåò²W½áS—ÇP–"ôÓ…f¾‹>Û¬¤øêyMXþšö]AȾX-®—Ü„û2 ñèáäábôc”ý2•ç‡Ý µ`Éè®/Åçd©¥Ü$„]>#•û:Ç{ýÒQø„1UöÅ¢¾©KŸA1ãâ§}_OŠU9ž•ž\ ëðsœÜ´üôŒ®Ýq~ôcäùo£ =l«ê’×AÖ¾G¿J¬fçNUFò¦FŸÚ0–™ÏJS~ìÅÜðaú¡}NLøº`4èÔ $ÛA5Uâ„jü#¾ºR~'ƒ¼k S/žiåØãˆ„‰0Xa\“£¬{ ¼(SE . "û–Wc¬vÆi»øµÙ¥W?ðq@ºô-&–1*4YtO¡Ý=¢Ì@‡a.šé‰sXLE Ñy\èíjà|®k€øL³,®,CôŽì Ú¨ü¯[j~çÂìnkÇÞp¼}N;A¿ØPK¿œvÑ%Xñ¡ä¡¤ß)¦ÆðØ7Θ(ïõ]ÏÃ#½°êqâf s’ ¿†„„×°c¹=ýK -«\ñÚ‡i’šƒf¼k8ÓÅÕãy¹ô¼2©¦ã;#Ù±9!éIŒU¥Htw"yþ¯í8Ø~N»І4~ ¹ºBüìö¾g üä†Ò>'°t­p´0Í!qî¥;+gA õ¼ "`òøùézÔ:í¤(Ù>ΓoŽ“ç}©ªœŒŒBPð“l•÷{£9ècTòö  |¥^,–_äµ\¤#¤øªÉà{zD.zìÃ}Ð…9ÀÀ# ù >¨#q=ŸP^‹ûMtÀß `ÑïG$Ú±‰$©’\”´Ìt   Ìà/Ÿì³³jûE ’bµ@2kÈÐP˜v PÁ ÄYý^×.—³€—… <þ2¶ Fàgù¼‹ß2 ˆ™À*b ân =@B†¬§©Ä­»³&’—€;'ô»Â¤;ó 2 —d@´÷2˜&™¤ƒ}ÂĆõ0€Èr;k>jâ›-ÕSŽëÃvŠn¬—‰Zˆý¼õ^žÕ'È­nD|¨&½ä%?|¸?ã¾%ž‹Èîos|mAVÉ&ü—z©>Þ-ßÐ!ÿà·TמÅNoÅèLš”çTûú)íÜÞUÐh}M—GÒ}–>šSÿ;½$l ¥Q}*M’Ãä¤6 @ %˜S(%l‚­G‹ÛüKO¦éb’“‰Ðš ‘ ôG¬y×ôžSÁ÷Y >uè"¤\èû†î,’4)þìÇO Bîn*¼¿T©áþý™ˆlpÊi¥ɆL<—Ðo~öδ@€´J=²y´%ùº×$ð«ŽNÚ,}7çÐQ_f)P¡êV0Ô{ð‚BqϯƒÁiyŽÊ,‚a9JG¡5xÓùÓ¦Š'=÷ëÎ\@i¸1£0¦:d%ªiÅ$ù™dVÃÖsª?NýŽT~ª%Ö ïj6.¶`AâPÎdz=v,U ๸Oe9¼ùŸe{¤®H6ŽßWþË#N_NêœFþú&kjžÝ«:®s´Óx̓rÌâ‘q£w@ðý‹^R€$£+‹áˆÚÁLs0›jNrŸ-Œ ÖX—׿Ð>­Rœ­nuWì÷ä<$ù†¿=:ú`µþºË?Œ2e¡M«7`ú5o‡R^óSwRÞ§Ö!v‡VOp˜—ÓÜÞìÀçšf< "¡ÍB`§ê²Æ1Úø:˜Mc Ùš‰ ÞJ<2YøœáJ\¾…‘«ŠP\.ÓpHÈ$ršñ6Õޡ·ñ§±VOoUÊ‘p,TÙ²õ²˜”cç3Àܾ$f,c¼ºY3¿È#42¿îl˜²¦wxÁ&ˆk-§°PD¢Ñ Ë)¥N½HS}ç4ÈDlãÁ׊1¢ãËQD{‡ç˜Îb¢Ë̦^°r›=˜µ“Âj§Fã.\¸œà¢ÌÑ Û@–o&³ëi‘wþ~4 ·™í9Ž£Á碼¸Ül@!ÊÍ—íß‹+4T,Ž—”ƒ–ƒãÙòrœwè>D˜bÑN¶’JyGpfÏãMÞ¡?ØÄt¼¾üŽ›9jÇG¥±AŠUÞi¿;úF,tgÿò&ï¼?œN[èå|“ÈRíM9¹“MÖë“ËÅçüv)A€›>[/f—$ûT®Ë³rêéûøz×p6[L>o -ü¥œÂA:L~(Î7p ÿ §‹æ{ëõiêõn±„œï›Íâ ²`3¾X\-¡—é šUšj|8ÿGY|&9¯’ÚŽëfd˜ùšà‹{ë5¥ý•ô_<N¨À É[hŸ ËocÑò'PÃ?#”*ƒ³L‰D   Ìà/Ÿì³³jûE ’b¶@2kÇÐP˜v PÁ ÄZ¼×.—³€wÄ <þ2¶ Fõ1!ã;±q ˆa•i`<ÁÐ,Íûì;‘ÌVÞ{Á¦åzõâäÄ×­QüF¹9AàÀ:#çÉò&ñ’ª2ªÀõXo*ÚÛ;q%‹ïÁkþ«›£›5OÊÙÿŒ—l·úÍ; Ï28fÖ¼¸¢H~ÖÕËÛé ñ¨súÉA‡­\ïK|•–Cöj£¡£PÂ`c»m$9›‡ëþ¦a¾™Ë ³ãnÚJð-ä§ñOÉ ,%ÑÔòsúÉq·Kvúæyhîƒ?œ†Å uÍ¥g ú¶xΉ1AÂ/$ΞãÊ©H&I{òÃKl¶ÁFÃ~¹Ö‰›ú°šf‘”ôIØ S™ú´FÐôTrazà.ßoj|Sð? G6Í–×—ÎeD  Áôôi*$iuXÇ㤠_dpžƒe´k Î@|˜\æaåÒמ#§^Ù ¤ð/¤+¹Y\Õ¸çç0?®n¤<%qÈXëŒb`%FµjU54°,2‘éBßG¹YÑ: \ާÈB'-Vg’ÆvÛžXÇp5^]”s¾œlÝפ®´(/iÝ?&™15ÐJF‰mH¯|b@RP2|pCÙ^s^׌ åÆãÍ%0¦7ÍnF?WøI@ rL×ÇÈGŒrv¢¡SYe1ÿ¯¢ebž}"ûNç­ø2éÆõïñØBŽ %xa–‚ã¡·¿9ö¶ç«±s €Ç ?ïøà=OÚSœ¿Ð ù£/ÎaËÁVV>1æ&8¶ÄŽJOêI q`YrôÍq’Fï’<àY˜¼æŽÅdsô<ÿíŽC¶„‘¨S÷´‡=ü@G¶4&‹p ’°þϰ¸ ¡È¦MÃUT±CWŒ[‚e36!5˜CCw,×CH46[iˆQ]m†«É!˜ æ…Ä[(0¤øoÆí—sf«5r²¢ºžoÊ«âÄåöë“«ƒäÒ¾ÙÜOß²¡á¤ü{¸^\%=О0WZ–7Å GÒ"¾Ì´´o<ø8àA†´)¢ìÖ²Ž ÐæÄ\a!¤)%No!_NJOYdSÅ ¹Tr/;†÷±¬ÓØÙQµ5홯½Ú ¢ÃÆ ò’¨Il³(S ÎÎ<¦øÛyåÍÖË¥s]ÿèÙfåÈ7OÖH“ôû›àÑÓ£Ï]þs—ËχÔc"Ñ;5É|1/Ëž›i“4gçò¼ÅÍ7 T9%”çÃz’c˜¶ )Oœç\³½=]§O§þ~Þ¹(ɹ¯˜Pt/ôÆÊ;ÑÃn(’W_Ž\‹Õv:Þôâõ¶¸—³-d{{ærË¢ÌVŸÒÛ®06úv]ŒW“KhvFMo©öõj¶ý\¡“ëÈìùé ÙØ~ƒ‚õ¯ìÔx:@7Á5HΧƒm#ý%o?qE :ú#ž~nõR˜Õ)H×ïO;ƒß±oáÓnÞù—§]µSÁE¬i?k‚3a²ß‚ÐxFî‹vzÉ ²ój¨ êʘ¶@1£l?Œ DÌ_•ŸŸçPÃ3æüV+¤cp)5«Ïk(H.ȘiÃ}„‹ÏífŸJôÊLòß_½Kä®k|µÞa'™ÞJ#ç”>ÿÉkí>%Ï»Š‘)&Iô%m‹e|{üa|s"<úú·7ø:$Ø®>÷ç·'ïðàzäÌŠf¦vóæÛÃ%Ã=§©B‰µ—à½EBß=]ÑÛ‘x…×ì›ñæZfô“nD®I7R‚O›/6W‹)FýÂÛ%o¶¤k£1K86oçyâ¬â 8Q×K  ¤Â*ƒ³L5K   Ìà/Ÿì³³jûE ’b·@2kÆÐP˜v PÁ ÄZ×.—³€‰ñ <þ2¶ FöÇ+ïI´¨MÃð\¨| +¹ûbEK¶ÃDIÀ™q ãJ2;ô“feit ‚µ¸1Ö8Ò‹GHìJ;7Ó¥íòlj¬Ö;2Q«Ã¿WÙ|ɉ>hÕ`_¶¹9½¯Í›N_Œm4Ô‰‰l ¶ÛˆŠo¯µvyƒI É#E)êZâBþ°úä4Èbv MtÌåw°è­t·ýxº(sx ,ñÛ‹wøábÒãË£Wè µ$Þ¿ööæÊ%ñ¹§EJh;â;ük±¤/dÏÐÇ+|Äóyðo´ € Ñ®Ìfa¯óæ.ÿ<\´3ÄýEv^>áÂ>‘ŠûÔøÞx‘®mjÉÙܤ·DQø"EkõÃ2}Rµ +¢?S¢0DB3%:DZh$B-znDŽ a5rƒ)°AY8¿›ÃNq‘0Ÿ_¤ÖfÝÅ7ø?NÞþ´.»Ú —|X/æ]f±þ¯óíÝ^ áÿmP–3åzim‚ùˆ1\'!UÍ)”¹²¾)úîÑA3[LÆØ$=]Ìgã…óÍ rˆ‹(AxVr¥ÎÍÑçÏŸð¡‰#h¬˜O€Îq Å×¥ +jk¼þ2ŸðÏ›ËUO¢¨þõÇþ¸Ù,ÿTƒ´Æ÷&%݉Bž¯vH/rΠóíöP }7Áȶ• Sƒ*ÝÄ·Wj;jqŽƒ°û¦NÐ~3ù±œ¬ëÅù†{÷îgÄ.s?C½ûrP½¹šE@ºšeävŽ¿vpáÛM>Íÿ{ñ…gv`1¡"wئH¶ ¹ás»p4—óÄ#Hžtž$wü4ñÂônï²b3¾À¿ˆ)HhssâpŽx—<Äsö‹ùRñ`C¾û[‡ 3[ålhØ\1_ë²½2AƇŒ ŒFæðÑGô¡Ü€ñ夽ã´,bæØæ¶­{)šRâøjL½#¾l HŸ6òÑØümåMlÞ i$=ÕÓ$P«Ûm¢àÔ$XÕÇ!Õ˜N„vÉŒ$aÀZÔÁ=í?2³cjºkÒ l\ueÛmeê@³°Ó\:!=o·Ma ä¾VË,a<–u†Ãö³$ÇZP¹…^p) EúwQ;OÙ7åyHÅFyðµÝú°WK¹ÍÆ'`„ê)G?Æü’¹ù ŠX’‚ÐÆé-þ˜2¬wÝ¢È,ñ5¬>éänõ[¢¡sM-B‰¼;<î’œµf!Ü=)$Ú ù €u³˜>%˜"ð¡l«)¯ˆ jïE÷„Ûèq$s³Ã1=dçpMm…O5ï4:&ÒŽ¦ õ‹ `Á=ט¨¬ ´À€RºÜQä༡7ŽÑü¥I‡Ç#º¤_@^*‡Ùv˹OƒÜKàS ÊWÖÒÂu¡Ø±rvøKízÛ,#Vø;_#ªÎj–]¶8N´×« ¯,œS_\¢ ~£Ö: žÐwå«â½¾0WÜ”ª‹9©;ÜŒfúOÅ7õ¢{¢)y ‰n‚ Ÿ`añªð Hlx•Ú<ÝÁhsD£"ãìÚþБ²y ïhØ™\Î:ôíÙä¸Ë);0".2¬MXÍ…6ï\b~^z c*pc°0ð/™‡ðË\ÌѪ^CŸ¤˜¿…Ìöd:à2Zxø—x»Ì—ËÐ#fziµ§"î0¤†ó·ÛûŽ~fDy8€HÂÕýà€›÷9Â2À[UtJå¹²<–õ·¬Ð9ÚÕÉ›ó#-ytRÎ'ÐÓžFÿ3d°îoý'X¦#zà×µl+ŠyÞ¡Òúvþz$ 0Jö2LBN˜è[*ƒ³L›K   Ìà/Ÿì³³jûE ’b¸@2kÅÐP˜v PÁ ÄZ x×.—³€F$ <þ2¶ F}ÝïˆE*9ÂóD˜Ü¡O jS[Iv€fÏå:cØ4>äÖ⊉"7vâ¿Xû±†(AdëT,ÖqytPùý4~±t Ÿ-V¯ÔÎHn%[›|†4š‘5;Ÿé*×ø0äâšCdáÜn±N@’º«WÊ!…¢Ñ siv6Z;Ò„â¨ßóD 8íðcrœ‹¥å0M3T[àï£nøgB.TÑ(л((k›¸_==Ñ/§E{C$juýü^w÷6Xú§…Û¦MZBá ¬>´ç4¦D+¡É×ýZ•*K‘V|ÀNÈ7ž[ב­=þ¯VhBM%to½âQ÷¹§þ¨{ßWèpÍ©êO¬»Àz€IñÕ\ó~bQŒ;¦ •Ðn³vioí¾‘­ÂDsDñtÇ/pË}ßwX:wõúîWt”–jy&˜½T§©»Õl1i¡ñ U‘Qã{k~‹¾š•^ÉlÍ짺îÐ]Ûµ¬'ÓS‰…e#ÕG6§Ï?Û¯—¯~xõîU"¢Y/Ïý,v.éЊ€á#Á-AÍÈ=‡L@åùkùYO}Yft‘%ÙC#[ ™4#ðcç!è7I*ò{ÏÀW{ûWEo@§ÿáóÂLAó‰±A϶ô¶é4.Þ{%´;5ž¶«µ½ÆKχ¸…7Ú¿`Ë ðˆt äèƒ-Еub¨ý†A'Ny®ÐÍŠ‡Ç"Höº™!Ë~ô´µ½Îíö «Ñ¨K¹Ñü5}ÉçùÓn—Î"Ixöm·›ò¹éèâ·ÝßG)ÇOŸ~%u’þYtPs ûP¶é0,‘¶ 䦸ºJÙ© Œc“”Ôl»Ê¾‚<¾,µ-;Ä 8Läs›"–dïÕ2ŽT¶X]@èv€3g.^Ll6»¦!Œ÷–f‹Ðì3 áC]èv{¸!Îr²ñŘƛDirø0³Á­Û³ßô–’î+|è-úw½‡ÚSÖÇÈj˜'ûlô5Û‰òo“è’@} Œ54ŒÜX¥YíÔùÖ‚îÇ#MäºÀ{‘¦x[Û›j£%¨oÓxÐPËzqB;ÿÞä©·"ëNØdÀ>hU ¢’ñ“É ÈmÆ=7äQ¾”+ŸCÍ¡›(w]›íÌÍ%$²3ËIZZ¦•Xûœw‹¦ÁíÛ†i~øüš5gû™hŠx^‰›©¨U;Â\gè úw]Á{Ù*ƒ³L¨S BB³³jûÌà/ŸìE4e8@@`à ÐP˜vÁ P×.—³ÄZ¼€€ÐE 2¶ G<þ*ƒ³L· BB³³jûÌà/ŸìE4—'@@.Ô ÐP˜vÁ P×.—³ÄZ€xAy 2¶ G<þ*ƒ³LÑ BB³³jûÌà/ŸìE42@@µÉ ÐP˜vÁ P×.—³ÄZ x€€Ð:à 2¶ G<þ*ƒ³L þ   Ìà/Ÿì³³jûE ’b¹@2kÄÐP˜v PÁ ÄZÖ×.—³€ä} <þ…2¶ G¹ýv³Áb~xö±ÿ“Úø/Q¥—ÑÒÒFA×€§møÏÃTlí¿ S‘/Ðçþ9ô«u/´÷"ð?¶jù&|=O(8!“to23ÏÎçO g‹ÅLŸÏ:Ÿ³¯È=_í64Tý|ž:NüTƒÊ0Ä…—Ìm$_=ذ3<ɶ[ì°6 0<¤íÂBƒó¹>ŒÆ&Q%l«ž¸.ª­g ©Ö€‰Z1fÔŒCFxÅ'ÌUžŸýn£òfQµ•‘œÄ°úA2)PªžuÓ6ް)Q°Ý€n¥Do³¸«by&Åü0Ð!EÊc|c"¶ú^nÌ+fT°Y_qß-‘¥ݪqz¾|€;ÙHßË`e1\§ŸË‘¾Y¨ŸK*É,¶¤‘“¢b£!6Ï[“C¸ŠÑ(Ëz÷yf†Ãá±ÏäÒ8žAkÞE,å5L;R|F$&âJ› aêc18oÐCæsîë»´Z‰AæØØ ®î¯³òJÊv{{—┥Úð`%PФîH”°v<‡r¥^3¬\˜QY‰ðº^}{¤ŠE´æ½"mŠs¯ÊÉÑ8Iéé ÚÔž#"Š+.¹1×éB)bø”!YgæJO<¶!?<âMeØ ¹ó&vÕÅ MQ…´ÚäN‹Ãô  `kX/˜Ÿu‰Óëî4»ž—¾-~;‚Ó}M *&ãyŸbl}1šÐÜv{œ¶°XŸ»ojbÇ $}B™ýJ ”ÌÕyÈí<€FÚtß§£<÷ŽÓ'—¶¸Eà ›5°ÒMJÈ &£ðŠ²Ñ¬•¬¬i2=´K¶Å›…1åÃЫGâ“],6‹WÐ+›] ବø‹¼ª\yÁ>"\Í!©6k.σp+>°J‰UJŒƒÒ&e"Ï*thkcŽ—+¢a¡I‹òr‰O!«ÇÌ¡¯FVË´rŽE6»·ëàäËÅçy/ŽÓŒrþ¼ì¬—¦¿cÆ":>!É7óž;Ƹ=>>ß^oL5Xy…Ž,÷ðŠ8È:f‘4+‡gU0•‰Ït9ñ=<=“(ó ¯ª²÷€›¹õÎ@ÞÏçF!t¯Ê6Q ÔÜåôzEšØžA϶Àm(v×g¥ZöŽH¹¶è¼WnÐÃiÐí©öÀ–ñq6½çëÒ¸èLw¹#ÿ,€æ»[g>M€Í¶GXß~D7P˜E{è.šƒ#Ýâs-w*¦|Þ-fÓàÀ¼ëû#Cþ3|o1ŒÇبú—Ùœ#‡þt¯Þ{ sMmaê“%ùÝ϶í¬Úl‘Oðd±n.ŸÐϟߤ§i«ÛþCú‹¶´"òò¼Ç{ øf‡_³/„ò’¤y}çî@â'bq:_Y¤á’m´ôHoíUËJ¤÷¼½^NÆÓ÷Ô6Ö›"%ù…hs4æÞ>ëc#š üÐ :Ä0lÊY5È–ú#ÍÑòCAjÈyÿC•=\B»"‹“[¶ Ø[§N¡jüxUC'6Q6E”`*‰½`Õ¡Å”Q«¢:ßwáå p™±¡‘ºqÕh¬žwá¿Áª·Ó…¾¦%q›ÏøÌ5 X-®Pþ¡“YY38ñ²Wl}bŽ¥; Ø,ø7±(øˆ§¢h’ûFk—t¤Û»üe¡?IÝC)ĪK—ƒg*o7qÒ°7½¨+g.ÁÚP¸3VÊùü¹oÞÌAØCå¾Ç×M9ù˜Ë·*ƒ³LØþ   Ìà/Ÿì³³jûE ’bº@2kÃÐP˜v PÁ ÄZ4×.—³€Fo <þ…2¶ GÖº.Ú#ÒÖ C¤¥n=úáÃ(?Äî°{sF5èí Ù)ƒã^7“š«fÈÒԱʩýX—ó϶½c40˜‰™+ 3rpâ¼:µæ7R¦þ<ºÓC¬â­ÌÉ¡àj-Ò úMlFSăÆã8CAëjTIª6U¢õ*?bì6%ˆYNÄ5…’“¡s¡¤çÖPe½]Z2^êF·Ž„B¡üß«V¢·½Ëëù!DúQ<}D§€…\Æte"*d‡ØåùùåîUÛêˬºA–|Ó¶SñÛâ™Ý;aqžoŽBÄíäœwjQéd ¡‡ÓµYrTÖæÙsÉÀ¨kS¹WgŽIßmâ@*Æ? 3¦¨„[-(>Œ”A£¦Ÿ9°`Ýì8«}Zw ´„{€mnà™>Ñq¤Ñ6÷²‰—q´,Gü³[¤þ½H¹U+cÚHå³@dôqyI0U±Ð GG,>òã¸ôÄ=-–M>‹y8¥Ðº+w~éáÖ×ÃÍÊX˜Z÷@\„“ì¿u» Ï­7½§ðÃù8ý¾Ûíd<Ï+ÜD»†$¤D¢‹ƒDÞµTGÅñ¡Fð9dnUy0Ø·µ¹yS~ÙsÑ$é©h"úÈÀzò·Y¹ÁWÜI`ÁßÊBDÙi}P玹^&À§Ì¨ú]iÑ0àýጟ໳j,Ë“µ ƒ"ûž}ˆ£{Ë=©Då]?I+œ®±°Ôš @[D9FtéÐ÷ºÈ`‚œ\›ï1tìë³²˜oþ„â5†¥ÜáFaÀÃÌÅ 6E#Ë›œ¹÷5iœ[F³í·ôKži¬LÝ+" ï°(õ#÷’y^2ˆÃ‡K-cÀ,„ž|—sà ÕB¸¢IMOÅÆ@ôø ½¢·:›Pkï`—H©¶KÁ{œéûÝ•âm',IANš†i´áo‹Ô­íåø¢øOÖ ‚× Jþ¸˜3 %Iͯ'«Ålæ‡ã¾Ó#7²Œé`/øÃtóׯìÆÌÂ'hG¦Gœì‘Øn¤ãþs׿ c‹ýŒ¹aˆ*Gï7Nÿ™ƒð›=œ‚o |zÙ…èA(¬½ˆm Ü‹JûoÀ‹]ẠÝÕ«„—¢`¦ëðÖ¤ŠqPrØ:8qx7pîCæm¤Cáׯ˛bú³„Œm4*Slk8Y6½!ø³U1þ(Vìÿd`ôGJ7t¡$8ɽãåMŸEúùø9võüYÇüK³ù¯éý`TK å»ü/#È7 fÿOahüÏ ÿá·&"QØ­žD(­ CNcgœéf:öLÆÞÍx -‘H}òQ¾ü}s´Kÿ˜®_ŸÐ*ƒ³L 00Ìà/Ÿì³³jûE "b»@2m2ÐP˜v PÁ ÄZ’×.—³€J <þ…2¶ G¶ò"e”¶þ¼ŠN¹oμg§8–k1›¹™údóz¦}¯Ã–¦kÚè€É›Úƒ'@*ÿúâ;O›¼¹™úZ9Õr­­C2!D"‹ò‘óHžvú½–þÔz{ÚÝnk3Ž÷Œ£®ÿÄ­Á.S,*à§å賎ÿþjÇtŽ,Ì¡ô›9Wgròfþ½ãfófHÝ…çrt'eü³¾æµ8Ï£Zî±OM^MEÌ.Ž9ô%Í<¯í ­‹†%-;f•‹Âi{¾‹SÚ ¥êÿP\=ëw×d[j†zÏù”9©hÇ5kI|r‡rqûf–¢>6b‚›Ö¢¥ù½^½2fÅ$á=£`”d l›”åN0 ._7ŠƒF'üšX ýÕfdR¯ÞúSÅNweœ;õµ†|ÍJ?ʃâ üµ ÜåG® ~¥-ž /+Gl¾/ˆŸTòZ?Ô]£8 ‚ØJ]Ê1Cc³‘¼¾xõ ww5föîЊ"_ˆ8^¿ÙŠë!OÍji“ +œ‘Éjê³s‚ ÷ˆà[<Èœü`ÑØI”ÜÚ#õ®g ºöû ø{c©×nÈ…_6ïK;Ãö~ÂÍUû«4°³Õ{¨ÆŽfÈ`Û54Ä€.žݦ2$:¶ãº¬èB*˜dâÌ ¶ˆfÀ–@›„ûPÉã‘STã ¤DC쬘o—`‹‘ªô R«Á$Ý£3ˆ|#ë­ÅV¸”«bs¹˜’Cˆ$I‹¬n½ågÛ1oÝi7éçrÞW X² *Ö=ÓR£wKo¡­ (SÞF’)ω[ÍÃÝ£Ô¦ó`4`Wö;¼Æ±–ìn–ŸÐ©Ï¹‡a…› V= ÿ¥Óz"Å.ðϰ$Fïšô‚‚#µ«êGqv»´ô:Æí6(EO¿Ii~ôCÞ€ ^Ã0QêDA‚ÀyÓÀ½HKoeôœ¶E¬ÅÿŸÐ0*)‰7Ïû•{êiD’'ÿ¨žaL$và%LÍ+Aà j&Äè1ÆŽòz2€¯ïƾ$€®tAC£óÏo¤=ÆWÛÃâzSÓÓã¯ì‡+ ôiŽž{T¤Ú-½f¬5]¬Wc‡Û ËÙ¨¶dɳÃÒÚüMÏÈc  ’7yôdœWn<Ï<^£ViŒ.âä- §Íñ JI¢z•m’ðý,š`e¸]Â"½f¹SuT¯ïƒ¢KË–ŠJF¥rM®Ìä|å LÚã5÷”Õ"!› ¡Ÿ7›b"Bª.×U‡ï~÷šŽÑ%ÁGè1ý•H£Ü‹„l#$jÚÿ惧^,æç³¯Ðúÿ/È -•‡*ƒ³Lù BB³³jûÌà/ŸìE4Õ#@@ð× ÐP˜vÁ P×.—³ÄZ4€€Ð0 2¶ G<þ*ƒ³L BB³³jûÌà/ŸìE4e@@©– ÐP˜vÁ P×.—³ÄZ!€€~})  2¶ G<þ…+ƒ³LeûNN³³jûÌà/ŸìE@X<ÿKn  ë¬5,ñð<6enm wikipediaorg+ƒ³LÔ”Ìà/Ÿì³³jûEôo,@òÊ  5ë¬à8<6€enm wikipediaorgÀ  âm wikimediaÀÀ0jÐP˜À¢ýc0org afilias-nstinfoÀ¢ýa0À]À¢ýb2org afilias-nstÀÀ¢ýa2À]À¢ýd0À“À¢ýb0À“+ƒ³LΣNN³³jûÌà/ŸìE@Ö@@ð[ ÐP˜Á¢PËf-®°ÿÿÉŸ´ 2¶ K+ƒ³Lä^JJÌà/Ÿì³³jûE <@2ÔDÐP˜ PÁ¢Üè;Ëf-¯  £„j ÈÒ2¶ K +ƒ³L~BB³³jûÌà/ŸìE4L|@@yð ÐP˜Á¢PËf-¯Üè<€€Ðg× 2¶ LÈÒ+ƒ³L¤~³³jûÌà/ŸìEv@@¼( ÐP˜Á¢PËf-¯Üè<€€ÐT 2¶ LÈÒGET /wiki/::Home?wasRedirected=true HTTP/1.1 Host: en.m.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 Referer: http://en.wikipedia.org/wiki/Main_Page Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive +ƒ³Lí;BBÌà/Ÿì³³jûE 4íä@2ægÐP˜ PÁ¢Üè<Ëf/}€æÅ ÈØ2¶ L+ƒ³Lhd  Ìà/Ÿì³³jûE ’íå@2áÐP˜ PÁ¢Üè<Ëf/}€5ü ÈØ2¶ LHTTP/1.1 200 OK Date: Mon, 11 Oct 2010 21:35:39 GMT Server: Apache/2.2.14 (Ubuntu) X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.9.2 Status: 200 Vary: Accept-Encoding Content-Encoding: gzip Content-Length: 3442 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: text/html; charset=utf-8 ‹­ZmsÛ6þÞ_ãMNíŒ%ÚÎ¥Il‹7Š_.ž‹cí6½Oˆ„D4$Á då×ß³ßDÉn§½i'& ìbßÐÙß.nÏÿ{wÉ“¥ìî§Ÿ®Ï™7öý/¯Ï}ÿâñ‚ýòññæ;š²Ç’çZ©ržúþågy‰1ʼnï¯×ëÉúõD•KÿñÞ¢½Žhqý96½•“ØÄ^ðÝ™%Ër:JM9b)Ï—Ó‘ÈGì)KO¶F¹žŽv ½ÿÞí? ¾cì,<¦|iR|‘_e!bÉÏ|p“™0œÑvcñ[%WS/R¹¹›M!ß^Ý~útûÅÛ]ƦÌ[I±.TiÚ¥\ËØ$ÓX¬d$ÆvpÊdÅðt¬#žŠ)ô|Ê2þ$³*ëƒ*-J;æs€OR £y¼(R16ªŠ’±UÏ §1‘O²ÉºQŠÕápŤȗíÎn{•²0NTN'¿òwPÏZMÅ—˜êCîϧ^Oû¿þV‰r3ùU{Á™ï€Áÿs:ˆŒ8Yø‘3¿1ͳ¹Š75ÝX®˜ŒaؘåÈA{p-x%sõÔNaRfKÆS3}a©Zª‘Åt_ºŒ`†2³Ú_O–rÑÚ“]ºPeÆxDÔ0bQʵnH…s^’½šDaÓ%ì³[M¤ó¢2=ή¤H㑳Ò&ä7ŒŽß6¦ÝÀW<­0Üâ¨wÖ(އʕ :€·ÐævÆb.UÖ¨æ™4´È!õìÓ‰[±ö7µtë³ç|å¤HCqÕÂ𠯑çC»5GÎhíâ%*ŽC/øˆï–¯mv^&@ÊñONîy«ì%j¥Åhè9üg(öÐÿìI‚Xgq­F\Ì×%,{Ÿyf\æáÀ:“ãàQÅ|3ÒìJpS•"f³ÒH¨>pÜÃlvYÔh!wh[&7´b§Þ"UÜœ¤baN3^.e~r8y#2v8yoÿý'ýëõ7Âz^‡"'Û+™Š“›hYŠ¥*'¿ˆ9NžõÙ|1õ¾È4•êô²„%쳄›V:¼Õ"üÈs í¶‰5H욌£A ^šµú}Žö¹BÝ„ÿ¾{ó¦%å`Ì‚ÞÀIªØ)à·Ê²’ª‘¶šÊUQÊÜx{ËŒºø9±%ã«ã·:Vƒþ-‹µÞ.ñ§|·vR×ïcªå]ê ëÓ=…ûÏ·³ðüãõçˇË0•Õ“äj®Â¨TèTâªùO²b¿Xdd[¸÷ ªdÇïýße©®ãÿë{‹{øÁ>Ü©é«tk˜ÊFðãL}[éE¼'ͽÐ]Ü>½(#ÃÙ$¼@àTyÜ«©¾œMX38H=lLë`A_ðT„“v Ò(ºz3ìù´ ,¨·þBy`wçó¤„wª"q<ßI­Q?Å=Géaó=Œ ?ÕÁ;Šp"¾v•ÿž¦â3bMÞˆŒš†4¼+å7¢;¾„€U&£ð!’…VÇŠ]ÁšÌ®°ub½‚µ+‚?ŒJÜ­Sù§Ôÿ¸çXg-©–Óá,7H ýt“¬ öAmþA5°Ç i•V¶ùCÊÃÒðEš=ü¦ŽÚÏFlQu¦h;„¡ÉT%uþúÕì-W•ˆˆ|ùöÀ ?rM&ßö6Èpá çd§í6d 0èì6h`õH{ò1RŒ©èê%BsiÊM?/7s¬™ ¢ ¬E^Kh@à? «l¼[:5Ê{Áósm“”îÐü€’¹ßk6ã þpK‡Råó®A·ƒ€þ}Q —¨~PÓVz[ 8ØwªØåùò!”z[0€±èBDäY•ËH<µE+ƒ³LïŒ>>Ìà/Ÿì³³jûE 0íç@2âhÐP˜ PÁ¢ÜòøËf/}€Ú” ÈØ2¶ Lê ’ß'ê-Ù„ù}yÇÛÔ¦ú>ÞÌÆ‡G7€Êh€Âm [¤”wÚø·ÿ@݆û¶»i“p¶£ø°=*Ð!ÔCŽi°/B,5XDeôžÎçò‰ò®Ç]­ÚA ÁÖÐé"G;†È.YE_ÑD˜}G¹†ôÊœ»÷©ðý¶Ìvgµ…Ã,kp‚&ÿš.¯3TÐhhÅŽÅß U¤ÂÖÍ÷¢¨æ) ¼ú<‘9ï¥jBB‰Ü dJ@л[1 öþX¡Ü m¦ÃX,Ýrµ›ÚYæfY;$}0Ýe¯SÝî;ƈ¢+lŠ®=ÕY÷ÝÚà™ ¾/dd YôjÒæ”’2•þ¡ËÌw‚ôi3gK¦™Ë­vÚ%Ö&Ýö@M}³}•J©ô=/KaLøQ¤Ýþ7QÞβz–Õ³Á½"á&vÔÊ$榽âë® mW.˘Q÷Z•›K°|7y¦µ£×Ó12á2?qqàô囀î]˜˜ÏÑC¶M–CïKw¶}ÛÛ\ç'„Á,†}éÏm úû=õÝJiªÏ·n˜*kwià.ÜÖÚ÷ OOP1–T½‰þí2ýö,«gmî<)r3nটoÓ©ï8œßïû¶_;Ÿù³OpJ™áßðm”p2‘W£ýWÙ:ç Æ¼ý~÷Œž»×ÿµŸ©9lÿ¾.&ERü˨)á¿z={u|…ÿ‡«¢1þÐKXS°Ó¬€P²on¶{¿ýàƒG±úà^!Êl÷A¯U*šú©ƒoßC|ÝU` eŽqø„»^¸SÙ}‡v¯­ÅÆ:Ì(x„™ÛÔ¶âÒþÖÂùæVŠ=+ÐÁÍö²5A)ìý|x®2tèh­ |n;©ñC‚öv–ʯ"|=9 ÊéG#zŸ NôÝ£ YÍêÕ¬·Ú·«Çv9«WˆeFo F¿’ØL؃Ø=K{ÏbßÔÜ)Ú#=Òt’Ÿˆ!;¢PøS]½PbŠ…Àô¤Ó¼•"⬠ë/SòX ´[?.z†‘ 2v†]µSì:&.†r–CœôL ›·ºoný>„WÛß‚œÙŸßý¢4;‰%+ƒ³L¢¡BB³³jûÌà/ŸìE4ò@@Ô[ ÐP˜Á¢PËf/}Üòø€x\Ÿ 2¶ LÈØ+ƒ³LýªBB³³jûÌà/ŸìE47W@@ ÐP˜Á¢PËf/}Üöô€ÑXJ 2¶ LÈØ+ƒ³LÑqÒÒ³³jûÌà/ŸìEÄ 6@@»¦ ÐP˜Á¢PËf/}Üöô€€Ð õ 2¶ MÈØGET /stylesheets/iphone.css HTTP/1.1 Host: en.m.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: text/css,*/*;q=0.1 Referer: http://en.m.wikipedia.org/wiki/::Home?wasRedirected=true Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive +ƒ³Lñ£NN³³jûÌà/ŸìE@E<@@$ ÐP˜Á£Påú±"°ÿÿ+”´ 2¶ M+ƒ³L+¹NN³³jûÌà/ŸìE@¬@@@ ÐP˜Á¤P¿"³°ÿÿP´ 2¶ M+ƒ³L½H  Ìà/Ÿì³³jûE ’íè@2áÐP˜ PÁ¢ÜöôËf1 €T> Èå2¶ MHTTP/1.1 200 OK Date: Mon, 11 Oct 2010 21:35:39 GMT Server: Apache/2.2.14 (Ubuntu) Last-Modified: Sun, 26 Sep 2010 00:36:12 GMT ETag: "3802b3-1983-4911ecc735700" Accept-Ranges: bytes Vary: Accept-Encoding Content-Encoding: gzip Content-Length: 1702 Keep-Alive: timeout=2, max=99 Connection: Keep-Alive Content-Type: text/css ‹íXIoã6¾ûW¨1èbid»Îâ`zèôÞ[ƒ€i‹$ ÇSô¿÷qIÉN¦@ÑK3K,òíË÷ž<¨¨Iòç,I Æ1áiß¡’¶ûm’'_Ѧc\ VÜÃý‘bQm“ež¿»ÈKVרëÉ6±Ÿ"6M|ÝKÒ³šâd^–¥¼éÆJÓº{‘Ï â{Ú¦‚5À°ãä/¸Ð6 ¼°Ÿ*eð%Ù‘t_ŒsxàÏ5AHâé µŽøÔ}&XiÅ¢òiÏÙ¡ÅÛd¾»“Š´ZMˆ3Îvwbb#X·M¸d-z.Ø‹¶c­H{úò‘gw¤Ñü^êüì61¢2ŸRA… TäÓOðóð0²ÖËÄV&*Ø3)HÍŽNð8Og¹¥þnÚ¢Ÿág°Èø»Ú¼ÙøF-ß üv 1}þØ‹SM¾ýpeˆ¯>ÅìiMvbÜU>§û*&1úÞ¤9‚Š ¢šJ¡ã$=rÔMZ4­¦Ø<ã'żZC¶s†¢3Ÿfõºs„A»éá 軵üãqh­kgZB7QÍä¡em fΤ‰dz¶Ñvdžž|,¹¨ñ >‡9#^üXæòÃÕúêÓHP\¤Fêù²GuMøé‚/”Æ©Š… º“ÁCLû®F§mRÔ¬|ºù cbÂòX­ý‘«ÀÕ:6Ñ™Q¦Ëëœ Qš"–~Ù'´½ÅÉ) .;*È‹ˆ»HÍŽt¹ÒÃVñUŠjº©%iáAâ ÛC³W'ë”ë3ŸO6Âe.ìÀeà tŠÞUêÊUj¬ò úÒ¿¾€°_fþ€Ào÷d`q©¹äØ5Ó’nh«xL…¬ó\×álV‰¦VWÁä¿…É/¯ †uçÖ´%iE´ûK0AeÎó\gØØ»Ý½¹C ­¡){ÔöiO8UW0Æ9Àä1}Ù&Ř´ò4=’P9UnI[R„ÿ8ôK•EÝlY$¸^€‚Äüˆ¸ ¥ÁýÐÒìz£Ù¸¾=;ÖffŸ:!oëÔígk©™žÊrLJÆ‘ ¬5†áZÅ­.´}¦=Øc!ÌÒlÐúúîÚÒ RÐg‘ìºÉsKRÉpú•î[)!\FEÙ‰²–‰úeÕÛÇAŒQ±5L2½‚ÁßNR{>TÜh 0¢Šú  ÈÀ”§^—œž“ ü}~éªs^B ²üv(I†¡šÙ×äòdYæ;Ê{ñ+ART\ØËìÆ¤Ëd;¸³©ÌzRÊÐ=¢¶¬ïÍ^— JEæJO»o÷ëQÖqÚ ÖÖ'pZ>mµ iwhKaN d0Ù!8‡ƒß×w··¡~× ³qd-S €S0ŒNîàœ=w+ƒ³L#IÝÝÌà/Ÿì³³jûE Ïíé@2ãÇÐP˜ PÁ¢ÜüRËf1 €D´ Èå2¶ M¼ÒŸz²}išƒCp½Þ×åmÃ>Ÿ¹:3îÏ$/1SÐü¢mKxˆxv†xoŠ\%êdJÆkÚýH‚ÔkGëÄ,óÄ3UÆŽ6{­Rû~)†:ÔªÞÕñË_èÚ5Õþ(A©#<«XC’j9®é‰D:¨vs^ˬ€ÍgonÁ8ù/—ÿOjÖ P$;—‰êÞ—;pí‘lïÖh†0V›‡ãÍðDÛî †Çâõ 3@j›’fD­€Ô¹N[õC7Îæ=\VvsöRÀ‹­Í/-÷Õùr_ÙöL@ ÿ ¢i`©3¾Æòæ{öã Ñnè·Ú×_¿§ Ú“þ}Ÿíéî(””“à"pv;ÀÕjcͱ/¿7>™”Ô8ì0ÛxSwÿ,ŒãÂóg_ ”SLòcáGæl‰$Äç⦉Š}>¢¸X®£XÞ®Ý@ÛäN¦3Ù;ÃÄÓþgfM™KõA5_0Ù(kŽ Œ3¨n½¿ŒZÐã×gMü=Ötø&»{ÏÉÉ3«!}‹M 6‚¥qd®‚€£¥ ó’tH²‡‹ÁºhäA< ÅÄ5&‚åÊ~õæÙs3,ä.Yw承A‘Æf×p«Ìf¬Î8ÙNÚ’ôɰ3oøCÄbÖºán8…—¬¤B¯”æ4K¢‡ŸKgj÷ÔŸy01·F5ãb´d-fºrÝy¥Ç]oäÜ̃¹%¡Â+Ä1‘ƒ£ðÊ[ÍnV¯ S‹zå÷ Q¾«È“Ñ[zÕð+Wfþ]Y«;cÒÿ3ëßœY«•ólj¼±'>¸omä’•Õ¨Å=¬™$‰²ç¿qí%ž ˆWô›M´GiÔyI]‘iä ƒ+ƒ³LeJJÌà/Ÿì³³jûE <@2ÔDÐP˜ PÁ£Š Ì’åú±#  µj ¨Y2¶ M +ƒ³LEwBB³³jûÌà/ŸìE4ß8@@ç3 ÐP˜Á¢PËf1 Üþí€~ÑO³ 2¶ MÈå+ƒ³L\~JJÌà/Ÿì³³jûE <@2ÔDÐP˜ PÁ¤‰Í ¡¿"³  †³j ¨Z2¶ M +ƒ³L¹ BB³³jûÌà/ŸìE4WN@@o ÐP˜Á£Påú±#Š Ì“€€Ðyà 2¶ N¨Y+ƒ³L«BB³³jûÌà/ŸìE4´@@\ ÐP˜Á¤P¿"³‰Í ¢€€ÐK 2¶ N¨Z+ƒ³L0Çdz³jûÌà/ŸìE¹îR@@Ö” ÐP˜Á¤P¿"³‰Í ¢€€Ð¼R 2¶ N¨ZGET /javascripts/application.js HTTP/1.1 Host: en.m.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: */* Referer: http://en.m.wikipedia.org/wiki/::Home?wasRedirected=true Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive +ƒ³LÚ$³³jûÌà/ŸìE´Ì$@@øÇ ÐP˜Á£Påú±#Š Ì“€€Ð‡‹ 2¶ N¨YGET /javascripts/jquery.js HTTP/1.1 Host: en.m.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Accept: */* Referer: http://en.m.wikipedia.org/wiki/::Home?wasRedirected=true Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive +ƒ³LN½BBÌà/Ÿì³³jûE 4(À@2«ŒÐP˜ PÁ¤‰Í ¢¿"´†€Ê; ¨b2¶ N+ƒ³Lé„„Ìà/Ÿì³³jûE v(Á@2¦IÐP˜ PÁ¤‰Í ¢¿"´†€f ¨b2¶ NHTTP/1.1 200 OK Date: Mon, 11 Oct 2010 21:35:39 GMT Server: Apache/2.2.14 (Ubuntu) Last-Modified: Sun, 26 Sep 2010 00:36:12 GMT ETag: "10015e-912-4911ecc735700" Accept-Ranges: bytes Vary: Accept-Encoding Content-Encoding: gzip Content-Length: 994 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: application/javascript ‹•VÛn9 }Ÿ¯`å Ñ¤ÞqÚ·6È] ‹Í¢‹Mö­€!kèÁ²44v‚Eþ})ÉãKì´häBR‡yäÉÜ÷:hœõZ! –Æ%š€5¬[tÿÜÞ?€Chþ¾åÁa‡"(ZÍ&FµÂ©èºiÄ¨Ü Š›9<Ù–bàUcÔ\IaÈV˜)A7îž² }W*åVè¼²†ÌöÍŤ(Îxmeë*+‡¢~âóÞÈ@!¼ü¯8ãl¤mcYYI­äbÏ ÑŸ#ŒXQ@°M£‘—Wd.‹|ºýPyL'¦-á+Ó¼µ†`U?Â5tÂy¼1ŸñÐ*_V ~YVª¦j;-$r˜ Gø÷ú]9;{Ï Le¬—Ó\×tÆR+~\›VfAEÖ’¼jΓ·j…o+ej|¼ScX ××p JªÇá …žÎ­›Æð½“Ñž·5EÜ J[)bM?Kr*Åi”/f£ï<%·NQ”ÈW¿Êž¥­1]œ< 'Û?ꚥ€ì­VBóÞ —¢C¾g+˽¨ŒTÐxp¸ ËãÓɘŽÏñÇäâ¸F{” ŸvHöΑìÎ=&®CöÎlýtîAjA)BpjÖ‡´uÁ Æ …©S _qNÿZ·³|SMK¦Ø_2A­÷ç,5„Ùжٛø5#EX\¥Ø€~Ü ¦~ûø‹9¶ÝÌIž‹gbuwVmÄDäé˜âmGH6ÍÐÍÜÒ»†5’}¨?ѳMKš$_C·Ì^¿²bÒH¥¤aÛñpj›òîÄnGY‘ NÓ]Ä-î`Þ¬eŒ$9£µZQèலÑsFöJZz!L˜ÎhO,ÉAmÏUMZøÖýí[x³C¬”ççŸVÊ«™Æór+8?ÐÔÝÙSª:TrRU*«E–±Dñ~+_?´‘¯ôdŒ3ƒw{!$έÒ5UÍMV ó­]¿xz~¡U5 djËhhÁKŒ!v)hšh:^ ¤.D"¨R“€>àc &^<2Û":¾ä <ÝÔœhnTÕ>Ž-c›ÛŽŽüœÑï9Áùx¡¼eôÁa@”GuÊ[Dò(Õš2¯MZœØ ø÷ÛW˜ WÐàÑzîs«Û><„^šÆ|ƒÍšeÔË/Çð>ð?õQ#è +ƒ³LsÌBB³³jûÌà/ŸìE4†?@@@- ÐP˜Á¤P¿"´†‰Í%ä€Eˆ 2¶ N¨b+ƒ³LùìBBÌà/Ÿì³³jûE 4Äð@2\ÐP˜ PÁ£Š Ì“åú²£€ù ¨c2¶ N+ƒ³Lþ  Ìà/Ÿì³³jûE ’Äñ@2 ýÐP˜ PÁ£Š Ì“åú²£€3± ¨d2¶ NHTTP/1.1 200 OK Date: Mon, 11 Oct 2010 21:35:39 GMT Server: Apache/2.2.14 (Ubuntu) Last-Modified: Sun, 26 Sep 2010 00:36:12 GMT ETag: "10015f-d9de-4911ecc735700" Accept-Ranges: bytes Vary: Accept-Encoding Content-Encoding: gzip Content-Length: 16759 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: application/javascript ‹½}yŸÛÆ‘èÿù$¬p€!xÌØÙÍ’‚¸¶ìÄÎó‘µ´çq(ÿ0$8™hÔŒDN>û««/INöù—hˆ>ª¯êêªêªêÑùï:ç×ÿµOŠ·‹áåðß:ƒÎ÷É]çoñ›¤ó—øM\.‹tWA),ø<ß½-Ò›Ûªã/ƒÎåxüÇÎ_òÛ¬ócR¦7ÿõ¯g¸Ì·–þro:›t™de²êì³URtªÛ¤óÝ7/;>ü3øö›ç_}ÿâ«au_Q…8[uþü×o;>üãd*(åP:òä˸J&ÔƒÁøƒËÏ:ŸM./'ÿÞŒ?;þ‹¸ ;þ]ü–Š'TñÇäͤó‡ûãè{ô;½Ï–Ušg~pxŸy2¢»4[åwCþ ~¢žL±T[!]"Ò Ëd“,«¼—yV%0C‘Tû"ëd0Å\k¸Î†i–VͲÓjê×}ºüå«û]^Í_=]œûOýáñª úÏ‚ù«g‹ó'ÇWŸøWwýàÉ(LËév·I ìpþjòÉÕüj%F!Îþ:Í’ÕT7ɯ]‘Wyõv—DìÈä‘Þ«”Hý8Wùr¿M²jš®u…a–¯’—18T·i9/t…)& 7IvSÝFS™Lœ>ìF¾îèv"¯¬Š4»ñxq¶qµ¼ôŒ “ûd©[ ° T¢×ã¿ó‹ÅñØU½*ÒÝ„ÌÂr“Ä™?Wù ³ ɦL¨u¨±Ôx‡7Iõ$ÀÏ/Þ~³ÀŸ.¨X’šÃÃtÕt¶Œ˜[õƒ!,ÊÊ‚›Mp¦º¯óÅôáûó;·œêk•í@?diù§ú⵩ñsƒŸE¯ÞÎ<úãM¼M¯¼E³Ó´´eR}^ñ[Õä6þ%áÓâô!dR1ñˆæxa™¾K&ÖN´!2²@þ1‡0õ¦p¶ßšmµßF‘FõY£ /˜NBQ˜Ìp·/o_Tñò'½d|°‘µ% 6Lòæ‡ë×0˜ˆW‡?P¿ÏFüñ”ʘ­7Ä~ ãÝnà Msf„I¼¼5p—ñfs =ãâ¦ÔS cÆ¢ É-PE’{·{f´ƒ 6ñÔa±^ð™×n†¿akOðoH3 Àãª*¬µ‰·Iø&Þì“°"r€Íä;Ì+#ÌÄÍ‚áÌÈ`§ïyÓ¿ =@Õ¬5 ¬Æ{=îæÁ6¨)¹!‚– ¬Z=P¸]¡ÃŠèÆ <á“heõ'" üZ¢ê7&Ã0ÔÂñÞvIê› ºXÖé}¤Ö„á éÌʪ%3Äx`Òo݇rêˆYåÛïâ,Ýù@#iÂˈQ®c aTÖQ&Š.ÞOÔͤ:¹±i8.~KÛÜlÚA Míõæ¾\S‰èŠÌ@Û¨ù_W6®|`»msðaÍ3Ø•/Òë $Ü…GÖÀœèÇ£`Ò7sˆüT“!6;¬Œ4!ô½Ö[÷0uسPãˆÓÅø£ù«þ³E‡þ•)Œš×¦ãü‡µï ‡^ðlp¡¸ž}–Â9-ÜÇDø 8^X§ÿœnsþSjäÄð×E~³=Ü–iÒëu5WùÓwß©âÝǰ¨†F?™ŽÃrÄXÇp†—fz/ì´ï­Ò7p érÎÆ"h5>Y1ï¦FФéë—ß}»€@Nž¹­S¸ ¦ÛÈäÑRyçPÁlõ"Ù¬NÕ‰Ž"áÉý 勮ŧ8t6b(ÐŒOC Ë6}_[iÛÞÿTN[ê¹€• YÅUÌøèqÌ'21XqdddéUò-´½ ]çO¥§!¥ 㕬À<æÅ.;‹öTêUó|\§‡6˜]Ö¾/‘e;8¼šÛ²ÃTÕûùc• }S`¸ÝoªôOÔ7³eáÓYÞ"(Ó"Àí,­Ñk;:xt°';C$2`÷wu™öôeÒ’XûoÓ_-Ÿ‹„Òë©„y-gphnð¨@Cêw诮ß$¼V볚¬AÓ3ótLüt×èøDYµRæG§Qh¢šž¤¸a& …y?Ú‡3Ö>œIM3“G¤[´<ݹ®ž2¯§WJ¦ýÙ€ÞÆåóM\>šÇ–px}K€,¾©e$ ‘¯ ÙÒd†›­ñ’HKÍi€ëý=H.¼{/]4lmlwY¡ /§'[¶>A¢c,zï@ÊÓ#AÔ± ÂRtYdÏ:ÍѦCµc‹iL)>:  Ô 6²ÙZ5…j3…ršÙš `Ò&ü+)ÿ–V·§Zda ÉLÞæo@üE.þ׉Í9ªG¼%ðÓ0í_`Iú<Éñ룡®‰£j¶*N %DØ·¶\ªtkï9vÚ…‹QplfD‹tØ1_xj4È–Õ+ƒ³Ld   Ìà/Ÿì³³jûE ’Äó@2 ûÐP˜ PÁ£Š ×Oåú²£€¤i ¨d2¶ N¬…üV«. 1D(à!(Ô&­ðĦ”8¿XDêÇ õ1ñ¼i«RŽbkÌñ¼¹”`¾Ï÷àtý2  ¾×õÂ9¬3§êgaŸC”[gnQÅÐüd„Ë™XQµLð³E4Þû@ í6O梹Ý<¸™yÞnŒÎ_ÖWçC4CSWèJŠ60QãVñõ&&ß$HÔckRš°¬y~½ïŠRÛ‘Y ãF±ž«ÂÂ5–^ò©Ênk:‚¯_³Â Ïì´æŽjš2½ ™M`qe¼ª®ZW5åo_Æ7TØ«®óÕ[åCÖ:bfsu!Uª3+Í·¤j&Hy`+ ©c¶ÚQsU´нÅ©úˆ¯Gõºš’L5 ÝP=¿D˜‚ú[ÝEÙš£¶*ê@¸L„4ý¡Ü¡T0ÊL *8KÔ¾eÒu _–ßiÞÇË`¼Ïž>(œ¹‡†Wf^TB *ØjIéó‰0ù²Gt!we&Oöw¸J’]ÄÓ#¼.o7„ä2i_ä9îçà@U¸Ä´Ñä59M£Kûþ–‹9Wµ 5/díK·#8%Ð0Haò€Í¶]ñïÀ¹ã•ˆ"L—ÒE —J0¨_ÝÐì¶È¨ä.f™ïÞFÎõŒ™8U0;@ Sš1ËŽóÒëa²°FÝÅsn79kMÀBèÒñèS%c6_LuÐp¯øeKâ.tÌ5—Z¼xlO :©Èãx}ÂÅp¿OWÑ8d<^`EÂä~¹Ù¯’hônÀrÔq 0˜ÝÑÓ1ßÅË´z{|—çÛã:1˜ñmÔ(D[Ç ÔþOšÜ=Ÿ•HhãÎÁ!ËaÏ­ÿ²t+81ÁA›VüüDM}à_ˆÝ†«$A\©‰ ÌufDñu¦Wouµ½¬ì;El{=ø°vGW‹0¯æWå|1S E†Yg}·B¥­_·Z-C5;r²@Ë”ŒÇ‹¢F|dÉõ«s*©ÒîQ…u¡uCà¬ùDÜÁf§`À[NVloÛ$^µ™;Øg(–‘#Ô,²;ž‰ïIe¯:Áäø`¹ßC‡UþßÐçâyŒlQDWänjðáxM€ ÔØ{ÝRÈK¨/ø"1Lš™½Mç%ëWTFkªIœLWA==ê÷‘B¨ûz£ü§ÞÌÓ•Vë!騇NÕË Å¢ÕSjH™µ—›@'Ú9hkªûع¾A63<87I•tÚ»5ÅñfÚ6hÀ¸Üû…¦˜Úi²ôŠ™"ž­*ÞªFÝ~>,ÑšÈO SÄ >Wº§ -Ñ—úÿÄP…]>Éj6$u¦§1Vœ—ÔÚµµÏE­3Ý{ WñDS¼% ßœ!‡3AƒS˜X™GÝ\¶à4`óÛ:ª˜`ÓOš;åt§µzI掔«O•þÝmƒÕC©H‘]9uª÷ûÀù´’Séþ9ßÕv‰1ÉQÆ'Ê[+Ü\`é‹Üë[EÔëÔ#ò Œ‘X˜à¡Åœ—Ôƒ+½Ý½7ÕT¸Dm7Ôƒ£î§öuféZ{ø&ƒõ ¬ß]•ýQ`„°ÔÚÄ#‹Ä©rÃÛ¸är:ɸ9ý+ƒ³L›7 BB³³jûÌà/ŸìE4?@@‡e ÐP˜Á£Påú²£Š ×O€xnð 2¶ O¨d+ƒ³LÉ= BB³³jûÌà/ŸìE4¢Z@@$ ÐP˜Á£Påú²£Š Ü­€€Ðh: 2¶ O¨d+ƒ³LŽø   Ìà/Ÿì³³jûE ’Äô@2 úÐP˜ PÁ£Š Ü­åú²£€ÊF ¨j2¶ O¨Vtæu¼ ô§¯SlmÀ#ƒk“Ý\Б)ÞmÚ¿Ñe˜[áÄœX3"üQë˜Ö¬á£ÁÈë<Í|f€š"º¯85¬ú͸Rsš‰­õ˜Y¡NC¾JóÝuÅ›o$_å]\Gvu³àª>òÍ ¨“"äËÁIJ%Úu ©¯'Ô„†‡¦6/8ÙN–j·n fÎw€µdœ¥C'òÈ Ì;å“ypO+°‰”Ña——)1Â^|]æ8¼ðMZ¦×)ÌãÛ‰w›®VIæ…«f6†„ëM¾üÅ{ïnÓåmä46›{ß&ëÊ ½©±Ådî½ÌwðýE^UùÖ[aXÇ¿}M2름Y×õº„˜2±¾¦QLYU¹ZÁ’Ãas«¤ˆÆŽv…ºgkW¤|?²,â"剔óúÖMêñ8žr+ï­ÎŸvߣx2)Ø ¢ïâêvXä°-}Õ1®Èl›úÒÍÝ„Ö5\Ìœ£µ@ çв†TF“bjlßûc$òæÆ§¥ÿ.!®QÎ#è&"!!«µ)Ì:/ó `¹ÖÖtküz¯ã"U·\êc³K0DIãy¾Ýz®^`Òèe”]øs<¢•”ý+ÌpíoÉ,Ï÷¨œºHÌQÕÓJCGŠ8C_¶Š¤‘…º–m±€gÞ…7!ë…¦X‚½‰{=iWö’lÆ2~“D{˜ï+”˜§ÎWä;°3ÓUçzÄ«åbu=¨!™”û£5âç( j‘*Ê›Ik×ëQªü¶Gâ5V+<¶šæ´·íѧǬ0Ó7þüóÁÿ]x 9xrá!ÿ6¿ÓB é¢í–>!Hbå‘ÎE£!ÒÉobŒe#LKÛ /§K¼ÀÁqÄÜb5cÔù` /ÇQlk©ÎpŸ•·éºÂ|áM9ÝU\1 ÊAUpÀ†áW¤’xw ¦íÉ‘ÐhÚçQ ç`Á¦Ý:YoNÉËðJ}RŸ½™¬Ù*N Z©N#z¸}—BíÛTv­ ì6ãÊÀlÁ¾ÀY¬$ôD§æ] ü«;Dj´ÇFT3N†î‹Ñ£WW«¾¿»fOF)sº0@­ÑÕjdx8N…6àϰ(ñ€åæ‹}V¥Ûä…ζ'7;Ë¥ ؈Hçxª·ÿp—Þ'lŠXo»èc qïŒI›rÑ PÍóÁx)b?_L%-’¿®‘V¦Rž«/Š¢3Íßž50uƒrI&›sóû”Ùùc76Ö%éÛ,ûžòã Ì Û 3$VIŸ&­§°(åSòå"Ï®Yp5zVGÝu# «øÆ\Æ7Š ¿òãëëâÿúrL·7Ç4ƒýŒÊÙ_ŽÛ¤Š@®âíñ¶8ÙŠ ôtz³MÔvß{öt\M|¿qNp•r1»Äkd)ÁÝͬ•æD²Ôþ¹*ÏGx@Ûßu9 úÖ°rg†¥ ‚¨pѸ×ÓâCíºµ¥IxbB£ªÑŒh,n.G»ÑÉåÍðÌuúï,y­HQ2R;®y³ëgÄ*c„I'Š4jYw7Rþ¨d'c¾G*…¼ºßn¢†5>uýYsgëàCÜ5mvŒÂ»D-*‘œ©¸åµg_L‰pƒ†Ž ân‹d}Ä»Lâ%F–Žoj8=eŸÖ”ÈDN¬_§;m Y«oÐ3Qõ¹+Ý[ìÊÖ“à)ìµ›„”ˆYõ{ýê:Fu;;a†ÛÌΪÎuÒYÞÆÙ Œ‚ø$×£ð¤Í†BajXl­¡§½Å,¶}YÔ^Äø¢Ùn[Jw„®ÎD™Õ¼¨iÇ%ñ\Ÿ_yDz˲Ľî)«%™J.bõ†<=¯/å Xä¶-K2kŒ†ë_²{J3Gï$‚±à¢‘x‚©öH] Ç;êè‚ÙY¶I|ë£f1ov·ñ•?,ί‚Ïö}R}“)ïÊþÙ4÷}ü½7ó¼‰GU|i=’)9¿û^`™ÞZm ð‡9C44ñœù–Ê..ÔWæ®»‚¾í#h»GZØi|àÏãÁ;(—þ6±ÈBå[ð0D^±îIªL–‰ówæ“þþÿD,‡úذÍÚàÓ'èº EÞdôˆ’¬©”1èxä R뤂•M ˆJBí-n<:(…I?3)¤Çš©ä‘ëÐ}Ñh×H¿ôݘ¬©ŽÝÛš™‹j6%~tR™rÔ}‡tYFxù‡#|¥fd²â0/#ʶ&§•­2®£¢[´ ~!N³o¡õQnºN€hWzÀѰ«Æ#‹®Ðvñð0ÅkҚσ\þÚvšj‚ÙžzENté+¿È[kªYSüáÁÜÆd…˜â¢^À4¤bu¥šfo\n Õ8…]к žA¦‹0 \Ö…,£\Þd[¿,©ß’ü–>»ù¨­SÚ‚ØxŒÏ±Ÿ ¡î_°YL±ÜæÂ£΄ ±¡=`ëç7¨Èâ7éMŒŽH:­¦ftq<: ù)Þ‡ø¦‚ÕaߟMŠ7G E|„­0¿M: ~µ.ú@fA²Y ­ ™[™Œî’ë_ÒJ˜ /I<ÑŸf.n³Éÿmä+s²Vþ.Ýlªüh­Kš½¸Â›„#w.h”c‹0£3nc gžÉ‡cXþY7ÞºÎï¿z°™ÔõþÄ2ânaQ8=Ÿ¿xqñœ<¾Î˜=‚vÐ%áO𠘼ĖÕU ¤±¦ybzª~Ùiæ§ŠaLòlóvBM~€_: It~~K?½p™l6%°Ù 4/øÃCä³µEf³ò2 %^ÉÓGy¢¼¢Ki¡ï©T]:3'8C[Õ¬â-‚¤o9B{âŽþæÃkcé4ß—6„è4x¼÷møˆêm=(ù÷{&PJÕ u-U‰l!‰£Pà#:‚n¨¢¼gfk"Ǻ@tfJ‡ˆ ŒbÒNý;ª]Ôô?ä¶Tý`x;¾ÇË´Ä:¾í„k»-Þjß•,°cP©ŸS<¼Œ<唄XéYJ^} ó"½I3.ON$O Ú“äG½)ZY—›ö£UîŠ1ó¹êÏÂ7¡“eÌÀÜÀx&´Àªò››ÍÇÀš7€£­K2†ÁÂ&Qâ[­$ÖPë0Nø‡kç_­„Z×¶‡Ä’Ú Wyeœ+C5'Ø]ßš5"%ÐÕÂjõ0Ž‘ë=„ää7i´î{ÏtOµë õ°$RYŽ7mý(:ÖæC•Y.|Íý1÷ØÒ¸ 6áXØ×>™Vo‘ ›ä¶0•Њv`‘ÔôëÓH:H±Gm7XÙÜsàxRøðú¢zkÕ“õz qî‘r]~/¿eµV³Øn4üX·&zdªÔLÛ è5å²È7žî†S.Oc{¡÷ƒsÊÁ¨áØ*{N[—¥v5$§dÛÇ•2ш!µÅ{˜Q\;ü‡.WûŒÐ~k,yv‘®,µ¾©i¼ƒÝÁJln^ŒÙâˆ.Âo¡Z‘W¸R©òE ž~vñï3dŸùÕÕÝùσÅñ þ@í$ñj?¾¸üãàjÿ'øÏ.RXFÚ´z4ý˜Ü|u¿ó½WÏ®®ÊsßëSÇú^?ð.ûÍ—nA»ŒÿIÐV…Èy­Öü“ábf•>Gu[M8Iîwˆž¥OÓÐðgÛù%^ëœ{Í›8ÄL$ëÞ''ëÇ®òÒKWh‚„±ÞÄ›6Õ©ºéÓíüÓÅ<Üœ.ôLÊlÏéú0°L¥5GéÓ¥ˆÒ:M“Q„Íáå[ RXØ…LdlõÍD;à~ÉsÛ’·Vg‹º4 VÖžok®­c©Ý-åœ|R¢(Fx8€GÀYBY_:†-BˆÀF9ò4ìîûaŸ±êò¤=z+^[ã6M×ÊIh¤òN@÷—ǘ¯j_’†Vq‡º Xg«ôÕˆM¨©Æ #l¸ØÒe[ÚbrðÑ—0HBãИÉu#6Lª0vªTFÀ¡1ýz¤ÉHšÔ;»Þd$MÖ ØMFv“I†—¿«öY°”‹Ùò³}­‚⢽œdRhQ¾k/§rõ0ˆ­CsÓÖ ìh& ÓõT! ‹¡9Ú R†]R…ïh+¬òìòÀí¶b¦Ûåv@éïò¢m´žÊ³Ë—ûëmÚ:6Î±Ë¦Ûø¦µ”áÌCR&­@)Ã. „¿Ê[‘sšˆh1ª ÇgÝíÛš±)/çŒLx¸¦20‹5Ô n€ïZö€ã·p«PCX/‰WvH.Ó‡Û«U{Sqsw9m?eB”nå0œ¶qÉìÄQ„.ÏŽA©úô@D±L&óÑ+ÿjtÎÿsæÏ¯î‹>üöçÝó'¯þ-ÎñãlæC0Dû©Ï:çW‹Qu&*~å{³³æûWøïUÌæ¯|´·Â ¼ï«q“á'ÙeH¡¥Û°Ô>Àip Œ¦} о5ér…z=ü·‹ÿämá'écב+Ö@Nñ;Z+çÚì[šTËDj›ÈÜ M_?-6Ó×êz)‹ÐŽò0#ø·ïÍpz_/ìÙœH+ƒ³L-! BB³³jûÌà/ŸìE4–@@0V ÐP˜Á£Påú²£Š â €xd. 2¶ O¨j+ƒ³LG! BB³³jûÌà/ŸìE4Î%@@øF ÐP˜Á£Påú²£Š çi€€Ð]x 2¶ O¨j+ƒ³Lš# BB³³jûÌà/ŸìE4t4@@R8 ÐP˜Á£Påú²£Š ìÇ€xYr 2¶ O¨j+ƒ³L¹?   Ìà/Ÿì³³jûE ’Ä÷@2 ÷ÐP˜ PÁ£Š ìÇåú²£€éš ¨j2¶ O’5ãdŽM³(«O{æhºÚ.YûÉ­öz4¦ºK§ ïxÌÞ¿J ,а䎑—/c»(žò|P+êàsmuƒæRhti׬в ô8@¾Úß|Ó"Û³SÚ-ÁQçFÎ^…>^õ¡îþH†ª•”¨ô¢g¾ŒDdT —µ]·æcÁB:¦M%¥:‰…S·öÉt„jÆüJì tü÷öqpAälËF~Ÿxl¡a,uDÔÀ€ÿ-áOÙ†Ž)¾ø7^ Q÷Lë%Y›V(èõšV·Ãï!·pJ—†ämý³ù‡wÖÇŒþ™·8ãëô3%<Š®ßÅym2%I3އ#ü^ #Oû Z'1In"kúÀ ÿ™`"¸cI4C'šsoB"2…Ù¸!G†ÿH(­diÛLpkxdÍìM‹š1^(@Z¥C4–ÍÅÂifb&É}EêåÒC’Qnwµkñi¡¦ÃIÛ­ à@µ±Ìb*ûºˆ m*»ûÁ%Ø—lC[Xß­×8„*,„Úãõù°N!0­Ò0ŒÍ üÒ§óÇox‰¹ ÊS·Î Á2´%b°íÿÓ÷ÍŸ'+ËO¦>Í¥qªÅÃʈž$w2í­P¹U–@|ñgÐ Ó‚M5”.çºvæÐplÈ8Ƹ LÂOPõó)È•†[g0;=˜m„¿k$ ˜é"Þ&â~дñ1¢¥ðÖ<‚›Ún¤Æ‚a J»‘fi/Ï\¼!ŠZ°Q³‰~¶…RAû…}Ð^þÔ­2w6 iQ#„íX•àao®¼à¨×¨G¸zá»(V4lŠí-šÀœ†wʺ˲?Éw¤fv_ð.råcJ=ÙOÃGutQï¾;å3‚ïw¸}ÿ°Ði]J캉¯(*¿³ô#@øRà P§â;uî`!…ªÕ—óÈÓÕÿ¡áh 8F‚|…3¯ñ£, M©-†%Ð.«®äqáÓBµP0gÑÈ€(uµ:2ߟM®úÇA0ÃÏã4.$ÀBµ@ö.3"ð”–¯VœÔ¿€ÄîèêË‘…‰3Î@’âÇ’XùX}øÇ%d_Á`òîÃ4Ò„~úà9ÂdôoĆYú¸°ÆëY×`D] ·Ç®fÑ…ñçŽZ >„Ëä/ŽÏ¹ì÷§5>”ùñj%¡ :O,6™4cƒ(,nXv\öZ¹û½‚$F=DùˆV Ú ®V.–e4A6¢Ñô˜—¥PP3Ãf„HÈ6‡8|¬³¹ÞÃv%hÂFƒó=š‡ã±Uuìõ1äÒô=u#[ÝPœŒ¹¹V)¤ÏæÞ&Æî¡˜]œT¤Ç«ðCŠõ U²Âí‚R7]Í@¦’ó! Ø=Hùúmâ±÷…ƒ Eä¶}Á"<üŸa©sKŠÕ¯Pž/’r¿©°_¡²;Á„ˆÿÀbOýVy±¢Ìo74»Õëõûô ‘ÇшAŒeW Ík ü„Èu¨ï†^/ëŠi«‘” àÔ¶·Â‹í¨%âNJ¬y‰ÔŒœqګℬ0ÿ–}0?·®D¤ÍáÍ>]ö‡DŸ„_°½u(¤ZØTÀo©3•¿‘„rÍïßâåuón{µÇ§ÅËEÕ>Eøâ§'ž`$õ<€šy!Ÿc¸-8£€äÕÜá]ÎÅáÕ⡊í$«yöÉÉeè2&Ò!&ÉPÌ­›sC9lslÛþœŠC‘ËÍV;—Ûà¹tF«è°z!¬Ô VˆHNÙ¯$ؘT‡Ö2QË#q+ƒ³LpA   Ìà/Ÿì³³jûE ’Äø@2 öÐP˜ PÁ£Š ò%åú²£€ˆË ¨j2¶ O®àzZò‡÷;+(‰ŽL¤÷ 쪯°â·iY%™ø°6RùΛ{ȵž+TÌ(Õ ê ¾—g^ß‚€4Wvnïž…ÞΘ8¨Lv¹uÈ#!Ö\Hð;Œ“Ö`Ç!I)>hC¡”Äo­™W?4ú—Ž3šÖ¯rŽí'Qéüyå濵R±ö‡eJc†ØçæèÊ΄‚e¸ŒÏšèPššrîŠ)gb“þoì=AòæöQ-Š€Öò¢£ÉTGÔ:õ„ îµaU[ß&a[•z¬U>Ô`uí]`!Žg¿u«VI\Àñ’=º[y­[6lKïÙÓÔ»u¯’Ú>¶¬}|j q)pc¶Ì(ÞêØÕ™ÎúD¢ùÈù3Õ8ØtžÚnš¾¹{õd ïŸä4²T8zì »Õ¬ò,®Ò7IŒNQ ²iy¿ªH›´%´þµKî^ÁðТ÷ÇáàBô•2­øBõt,ýƒM•­(?+´ZùsæX´}Ô"БÎõ8 aÍãM!å3R€OŽøcÁ~º%à‡‚¢.6NQDÕ/ŠdÖÐFSžUc…¦kBýç ·±§²+ÛŠÀ³VùƒšÄ7qåD…ÅLŽrowŠŠ Ø)ý10yòU7õrQÕ *»¶f‹È¨és¸Æ3…A~wÁéÑj\~ã“*î Ò/D€V@oÝE#¡ÑŽ&;Ø-ŠòZÐR(]!¿B+Æ–u§ ÁRôÛn³k'4% ìòƒŠË@ÇWN Q¬SHü%Œà«¶žŠŒHÁÍG÷#æè`?ˆø‹>fyÑ R;}=<Ô*ð$YoµÐE<.bíÙ5  7 Z%¢³I¢'¦âˆ¦¼Aìß‘sn¬Ó{†v"•¹Jh—¨ØY­koÄ;FIs$s.ÙñÕ×(ŽO§‰ƒ°ˆ ÜP»ÌP~1NY‰¾QwäÊ €Že^lÁšƒ“5q¾Øõ‹#zñ¦ú?É[r³~Níô7Jçz}½IÊ›™ ãû2Ù áš>‡ýÔa{àŸäïß;軯 8‰Cô’3=ÎÑA"Ýpçÿz¯±.ò­ÜÑè'è~IÞ` Xƒ€²äŽÝõP$Ìhòýû÷Î=* UBn0ê·”/—E’d?Éß¿wˆtae±T}àc¤£‚N•ë,ä·ß¤É]çî6I6_&ôÔÆêx¶)Í®VKNÓÁ à%e vºXDΚ˜ôim鉵!YäŠÖ¸ZÑà±L@J7›ÑŒfTQ´vt~´µ²Á£¹>0²}A(ç®"[jy¢Ú7ÞÿÜñi$Š4°?¤’Yu7þ”]Ôyn±†”²¼ûLËòÁIËôÚà{ÐR,j”Šœ–fò¡rÒ(oF@ÛƒVÕºlUÛOFŒÝN!usû© ÛÚG»|ò*²á>F;±R¯Goìäq0ÀòRY¥YÐÿî@ÿ{úË|לR]Ø’$ 3Á¤MÛëù2QŠ’‰l¨¿1M0sÓdÂ…D0j‡&E-妅éeàdFNÞ´Ñwþ`ªìt·sz³‹‰›r9û´–òÙìr2Æg £…Gß[¶ÅëŒS‚ýa ç:sþ&O^Õõ§À¦lÔ³¸;9 îÛÉtS6/~ Ì̘ç«~‘õ*‹ÅÍw°ÐMh›ïK +ƒ³LO BB³³jûÌà/ŸìE4ðK@@Ö ÐP˜Á£Påú²£Š ò%€€ÐR¼ 2¶ O¨j+ƒ³LR‰ BB³³jûÌà/ŸìE4ß@@çX ÐP˜Á£Påú²£Š ÷ƒ€€ÐM^ 2¶ O¨j+ƒ³LÏã   Ìà/Ÿì³³jûE ’Äù@2 õÐP˜ PÁ£Š ÷ƒåú²£€Y¼ ¨p2¶ Oëx«Û„w"ÄÒ¨…‘‰—®éQV‚ 2aá…mâúд©˜ãÙH«µÏÝ™}ö¯êŽ$·±w)4–ÉÖçtyðÔañžiΛ¾WCÛPVËŠm’øMò¯^±}õØ Q“ÿìŸèÍ¿~½¨¹ß´^Î#NÚïßµÕ*Ë¢W$¬}¶Éã•Ço±ÑWváÉc¯žq÷´×(UDÙW*ù ž~÷­Ýþ»lLZCÅ- Zm¢Û–•çÚzˆZWNßÌ<æüÈ0Ñà¦6BîEmö|¿· ÛmVÕfØ(¹>ª…†nÉ ô“Gë3ã ì¾ÔôÓÆ—³äæ6}j9a­ø²6F³qÖ– ~{•:r±Ça\“‚ŒüZ2.¿O[9ßDÇÂ~Ô*B¯Ú1ñxnžÞ•¼Å³Äž–àæì‡}å®5¡ý™¡÷g!— ì¢,gRœ'ðlw&Ý>ÖSëÉ J Ö¢ðV§M7:AE½6_·^¹‚àn@çFY™tb¢¬Á¥• Eœqâ¨öUßî·6›¨÷Ú}¬¢žk_•26ÙóXÎ˺ŠÜ{ ÒE¯pRVeb\ _ I°HxÚ1ÕZ¥©:TAufUUãÔRBýºÐ\êºv­'+øÞ—?|'®h߉‘¬ôéIíª»ŠSö¬‹".¿õWk&£¡‡vNˆ@ðý‚$ ßÃÀÇžQýzôÛò„O8âWÐáØ°®vÿ)ˆšßÖÿß012>Û41}ªÁSLœ·IR%°¶A3Få³ö›‡}zé$êãAìT(Ôt9ý å³;L-½¨@ îFÞ†çÈòtw²Ñ3祿Z­¨¾9àšTuí‘;xy>Û.q&^`Å]{d5PJ°ÿž=4¸ ¹ ¢ r÷Và^ôúÞõÝ… “eˆ¥ÑÒ(}—„,m‡ÌÒ…tä…«ë ÿðúÌi"Í<þ~Ç‘ëµ*î8ä0šâáˆõÙg_·% ðN¿’ž»X´÷ôË>è»ÐŒÙ`â2ÔBDX,Å:›™ÓM—˜8¯K€Ûá¹#÷8·lŸXµ(x„¿àäÅô éÔä?NÔ(‡ì¨ÈKNÉÖœ&‰JáµVÒ‘ðàaƒm3…æn×>u,Æÿg„41é„ ”¦ï‹MH&úv\9cÙÝ茭Î›Ý ØXg=_¯#øp\–pó@:]šR3‡ òÝ)d‡ø¥Œ«á·•;!?0Ïõèhu–ap`=9‹Oþê%=DÈC Ò¶'³$/8h°œ2å?rXÓ-«¤;òx«ª³}„÷×^@‹2¼5?†ªÌ—õã·8ËæÔ¼z‹!Ô<~%P-‚P<ËD?)ñ©‹j϶)üMPöË%ì7ïxÔIY^móUºNÑ•»3ÄtØõˆ±‡AÀGÏ<ýô;4[ ÜåYI¤eûS~:ѯÊà|v5âïglï°sªž3© ¦Ô "T:œâ¼^J†‡„kÁa>hN’8Æéhr’ÎÒðóª4_æí¦z£il¡öÂ5GVÆúÆv€Å.ñhaB…>²bÍ¢a¤`4œ^@—¼×cXâ\~<ŽjnÅÊÉWG"¯5(GNšì TnØNa²ü¡×Àœ§u4,"V£}¯ýšœÜã?øœZ…¦ÂÌÍ/è =Ãmä{À±spas!"=Ÿ<š‹þ;~0­GúópÛQT!ÿÊwôã¹ì,úø i4çó6âß”ìÄ‘•ÛçUnV-b+ƒ³LSé   Ìà/Ÿì³³jûE ’Äú@2 ôÐP˜ PÁ£Š üáåú²£€˜® ¨p2¶ OX®­éu¹ŒøÎ£&ÏÜØŽëH#H:Ö…-´Zi¿‰j(Ý•Òí)S/w™" *š¤¯óC¡&ݸ&RXTÐ[~ðÛí³96j¾ä°:˜2c2ÉÀ¿¼øáûG¦àLwž¼×¥8æïòò_?£pÀ<2Ÿtü¶ e”stªÀCV6ш Œ*VÃ/¤H¨ËPô=¡#g“/éÊnˆ¾6ÊÔ’t;T̯NÆ*:"K¨–H¹úè~pww7@r7°I¶ÌI¨Ù9žk%¨ü¬;ý¤I eÇ8¦´…éKÇ‹ ¯ægWAoï·›Z“ÛMØ¡ç…ïñxÄ3lÂÏ óyÉ(4©¿@vl ÖËÄ!â‡Û¦HvAнÁpáL3/üYž¹šxç£sïƒí|'‡,š®âÌ[ëb@íÝpš’2lI„Ú­ë(²‘g;è;ºuGW3¿w|‚¯$ÉaÉŠ4äA˜ ×¼µ‘S Š^ ÕÕb™ C¶u×^œàò:œfAã{VÚp;O3Š3^ÇØ0I¥ž¤_ògTËfDfe~‘)¼“Š9‰è‘þ"½ Ò儵$5ƒ Vnübÿ¯\rýn"­kË2Ê0zÏzÝÖM{zÃÁŽ£L–üÜ̆µð#̯{Xä/Í,`êým!VÃÏ úg—ÇIñ½ïÒe‘—ùºþôÝ·_¿|ùW/˜`1üªªÝÜ€:´Ï@¨n•»&ZLø—øŒÐ 1*ór ñH½€È–¡ÁXV\zð5ÅTò=ÑßÿÛZ¼‘ô1]+àˆoÖUbð"Í–‰ÖáÙüÜ:·€Séåí>ìŒ/:‰³ÎÅüû¸3Oè?cÚÞÊOI€V(rè¹sz²æçÄ|áàÔFG‚+,Ùܤ.f­©}/ì ?4ѹCÅ(µ$" 댲¶a¾|èZh½õ~0´Í!mƒ "¾Î ëJMîÈ,’ø¤hÓsjp! «GvmZŠ"—·¯µz=€[;doÎÏŽG] Ÿ1â_T›í£.bR´š>àSŒ…rYä´iJ/0±­NØ^OÿnH†} Ë.Â,vÝ·Y ‹Ì‰AX=¹Xþû\ã"¯†rG“è©tMÓ6Tp ^Àb4¹h0L…6ò“ãØx" = ÔPp¯9ŠBKcäÔ›¯~LJÚÌü3¹A4gµ’Âóo1²äwZ'ÖÀM{^RpzŸFÒ¬9 ñ}°ï?ÙHƒt ~Ò$°ϦÑÔ>S%$¦¼èv29BŒ°|[ý&↟ 8ÁŠgãÀºŒp#Dƒ½Ÿj4áûŸéwÕ |á 0…A= +ƒ³L}÷   Ìà/Ÿì³³jûE ’Äû@2 óÐP˜ PÁ£Š ?åú²£€®• ¨q2¶ OH f’OÎI€‰Xü©ñ¶´l…âÕsÍô[>ýËg±[&úé‚`•! º=³TÜ úÌOß^ÚkQi¡¬&]®n0pˆß£\]¾³ž­pÚ‰¦Ú’J- _SÈ_ß)ðc¡VÔ@„"ðr¯'ãÐ"G¦#„|ˆ3Üç.¡µÚëi.¤Õ*_æØõ‰o >‹.Çc"Ã’ðôÓ1ÆV6 Qôéø37áâòòӓѹí‚ïc(…{â„5ÂéŒA‚6™ul ¡Dm„‰Ù‡áÀH¡ãŒˆ˜fspêÔˆ„Q`/ñÍC‘P‘ƒ¯£±Ä˜FV`3ÌD×:ÒiDð5ãã•G3±¿ñƔޭ#A¼n oFî"¯:g …ì ‘QÓ¢¥×ªíh¤ µxs|…ÙqTêÈa1|¯Ï"~`V™„»¾zsr’¬£^LkQ«cäß׿’ÅŒ­õŽíûÂRž”"eÝÿø  홺,@îºjƒS%øù¼€ý¶ÅuWûÅôÜÙüõ¢×‹é‰ÓFÝžáÓ¨Ô¹×vÊêÎoÑÔøbÇ‚þëúЫS_çiæƒ0n½|÷ûË1^{õ=çÎÁºn-oó;‹èî’dÕÔdS2ßiK@VÿpKÏL<à…wøÆú×哬²m¨yŒðÖ›Häæ›|3æ¼íÎ6ž›=OOïŽ¸Š©ßƒ™1”wõu¢×ç{%Þw}¯c].¾Ì}ŸÅ¶t‚®v°5ÓÐTùʺ%Uó-Y Á›ZžÕ|/4LønCP'ÿÔÊ ½2ü¡W†>ß·2xûÔÒ¨u¨¯Êéõh›Mž¢©5ðŸÅ¬Ò +'´˜[†ëì²~ßbí–u´ùb%ž3iªÝ¦q¢ì83˵ôܪO=»’ðJ3Bf:1w..ÓÒÚ3ÞF²f _Œ\Ë |~锟À‘GömàÿÞýF°íˆ¥À¾¬­àGÖ³Ú¾Ž1ÒÔGÂ}™°?ØQ³?îɹ@¸/ó:Ø*ÿPÈUÞUаô”—Kâ2ÍnjÏ0æ» ýoeƒPA¿½¸mÜ0çjC8Ï÷Z•=ó»I)°´›Ç~õ©]¸.Ò—ÚÔá!ä–‚p'ñø£Ó»$4–,xðïðÐç÷Oв~Ìw ·¯ˆ¥ÁÑd€(Ã9ª9j\Eú1Ö¿DîwŸø8ðAÄŽ¬£ˆÛ#¤‹¡µÚz“ßE]Ti¬K°K‰{]KYóŒux_|¨ÐœNšÇî€0Ä„Ùs9.éAE„ïÑbf+ê7·G¼#8wh¼¡^›$ÿúdNj×θ‡.1C«ˆ…ÏÝÒÞ8² Íù½?ЯÂûóþ`£}Õࣙþð–šrë¾JYýÎ)sÚ€@É\ýAuƒÄ`7}ý S8ˆ¼ÙàbrœCVÐgpØBYå[Ÿ>CÈ¡a(­N-íW<Ï5T’ G!íÙ¿V›’1$¸_¯´1ÓÁaq 69[ßó%ISnh";2QšU{zå¾’ô¨³ Ålhë‹dœRÛjXþsLîF¦¼¢ÄËöà)åøöƒpI\üBoò*ÿJ½•Ìïè(ºô…™ò¼½¹ñùB8¦Óû1óTNJ¡kw8âÄ"çKD†¦IuI`D 0´%Ù! /xp¸lº ™{%Ü¿¦ïv+ƒ³LÑù   Ìà/Ÿì³³jûE ’Äü@2 òÐP˜ PÁ£Š åú²£€wh ¨q2¶ OŠÏ…fX,õHµD±bÒÀŽCü ÊÍ&oJÎî̯ò–vðžÒêúÂXºq5£úujûžÉ¸"g'4ûùòê¸3ýÕŽgò«²ýc¹Ø˜˜îhù Ïã:§ dzö=ƒ³“2z=úãn¹ãb@c« Ç_=À˜fÛ­­NU®ö‡¶±û0±!ð_õm÷¢) *÷Ž*3òí¯^ÏþrGóý~{3»€!Eç.LA]VzÍðfÙgüÔþ¨‡ €,ZX¶ÃáF̦h%›ÒZÈgݧ†ÝÀ‡€xf›4ª`±saƱlaÂUº6F|*µ©ç†º¼shž¬êûzÿn™—þîœ~þõ›`tôÇÃ?çX´¯*¢I:/ѯoÄ.jmÁm#ߥØ)àÇCæc¬1ùe%âv”’x¼:ã“aiA5ô*Ëù71|ø,ÿ$¾O-{d€næ¥Nâ0H„mb°cÉ êF¦Ò§­VÙ0˜ìtÎô¡â gaêpÌ—T6e‘Ý'ëw¨¥ÚWoµÃ©•q=¹žBùnu ³5Fa0@VÁÒ̺·Ån'ƒi­Ór™Hƒxcç(&]BDÀFcuý¤ž¶°ÝB¨©»çoq‘) Ù¬3»<å«ðƒÆÎåMên\ÙÍõk÷λ@IJN *PZT}ÿ cÅšc5#E_/äa‹‡u×HÀ‘t˜…gNêÀí»[RF£wlÃÖýtQÛOliíiБïŒY‘FcþÛêõ“@ÁMVr,ËpŠÜ貤y~QVánê4Û•êõ2*¹þ‰ok¢E½ÍT²EÇýÞ££> DŠÓµX-ÛVGðßÞG:xìîäÔ?†¶»°‰ñ»ß´Ó¸ ÞO5+­PAtàâäÔ»lÔŠÅGµ¾¹²¹SX1¾¾SfHÌ×Ì£?ÞÄc>Î ¾iø±qx¶6´A}ßWÛÇLp®ºԶσ#å׊Ͱ„,`”“C ¸9ù·ñ8\ãˬ—ð¸˜Égã±Ð…ƒ ³dÅ÷ ŒÞËRêü’2Ô`…:zÒcU ÛÔP*N§¼;º.aŽ'å½!ÐýÁª Ói“¨3³ŒhVLÕúð‡1î-¿íÕÎPôØŽà €~C}p£–‚cÚ“HO(‰~5—dד{d½ÁíñkÇÌGSÂ_­Òv F]•Ô»,)¾Tñ ø2ý2j¼Ï¬dþÃåe¯×Å«ü:‰ÓB¹Z¡âç7襽‰ à &«é“ Àºg…hezjàxÑN~ü°žS¸¬Aå¡_ç÷Ñé2€ºè- …†8Í}ûuîÆ¥¹A9œ‰a-X"X¥HX‡ñyPêÍ ­ž 1>’@„!$k ©¦õM%Ù×^ã€êÙ)vý–t‚ë°Íߥ›MŒËüªòÑ?ï¸:ÞOÔZ;Uågº‚DÁu^ ¡„Ó'böhÉ{=D)Û#`ä!jd#ùèNøã}šY&v‰©³;Z¦BŠ=´9G+ð4?؉#:ê螸…ø;(˜fHÍNçð\—Æ9Ø+ƒ³LNý ´´Ìà/Ÿì³³jûE ¦Äý@2 ÝÐP˜ PÁ£Š ûåú²£€1 ¨q2¶ OÉèõÉ„;ÉÂU7©±^60Å5ÐóÄú>V–d'‹qÚ¹Àú²Ž½žOkp<šã7)ÝõНË|³'‹m8ØœN¨Ôu*éýB;ÉBÕz¢7õŠªýS{ýŸÙãB·£jqÑùiÏÿy°¬ëdÚY{‰veX¦Š\ûô7’ø¬ðtQè‚]Ò6çÃ66!¾†¤0Òd|^ŒI:Fâf’+•¬Ÿ8‘ã¨-À–Z¿Éc‡›užÉ'G{ã1c¥€B3qPQäÉï¦3€©ÑSa7 åƒ}õH ¸°ý‰ ‡–4|3Óî%è¾ ªjžÎÎ(p*#ÛÙ„¾~’/Ë3¿ÿΜ§F…ULX\¢Ä*YuH}³/º³œÞ׬l =¦˜'–´ÚDéÌÃÉé fÀ ¯ Lù‘*O¼/òªÊ·žµÊ^šÿìõk1]Ü qYãÝÐ…ô5ñv@®QâëW›Öäë"°)ñÜË÷UK£Lܦþ92QÁ6û2)m¹×…É•f¦'Ôû­R¡Û“±D À?ÿuk1ÞÙ+ƒ³Ls, BB³³jûÌà/ŸìE4H@@}í ÐP˜Á£Påú²£Š ?€€ÐB› 2¶ P¨p+ƒ³L‡, BB³³jûÌà/ŸìE4@@³O ÐP˜Á£Påú²£Š m€}„8¸ 2¶ P¨q+ƒ³L/f OO³³jûÌà/ŸìEAMYÿVP  Ö¤5-Ï2:Elists wikimediaorg+ƒ³Lg® ééÌà/Ÿì³³jûEÛy.@èá  5Ö¤Çûx:E€lists wikimediaorgÀ  x[Æ®À¢ýb0org afilias-nstÀÀ¢ýa2org afilias-nstinfoÀ¢ýd0ÀDÀ¢ýa0ÀeÀ¢ýb2ÀDÀ¢ýc0Àe+ƒ³Lk® KK³³jûÌà/ŸìE=µHÿîd  ×…5)Rº 4enwikinewsorg+ƒ³LE!SS³³jûÌà/ŸìEEã^ÿÀF  Àx51rÏewikimediafoundationorg+ƒ³L`!WW³³jûÌà/ŸìEI˜Iÿ X  ôB557ÕîAwwwwikimediafoundationorg+ƒ³L'Ìà/Ÿì³³jûE ­c@´z  5×…ùd 4€enwikinewsorgÀ  ×text wikimediaÀÀ- textpmtpaÀ2ÀJ ÐP˜À¢ýb2org afilias-nstÀÀ¢ýa0org afilias-nstinfoÀ¢ýb0ÀvÀ¢ýc0À—À¢ýd0ÀvÀ¢ýa2À—+ƒ³LEeííÌà/Ÿì³³jûEß&@àå  5ÀxËʯÏe€wikimediafoundationorgÀ ®ÐP˜À ¢ýa0org afilias-nstinfoÀ ¢ýc0ÀHÀ ¢ýb0org afilias-nstÀ À ¢ýd0À~À ¢ýb2À~À ¢ýa2ÀH+ƒ³L—r''Ìà/Ÿì³³jûEÆI@›ˆ  5ôBôîA€wwwwikimediafoundationorgÀ  ùtext wikimediaÀ$À9A textpmtpaÀ>ÀV ÐP˜À$¢ýb2org afilias-nstÀ$À$¢ýa2org afilias-nstinfoÀ$¢ýc0À£À$¢ýa0À£À$¢ýd0À‚À$¢ýb0À‚,ƒ³L²}¹¹³³jûÌà/ŸìE«ô5@@п ÐP˜Á¢PËf1 Üþ퀀о 2¶ TÈåGET /images/w.gif HTTP/1.1 Host: en.m.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Referer: http://en.m.wikipedia.org/wiki/::Home?wasRedirected=true Accept: */* Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive ,ƒ³LÙ•¹¹³³jûÌà/ŸìE«s-@@QÈ ÐP˜Á£Påú²£Š m€€Ðòx 2¶ T¨qGET /images/s.gif HTTP/1.1 Host: en.m.wikipedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Referer: http://en.m.wikipedia.org/wiki/::Home?wasRedirected=true Accept: */* Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive ,ƒ³LÊ¥PP³³jûÌà/ŸìEB½tÿæ3  Áž5.Ìæˆupload wikimediaorg,ƒ³L¹8ààÌà/Ÿì³³jûE Òíê@2ãÃÐP˜ PÁ¢ÜþíËf2„€úÁ È(2¶ THTTP/1.1 200 OK Date: Mon, 11 Oct 2010 21:35:40 GMT Server: Apache/2.2.14 (Ubuntu) Last-Modified: Sun, 26 Sep 2010 00:36:12 GMT ETag: "3802a9-17b-4911ecc735700" Accept-Ranges: bytes Content-Length: 379 Keep-Alive: timeout=2, max=98 Connection: Keep-Alive Content-Type: image/gif GIF89a#Äÿÿÿ@@@ ßßß```¿¿¿ŸŸŸïï€ÏÏϯ¯¯pppPPP000!ù,#øà`£¦€N0˜ÐjÈtðG<ŽF¢!ø‹‚0"0’ËÑQXF«öÐT„…\õn£òõ‡Ðæ›Âl-üæ×`½÷& tVE+‚ZlEf ƒk#p^/Xt(jƒzf‰M^ ’ˆ? y?;fŒ¨ZLš^¡«^vµ±_?bZ#¼V7m½v#‘Á³£Í}Èg?‡Ó?¼•Ò")u2*#¤ÒnMţ´¦xåV·TëÖ£EåzÀÊ2§ïZý`†î)€ÔèÔBsâŒ8†Ð93v¢U´¢€¢¹P…;,ƒ³L#:Ìà/Ÿì³³jûE÷ D@T°  5Ážã戀upload wikimediaorgÀ ºuploadpmtpaÀÀ2•ÐP˜À¢üa2org afilias-nstinfoÀ¢üa0À`À¢üb2org afilias-nstÀÀ¢üb0À–À¢üd0À–À¢üc0À`,ƒ³LøS  Ìà/Ÿì³³jûE ’Äþ@2 ðÐP˜ PÁ£Š måú´€àÖ ¨œ2¶ THTTP/1.1 200 OK Date: Mon, 11 Oct 2010 21:35:40 GMT Server: Apache/2.2.14 (Ubuntu) Last-Modified: Sun, 26 Sep 2010 00:36:12 GMT ETag: "100157-6cc-4911ecc735700" Accept-Ranges: bytes Content-Length: 1740 Keep-Alive: timeout=2, max=99 Connection: Keep-Alive Content-Type: image/gif GIF89aÄYYYdddlllrrrxxx‚‚‚‹‹‹”””œœœ¢¢¢®®®´´´ºººÃÃÃÏÏÏÕÕÕÛÛÛãããìììôôôýýý!ù !ÿüICCRGBG10120appl mntrRGB XYZ Ù  acspAPPLapplöÖÓ-appl dscmòdescüogXYZlwtpt€rXYZ”bXYZ¨rTRC¼cprtÌ8chad,gÿTRC¼bTRC¼mluc enUS&~esES&‚daDK.êdeDE,¨fiFI(ÜfrFU(*itIT(VnlNL(nbNO&ptBR&‚svSE&jaJPRkoKR@zhTWlzhCNÔruRU"¤plPL,ÆYleineÿn RGB-profiiliGenerisk RGB-profilProfil Générique RVBN‚, RGB 0×0í0Õ0¡0¤0ëu( RGB ‚r_icÏðPerfil RGB GenéricoAllgemeines RGB-Profilfn RGB cÏðeÿ‡NöGenerel RGB-beskrivelseAlgemeen RGB-profielÇ|¼ RGB Õ¸\Ó Ç|Profilo RGB GenericoGeneric RGB Profile1I8,ƒ³LhWÔÔÌà/Ÿì³³jûE ÆÄÿ@2 »ÐP˜ PÁ£Š Ëåú´€^ ¨œ2¶ T9 ?@>D8;L RGBUniwersalny profÿil RGBdescGeneric RGB ProfileGeneric RGB ProfileXYZ Zu¬s4XYZ óRÏXYZ tM=îÐXYZ (Ÿ¸6curvÍtextCopyright 2007 Apple Inc.C, all rights reserved.sf32 BÞÿÿó&’ý‘ÿÿû¢ÿÿý£ÜÀl,ÿ %RSiž¨9®RäºM’(ÍkÛ¬­@ÆÍ‰ˆ^‚oÙ3 _‰ÒK dˆB ùŒ(×¢GP8G!è ‡Š¨‹7XmĶðŒ‡[O <pr ? ]n‰a‹oC ‘7~c Ž=5›r]Jƒ¥aJ¤›}r =µ \’/¢ m>w/œP=¨[LˆÒ¹/ Í>KµÓ7j w™KŸ.é]:ØÕˆóô. Αqô]*ÔcÀ ^J€€"^)¼ÔL‘ 2jÜÈ1#‚¬ C†É“(M2°H!;,ƒ³LÐ[BB³³jûÌà/ŸìE4îB@@Ø) ÐP˜Á¢PËf2„Ý‹€€(Iý 2¶ TÈ(,ƒ³L`gNN³³jûÌà/ŸìE@ !@@ºA ÐP˜Á¥PÃAo°ÿÿàù´ 2¶ T,ƒ³L}NN³³jûÌà/ŸìE@@@6R ÐP˜Á¦P°:‡°ÿÿØ ´ 2¶ T,ƒ³L.}BB³³jûÌà/ŸìE4fM@@` ÐP˜Á£Påú´Š ]€~Ô-Ò 2¶ T¨œ,ƒ³LÆ#JJÌà/Ÿì³³jûE <@2ÔFÐP˜ PÁ¥ƒ5›ÃAp  )j Vö2¶ T ,ƒ³Lž=JJÌà/Ÿì³³jûE <@2ÔFÐP˜ PÁ¦ƒ“v¢°:ˆ  ¹j V÷2¶ T ,ƒ³L³MBB³³jûÌà/ŸìE4/}@@–ñ ÐP˜Á¥PÃApƒ5œ€€ÐÇ{ 2¶ UVö,ƒ³LQ[BB³³jûÌà/ŸìE4y@@Lï ÐP˜Á¦P°:ˆƒ“v£€€Ð}o 2¶ UV÷,ƒ³Ld[³³jûÌà/ŸìE…@@?… ÐP˜Á¥PÃApƒ5œ€€Ð>  2¶ UVöGET /wikipedia/en/thumb/b/b9/VOA_CHINESE_liuxiaobo_cropped.jpg/100px-VOA_CHINESE_liuxiaobo_cropped.jpg HTTP/1.1 Host: upload.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Referer: http://en.m.wikipedia.org/wiki/::Home?wasRedirected=true Accept: */* Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive ,ƒ³L–pææ³³jûÌà/ŸìEعa@@ i ÐP˜Á¦P°:ˆƒ“v£€€Ð2 2¶ UV÷GET /wikipedia/en/thumb/d/d2/Mcgregor.jpg/100px-Mcgregor.jpg HTTP/1.1 Host: upload.wikimedia.org User-Agent: Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7 Referer: http://en.m.wikipedia.org/wiki/::Home?wasRedirected=true Accept: */* Accept-Language: en-us Accept-Encoding: gzip, deflate Connection: keep-alive ,ƒ³LÞ.BBÌà/Ÿì³³jûE 4¨`@2+îÐP˜ PÁ¥ƒ5œÃA >€Fj Vü2¶ U,ƒ³LÃ/ûûÌà/Ÿì³³jûE í¨a@2*4ÐP˜ PÁ¥ƒ5œÃA >€c Vü2¶ UHTTP/1.0 200 OK Server: Sun-Java-System-Web-Server/7.0 Content-Length: 4071 Accept-Ranges: bytes Date: Mon, 11 Oct 2010 21:34:42 GMT Content-Type: image/jpeg Last-Modified: Fri, 08 Oct 2010 09:31:19 GMT ETag: "fe7-4caee4e7" X-Cache: HIT from sq81.wikimedia.org X-Cache-Lookup: HIT from sq81.wikimedia.org:3128 Age: 58 X-Cache: HIT from sq52.wikimedia.org X-Cache-Lookup: HIT from sq52.wikimedia.org:80 Connection: keep-alive ,ƒ³LÑ1  Ìà/Ÿì³³jûE ’¨b@2&ŽÐP˜ PÁ¥ƒ7UÃA >€ÐÒ Vý2¶ UÿØÿàJFIFxxÿþRFile source: http://en.wikipedia.org/wiki/File:VOA_CHINESE_liuxiaobo_cropped.jpgÿÛC   %# , #&')*)-0-(0%()(ÿÛC   (((((((((((((((((((((((((((((((((((((((((((((((((((ÿÀdd"ÿÄ ÿÄ;!1AQa"q2B‘#b3Rr¡¢±‚²ÁÑáñÿÄÿÄ%!1"Q23A±ÿÚ ?¯Ú_‰§®ïˌڎóSO”¸7%IO¸›‡<Œ÷k­.½5¨‚܆\\´‰ŠÙÊã••µÿPÈÇ=0x§ýMl·ê+ΣrÏæ­1š‚ãKè %µ,>R·ÁG&†õ,&âÛô½á†¢4‰1”ËPc.”¬“’¡°äqÏAZm{w ´ÅŽÝNΟªÛu2ž–ÜXÑ”°ËŽ9—[^Õò¶çú1߉Wð»oU·U 2&²ó÷RÙ,¡²6y1•þ¤üÃûºàšçÌoVë+Eš÷=½âì¹2å•-JZÚ|Äe!$€¬×^ŠÖçE߬rgEøg¡Çî@*p¨68% uÝè* \ë„ø–ØŽJ¸If,VÒT·^XBRÏSQ¦üHh;,…1 ù—wÁT&¿–Ä¢úŒŠ®ú½oâËÂç>Jþ+1Øt”¶„ú¥?ùïMVÿµ“¼·˜l3ï ¸ÇÚ±y"»f‘Å)t‰­ÿÅ¥¹9ø}'-|o˜”sž:$öçëǽwÙznI ¼XîpI8ÜÊÐú@Áçôž¼tïQoe$Ë€9JZÂéá kù­·ïȬþD.¬¿Çt[m%â>“Ö.©?}‹"P1Õ–Ý>á*Á#ÜfŠWÁôö¯š·«=ÃLÝK‹Cͤ<ÒŠH÷r*Ø~¼RVÛ—¦ï®©Û¼·³!G*}¡ÆýC׸÷­ÔŒhÕõ¬žÝk.Þõásž}êåMe;°vŸÞ•l wÿšTL, U¦Ët—ÄhmébŸ†eô:™³ ïìàççspÝ‚Ÿ/ àP¿•kEÊ+.C‰¬»ç—Ap¡ ^3ò‚»;F§Óx³—{¬(2!¢Ý6Þ.1œue”–†  Î )ÁÊš— |“!‡”üpâ’Ò‹gr’¡…a#ŽzƒžjÉ´¶– Ú>¨šî¯Ôú¨Å†Á”Ü–Ô‡”KEô«  (dž=  § ?¶—f™–…¸â’Õ%@„ý3A2ュƒÍùJbÁ éIm³Èìœñ“ߊ”¿pË‘®Rvn!Ii žOýÕ†y8ÆÑ®©M&M;B~°„á=‡ÚŸj)l%@ɽvÛ£y-#<iÕuÄ€Ò@©Rx®““;‘{P.õ½iR±ž¹ãÍqŠ[{”§ÿóÖŽf)ÆÔRò,ƒ³LX  Ìà/Ÿì³³jûE ’¨c@2&ÐP˜ PÁ¥ƒ<³ÃA >€±é Vý2¶ U†|C׊J‹iŽx¡Aƒ{‘øßke0›šÊ ,àgéï‘Qǃ×Ïì߉úzà½Å¤KCN„œe ;O׃œT—â£ÊŸÂRBr¼Ž:zô?½BNÇy™ˆ[`¥ÍáH8Ï9ÿZìaOí«8y¿6}2P”3À=ëƒÒ²„£çÚœñßæ3éL.Œ ^”«.*(]§^4ÅûK½|n\¸v»#–Ð˜í¥—›Þ‡BTÚ‰ ‘æ$…8”‘’%†¢$¥à£iZHüÜŒ{wÛÙ A¶ÊZc.ÙJapR· £rU™#$ûŽ”í©“r¤­Q®¶Øi©2ZNïI[]HÂTŽ;õëœÔ–7?jþ$¨Ðl?äÌe‰+eÇJƤº·00 R7@ 98©;ÁÛbaÁr3s1‰%°âUðêR³úwò{c¥ h¯‚±ø•g‰*[ÖûeÞÊÛËuÝí¥oÅÚ—°>@éç„¡Ÿ—5%ivx¨¸DKå¥,8V !AÌç×9–ÔM(ro§‹”ø%h]€ÔtLY-8°„>îÐ:crIIÇ×> Síâì!o,6Ø^B7mÈ㞃=¨9´.áª-Ð\³K›(9ónZ†Ñ¸<·½>®×6wñ(éeµAÉq­¼Oéã·_§Òá?¡N¼ºcÞÿ‹²îdIP  T ²:à Êi§’•o §iCFzÖÛNŠƒT¹¡ˆ×'~gÙRT£‚3}n½ë]ÂЩÖ÷™r»¶ˆëJqQcpØŸå’‘»h<ðAÊ4JQ’¦ÈŒ%Â"¿ã³ ßk¸miwj’TÖ:ð:štÖš»Üušk6¹J´®|`§Ýw'ÍH$$à¨c¸câ½†ÞÆíšaÇf¶‚æ ÝP'RÔJ•Éîjh·ÛYU¦ÖÒ#+|e¥¯;ÂBv·¡ Á÷¦]I Ë œäÙ.¹ýâ³êk&²9**åÀçff&‘~F”Õßá–âsÀ,ƒ³L­XBBÌà/Ÿì³³jûE 4ë_@2èîÐP˜ PÁ¦ƒ“v£°<,€ü‡ Vý2¶ U,ƒ³L2ZûûÌà/Ÿì³³jûE íë`@2ç4ÐP˜ PÁ¦ƒ“v£°<,€ºñ Vý2¶ UHTTP/1.0 200 OK Server: Sun-Java-System-Web-Server/7.0 Content-Length: 4068 Accept-Ranges: bytes Date: Mon, 11 Oct 2010 21:34:42 GMT Content-Type: image/jpeg Last-Modified: Sun, 10 Oct 2010 00:19:11 GMT ETag: "fe4-4cb1067f" X-Cache: HIT from sq52.wikimedia.org X-Cache-Lookup: HIT from sq52.wikimedia.org:3128 Age: 58 X-Cache: HIT from sq52.wikimedia.org X-Cache-Lookup: HIT from sq52.wikimedia.org:80 Connection: keep-alive ,ƒ³Ll\  Ìà/Ÿì³³jûE ’ëa@2ãŽÐP˜ PÁ¦ƒ“x\°<,€ÝÉ Vý2¶ UÿØÿàJFIF``ÿþ=File source: http://en.wikipedia.org/wiki/File:Mcgregor.jpgÿÛC   %# , #&')*)-0-(0%()(ÿÀ dÿÄÿÄ?!1AQa"q#2‘¡±3BÁÑ$%5Rbð4drt‚„ñÿÚ?Ã/u}Q.åQªj!C»“ÏçL[Sbjº‡N¾õ'õ¯Ž­©ä‰j¿Þ_úÒ±©sŸñ+áÿÙsŸÎ¬ú_ñ¶§¢Á«YìÍa30ŽT’BX/V9ÇoZ•á^ãm~Q†¾³¶æU2ÝݼYºŒ’hn2á>0áwStú›ÀÌQfŽâGVÇpA¶«¨«ÚŽ 1±áÆãH}[RüÊøƒÿrÿÖ›mcSèu;ìy{ËÿZIÕµ,ÿ˜ßËÿZùµmLçüJüŸ?yë^~ÖÔG]Nû?û2Zöøföm¿Œ÷õ¡×™r1^HÀs•j¼Àµ½ïsÇ=ßÇ ²àˆ –sÔÐ.ÞµÐZ&¢¯ga7‡j±ªÄ¢‘Ôm·zšI„P¢G ¿t2ìsëOˆšêm=¨–Ýó•uÏ/õsìï….Yš÷@Ó\°å-áõËéY‡û±¸G¹àÍEmgû•Ûæ6ôWê>¹¬ˆ8VÐ.¥ƒYÓî-d‰¹X²R}lj@ÎFõé=@Û¥|02¸£o[ûäýþ3úÐ䜌{Qú€ºÍ“Þ6ñÊÃl–}3ŠÞ濇W»ŽòÂÊ rAÆ0EY¸d_„õRI åò­Âéü0žîqÝXþtMÄ·HœÊœªÝ;U~ïS¹•·óÁíQåÅÆLl ó`j6p.TÛj¢9ôùWH¼Á|³žÇ|V5íÙg¹ÙÝk<:­óKh£>ó^äw¬‘ÑÝ7ïHt »v£5 {íÀ9ÞF:¾?£X]êúœ~žî.'äŸ 7­ë‚¸^ÓHTñnâT.Çlžàv­WOž(UBòòŽæ§¬nÖL¨'¦Ôy~hΓŸ@q ›¬2Oj‘pzõ¨$} Â±ø¿óõ½h© Iâ&`Ý 0;úÑ6–Çyˆ<ÅèãçÒ¹ßÛ³Æá`êV "ðóG¾ñ¿t?­eRF yQ:€þý8 ´;ýhnQõvöiˆ÷iðÉ÷yõ¦i—Å9ˆ!Žã¦õrÒ.]9I,Àò6úU»N”` ê=zÕŠÎNX”±';àv¡µ°Î@o¥U"µ[xÕpƒ•ß÷©KHòçâE;lwÚŽ·å¹9A;`šˆöƒ£#à­bÅWíŒH3ÚEÜ~5ŧ#•—!×b<©ÍCþ¾àc?hß­0wsçZ—YÉkʇãøèwÞ­ú:ÊnIl†Û9Î:UçE&h¾5 :®ØùÔå°håT‡Tõ»3IPFØÏQJºbв °:õÏÒ«·<员ƒ€÷Æ´m³†ˆÈd;8;J–³bÊ«!‡±(ø•<çøºšàÍfånµkÛŽNA,ÎáX䌱ڙÔZþ㘙õ¢ô=:×S•­åœÃ/0*q³ãçåZ5,ƒ³LJ^  Ìà/Ÿì³³jûE ’ëb@2ãÐP˜ PÁ¦ƒ“}º°<,€ÿä Vý2¶ U®§›Ë„ßV5pAÛo:& }c•®fDú*zÓÚžŸgn_\`**ïÁ~Ñtý1Þ[{»<¼Ç Óήîªq$tê1åL yÃóèjT¢_³û¤óòÿ ÷9§¬¦l”ï¹;ü¿*›Ža*ÒžQÍþê–¶‹íUQùCŒcb¸Kˆ­Ç_Ô­n,±\ÈŒoÆ…Õ1ï÷C'÷¶}hXØ!Î7î+ã¨Ïb7•Tÿ rA?#ZFƒ¡_q&&©´¦Þ5Á%F#š¡_æÃPuhƒlrkFàÞ-„Ybó@¹–ÉAšÐI]Ž1ÜVÃÂMjöÖëa|ol%RIç‹ý®àüêÛ%â9HÆGz‹º"yc+¶ãÊ“y ²´Y¹N]—áÜ횉Ô5½[ö••…¤&ÜÏŽ·‹‡6>Ž›ùU냵 µ-H½ºå[™¡V˜/@ýóÆ~ѯÒóŽµÛ„Ê¯y.ýC˜Ô6¥ŸÚ78ûFýM +yd* ®.!‰@Ì®¨07Üâ»C…4«]„4í2‚!@1ÈÆÄþf±ßjüÖ:ªjš;¼i!,ê2yO˜ù×¾ÏÚk[€—DI!WÎ;ïåW í&Øê"{H#…‰ÌåÉúu>•;jÎ"êNv š&ÎV–øÆåwßʤïUX“qÏ ÔLÉ$N0zzжZpµ˜< a¶ùßzšµ¼¹dn¬|ÍHÇ8*Ê«¿j~ðcYzJS›=ð7N±,§OVVÄÌCŒì2Ý<ñU+M&7´¶ŠÚ从O¦ðÀ9bw?…W¿´}Ãi|7¢ii€Ò©%²Fˌǽs©r?à© SüÆèŽoÞ°üèFÊŒŽ¿*µðgj1­C¨ÙªàH¼¹È­i½³j—º†"áå¹·$"Èc$˜ µLãÙu8ñº{‡ˆøòØ8ïW~â¨Ø¡‘°\}MMxöÖÏ!‘±Ëñd ÏJ•ÓdYÕ䉆ƒ õ$žØíÖ¦/%ðX0Œ±U 7'b¢uá¬Ï.•6mÉ‚Viby„|ÊPŒdô=?–á‹vñ‹\Úµ¬× Fì.™®nöí¯K­ûDÔCÊd¶²ou@Ø*õÇÌäÖrçîþU'ªgö•ßµm‡ÌÒt»7Ôµ­#æBçrp<ëL–ÇNÓt”‚Ò4„#±P_eæ-ž™$éWK±]:K›„šÑì”9… |u\üDî}+MÓ&~X_žL˜—ã|gïëééSVŒ%V‘ ˰ŸÅ,ƒ³LlBB³³jûÌà/ŸìE4‹i@@; ÐP˜Á¥PÃA >ƒ7U€€aÄ] 2¶ UVü,ƒ³LuBB³³jûÌà/ŸìE4,!@@šM ÐP˜Á¥PÃA >ƒ<³€€Ð¾ 2¶ UVý,ƒ³L!BB³³jûÌà/ŸìE4§@@T ÐP˜Á¦P°<,ƒ“x\€€azz 2¶ VVý,ƒ³Lã‚BB³³jûÌà/ŸìE4­@@Z ÐP˜Á¦P°<,ƒ“ƒ€}²rm 2¶ VVý,ƒ³LÍ(mmÌà/Ÿì³³jûE _¨d@2&¿ÐP˜ PÁ¥ƒBÃA >€®Á Vž2¶ U,¨àv#)<Ѽ¹gxdÅM¶ûi±1=§h¥m:þAù¹AùºzV‰vK9¼AÓhÓú"ãlaÇÜn§y”îPQ(\V”’¿êã§SMÞ jéíVì¸L9d1¼Ÿ—ÍÛû‚GíOþ1Þ™~嬭).72]î<Ð…6Qåµð¼©C›$ q’j/,†š Œª°ë××¹>µŽD¥¥¢Ü]–¾©/ÏqİÑsò ãƒî¢xÖh¬¨®LéV3´eC>½€¨Ex¼Í®4xš>_k L´ ÁÀ:Ž¡]‰ä¼TÍY-ø¡MÀ¸?‘€í<ö>•ÌË"àëbÔAª°…ùj‹2B€W RjÔצ›)ŒÒúþb9?jÂAÔ§|ÀÑ?” P'Œ“ØÐúaP²æ¢¼¶P…’ÃákϪ¹HûžÔbÇä“)›3§Dâ&¢:—SH”Ù?×òc‚@ï÷9?z)ü5Þ]³xÇ`-­IfjÕ䎋K‰ ÿXAú¤T`G4ç`¹½a¿Û®±ÆdBÔ–Æqó!A@ÛÒªèæ7gÓ rzšó<ûÐæ„Ö–Mufjça˜Û¡i z9Pó£¨õJÑÔxÏCÔ(ˆt«¡rOQ÷4«!ßå&•T챤õȬmeøòT|¶ÖÛÉåNVž=Hö¡pjÛdÓʹ|ìÊÒêa†ã¨¡nŸŠ6r1ÉÝÓåã©_ăÞê)Îù-“T ¿­I½~µÙ<7‘ªlÖ»£¶ÕµkšæùctvÛÁI %IuJ'žyÇZÛ®?`%âá:ñx•t»=æÍ’¤­åã!!)ÀvÌÚ’p0Ï9¬u!…IJ}pp•ÿ´ûš¬]5µ+Ó­GÑ«&¼Òw{z%ÄÔÀÒÏåøeÄžáH^4«ç1–ðà8p=y¥SaEÇñ--Åü9´i~ϵg<––1ÏbWUø•©¢ié6f¦¤ÅPòw-kKe²’€OOlûÒ¥LG¦gèPʲI$NOZÉõ¼ Icv¥J–4 ôÁL­M`qÄ'ÎYYqÁù–ry'×µj‹öí;"t]‰–ÐRJrT¼p>Ãö¥J•Ëû뾌ëC6½¿ð‰ljàˆS&¸óÒ&5!çT¥õR]Ú?÷õ©+JXáJè‹B‘Ø–m[öðœù„|ÊüÇ€@õ•*lòM¶ÛdwâL·9QÚj:Ô4„á)0jQ¥J  —ÂFd”ËŠîœb•*ÓJ•*ÿÙ,ƒ³L¶7BB³³jûÌà/ŸìE4@@­X ÐP˜Á¥PÃA >ƒG<€…µP 2¶ VVý,ƒ³L«;jjÌà/Ÿì³³jûE \ëc@2ãÂÐP˜ PÁ¦ƒ“ƒ°<,€åM Vž2¶ VŒU«NÒ½íyî—™>Ì|ëþÑ¢Šö¿Ç‘p *Yr~Ú¼;4ëá±”!ÛÌ×"MvòHÍ,­$ÎÅÞFl–brI>f·+eÎAZMµàð³)<ÌIëŠtÚÌ÷×s­¸t0àò““Þ¦£áù"HÚhJ#ŸàÏÄ6óíüªM¸i´ûrÉ›· ò£ebÛ?]ZøNÞÜék$˜'Ä+–#œyoµs¤Ù®ŸG³'0æ#h™º’wãlv $ÓÅ…°Ÿ”2;¬#-± Ôã®=iËmY$’m]Â)g%ÞU;þ}έZX[iVKtY%(FŒA$]ªßgw i·Úî´V¡ŒurzŸ`+–8ÛŠ¯8¿‰®õkÞeñ$1v†!÷PÍÉ5^‘ù1“ôÍ1Ïâ¹$ý˜;ÓLåÉ9Àì*ÕcvF©$ ;*<ä²ùŽo>ÕcTŽîì–iÐs2äàê=1S:"¡&–3ÌÞ#¢çlg#ð«‚ÇsvÐñálª»“Žç¦Z–€+Ýx6e+~D`@†ܓݶÏÖ«ÜG¨›®q$m"ª°"4dž¤d}w\üý/ƒôÛI§ˆÇyj×(ó«øg¸làgÓ¥lœ=Ã2ZÁÍ4e¥w2Çrsµd?Ú‡]Š4Òxf CLŒ×·ˆy9cSëŽsQXc';S\ÅÎv¹ª×®Å|ª `çð£®.½ßXyÅÉ+¾f­:ªe¶fKŽRG,‘ªåÙsÓä{ùQz.­,ÜqÆÁ|W É’3æ>U¨éÖò¤wrJ¨"–nTU,Az÷ü¨†ºŽÆÎöI?w ^*0#,°à~ }Mgq«Ë§ÖᤂñÅÂ7'0ø`ôÈ$g>Y¬ºmVñžR³º+±blQºgqœ¼º~¿«ZÆv+ äŠ?qQóO4óI4ó<²ÈÅÞI³1=É;“L1-ò§¡œ ”yšJ‚ÞYïDåMj[ßÜvûFýi»[©­y¼+ͳ1åOÛ_´w‘LÁ¾c¶*ëcí"æÊÝÕTÎÏ.ø\6Ì=qœúÔµÅW—±„ŽFH¦F2Eœ¨fêGÏo­@µõÓY›o̹ùKscý*Ãw©étPEñIq0ˆ¬×qŽRÅpJ¡éßÏVGÞRØœߨ¦Àf#ÌÑr°‘•Q¿Î¾W1ÓÖ½,ùê~”Kû?Ÿ9ýh\:מuñCV­ ׇ¡·Šóˆ¢º’cuŽ K€%gñÆgyf«R(ç"1ð×È„`Ê•aùæ¾ g® .Ê]Ø„m¿zò KîzùÓ…9wÚ’µ?¨F ìÄ÷sB¤@æ¼1‚qœRJ·9cIÅz4‡UæÁ©VÀsŒ‚Ô€€îsߥ{᪌ïŸ )ÎÔ©Î1‘Š`'_ÿÙ,ƒ³LšSBB³³jûÌà/ŸìE4VD@@p* ÐP˜Á¦P°<,ƒ“ˆ@€†kj 2¶ VVž-ƒ³LæÅBBÌà/Ÿì³³jûE 4(Â@2«ŠÐP˜ PÁ¤‰Í%ä¿"´†€Ä0 ¨ *2¶ N-ƒ³LÓ• BB³³jûÌà/ŸìE4Ç4@@ÿ7 ÐP˜Á¤P¿"´†‰Í%倀ÐCY 2¶ c¨ *.ƒ³L~GBBÌà/Ÿì³³jûE 4íë@2æ`ÐP˜ PÁ¢Ý‹Ëf2„€ÉJ Èð2¶ T.ƒ³L{©BB³³jûÌà/ŸìE4Ú@@ìM ÐP˜Á¢PËf2„ÝŒ€€ÐHw 2¶ iÈð.ƒ³LnÏBBÌà/Ÿì³³jûE 4Å@2KÐP˜ PÁ£Š ]åú´€«² ¨ 2¶ T.ƒ³L.PBB³³jûÌà/ŸìE4õ@@ÑV ÐP˜Á£Påú´Š ^€€Ð*Ú 2¶ l¨ .ƒ³L-˜BBÌà/Ÿì³³jûE 4“y@2@bÐP˜v PÁžÄÃõþÁ«ñ€– =2¶ >/ƒ³L*BBÌà/Ÿì³³jûE 4©H@2*“ÐP˜v PÁ¡Äè¨ íZe€;* =%2¶ >/ƒ³LðÑBB³³jûÌà/ŸìE4, @@™ò ÐP˜vÁžPþÁ«ñÄÃõ€€Ð- 2¶ q=/ƒ³LâBB³³jûÌà/ŸìE4,~@@™} ÐP˜vÁ¡PíZeÄè¨ €€Ðº: 2¶ q=%/ƒ³L%«BB³³jûÌà/ŸìE4ñc@@Õ ÐP˜Á¥PÃA >ƒG<€€Ð³è 2¶ rVý/ƒ³L·²BB³³jûÌà/ŸìE4Jd@@| ÐP˜Á¦P°<,ƒ“ˆ@€€Ðj 2¶ rVž/ƒ³L¢¼BB³³jûÌà/ŸìE4x@@NW ÐP˜Á¤P¿"´†‰Í%倀ÐCI 2¶ r¨ */ƒ³LüBB³³jûÌà/ŸìE4Œ4@@:8 ÐP˜Á£Påú´Š ^€€Ð*Ó 2¶ r¨ /ƒ³LL¿BB³³jûÌà/ŸìE4¶^@@ ÐP˜Á¢PËf2„ÝŒ€€ÐHm 2¶ rÈð/ƒ³L#ÄBB³³jûÌà/ŸìE4(Q@@ž ÐP˜ÁPŒ |tf3€€Ð 2¶ r þ/ƒ³LVÞBB³³jûÌà/ŸìE4Z@@µ ÐP˜ÁœP?_æs§¼÷€€ÐÞ¢ 2¶ r þ/ƒ³LlÞBB³³jûÌà/ŸìE4© @@e ÐP˜Á›P¼) öà´×€€Ðj  2¶ r$*bn/ƒ³LvÞBB³³jûÌà/ŸìE4™n@@- ÐP˜ÁšP“hËgÆSq€€Ðº 2¶ rgœú/ƒ³LÞBB³³jûÌà/ŸìE4•R@@0© ÐP˜vÁžPþÁ«ñÄÃõ€€Ð+ 2¶ r=/ƒ³LÞBB³³jûÌà/ŸìE4©K@@° ÐP˜vÁŸP¥Å ƒÏ€€Ð‰T 2¶ r<þp/ƒ³LhìBB³³jûÌà/ŸìE4K_@@zœ ÐP˜vÁ P×.—³ÄZ!€€€Ð&‹ 2¶ r<þ…/ƒ³LyìBB³³jûÌà/ŸìE4¬\@@Ÿ ÐP˜vÁ¡PíZeÄè¨ €€Ðº8 2¶ r=%/ƒ³LµeBBÌà/Ÿì³³jûE 4¨e@2+éÐP˜ PÁ¥ƒG<ÃA ?€3Š VŸ2¶ r/ƒ³L7lBBÌà/Ÿì³³jûE 4ëd@2èéÐP˜ PÁ¦ƒ“ˆ@°<-€é« VŸ2¶ r/ƒ³L|xBBÌà/Ÿì³³jûE 4(Ã@2«‰ÐP˜ PÁ¤‰Í%å¿"´‡€Ãl ¨ É2¶ r/ƒ³LzBB³³jûÌà/ŸìE4?@@³/ ÐP˜Á¥PÃA ?ƒG=€€Ð²Ç 2¶ rVŸ/ƒ³Lè|BBÌà/Ÿì³³jûE 4Å@2JÐP˜ PÁ£Š ^åú´€«I ¨ É2¶ r/ƒ³LSBBÌà/Ÿì³³jûE 4íì@2æ_ÐP˜ PÁ¢ÝŒËf2…€ÈÅ ÈV2¶ r/ƒ³Ls‹BB³³jûÌà/ŸìE4Es@@€û ÐP˜Á¦P°<-ƒ“ˆA€€Ðhé 2¶ rVŸ/ƒ³Lú’BBÌà/Ÿì³³jûE 4¡Ö@22yÐP˜ PÁtf3Œ }€…’ P2¶ r/ƒ³L·£BBÌà/Ÿì³³jûE 4úK@2ÚÐP˜ PÁ›öà´×¼)!€è— $*d£2¶ r/ƒ³L̦BBÌà/Ÿì³³jûE 4pØ@2cwÐP˜ PÁšÆSq“hËh€8… gŸ/2¶ r/ƒ³L¬BB³³jûÌà/ŸìE4Ç~@@þð ÐP˜ÁPŒ }tf4€€ÐÐ 2¶ r P/ƒ³L"¯BBÌà/Ÿì³³jûE 4@2ÓÛÐP˜v PÁžÄÃõþÁ«ò€•Î =62¶ r/ƒ³LM¯BBÌà/Ÿì³³jûE 4D_@2ðÐP˜ PÁœs§¼÷?_ç€]$ P2¶ r/ƒ³LV³BBÌà/Ÿì³³jûE 4£ò@2/éÐP˜v PÁŸÅ ƒÏ¥€L =62¶ r/ƒ³Lz¶BBÌà/Ÿì³³jûE 4b¼@2qÐP˜v PÁ ÄZ!€×.—´€¥™ =62¶ r/ƒ³L¢¶BBÌà/Ÿì³³jûE 4@2ÓÛÐP˜v PÁ¡Äè¨ íZe €:ä =62¶ r/ƒ³L)æBB³³jûÌà/ŸìE4S@@sm ÐP˜Á›P¼)!öà´Ø€€Ðg× 2¶ r$*d£/ƒ³L@æBB³³jûÌà/ŸìE4©n@@ ÐP˜ÁšP“hËhÆSr€€Ð·Ê 2¶ rgŸ//ƒ³LKæBB³³jûÌà/ŸìE4ö @@Ðc ÐP˜ÁœP?_çs§¼ø€€ÐÜa 2¶ r P/ƒ³LVæBB³³jûÌà/ŸìE4i @@\î ÐP˜vÁŸP¥Å ƒÐ€€Ð‡ 2¶ r=6/ƒ³LbæBB³³jûÌà/ŸìE45 @@ñ ÐP˜vÁ P×.—´ÄZ!€€Ð$Ù 2¶ r=6ocaml-cstruct-6.2.0/ppx_test/pcap.expected000066400000000000000000002566461437471254600206530ustar00rootroot00000000000000start parse total pcap file length 216805 pcap_header (len 24) magic_number a1b2c3d4 (bigendian) version 2 4 timezone shift 0 timestamp accuracy 0 snaplen 65535 lltype 1 ** 1286832922.783199 bytes 54 (of 54) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 248 proto 6 tcpv4 port 5223->49559 seq 407703533 ack 3892329100 win 1024 off 0 flags ? opt 0 fin false syn false payload_len=0 ** 1286832922.872360 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 48 proto 6 tcpv4 port 5223->49559 seq 407703534 ack 3892329101 win 78 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832922.880940 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49559->5223 seq 3892329101 ack 407703534 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832935.715078 bytes 76 (of 76) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 255 proto 17 unknown ip proto 17 ** 1286832936.642015 bytes 284 (of 284) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 64 proto 17 unknown ip proto 17 ** 1286832936.698700 bytes 76 (of 76) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 255 proto 17 unknown ip proto 17 ** 1286832936.699259 bytes 284 (of 284) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 64 proto 17 unknown ip proto 17 ** 1286832936.711027 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473116531 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832936.761514 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281406477 ack 2473116532 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832936.765220 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473116532 ack 281406478 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832936.781155 bytes 447 (of 447) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473116532 ack 281406478 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=381 ** 1286832936.828485 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281406478 ack 2473116913 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832936.830532 bytes 628 (of 628) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281406478 ack 2473116913 win 14 off 0 flags ? opt 12 fin false syn false payload_len=562 ** 1286832936.830713 bytes 86 (of 86) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281407040 ack 2473116913 win 14 off 0 flags ? opt 12 fin false syn false payload_len=20 ** 1286832936.838365 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473116913 ack 281407040 win 32835 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832936.838667 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473116913 ack 281407060 win 32830 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832936.910983 bytes 461 (of 461) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473116913 ack 281407060 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=395 ** 1286832936.960946 bytes 593 (of 593) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281407060 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=527 ** 1286832936.962011 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281407587 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832936.963024 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281408961 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832936.963843 bytes 1414 (of 1414) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281410335 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1348 ** 1286832936.986201 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117308 ack 281407587 win 32844 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.4584 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117308 ack 281410335 win 32632 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.4597 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117308 ack 281411683 win 32295 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.34216 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281411683 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.52055 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117308 ack 281413057 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.52282 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281413057 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.52338 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281414431 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.58966 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117308 ack 281414431 win 32632 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.58989 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117308 ack 281415805 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.64450 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281415805 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.65358 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281417179 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.66140 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281418553 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.74607 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117308 ack 281419927 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.108899 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281419927 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.110917 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281421301 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.111208 bytes 452 (of 452) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281422675 ack 2473117308 win 16 off 0 flags ? opt 12 fin false syn false payload_len=386 ** 1286832937.121830 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117308 ack 281423061 win 32192 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.250897 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 255 proto 17 unknown ip proto 17 ** 1286832937.251331 bytes 537 (of 537) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117308 ack 281423061 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=471 ** 1286832937.251353 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49563->80 seq 3154388409 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832937.272222 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49564->80 seq 121593356 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832937.272247 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49565->80 seq 2359297700 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832937.303118 bytes 567 (of 567) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281423061 ack 2473117779 win 18 off 0 flags ? opt 12 fin false syn false payload_len=501 ** 1286832937.304256 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281423562 ack 2473117779 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.305125 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281424936 ack 2473117779 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.305951 bytes 1414 (of 1414) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281426310 ack 2473117779 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1348 ** 1286832937.314094 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281427658 ack 2473117779 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.314742 bytes 1221 (of 1221) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281429032 ack 2473117779 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1155 ** 1286832937.314873 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49563 seq 4141914146 ack 3154388410 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832937.320774 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117779 ack 281423562 win 32850 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.320801 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117779 ack 281427658 win 32295 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.321902 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117779 ack 281429032 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.323504 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49565 seq 1946509275 ack 2359297701 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832937.324295 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49564 seq 1940372050 ack 121593357 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832937.325276 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117779 ack 281430187 win 32687 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.325294 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49563->80 seq 3154388410 ack 4141914147 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.342020 bytes 280 (of 280) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 64 proto 17 unknown ip proto 17 ** 1286832937.351138 bytes 536 (of 536) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49563->80 seq 3154388410 ack 4141914147 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=470 ** 1286832937.351157 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49565->80 seq 2359297701 ack 1946509276 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.351168 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49564->80 seq 121593357 ack 1940372051 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.351182 bytes 539 (of 539) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49564->80 seq 121593357 ack 1940372051 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=473 ** 1286832937.351195 bytes 537 (of 537) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49565->80 seq 2359297701 ack 1946509276 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=471 ** 1286832937.355242 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274104123 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832937.355268 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49567->80 seq 68329577 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832937.355877 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154158 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832937.358722 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982122739 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832937.373028 bytes 477 (of 477) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473117779 ack 281430187 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=411 ** 1286832937.419351 bytes 567 (of 567) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49563 seq 4141914147 ack 3154388880 win 14 off 0 flags ? opt 12 fin false syn false payload_len=501 ** 1286832937.419952 bytes 1024 (of 1024) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49563 seq 4141914648 ack 3154388880 win 14 off 0 flags ? opt 12 fin false syn false payload_len=958 ** 1286832937.420097 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49564 seq 1940372051 ack 121593830 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.420604 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49565 seq 1946509276 ack 2359298172 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.420769 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301142176 ack 4274104124 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832937.421381 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49567 seq 3305922067 ack 68329578 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832937.421518 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294207838 ack 3610154159 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832937.421629 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303560391 ack 3982122740 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832937.422081 bytes 567 (of 567) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49565 seq 1946509276 ack 2359298172 win 14 off 0 flags ? opt 12 fin false syn false payload_len=501 ** 1286832937.422362 bytes 566 (of 566) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49564 seq 1940372051 ack 121593830 win 14 off 0 flags ? opt 12 fin false syn false payload_len=500 ** 1286832937.424113 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49563->80 seq 3154388880 ack 4141914648 win 32850 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.424447 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49563->80 seq 3154388880 ack 4141915606 win 32611 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.424467 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274104124 ack 3301142177 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.424749 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49567->80 seq 68329578 ack 3305922068 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.426056 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154159 ack 3294207839 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.426228 bytes 1188 (of 1188) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49565 seq 1946509777 ack 2359298172 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1122 ** 1286832937.426263 bytes 242 (of 242) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49564 seq 1940372551 ack 121593830 win 14 off 0 flags ? opt 12 fin false syn false payload_len=176 ** 1286832937.427246 bytes 566 (of 566) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281430187 ack 2473118190 win 20 off 0 flags ? opt 12 fin false syn false payload_len=500 ** 1286832937.429040 bytes 158 (of 158) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281430687 ack 2473118190 win 20 off 0 flags ? opt 12 fin false syn false payload_len=92 ** 1286832937.429812 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982122740 ack 3303560392 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.429828 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49565->80 seq 2359298172 ack 1946509777 win 32850 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.429835 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49564->80 seq 121593830 ack 1940372551 win 32851 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.429845 bytes 483 (of 483) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274104124 ack 3301142177 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=417 ** 1286832937.430691 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49565->80 seq 2359298172 ack 1946510899 win 32570 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.432845 bytes 458 (of 458) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154159 ack 3294207839 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=392 ** 1286832937.432865 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49564->80 seq 121593830 ack 1940372727 win 32807 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.438337 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473118190 ack 281430687 win 32851 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.438358 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473118190 ack 281430779 win 32828 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.438369 bytes 460 (of 460) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982122740 ack 3303560392 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=394 ** 1286832937.438382 bytes 463 (of 463) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49567->80 seq 68329578 ack 3305922068 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=397 ** 1286832937.471021 bytes 443 (of 443) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473118190 ack 281430779 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=377 ** 1286832937.474266 bytes 466 (of 466) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49563->80 seq 3154388880 ack 4141915606 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=400 ** 1286832937.477782 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301142177 ack 4274104541 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.478717 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301142177 ack 4274104541 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.479592 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301143551 ack 4274104541 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.480506 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301144925 ack 4274104541 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.482224 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294207839 ack 3610154551 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.484721 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274104541 ack 3301144925 win 32289 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.484955 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294207839 ack 3610154551 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.485658 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294209213 ack 3610154551 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.486421 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294210587 ack 3610154551 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.487788 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274104541 ack 3301146299 win 32969 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.489908 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303560392 ack 3982123134 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.490863 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303560392 ack 3982123134 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.491455 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303561766 ack 3982123134 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.492218 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303563140 ack 3982123134 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.492318 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49567 seq 3305922068 ack 68329975 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.493166 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49567 seq 3305922068 ack 68329975 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.493847 bytes 694 (of 694) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49567 seq 3305923442 ack 68329975 win 14 off 0 flags ? opt 12 fin false syn false payload_len=628 ** 1286832937.494606 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154551 ack 3294210587 win 32289 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.494632 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154551 ack 3294211961 win 32969 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.498073 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982123134 ack 3303563140 win 32632 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.500765 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982123134 ack 3303564514 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.500788 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49567->80 seq 68329975 ack 3305924070 win 32819 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.521143 bytes 568 (of 568) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281430779 ack 2473118567 win 22 off 0 flags ? opt 12 fin false syn false payload_len=502 ** 1286832937.521809 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281431281 ack 2473118567 win 22 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.521960 bytes 356 (of 356) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281432655 ack 2473118567 win 22 off 0 flags ? opt 12 fin false syn false payload_len=290 ** 1286832937.522487 bytes 574 (of 574) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49563 seq 4141915606 ack 3154389280 win 16 off 0 flags ? opt 12 fin false syn false payload_len=508 ** 1286832937.523218 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49563 seq 4141916114 ack 3154389280 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.524134 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49563 seq 4141917488 ack 3154389280 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.524854 bytes 1414 (of 1414) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49563 seq 4141918862 ack 3154389280 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1348 ** 1286832937.525398 bytes 1351 (of 1351) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49563 seq 4141920210 ack 3154389280 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1285 ** 1286832937.531349 bytes 496 (of 496) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49567->80 seq 68329975 ack 3305924070 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=430 ** 1286832937.532367 bytes 232 (of 232) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301146299 ack 4274104541 win 14 off 0 flags ? opt 12 fin false syn false payload_len=166 ** 1286832937.534433 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473118567 ack 281431281 win 32850 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.534453 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473118567 ack 281432945 win 32560 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.534464 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49563->80 seq 3154389280 ack 4141916114 win 32849 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.534477 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49563->80 seq 3154389280 ack 4141918862 win 32162 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.535877 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49563->80 seq 3154389280 ack 4141920210 win 31825 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.536504 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49563->80 seq 3154389280 ack 4141921495 win 31503 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.543640 bytes 771 (of 771) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294211961 ack 3610154551 win 14 off 0 flags ? opt 12 fin false syn false payload_len=705 ** 1286832937.546057 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303564514 ack 3982123134 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.546102 bytes 172 (of 172) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303565888 ack 3982123134 win 14 off 0 flags ? opt 12 fin false syn false payload_len=106 ** 1286832937.547904 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274104541 ack 3301146465 win 32934 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.553908 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154551 ack 3294212666 win 32799 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.555336 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982123134 ack 3303565888 win 32632 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.555361 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982123134 ack 3303565994 win 32606 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.582368 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49567 seq 3305924070 ack 68330405 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.582970 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49567 seq 3305925444 ack 68330405 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.583438 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49567 seq 3305926818 ack 68330405 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.583960 bytes 1286 (of 1286) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49567 seq 3305928192 ack 68330405 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1220 ** 1286832937.595347 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49567->80 seq 68330405 ack 3305928192 win 32289 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.595372 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49567->80 seq 68330405 ack 3305929412 win 31984 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.643263 bytes 444 (of 444) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982123134 ack 3303565994 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=378 ** 1286832937.680481 bytes 446 (of 446) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154551 ack 3294212666 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=380 ** 1286832937.680516 bytes 440 (of 440) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49567->80 seq 68330405 ack 3305929412 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=374 ** 1286832937.691601 bytes 445 (of 445) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274104541 ack 3301146465 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=379 ** 1286832937.691773 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303565994 ack 3982123512 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.692190 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303567368 ack 3982123512 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.692861 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303568742 ack 3982123512 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.693505 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303570116 ack 3982123512 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.695697 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303571490 ack 3982123512 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.695966 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303572864 ack 3982123512 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.705602 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982123512 ack 3303570116 win 32289 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.706386 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982123512 ack 3303574238 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.744433 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301146465 ack 4274104920 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.744670 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301147839 ack 4274104920 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.745224 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301149213 ack 4274104920 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.745699 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301150587 ack 4274104920 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.746495 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301151961 ack 4274104920 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.753936 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303574238 ack 3982123512 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.755184 bytes 873 (of 873) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303575612 ack 3982123512 win 16 off 0 flags ? opt 12 fin false syn false payload_len=807 ** 1286832937.775899 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274104920 ack 3301149213 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.775922 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274104920 ack 3301150587 win 32632 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.775932 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982123512 ack 3303576419 win 32430 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.775947 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274104920 ack 3301153335 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.819401 bytes 461 (of 461) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982123512 ack 3303576419 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=395 ** 1286832937.828018 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301153335 ack 4274104920 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.828104 bytes 664 (of 664) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301154709 ack 4274104920 win 16 off 0 flags ? opt 12 fin false syn false payload_len=598 ** 1286832937.834861 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274104920 ack 3301155307 win 32826 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.843133 bytes 475 (of 475) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274104920 ack 3301155307 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=409 ** 1286832937.872177 bytes 1209 (of 1209) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303576419 ack 3982123907 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1143 ** 1286832937.877410 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982123907 ack 3303577562 win 32690 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.889917 bytes 478 (of 478) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982123907 ack 3303577562 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=412 ** 1286832937.893996 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301155307 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.894310 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301156681 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.894708 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301158055 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.895263 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301159429 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.895697 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301160803 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.896145 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301162177 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.896556 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301163551 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.897117 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301164925 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.900102 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274105329 ack 3301163551 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.903863 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274105329 ack 3301166299 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.939441 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303577562 ack 3982124319 win 20 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.939804 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303578936 ack 3982124319 win 20 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.940635 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303580310 ack 3982124319 win 20 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.941048 bytes 88 (of 88) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303581684 ack 3982124319 win 20 off 0 flags ? opt 12 fin false syn false payload_len=22 ** 1286832937.948137 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982124319 ack 3303581706 win 32283 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.951845 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301166299 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.952452 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301167673 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.952707 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301169047 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.953136 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301170421 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.953573 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301171795 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.954041 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301173169 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.954505 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301174543 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832937.954653 bytes 741 (of 741) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301175917 ack 4274105329 win 18 off 0 flags ? opt 12 fin false syn false payload_len=675 ** 1286832937.963872 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274105329 ack 3301169047 win 32632 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.968004 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274105329 ack 3301174543 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832937.968028 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274105329 ack 3301176592 win 32463 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832938.588325 bytes 446 (of 446) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154551 ack 3294212666 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=380 ** 1286832938.591042 bytes 440 (of 440) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49567->80 seq 68330405 ack 3305929412 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=374 ** 1286832938.646255 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294212666 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.646877 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294214040 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.647490 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294215414 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.647824 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294216788 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.648277 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294218162 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.648783 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49567 seq 3305929412 ack 68330779 win 18 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.649053 bytes 1007 (of 1007) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49567 seq 3305930786 ack 68330779 win 18 off 0 flags ? opt 12 fin false syn false payload_len=941 ** 1286832938.667928 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154931 ack 3294216788 win 32289 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832938.667952 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154931 ack 3294219536 win 31602 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832938.667966 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49567->80 seq 68330779 ack 3305931727 win 32740 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832938.717166 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294219536 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.718093 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294220910 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.718364 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294222284 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.719271 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294223658 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.719788 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294225032 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.725628 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154931 ack 3294220910 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832938.730880 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154931 ack 3294222284 win 32632 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832938.734575 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154931 ack 3294226406 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832938.775591 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294226406 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.775861 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294227780 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.792169 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154931 ack 3294229154 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832938.801214 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294229154 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.801423 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294230528 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.802399 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294231902 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.803977 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294233276 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.805685 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294234650 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.805787 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294236024 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.807848 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154931 ack 3294233276 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832938.823479 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154931 ack 3294234650 win 32632 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832938.823505 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154931 ack 3294236024 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832938.851488 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294237398 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.851672 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294238772 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832938.851998 bytes 1072 (of 1072) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294240146 ack 3610154931 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1006 ** 1286832938.856825 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154931 ack 3294238772 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832938.885119 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154931 ack 3294241152 win 32381 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.195429 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 255 proto 17 unknown ip proto 17 ** 1286832939.234708 bytes 258 (of 258) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 64 proto 17 unknown ip proto 17 ** 1286832939.238542 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49570->80 seq 3412471214 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832939.286436 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49570 seq 433907771 ack 3412471215 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832939.294541 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49570->80 seq 3412471215 ack 433907772 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.294564 bytes 528 (of 528) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49570->80 seq 3412471215 ack 433907772 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=462 ** 1286832939.343021 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49570 seq 433907772 ack 3412471677 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.353384 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49570 seq 433907772 ack 3412471677 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.363577 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49570 seq 433909146 ack 3412471677 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.363759 bytes 1086 (of 1086) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49570 seq 433910520 ack 3412471677 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1020 ** 1286832939.369058 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49570->80 seq 3412471677 ack 433910520 win 32632 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.371453 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49570->80 seq 3412471677 ack 433911540 win 32721 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.422353 bytes 466 (of 466) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49570->80 seq 3412471677 ack 433911540 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=400 ** 1286832939.435185 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858411810 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832939.440619 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49572->80 seq 3206722304 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832939.477373 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49570 seq 433911540 ack 3412472077 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.477475 bytes 733 (of 733) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49570 seq 433912914 ack 3412472077 win 16 off 0 flags ? opt 12 fin false syn false payload_len=667 ** 1286832939.484629 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315898002 ack 3858411811 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832939.489285 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49570->80 seq 3412472077 ack 433913581 win 32465 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.491100 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49572 seq 2311921825 ack 3206722305 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832939.499897 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858411811 ack 2315898003 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.502531 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49572->80 seq 3206722305 ack 2311921826 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.525360 bytes 455 (of 455) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49572->80 seq 3206722305 ack 2311921826 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=389 ** 1286832939.533722 bytes 450 (of 450) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858411811 ack 2315898003 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=384 ** 1286832939.572750 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49572 seq 2311921826 ack 3206722694 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.574185 bytes 1412 (of 1412) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49572 seq 2311921826 ack 3206722694 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1346 ** 1286832939.576627 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49572->80 seq 3206722694 ack 2311923172 win 32639 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.584953 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315898003 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.589439 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315898003 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.589788 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315899377 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.590180 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315900751 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.604059 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412195 ack 2315900751 win 32632 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.605641 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412195 ack 2315902125 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.653454 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315902125 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.653760 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315903499 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.661055 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315904873 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.663853 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412195 ack 2315903499 win 32632 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.663879 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412195 ack 2315904873 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.664474 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412195 ack 2315906247 win 32632 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.671673 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315906247 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.672112 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315907621 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.675601 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412195 ack 2315907621 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.690514 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412195 ack 2315908995 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.713679 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315908995 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.715091 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315910369 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.718717 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315911743 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.719313 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315913117 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832939.720206 bytes 692 (of 692) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315914491 ack 3858412195 win 14 off 0 flags ? opt 12 fin false syn false payload_len=626 ** 1286832939.732275 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412195 ack 2315911743 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.732295 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412195 ack 2315915117 win 32132 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832939.878127 bytes 79 (of 79) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 255 proto 17 unknown ip proto 17 ** 1286832939.896615 bytes 233 (of 233) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 64 proto 17 unknown ip proto 17 ** 1286832939.896619 bytes 75 (of 75) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 255 proto 17 unknown ip proto 17 ** 1286832939.926021 bytes 83 (of 83) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 255 proto 17 unknown ip proto 17 ** 1286832939.926048 bytes 87 (of 87) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 255 proto 17 unknown ip proto 17 ** 1286832939.927615 bytes 283 (of 283) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 64 proto 17 unknown ip proto 17 ** 1286832939.943429 bytes 237 (of 237) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 64 proto 17 unknown ip proto 17 ** 1286832939.946839 bytes 295 (of 295) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 64 proto 17 unknown ip proto 17 ** 1286832940.97714 bytes 441 (of 441) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49570->80 seq 3412472077 ack 433913581 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=375 ** 1286832940.103897 bytes 441 (of 441) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412195 ack 2315915117 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=375 ** 1286832940.107978 bytes 80 (of 80) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 255 proto 17 unknown ip proto 17 ** 1286832940.145593 bytes 736 (of 736) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49570 seq 433913581 ack 3412472452 win 18 off 0 flags ? opt 12 fin false syn false payload_len=670 ** 1286832940.145955 bytes 261 (of 261) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 64 proto 17 unknown ip proto 17 ** 1286832940.152568 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315915117 ack 3858412570 win 16 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832940.153448 bytes 724 (of 724) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315916491 ack 3858412570 win 16 off 0 flags ? opt 12 fin false syn false payload_len=658 ** 1286832940.154576 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49570->80 seq 3412472452 ack 433914251 win 32808 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832940.157536 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49573->80 seq 3275824751 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832940.163092 bytes 78 (of 78) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49574->80 seq 2954377863 ack 0 win 65535 off 0 flags ? opt 24 fin false syn true payload_len=0 ** 1286832940.163118 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412570 ack 2315917149 win 32468 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832940.205766 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49573 seq 2206152091 ack 3275824752 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832940.212382 bytes 74 (of 74) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49574 seq 2207479458 ack 2954377864 win 5792 off 0 flags ? opt 20 fin false syn true payload_len=0 ** 1286832940.216499 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49573->80 seq 3275824752 ack 2206152092 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832940.219985 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49574->80 seq 2954377864 ack 2207479459 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832940.220004 bytes 528 (of 528) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49573->80 seq 3275824752 ack 2206152092 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=462 ** 1286832940.225430 bytes 486 (of 486) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49574->80 seq 2954377864 ack 2207479459 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=420 ** 1286832940.274142 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49573 seq 2206152092 ack 3275825214 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832940.274371 bytes 507 (of 507) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49573 seq 2206152092 ack 3275825214 win 14 off 0 flags ? opt 12 fin false syn false payload_len=441 ** 1286832940.274897 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49573 seq 2206152533 ack 3275825214 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832940.284690 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49573 seq 2206153907 ack 3275825214 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832940.284845 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49574 seq 2207479459 ack 2954378284 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832940.285234 bytes 507 (of 507) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49574 seq 2207479459 ack 2954378284 win 14 off 0 flags ? opt 12 fin false syn false payload_len=441 ** 1286832940.285804 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49574 seq 2207479900 ack 2954378284 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832940.286282 bytes 1440 (of 1440) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49574 seq 2207481274 ack 2954378284 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1374 ** 1286832940.289799 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49573->80 seq 3275825214 ack 2206152533 win 32865 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832940.292122 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49573->80 seq 3275825214 ack 2206153907 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832940.295201 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49574->80 seq 2954378284 ack 2207479900 win 32865 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832940.295651 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49574->80 seq 2954378284 ack 2207482648 win 32178 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832940.338125 bytes 1389 (of 1389) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49573 seq 2206155281 ack 3275825214 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1323 ** 1286832940.341942 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49573->80 seq 3275825214 ack 2206156604 win 32645 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832940.342955 bytes 1386 (of 1386) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49574 seq 2207482648 ack 2954378284 win 14 off 0 flags ? opt 12 fin false syn false payload_len=1320 ** 1286832940.349082 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49574->80 seq 2954378284 ack 2207483968 win 32646 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832941.574950 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49572 seq 2311923172 ack 3206722694 win 14 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832941.628179 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49572->80 seq 3206722694 ack 2311923173 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832942.149374 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49570 seq 433914251 ack 3412472452 win 18 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832942.239995 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49570->80 seq 3412472452 ack 433914252 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832942.446318 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315917149 ack 3858412570 win 16 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832942.544814 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412570 ack 2315917150 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832942.956461 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301176592 ack 4274105329 win 18 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.10775 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303581706 ack 3982124319 win 20 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.53744 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274105329 ack 3301176593 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.57857 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982124319 ack 3303581707 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.109349 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49573->80 seq 3275825214 ack 2206156604 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.111287 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49574->80 seq 2954378284 ack 2207483968 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.113826 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49572->80 seq 3206722694 ack 2311923173 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.113859 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49571->80 seq 3858412570 ack 2315917150 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.114508 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49570->80 seq 3412472452 ack 433914252 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.115747 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49565->80 seq 2359298172 ack 1946510899 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.122454 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49564->80 seq 121593830 ack 1940372727 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.122476 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49563->80 seq 3154389280 ack 4141921495 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.122486 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473118567 ack 281432945 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.122497 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49566->80 seq 4274105329 ack 3301176593 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.122511 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49567->80 seq 68330779 ack 3305931727 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.126056 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154931 ack 3294241152 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.126073 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49569->80 seq 3982124319 ack 3303581707 win 32976 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.157109 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49573 seq 2206156604 ack 3275825215 win 14 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.158775 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49574 seq 2207483968 ack 2954378285 win 14 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.161916 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49572 seq 2311923173 ack 3206722695 win 14 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.162304 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49573->80 seq 3275825215 ack 2206156605 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.163048 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49571 seq 2315917150 ack 3858412571 win 16 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.163667 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49570 seq 433914252 ack 3412472453 win 18 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.166771 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49574->80 seq 2954378285 ack 2207483969 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.168698 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49565 seq 1946510899 ack 2359298173 win 14 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.172983 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49563 seq 4141921495 ack 3154389281 win 16 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.173772 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49562 seq 281432945 ack 2473118568 win 22 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.175122 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49565->80 seq 2359298173 ack 1946510900 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.175906 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49566 seq 3301176593 ack 4274105330 win 18 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.175949 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49564 seq 1940372727 ack 121593831 win 14 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.176982 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49567 seq 3305931727 ack 68330780 win 18 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.177786 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49568 seq 3294241152 ack 3610154932 win 16 off 0 flags ? opt 12 fin true syn false payload_len=0 ** 1286832943.177826 bytes 66 (of 66) ether 00:1c:b3:b3:6a:fb -> cc:08:e0:2f:9f:ec etype 800 ipv4 hlen 20 ttl 50 proto 6 tcpv4 port 80->49569 seq 3303581707 ack 3982124320 win 20 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.189993 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49563->80 seq 3154389281 ack 4141921496 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.190016 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49562->80 seq 2473118568 ack 281432946 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.190027 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49564->80 seq 121593831 ack 1940372728 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.190038 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49567->80 seq 68330780 ack 3305931728 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 ** 1286832943.190050 bytes 66 (of 66) ether cc:08:e0:2f:9f:ec -> 00:1c:b3:b3:6a:fb etype 800 ipv4 hlen 20 ttl 64 proto 6 tcpv4 port 49568->80 seq 3610154932 ack 3294241153 win 32976 off 0 flags ? opt 12 fin false syn false payload_len=0 num_packets 380 ocaml-cstruct-6.2.0/ppx_test/pcap.ml000066400000000000000000000131431437471254600174410ustar00rootroot00000000000000(* * Copyright (c) 2012-2016 Anil Madhavapeddy * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) [%%cstruct type pcap_header = { magic_number: uint32_t; (* magic number *) version_major: uint16_t; (* major version number *) version_minor: uint16_t; (* minor version number *) thiszone: uint32_t; (* GMT to local correction *) sigfigs: uint32_t; (* accuracy of timestamps *) snaplen: uint32_t; (* max length of captured packets, in octets *) network: uint32_t; (* data link type *) } [@@little_endian]] [%%cstruct type pcap_packet = { ts_sec: uint32_t; (* timestamp seconds *) ts_usec: uint32_t; (* timestamp microseconds *) incl_len: uint32_t; (* number of octets of packet saved in file *) orig_len: uint32_t; (* actual length of packet *) } [@@little_endian]] [%%cstruct type ethernet = { dst: uint8_t [@len 6]; src: uint8_t [@len 6]; ethertype: uint16_t; } [@@big_endian]] [%%cstruct type ipv4 = { hlen_version: uint8_t; tos: uint8_t; len: uint16_t; id: uint16_t; off: uint16_t; ttl: uint8_t; proto: uint8_t; csum: uint16_t; src: uint8_t [@len 4]; dst: uint8_t [@len 4]; } [@@big_endian]] [%%cstruct type tcpv4 = { src_port: uint16_t; dst_port: uint16_t; seqnum: uint32_t; acknum: uint32_t; offset_flags: uint16_t; window: uint16_t; checksum: uint16_t; urg: uint16_t; } [@@big_endian]] let mac_to_string buf = let i n = Cstruct.get_uint8 buf n in Printf.sprintf "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" (i 0) (i 1) (i 2) (i 3) (i 4) (i 5) open Printf let print_packet p = let dst_mac = mac_to_string (get_ethernet_dst p) in let src_mac = mac_to_string (get_ethernet_src p) in let ethertype = get_ethernet_ethertype p in printf "ether %s -> %s etype %x\n" src_mac dst_mac ethertype; match ethertype with |0x0800 -> begin let ip = Cstruct.shift p sizeof_ethernet in let version = get_ipv4_hlen_version ip lsr 4 in let hlen = (get_ipv4_hlen_version ip land 0xf) * 4 in let ttl = get_ipv4_ttl ip in let proto = get_ipv4_proto ip in printf "ipv%d hlen %d ttl %d proto %d\n" version hlen ttl proto; match proto with |6 -> begin (* tcp *) let tcp = Cstruct.shift ip sizeof_ipv4 in let off = 0 in let x = get_tcpv4_offset_flags tcp in let data_offset = (x lsr 12) * 4 in let options = match data_offset - sizeof_tcpv4 with |0 -> 0 |n -> n (* TODO parse *) in let payload = Cstruct.shift tcp data_offset in let fin = (x land 1) = 1 in let syn = (x land 2) = 2 in let flags = "?" in let src_port = get_tcpv4_src_port tcp in let dst_port = get_tcpv4_dst_port tcp in let seqnum = get_tcpv4_seqnum tcp in let acknum = get_tcpv4_acknum tcp in let window = get_tcpv4_window tcp in printf "tcpv4 port %d->%d seq %lu ack %lu win %d off %d flags %s opt %d fin %b syn %b payload_len=%d\n" src_port dst_port seqnum acknum window off flags options fin syn (Cstruct.length payload); () end |_ -> printf "unknown ip proto %d\n" proto end |x -> printf "unknown body %x\n" x let print_pcap_packet (hdr,pkt) = let ts_sec = get_pcap_packet_ts_sec hdr in let ts_usec = get_pcap_packet_ts_usec hdr in let incl_len = get_pcap_packet_incl_len hdr in let orig_len = get_pcap_packet_orig_len hdr in printf "\n** %lu.%lu bytes %lu (of %lu)\n" ts_sec ts_usec incl_len orig_len; print_packet pkt let print_pcap_header buf = let magic = get_pcap_header_magic_number buf in let endian = match magic with |0xa1b2c3d4l -> "bigendian" |0xd4c3b2a1l -> "littlendian" |_ -> "not a pcap file" in let version_major = get_pcap_header_version_major buf in let version_minor = get_pcap_header_version_minor buf in let thiszone = get_pcap_header_thiszone buf in let sigfis = get_pcap_header_sigfigs buf in let snaplen = get_pcap_header_snaplen buf in let header_network = get_pcap_header_network buf in printf "pcap_header (len %d)\n" sizeof_pcap_header; printf "magic_number %lx (%s)\n%!" magic endian; printf "version %d %d\n" version_major version_minor; printf "timezone shift %lu\n" thiszone; printf "timestamp accuracy %lu\n" sigfis; printf "snaplen %lu\n" snaplen; printf "lltype %lx\n" header_network let parse () = printf "start parse\n%!"; let fd = Unix.(openfile "http.cap" [O_RDONLY] 0) in let t = Unix_cstruct.of_fd fd in printf "total pcap file length %d\n%!" (Cstruct.length t); let header, body = Cstruct.split t sizeof_pcap_header in print_pcap_header header; let packets = Cstruct.iter (fun buf -> Some (sizeof_pcap_packet + Int32.to_int (get_pcap_packet_incl_len buf))) (fun buf -> buf, Cstruct.shift buf sizeof_pcap_packet) body in let num_packets = Cstruct.fold (fun a packet -> print_pcap_packet packet; (a+1)) packets 0 in printf "num_packets %d\n%!" num_packets let () = parse () ocaml-cstruct-6.2.0/ppx_test/with-lwt/000077500000000000000000000000001437471254600177415ustar00rootroot00000000000000ocaml-cstruct-6.2.0/ppx_test/with-lwt/dune000066400000000000000000000001671437471254600206230ustar00rootroot00000000000000(executables (names ppx_cstruct_and_lwt) (preprocess (pps lwt_ppx ppx_cstruct)) (libraries cstruct lwt lwt.unix)) ocaml-cstruct-6.2.0/ppx_test/with-lwt/ppx_cstruct_and_lwt.ml000066400000000000000000000003171437471254600243620ustar00rootroot00000000000000[%%cstruct type foo = { magic: uint8_t [@len 16]; }[@@little_endian]] [%%cenum type foo64 = | ONE64 | TWO64 | THREE64 [@@uint64_t] ] let foo = let%lwt foo = Lwt.return () in Lwt.return foo ocaml-cstruct-6.2.0/ppx_test/with-sexp/000077500000000000000000000000001437471254600201125ustar00rootroot00000000000000ocaml-cstruct-6.2.0/ppx_test/with-sexp/dune000066400000000000000000000003561437471254600207740ustar00rootroot00000000000000(executable (name ppx_cstruct_and_sexp) (preprocess (pps ppx_cstruct ppx_sexp_conv -- -no-check)) (libraries cstruct sexplib cstruct-sexp)) (rule (alias runtest) (package ppx_cstruct) (action (run ./ppx_cstruct_and_sexp.exe))) ocaml-cstruct-6.2.0/ppx_test/with-sexp/ppx_cstruct_and_sexp.ml000066400000000000000000000003041437471254600247000ustar00rootroot00000000000000[%%cstruct type foo = { magic: uint8_t [@len 16]; }[@@little_endian]] open Sexplib.Std type t = int [@@deriving sexp] type bar = { buf: Cstruct_sexp.t; string: string; } [@@deriving sexp] ocaml-cstruct-6.2.0/unix/000077500000000000000000000000001437471254600152775ustar00rootroot00000000000000ocaml-cstruct-6.2.0/unix/dune000066400000000000000000000001461437471254600161560ustar00rootroot00000000000000(library (name cstruct_unix) (wrapped false) (public_name cstruct-unix) (libraries cstruct unix)) ocaml-cstruct-6.2.0/unix/unix_cstruct.ml000066400000000000000000000016451437471254600203710ustar00rootroot00000000000000(* * Copyright (c) 2012 Anil Madhavapeddy * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) let of_fd fd = let buffer = Bigarray.(array1_of_genarray (Unix.map_file fd char c_layout false [|-1|])) in Cstruct.of_bigarray buffer ocaml-cstruct-6.2.0/unix/unix_cstruct.mli000066400000000000000000000016711437471254600205410ustar00rootroot00000000000000(* * Copyright (c) 2012 Anil Madhavapeddy * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) (** Unix functions that operate on Cstruct buffers. *) val of_fd : Unix.file_descr -> Cstruct.t (** [of_fd fd] memory maps the [fd] and returns a cstruct *)