Quantcast
Channel: Hacker News
Viewing all 737 articles
Browse latest View live

SoundCloud Command-Line Client

$
0
0
README.md

The next generation SoundCloud client. Without all these stupid CSS files. Runs on OSX and Linux.

Screen Shot 2013-01-20 at 15 37 03Screen Shot 2013-01-20 at 15 37 54

This hack was built at the Music Hack Day Stockholm 2013.

Requirements

  • Ruby (1.9)
  • Portaudio (19)
  • Mpg123 (1.14)

Installation

Assuming you have Ruby/Rubygems installed, you need portaudio and mpg123 as library to compile the native extensions.

OSX

brew install portaudio
brew install mpg123
gem install soundcloud2000

Debian / Ubuntu

apt-get install portaudio19-dev libmpg123-dev libncurses-dev
gem install soundcloud2000

Usage

soundcloud2000

Features

  • stream SoundCloud tracks in your terminal (enter)
  • scroll through sound lists (down / up)
  • play / pause support (space)
  • forward / rewind support (right / left)
  • play tracks of different users (u)
  • level meter

Planned

  • play any streams, sets or sounds
  • better browsing between users and sound lists

Authors

Contributors


The Internet's Own Boy: The Story of Aaron Swartz [video]

$
0
0

something has gone horribly wrong 8-p

Prefer flash?·Embed·Questions/Feedback?

The Internet's Own Boy depicts the life of American computer programmer, writer, political organizer and Internet activist Aaron Swartz. It features interviews with his family and friends as well as the internet luminaries who worked with him. The film tells his story up to his eventual suicide after a legal battle, and explores the questions of access to information and civil liberties that drove his work.

This movie is part of the collection:Community Video

Director:Brian Knappenberger
Producer:Brian Knappenberger
Audio/Visual:sound, color
Language:English
Keywords:Aaron Swartz; documentary; hacktivism; suicide; jstor; MIT; CFAA; Cory Doctorow; Tim Berners-Lee; Larry Lessig; internet; activism
Contact Information:http://www.takepart.com/internets-own-boy

Creative Commons license:Attribution-NonCommercial-ShareAlike 4.0 International


Individual Files

MPEG4
The+Internet's+Own+Boy_+The+Story+of+Aaron+Swartz-HD1.5 GB 
ThumbnailAnimated GIF
The+Internet's+Own+Boy_+The+Story+of+Aaron+Swartz-HD??B 
??B 
FormatSize
TheInternetsOwnBoyTheStoryOfAaronSwartz_files.xmlMetadata[file] 
TheInternetsOwnBoyTheStoryOfAaronSwartz_meta.xmlMetadata1.3 KB 
Archive BitTorrent
TheInternetsOwnBoyTheStoryOfAaronSwartz_archive.torrent31.0 KB 

OnionShare: securely and anonymously share a file of any size

$
0
0

Verify your download

When you download OnionShare from this website you're downloading over HTTPS, but it's still possible that an attacker with access to a browser-trusted certificate authority (such as a government) could perform a man-in-the-middle attack against you, swapping out the file you thought you downloaded with malware.

To be completely sure that the download was not tampered with, you can verify the cryptographic PGP signature of the file you downloaded.

All OnionShare releases are digitally signed by this PGP key with fingerprint: 0B14 9192 9806 5962 5470 0155 FD72 0AD9 EBA3 4B1C.

Mattermark Has Raised $2M in Our Second Seed Round

$
0
0

In January I selected a dozen investors we wanted to work with and pitched them on our Series A. I quickly discovered expectations for a B2B Series A were $1.5M in annual revenue run rate — we were growing fast, but still only 1/3 of the way there at the time. In fact, if our run rate had been that high we would have been massively profitable.

We also had a market problem. We were pitching VCs on a product they themselves used — but they had a hard time understanding the broader market and even though we had a handful of reference customers for our emerging verticals we hadn’t effectively told the story. I ended up writing “Introducing Mattermark, the Deal Intelligence Company” to help with this.

Despite these problems, we did get term sheets.

After modeling out the cap table I was worried — the amount we would be taking was smaller than we’d planned and I would need to start fundraising again in 6 months, and then I would be up against Series B metrics to hit before we were ready for them. I spent a sleepless night debating whether I was making a huge mistake, and concluded that it would be smarter and more wise long-term to take on a bit more debt and hit the next milestones.

I was pretty open with my team about the fact that I was fundraising, so it was a little awkward to suddenly stop giving updates on “our Series A.” We had a lot of plans, we needed to hire engineers to build the improvements our customers were asking for, we needed a way to cover our steadily growing AWS bill, we needed to start experimenting with new markets.

It was at this crucial moment that Boris Wertz of Version One Ventures, one of our earliest customers who agreed to pay for Mattermark when it was still a Google Docs spreadsheet, offered to bridge us on a convertible note. This infusion of cash from a completely new investor who I already considered a friend and mentor gave me confidence, and from there began conversations with investors who would ultimately participate in our current round.

What It’s Like Having 40+ Investors

Like all relationships in life, my relationships with our investors ebb and flow depending on what we can offer each other. Sometimes there is a clear way someone can help and we engage a great deal, other times they’re focused on other things and it doesn’t make sense be in close contact. At any given time I’d say 25% of our investors are passive, 50% are in touch 1x per month, and 25% are in touch 1x per week.

One interesting thing about the new institutional investors who invested in this round was that I found a connection with more than just one member of each team, beyond the partner who ultimately wrote the check. At Version One I immediately clicked with Angela. At Felicis I talked piano and brain waves Renata, Dasha, and Aydin (and they have the best food/chocolate). At Flybridge we met up for drinks in New York and I got to hang out with Matt and Caitlin, and then onto Boston to meet Kate.

Just as with John, Forest and Sheel at NEA and Frank, Marc and Morgan at Andreessen Horowitz before, any worries I had about being a small check in a large portfolio of board seats was quickly set aside. Based on my experience, I think it might be a myth that VC funds don’t take care of their seeds. I’m bragging a bit, but I really do think I am fortunate to have some of the best investors in the world.

Okay, okay — enough investor butt kissing Danielle!

This post is the last post I am going to write about fundraising for a long, long, long time. As you can see from the graph above, we have nearly $2 Million in the bank and have identified a multi-billion dollar market to go after, so my job for the foreseeable future is to put that money to work building the team, setting our strategy, and hitting our next milestones.

Day-to-day I’m focused on taking off the various operational hats I’ve been wearing and delegating them to fantastic additions to our team.

  • I’ve hired Bryan Tsao as our Director of Product, and he brings rich experience scaling Kabam from $0 to $360M in revenues at Kabam over the past six years as employee #16
  • I’ve hired a VP of Sales (TBA, watch this space!)
  • I’ve hired our first UI/UX Designer and I’m hiring our first Frontend Developer so I can stop doing our HTML/CSS and design.
  • I’ve hired a full time in-house recruiter so we can level up in the battle for the best engineering, data science and analyst talent in the world.

We’re still following the same advice we got in Y Combinator. Pick one metric and just make it go up consistently. For us, that number is our Net Annualized Revenue Run Rate — and the “net” part is crucial because it is net of refunds, churn, and upsells. Our monthly growth of this metric ranges 10 to 20%, and as you can see thanks to compounding there is a wide range of growth we could experience depending on how consistently we hit the higher end of the range.

In the spirit of Jack Ma, in his letter to Alibaba employees following their IPO filing, we recognize that raising capital “is one important strategy and vehicle for fulfilling our mission. It is a gas station along the road to the future.”

How I Start: Erlang

$
0
0

Intro

Erlang releases are a bit like magnets. Everyone who thinks about them shares the same thought: f**king releases, how do they work?

Fortunately, since the years of Emakefiles, reltool and systools, the Erlang community has stood up and improved its tooling continuously.

Rebar has been improving non-stop and keeps getting better for many functions. It does depend on Reltool for releases, and despite its power, Reltool is hardly usable.

That's why Relx came out after the fact. It's a tool to help build releases easily.

Along with installing Erlang (version R16B03-1 at least), getting a hold of rebar and Relx is all you're gonna need.

For rebar, just download it and follow the instructions. Rebar will basically generate a self-executable that you can store in your repository, or install globally on your computer. This tutorial expects that you're using a recent version (>= 2.2.0), older ones execute commands differently and will explode in your face.

In the case of relx, its presence isn't nearly as pervasive for Erlang users, so I tend to still include it in repositories I ship it with for people who want to build it.

Once they're all installed somewhere in your system, arm yourself with the text editor or IDE of your choice (mine is Vim, because I'm a terrible person) and get ready to write a few things.

My Environment

Despite you being free to develop on whatever you want, I'm gonna go through whatever my setup is.

I use zsh with oh-my-zsh, using a custom theme (depends on hg-prompt as a script), and stuck in vi-mode, because vim vim vim.

For vim itself, to work with Erlang, I use these two lines in my .vimrc file:

autocmd BufRead,BufNewFile *.erl,*.es.*.hrl,*.yaws,*.xrl set expandtab
au BufNewFile,BufRead *.erl,*.es,*.hrl,*.yaws,*.xrl setf erlang

And I depend on these two plugins:

  1. vimerl
  2. erlang-motions

I don't use a lot of material outside of that, and the OS will tend to be my IDE -- for projects that I tend to work on a lot, I will use tmux scripts (see this blog post for an example) -- to get everything going early.

The Project

To avoid the usual Hello World stuff, this tutorial will use a somewhat more fun application to get up and running from a basic Erlang app that can be run within a module, to a proper OTP library that can be included by other projects, to a release than can be self-executing and distributed to client's computer, or on a server.

Our project will be the replication of one of the most well-known software programs in popular history, used in life-critical situations: Homer Simpson's console in the episode where he's so fat he can work at home.

From this episode we can infer the following about the software:

  • When the program boots, it asks you to press any key.
  • The program will ask you questions that can be answered by yes/no, but also Y/N or y/n
  • Most questions can be turned into commands. Each assertion is equivalent to answering a given question positively. For example, Vent radioactive gas? Yes/No can be turned into the Vent gas command.
  • Nothing should go wrong if you keep pressing Y all the time
  • After a given delay, a new question is asked
  • Too many times without venting radioactive gas risks exploding everything
  • Some behaviours aren't defined by the TV show, so we go somewhat anyway we feel like

Out of this, a finite-state machine can be created. The one that follows explains what I understood as possible, but you'll notice I'm not really good at having a consistent notation for events, states, and so on:

                [press any key]
                       |
                 (key pressed)
                       |
             [check core temperature (first)]
                 \________,________/
                          |
                       (yes/no)
                          |
             [venting radioactive gases (first)]
                |                   |
              (yes)      ,-<-,     (no)
                |        |   |      |
       [gas blows away crop] |  [venting prevents explosions]
                |            |      |           |
                |            '--<-(yes)       (no)
                \                              /
                 \______________,_____________/
                                V
                                |
                       [wait for command]<--------,
                            /       \             |
                      (get data)   (timeout)      |
                           |         |            |
                           |     [ask question]   |
                           |        /      \      |
                           |    (Yes)     (No)    |
                           |     /          |     |
                           +----'           '-----+
                           |                      |
                          [show result] -->-------'

Based on this, we'll be able to draw up a first prototype with all the required state transitions. I've also looked for transcripts of the show and extracted the following questions and consequences:

  1. Check core temperature. yes/no:
  • yes: Core temperature normal.
  • no: --
  1. Vent radioactive gas?
  • yes: *gas blows away corn crop*
  • no: venting prevents explosion (allow yes, show only the first time?)
  1. Sound alertness horn?
  • yes: *horn sounds in the distance*
  • no: --
  1. Decalcify calcium ducts?
  1. Special case: after denying venting too many times, the valve must be disabled manually.

The simplest way to write a basic FSM for this one is to use a bunch of function calls. Given Erlang has last call optimization (a call that happens as a return value does not leave a stack trace, and therefore can happen infinitely many times), this is more than adequate.

The sequence of states a -> b -> c can be programmed as:

a()->b().b()->c().c()->done.

Of course, there's going to be more data in our case.

The Prototype

Our glorious application will be called 'muumuu'. Whenever I don't exactly know where I'm going, I decide to prototype stuff. And here I stress the importance of prototype. Despite this fact, it will often end up being in production, but yeah -- that's to be avoided.

I decide to start with the basic stuff to prototype, state transitions. I go for them in a fairly simple manner, top-down:

-module(muumuu_fsm).-export([start/0]).-define(MAX_NO_VENT,5).start()->%% Seed PRNG<<A:32,B:32,C:32>>=crypto:rand_bytes(12),random:seed(A,B,C),wait_any_key().%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% States and Transitions %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%wait_any_key()->io:get_line("To Start, Press Any Key.\n> "),first_core_check().first_core_check()->caseoption("Check core temperature?")ofyes->core_temperature();no->noop()end,first_gas_vent().first_gas_vent()->caseoption("Vent radioactive gas?")ofyes->blow_crops_away();no->venting_prevents_explosions()end,wait_for_command().wait_for_command()->casewait_cmd(10000)oftimeout->{Opt,Yes,No}=random_option(),caseoption(Opt)ofyes->Yes();no->No()end;Cmd->casematch_option(Cmd)of{_,Yes,_}->Yes();_->noopendend,wait_for_command().

In this bit of code, we can see our 4 main states:

  1. wait_any_key
  2. first_core_check
  3. first_gas_event
  4. wait_for_command

The rest of the code is more or less going to be events and input management to check the transitions:

  • printing questions and getting responses (option/1)
  • eventually waiting for a command (wait_cmd/1 and match_option/1)
  • or, if it takes too long, generate an option randomly (random_option/1)

You can look at the code, find whatever you want about it disgusting. So that's the general idea I want in the code. Time to add all that option management stuff:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Options and Response Handling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%option(Prompt)->show_option(Prompt),Data=io:get_line(""),caseiolist_to_binary(Data)of<<"Y",_/binary>>->yes;<<"y",_/binary>>->yes;<<"N",_/binary>>->no;<<"n",_/binary>>->no;_->ambiguousend.show_option(Str)->io:format("~s (Y/N)~n> ",[Str]).wait_cmd(Timeout)->Parent=self(),Pid=spawn(fun()->Parent!io:get_line("")end),receiveData->DataafterTimeout->exit(Pid,kill),timeoutend.random_option()->Pos=random:uniform(tuple_size(opts())),{_,Val}=element(Pos,opts()),Val.match_option(Data)->case[Vals||{Pattern,Vals}<-tuple_to_list(opts()),nomatch=/=re:run(Data,Pattern,[caseless])]of[Opt|_]->Opt;[]->invalid_optend.

Cool. Not fantastic looking yet. Basically, an option will only fetch a line of text entered by the user, look at the first response, and return what it is. Showing the options just wraps things up so they look like a prompt.

Interestingly enough, the command has to be waited for in a different process. The problem with this it that Erlang's standard library doesn't support a timeout mode for io operations, which would tell us "wait 10 seconds for input or quit". Therefore, there is a need to move this to a process.

The rest relies on an elusive opts() function that apparently returns all questions and options offered to the user:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Defining Options/Events %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%opts()->{{"(check|core|temp)",{"Check core temperature?",funcore_temperature/0,funnoop/0}},{"(vent|rad|gas)",{"Vent radioactive gas?",funvent_gas/0,funno_venting/0}},{"(sound|alert|horn)",{"Sound alertness horn?",funsound_horn/0,funnoop/0}},{"(calc|duct)",{"Decalcify calcium ducts?",funnoop/0,funnoop/0}}}.

This basically is a tuple (I use a tuple because it makes random selection with a fixed position more efficient) of all questions, positive and negative response and consequences, paired up with a regular expression that represents fuzzy matching -- for example, someone typing it check temperature should match Check core temperature? as a question, and return both options. The code back in wait_for_command/0 will only execute the core_temperature/0 function.

Finally, all actions and consequences can be implemented:

noop()->ok.venting_prevents_explosions()->caseoption("Venting prevents explosion.")ofyes->blow_crops_away();no->noop()end.core_temperature()->io:format("Core temperature normal.~n").blow_crops_away()->io:format("*Gas blows away corn crop*~n").sound_horn()->io:format("*horn sounds in the distance*~n").pressure_too_high()->io:format("Pressure too high. Tank must be shut down manually.~n").vent_gas()->%% After ?MAX_NO_VENT, pressure has to be shut down%% manually -- unsupported in this here program!caseget(missed)of?MAX_NO_VENT->pressure_too_high();_->put(missed,0),blow_crops_away()end.no_venting()->caseget(missed)ofundefined->put(missed,1);N->put(missed,N+1)end.

Here the two last functions implement the special last requirement: after denying venting too many times, the valve must be disabled manually.

Here we use a dirty ugly counter for prototyping's sake. In fact I had forgotten about that requirement at the time and just bolted it on that way. The prototype helped figure that requirement out, and the final version can now be designed with this in mind.

You can run the code and try it from a shell:

λ → erlc src/muumuu_fsm.erl && erl -s muumuu_fsm -noshell
To Start, Press Any Key.
> .
Check core temperature? (Y/N)
> N
Vent radioactive gas? (Y/N)
> No
Venting prevents explosion. (Y/N)
> yes
*Gas blows away corn crop*
Sound alertness horn? (Y/N)
> Y
*horn sounds in the distance*

That works. Using -s <module> runs the start/0 function from that module, and using -noshell makes it so that the Erlang VM won't fight with all the io calls I'm doing for user input ownership.

Sadly, the implementation is kind of ugly and shouldn't go in production.

Making it a library

There are two ways to make something reach production: distributing yourself, or distributing it as a library other Erlang developers can use.

The latter can be a prerequisite for the former, so we're going to start there. By default, everyone using Erlang in the open source community uses OTP applications.

OTP is kind of often treated as a super advanced topic, so what I'm gonna show here is how to take any non-OTP compliant code and turn it into an OTP application. Fun fun.

First, the directory structure:

src/
  - muumuu_fsm.erl

That's all you need in terms of structure if you have rebar installed in your system.

Add a file in src/ called muumuu.app.src. This file is basically telling Erlang (and rebar) what the library is:

{application,muumuu,[{description,"Too fat to go to the power plant app"},{vsn,"0.1.0"},{registered,[]},{applications,[kernel,stdlib,crypto]},{mod,{muumuu_app,[]}},{env,[]}]}.

The registered entry specifies what processes are going to be globally registered on the node. In this case, none. The applications tuple is a list of all applications we depend on. All applications depend on both kernel and stdlib. These entries have to always be in there. On the other hand, crypto is optional to most apps, but we need it because we use it to seed our pseudo-random number generator in start/0.

The env tuple can contain configuration values, but we need none right now.

The other option considered here is mod. If your library requires no process to be started and you're just shipping code around, you're done. In our case however, we're starting a process (or we want to), and therefore we specify an application module named muumuu_app. This module is also in src/:

-module(muumuu_app).-behaviour(application).-export([start/2,stop/1]).start(_Type,_Args)->muumuu_sup:start_link().stop(_)->ok.

That module is basically giving callbacks to the Erlang VM. See it a bit as the main function in C, except you also have to provide a stop function that will clean up once the process exits. In this case we need nothing.

What's the muumuu_sup module? That's the final step to be glued in OTP. OTP has a concept called supervisors. Supervisors are in charge of checking OTP-compliant processes, to start them, stop them, and provide guarantees regarding their state.

Unfortunately, our process isn't OTP-compliant. The guys at Ericsson have long ago hit that problem and developed a supervisor bridge, which basically acts as a wrapper. This is what we could use if I were not the kind of person to want my OTP processes done correctly everywhere.

For the time being, I'll stick with a regular supervisor and will rewrite the FSM right after:

-module(muumuu_sup).-behaviour(supervisor).-export([start_link/0]).-export([init/1]).start_link()->supervisor:start_link(?MODULE,[]).init([])->{ok,{{one_for_one,1,5},[{console,{muumuu_fsm,start_link,[]},permanent,5000,worker,[muumuu_fsm]}]}}.

This will start muumuu_fsm as a permanent worker that can die once every 5 seconds before the entire system crashes. I don't have a good way to pick frequencies, but 1 in 5 seconds sounds like something reasonable for someone to mash keys in ways bad enough it causes errors.

So then comes the rewrite from prototype to gen_fsm. This is stuff that has been covered in multiple tutorials before, so I'm going to skip most of it. You can instead look at books and docs for gen_fsm, follow along the final module, muumuu_fsm.erl, and see for yourself.

The biggest changes there, outside of providing the gen_fsm callbacks required by the OTP behavior, are related to the general information flow. Rather than being really direct sequences of functions doing whatever they want, the OTP version of the module becomes a lot more declarative.

We no longer enter a state function, ask a question, and wait for the response within the same context. The logic has moved so that an event in a state (say first_gas_vent) causes a question to be asked before transitioning to the state that will handle that response.

This doesn't make the code particulalry harder to read, just different:

init([])-><<A:32,B:32,C:32>>=crypto:rand_bytes(12),random:seed(A,B,C),{ok,wait_any_key,prompt(wait_any_key,#state{})}.%% [...]wait_any_key(_,State)->{next_state,first_core_check,prompt(first_core_check,State)}.first_core_check(no,State)->{next_state,first_gas_vent,prompt(first_gas_vent,State)};first_core_check(yes,State)->show_core_temperature(),{next_state,first_gas_vent,prompt(first_gas_vent,State)}.first_gas_vent(no,State)->StateName=venting_prevents_explosions,{next_state,StateName,prompt(StateName,State)};first_gas_vent(yes,State)->show_blow_crops_away(),{next_state,wait_for_command,prompt(wait_for_command,State),10000}.

This form, along with the experience gained in the prototype, allows for simpler state management via the State variable, which allows us to be more transparent about our usage of venting limits, for example. We also instantly benefit from everything OTP gives us in terms of transparency: tracing, logging, statistics, and so on (see the sys module)

With that code in place, we can compile and run the entire application:

λ → rebar compile
==> how-i-start (compile)
Compiled src/muumuu_app.erl
Compiled src/muumuu_sup.erl
Compiled src/muumuu_fsm.erl

With this compiled we can run it, with a funky command:

λ → erl -pa ebin -eval 'application:ensure_all_started(muumuu).' -noshell
To Start, Press Any Key.
> any
Check core temperature? (Y/N)
> y
Core temperature normal.
Vent radioactive gas? (Y/N)
> y
*Gas blows away corn crop*

That's kind of an ugly command to run the app, but the app is now something other people can use to pull it within their own systems.

In order to run it ourselves and actually ship it to customers, we will need to build a release.

Releases

The directory structure we've been using was for an application and turns out looking like:

src/
ebin/

At the simplest level. A release is basically a group of applications put together. For this reason, we'll change the directory structure a bit and add the relx executable in there (the relx adoption is still low enough that it's worth shipping with the code):

apps/
    - muumuu/
        - src/
        - ebin/
rebar.config
relx
relx.config

All applications you need will go into apps/. Here I just moved src/ to apps/muumuu/.

The rebar.config file looks like this:

%% Tell rebar about this directory's structure{lib_dirs,["apps","deps"]}.{sub_dirs,["apps/*"]}.%% Build a release when compiling{post_hooks,[{compile,"./relx"}]}.

This basically means that calling rebar compile will indirectly call relx to build the release.

to build the release, relx.config contains all the instructions:

{paths,["apps","deps"]}.{default_release,muumuu,"0.1.0"}.%% comment this line for a release that ships its own Erlang VM{include_erts,false}.%% uncomment this line to ship a release without the source code included% {include_src, false}.{release,{muumuu,"0.1.0"},%% list of apps to include[muumuu]}.

This will create a release that will only include Erlang source code, but use the currently installed Erlang VM to run things. Then the magic happens:

λ → rebar compile
==> muumuu (compile)
==> how-i-start (compile)
Starting relx build process ...
Resolving OTP Applications from directories:
    /Users/ferd/code/self/how-i-start/apps
    /Users/ferd/.kerl/builds/R16B03-1/release_R16B03-1/lib

Resolving available releases from directories:
    /Users/ferd/code/self/how-i-start/apps
    /Users/ferd/.kerl/builds/R16B03-1/release_R16B03-1/lib

Resolved muumuu-0.1.0
release successfully created!

And a release is born! To run it:

λ → ./_rel/bin/muumuu -noshell
To Start, Press Any Key.
>

Pretty cool. This can now be shipped and distributed to people.

I want to make the release a bit fancier though. As you've just seen, we still need to put the -noshell by hand, which is totally unacceptable.

To fix this, add a config/ repository, and I open the vm.args file in vim in there:

# only show the programmed prompt-noshell# for remote access & debugging-name[email protected]# not needed-smp disable
+A 1

Arguments in there I merged into one. A good practice for any Erlang system is to give it a name, which will let you connect to it while it's running. In this case I could go in and debug the console as the user is maintaining the powerplant.

The last arguments (-smp disable +A 1) are basically optimizations for this very app: they remove Erlang parallelism (I'm running a single active process for the thing, so why bother?) and removes the number of asynchronous threads for IO to a single one (for the same reason -- one active process, why bother?).

In more serious apps, tweaking your VM options can be worthwhile, but outside of this text's scope.

The relx config file needs an update too:

{paths,["apps","deps"]}.{default_release,muumuu,"1.0.0"}.%% comment this line for a release that ships its own Erlang VM{include_erts,false}.%% uncomment this line to ship a release without the source code included% {include_src, false}.{release,{muumuu,"1.0.0"},%% list of apps to include[muumuu]}.{vm_args,"./config/vm.args"}.

The last line is the new one. Compile again and the arguments should implicitly be passed to the node:

λ → rebar compile
==> muumuu (compile)
==> how-i-start (compile)
===> Starting relx build process ...
===> Resolving OTP Applications from directories:
          /Users/ferd/code/self/how-i-start/apps
          /Users/ferd/.kerl/builds/R16B03-1/release_R16B03-1/lib
===> Resolving available OTP Releases from directories:
          /Users/ferd/code/self/how-i-start/apps
          /Users/ferd/.kerl/builds/R16B03-1/release_R16B03-1/lib
===> Resolved muumuu-1.0.0
===> release successfully created!
λ → ./_rel/bin/muumuu
To Start, Press Any Key.
> <Tab>
Check core temperature? (Y/N)
>

Cool, everything works. I now have a binary executable I can link to from anywhere in the system and will require no magical arguments to work!

Tests

As much as I like to try and get testing done ahead of time -- it's the only time it's not super terrible and crappy -- I often end up adding it after the fact when I know I'll have to maintain it.

For this, each app should have its tests, so I'll have to add a test/ directory in apps/muumuu/.

My tool of choice is Common Test, which while it is kind of full of annoying overheads for unit testing and is mostly useless for shell output (you gotta deal with HTML files), it scales fairly well for integration and system tests.

The test suite in there is going to be muumuu_SUITE.erl:

-module(muumuu_SUITE).-include_lib("common_test/include/ct.hrl").-compile(export_all).%% Copy/pasting from the suite-record(state,{no_vent_count=0,pid,yes,no}).all()->[demo_session].

So at first I'm just gonna make one run-through test. Testing muumuu is going to be hard because it's purely a side-effectful application.

Before going further, I'll say that the trick to getting this working is to use meck, which is pretty much the best code-mocking application around.

Adding meck can be done by declaring rebar.config dependencies:

{deps,[{meck,"0.8.*",{git,"https://github.com/eproxus/meck.git",{tag,"0.8.1"}}}]}.

Rebar pulls stuff from github, so at the very least, stick a tag or a commit hash in there, and not a branch that can be mutable. Call in rebar get-deps compile and it will be available for tests.

Now back to muumuu_SUITE. Time to set up the state:

init_per_testcase(demo_session,Config)->mock_io(),{ok,Pid}=muumuu_fsm:start_link(),[{pid,Pid}|Config].end_per_testcase(_,Config)->meck:unload(io),Pid=?config(pid,Config),unlink(Pid),exit(Pid,shutdown),wait_for_death(Pid).

Mocking the io system is a fun way to basically take it and make it return messages we can look at. That all takes place in mock_io(), and after that's in place, we start a muumuu instance directly (no application needed):

mock_io()->%% For this one we mock the IO system so that instead of%% printing messages and getting input to and from the user,%% we instead have a message-passing interface that will%% be inspectable.%%%% Note that because the `io` module is pre-compiled by the%% VM, we have to 'unstick' it first, and be careful to keep%% it mocked as little as possible.Parent=self(),code:unstick_dir(filename:dirname(code:where_is_file("io.beam"))),meck:new(io,[passthrough,no_link]),meck:expect(io,format,fun(Str)->Parent!{out,Str},okend),meck:expect(io,format,fun(Str,Args)->Parent!{out,io_lib:format(Str,Args)},okend),meck:expect(io,get_line,fun(_Prompt)->Parent!{in,self()},receive{Parent,In}->Inendend).

Ugly. The first step is unstickying the directory for Erlang code. Most modules don't require that, only those in Erlang's standard library. Unstickying allows to load new versions of code at run time, which meck dynamically does.

Here what I'm doing is mocking the functions io:format/1, io:format/2 and io:get_line/1 to send messages of the form {in, Msg} and {out, Msg} from input and output, respectively. meck:unload(io) will undo that.

We also had the wait_for_death/1 call. I'm using these everywhere in tests. Timers are the enemy of good concurrent testing, and if you rely on a timer:sleep(1000) of some sort to make sure everything is clean, you're doing it wrong.

Here the function polls to return ASAP, with a tiny sleep to not heat up your room too much via the CPU:

wait_for_death(Pid)->caseis_process_alive(Pid)oftrue->timer:sleep(10),wait_for_death(Pid);false->okend.

With this done, I can start planning more for the test. This here is something I always want to write a library for, and maybe some day I will, but right now I re-do that crap by hand every time:

%%%%%%%%%%%%%%%%%%%%% TEST CASES %%%%%%%%%%%%%%%%%%%%%%% Pressing a given key through the message-passing interface%% will yield expected output. There should be a prompt waiting%% for a key.%% All states can be cycled through using only Y/N answers.demo_session(Config)->Pid=?config(pid,Config),out("press.*any.*key.*>"),in("<tab>"),% the characters shouldn't matterout("check.*core.*temp.*>"),in("Y"),out("temperature.*normal"),out("vent.*radioactive.*gas.*>"),in("no"),out("venting.*prevents.*explosion.*>"),in("yES"),out("gas.*blows.*crop.*"),gen_fsm:send_event(Pid,timeout),% force a timeout fasterout(".*Y/N.*>"),% some questionin("No"),% who caresin("vent gAs"),% force a commandout("gas.*blows.*crop.*").

I basically just write the test the way I want it to look like. I will start expecting messages that will match the regex "press.*any.*key.*>" being output, after which I'll insert <tab>. Rinse and repeat.

Here, my desire is pretty much to turn the interactions I'd write in the shell into a bunch of function calls and matches.

That's why I planned having a message-passing interface. I can now write functions to wrap that functionality:

%%%%%%%%%%%%%%%%%% HELPERS %%%%%%%%%%%%%%%%%%in(Input)->receive{in,Pid}->Pid!{self(),Input}after1000->ct:pal("MBOX: ~p",[process_info(self(),messages)]),error({too_long,{in,Input}})end.

If we look back into the mocked function, the mocked function sends us {in, ProcessThatWaitsForInput}. We take the Input argument, and send it back to the mocked function (which runs in its own process).

If we never receive the in message, we crash, but printing the debugging information. Interestingly here the function I use is ct:pal. It works exactly like io:format, except:

  1. It outputs to both the shell and HTML logs for Common Test
  2. It's not gonna be used in production systems and it's surely never going to be mocked (unlike io).

The out/1 helper is slightly more complex:

%% fuzzily match the input string, waiting 1s at mostout(Expected)->receive{out,Prompt}->ct:pal("Expected: ~p~nPrompt: ~p",[Expected,Prompt]),{match,_}=re:run(Prompt,Expected,[dotall,caseless,global])after1000->ct:pal("MBOX: ~p",[process_info(self(),messages)]),error({too_long,{out,Expected}})end.

That one makes an assertion on a regular expression with re:run/3, and the rest is similar to what we did in in/1. We receive the output, match it, and that's it.

And there we go, we can run the tests (remember, you need to have called rebar get-deps compile before getting here, so meck is there and built):

λ → rebar ct -r skip_deps=true
==> muumuu (ct)
DONE.
Testing apps.muumuu: TEST COMPLETE, 1 ok, 0 failed of 1 test cases

WARN:  'ct' command does not apply to directory /Users/ferd/code/self/how-i-start

For a non-release (something where src/ is still at the top level), just calling rebar ct would work, without testing all the dependencies, which is legitimately a crapload nicer. To skip testing the dependencies but still accounting for them, the -r skip_deps=true arguments need to be added.

In practice, it will often make sense to develop all the applications independently, running their own tests, and only later pull them all in a release structure to build and ship a release.

After this, I go do something else because I'm pretty much done.

Startups from 2010: Acquired, Pivoted or Still Going?

$
0
0

Editor's Note:

This is one of the longest posts I've made - in length and duration. It's said that one year in the life of a startup is the equivalent of dog years when compared to more established companies. So looking back to a post I made just over four years ago is the equivalent of a generation of startups, and a quick glance at each shows what you'd expect from a generation of change - with some names graduating to the big time, others running in place, and yet a good chunk who've disappeared altogether.

My goal with this June 2010 post was not to highlight the top private companies, as I withheld inclusion of many of the bigger companies, like Facebook and Twitter and Tesla. Instead, it was to show 50 I was following that had promise, leveraging a tool from Symbaloo. I highlighted 50 top startups on the Web. I was reminded of this effort when, at the conclusion of my kids' kindergarten year, many teachers featured computers with Symbaloo organizing their Web.

So let's go back to the list of fifty, and see what's happened. How many are on the verge of hitting the big time, how many are out of business, and how many got acquired?

Walking Down Fifty Top Startups of 2010
#1: FoursquareStatus: Independent
At the time of the post, there was no buzzier company than Foursquare. It was the undisputed leader of the checkin. It beat back competition from Facebook Places, and its places database became the backend of even more third party apps. But its Swarm app has seemed to fall flat among users, and nobody's quite sure where the company's headed.

#2: SpotifyStatus: Independent
At the time of my post, Spotify hadn't even made it to the US. Now it has 1,000+ employees and is the clear market leader in streaming music, with Apple's Beats and others chasing. The company is looking to finish the music business revolution started by Napster more than a decade ago, and remains one of my favorites.

#3: AutomatticStatus: Independent
Automattic, the company behind WordPress, isn't going anywhere. They've got about 250 employees, and have been acquiring small services like Intense Debate, instead of getting gobbled themselves. They haven't had a big exit like Tumblr, or become a small part of a big company, like Blogger at Google, but they're a lead option for publishing, from blogs to full-featured sites.

#4: PosterousStatus: Acquired by Twitter
Posterous was acquired by Twitter in 2012, and while they initially promised their Spaces service for private blogging would remain live, it was quickly killed, becoming yet another acquihire. They'd raised $10 million overall.

#5: BlippyStatus: Pivoted beyond recognition
The Blippy I liked didn't turn out how I had hoped. Its initial privacy bump with credit cards being revealed online came at an inconvenient time, right as they raised funding and were poised to come out of the gate strong. That, combined, with an audience skeptical of their focus on oversharing, meant they had to do the dreaded pivot. Phil Kaplan, cofounder of Blippy, left with momentum flagging. Now they're an app for animated GIFs.

#6: SlideShareStatus: Acquired by LinkedIn
In 2012, Slideshare was acquired by LinkedIn for a rumored $119 million. That'd probably be around $300 million in today's inflated market.

#7: TumblrStatus: Acquired by Yahoo.
Following incredible traffic growth, Tumblr became the biggest acquisition made by Yahoo CEO Marissa Meyer, who has a tough task to transform a Web pioneer. The $1.1 billion deal in May of 2013 was huge in many ways.

#8 TweetDeckStatus: Acquired by Twitter.
The social networking client (which debuted here in 2008) was won by Twitter in a bid above $40 million, after a rumored buy from Ubermedia. TweetDeck founder Iain Dodsworth has since left Twitter, and is working in stealth on Gathers.

#9: SquareStatus: Independent
The company, headed by Jack Dorsey, cofounder of Twitter, made a stake for itself in an incredibly challenging market, and you can see their payment readers in small businesses or cabs. You could argue they got too big too fast, or margins are tight, but they've neither crashed nor graduated since the first report.

#10: QuoraStatus: Independent
Quora is an odd duck. They were a Web darling at the end of 2010, founded by early Facebookers, and attracting engagement from a who's who of Silicon Valley. With one founder jetissoned, and the company now being a fifth wheel at Y Combinator, it's not sure whether they're the next Wikipedia or Yahoo! Answers. Nobody really questions the quality of the discussions, but everything else is questioned.

#11: CinchCastStatus: Pivoted beyond recognition
The audio Web publishing service I really liked, and used regularly, is vaporized, as was my published content. The shadows of that plan show a site focused on cloud-based conference calls and Web seminars. Meh.

#12: Sports Blog NationStatus: Independent
If you don't remember the name Sports Blog Nation, I'll bet you've seen their content. This one time sports publishing empire expanded to what's now Vox Media, taking on smart writing for tech and much more. I've been lucky enough to see this happen in front of us over the last decade, and consider the founder of SB Nation, Tyler Bleszinski, a fellow A's fan, a good friend. If there are any questions about Vox Media, it's whether the content business can be valued in a world where it's so easy to make it for free.

#13: Bit.lyStatus: Independent.
Once Twitter switched to its own t.co URL shortener, bit.ly's perceived value for short link and analytics dropped dramatically. The company refocused on performance tracking and engagement, and is still plugging away, even if you don't hear about them daily, as you used to.

#14: my6senseStatus: Independent.
Months after my initial post, I expanded my time helping my6sense from consulting to something closer to full time as VP of Marketing. We launched a lot of cool tools, but there wasn't a big enough market (or funding) to make that dream a reality. So I left to Google, and the team refocused on mobile advertising. Founder Barak Hachamov is now working on Samba.me, a reactive video messaging play.

#15: Thing LabsStatus: Acquired by AOL.
Thing Labs, and the Brizzly team, were acquired by AOL after getting an offer in July of 2010, which I had incorrectly hypothesized was from Foursquare. Soon after, Brizzly was shut down, and the team splintered inside of AOL, to take up roost at Avocado, Dropbox and other places.

#16: PlancastStatus: Pivoted beyond recognition
Plancast was given a funeral and the post-mortem was written in early 2012. The social events sharing company just didn't take off. The site still exists, focused on planning and event management.

#17: SeesmicStatus: Acquired by Hootsuite.
After a bazillion pivots, and clear buddying up with Salesforce and Microsoft, the remnants of Seesmic were sold to Hootsuite in 2012. Founder Loic LeMeur seems to have retrenched into his annual conference, LeWeb.

#18: Lunch.comStatus: Independent.
Lunch.com, a community around relevant news and opinion, has been very quiet - but seems to have its diehard users, as many of these sites get. I'd bet it doesn't cost much to run, so there's no urgency to shut it down, but it's hard to predict a rebound.

#19: GowallaStatus: Acquired by Facebook.
After years of chasing Foursquare's fumes, Gowalla's team waved the white flag, and was acquired by Facebook in December 2011.

#20: DropBoxStatus: Independent.
DropBox is a consumer cloud giant, and has managed a significant position, even when faced with industry competition from practically all the big names: Google, Microsoft, Apple, Salesforce to name a few. The world awaits what will happen once DropBox goes public.

#21: LazyfeedStatus: Dead
The lead developer made many intesting apps, including a Twitter and RSS mashup LazyScope, and Joint.im, but users haven't always followed. So Lazyfeed is gone.

#22: HunchStatus: Acquired by eBay.
The consumer-focused personalization company pivoted to providing services for businesses, and looks like a good fit for the online auction giant.

#23: EcademyStatus: Acquired by Sunzu
Ecademy was acquired by Sunzu in July of 2012, and the open business networking community's content was later vaporized. Most the original Ecademy team is now working on social media tactics with Scredible.

#24: XobniStatus: Acquired by Yahoo!
Initially rumored to join Microsoft in 2008, the address book apps and plugins group was acquired by Yahoo! as part of Marissa Mayer's buying binge in the summer of 2013.

#25: TweetmemeStatus: Dead.
Nik Halstead's smart consumer facing link site that pulled content from Twitter was sunset in 2012 in favor of analytics and more professional work, a move that made sense when Twitter reduced opportunities for consumer-facing developers.

#26: FeedlyStatus: Independent.
Even if Google Reader is dead (a moment of silence, please), RSS isn't. Feedly was among the most obvious to benefit from the feed reader giant's closure. Nobody really asks how Feedly makes money or what its future plans are… just that it keep working and doing well. It does. As they debuted here, I'm always happy to hear good news from team Feedly.

#27: KloutStatus: Acquired by Lithium Technologies
I despise the idea of Klout. Independent arbiters giving you a score is distasteful. But that didn't stop the company from being famous (or infamous) and at least one other company deciding that their stockpile of data and faux reputation was worth paying for. So that happened. Congrats to the team.

#28: Justin.tvStatus: Independent
Justin.TV is still around, and is a well-known site for live activity. In fact, they've told customers that videos will no longer be archived, since nobody was watching anyway. I have to assume most people at this point are watching YouTube.

#29: AmplifyStatus: Dead
The Amplify we once knew, which encouraged you to build and share something between a tweet and a blog post, is gone - shutting down in February of 2012. Ironically, they pointed users to web clipping service Clipboard, which itself was shut down after being acquired by Salesforce.com a year or so later.

#30: OneRiotStatus: Acquired by Walmart Labs
After pivoting from the unfriendly world of real time search to the world of ad networks, OneRiot was picked up by the active, if not lofty, palace of Walmart Labs in September 2011.

#31: LijitStatus: Acquired by Federated Media
Lijit has had its share of bumps over the last four years. The company was picked up by Federated Media in October 2011, and in early 2014, spun out when Federated Media sold off its content business in the beginning of this year. Now, Lijit claims they're back, under a new name. Lost? Me too.

#32: EchoStatus: Independent
Echo may first have been known as a comments competitor to Disqus and others, and was among the first to capture reactions from the real-time stream. They successfully moved to aid enterprise companies with adding social platforms and engagement with their platform. They're quietly executing - even if an endgame isn't obvious.

#33: MyLikesStatus: Independent
MyLikes bills itself as the largest content and advertising platform in the world and has a top-notch board. The social advertising platform raised just under $6 million in 2010, and isn't noisy about trumpeting its success. Side note: Robert Scoble and I were introduced as advisors in early 2010 when they raised seed funding, but things are quiet on that front.

#34: OutbrainStatus: Independent
Outbrain, like it or hate it, is most well know for its “more like this” or “you might also like this” type of content ads spread across the web. Their goal is more engagement on content, and they do a great job at it. They've raised nearly $100 million, with the last round being in 2013.

#35: DailyBoothStatus: Acquired by AirBnB
In a “you didn't see that coming” deal, the photo sharing site team behind DailyBooth ended up as an acquihire for dodgy rental service AirBnB in the summer of 2012. Meanwhile, DailyBooth is dead.

#36: GistStatus: Acquired by Blackberry (RIM)
Gist, the one-time contacts manager, was acquired by Blackberry in early 2011. A little more than a year later, news came that Blackberry would shut down the original site. Oh well.

#37: SolutoStatus: Acquired by Asurion
The cloud service for remotely managing devices was acquired for more than $100 million by insurer Asurion in late 2013. Maybe not an exciting ending, but the checks still clear the bank - a good turn for $18 million funding by VCs.

#38: Tungle.meStatus: Acquired by Blackberry (RIM)
As with Gist, social calendaring app Tungle was acquired in early 2011 by Blackberry to improve their software suite.

#39: QwotebookStatus: Dead
A fun idea for a quote repository and database, started by my good friend Drew Olanoff (and listing me as an advisor) didn't really get off the ground. Next time.

#40: RegatorStatus: Independent
Blog and content directory Regator is still tracking blog trends and aggregating news from the Web. But I haven't heard a word from them in some time, and they're not talking.

#41: Untitled StartupStatus: Independent (with a new name)
Damon Cortesi's untitled startup ended up being Simply Measured. The social media analytics company now sports 159 employees and says it's used by more than ⅓ of the top 100 global brands. Hats off to you, Damon. I knew this was one to watch.

#42: TwazzupStatus: Independent (but mostly dead)
Twitter's battles with developers over web clients and search made some promising ventures less so over time. Founder Cyril Moutran lists his time at Twazzup as ending in 2011 on his LinkedIn profile, spending more time on his role with Feedly.

#43: The CadmusStatus: Dead
The Cadmus is no longer being maintained, but the team behind the Twitter analysis tool is working on a host of new products under the name Anomaly Innovations in San Francisco.

#44: BranchrStatus: Dead
The one time text and image-based pay per click advertising company, who once claimed hundreds of millions of ads on tens of thousands of sites, seemingly vaporized. Web site? Gone. Twitter account? Dead. Huh.

#45: Graphic.lyStatus: Acquired by Blurb
Graphic.ly, the comic book enthusiasts platform, was integrated into Blurb earlier this year, having raised about $10 million in funding.

#46: BlockChalkStatus: Acquired by Klout
BlockChalk, a Twitter-centric community bulletin board, renamed itself BlockBoard, and was later turned into an acquihire by Klout (see above) in February 2012.

#47: FitBitStatus: Independent
FitBit, in my view, lit the fire of the wearable gadget revolution. They're the default fitness tracker, competing with Nike, Jawbone and others, and I've been a devout user for the better part of two years - even if I wasn't at time of this post in 2010. So far, they've managed to keep independent. I'd see them being picked up by a big company before seeing them go public, but if they did, I'd invest.

#48: RockMeltStatus: Acquired by Yahoo!
Yahoo acquired Rockmelt in 2013 and the products were shut down shortly afterward, despite rock star visibility at launch, and the support of Marc Andreesen.

#49: Live IntentStatus: Independent
LiveIntent is focused on email advertising and engagement. They've been at it since 2009. And they're hiring. But if I had to do this list again, they're probably not top of mind.

#50: FabulisStatus: Pivoted beyond recognition
I loved Jason Goldberg's Socialmedian, and launched it here. Fabulis was his next attempt, a social network for gay men. I liked the idea, but wasn't the target market. When Fabulis pivoted into Fab.com, and had a meteoric rise for flash sales and other online commerce, I was again cheering on Jason from the sidelines, and root him on through the subsequent downturn. We'll see what happens with Fab, but Fabulis is most certainly dead.


Summary

I never claimed I was ranking these fifty startups as the most likely to succeed, or ranking them in order, although it's easy to see the first ten named were stronger than the last ten in my list. But when the list was posted and people questioned the longevity of these companies, I knew it would take time to bear it out. With four-plus year hindsight, we have those results.

Of the fifty companies named, 21 are independent, 19 were acquired, four pivoted, and six are dead. I expected more to be dead, outright, but it shows me many companies in search of an out found a willing corporate partner - be it another startup, or a large company, be it Blackberry, LinkedIn, Yahoo! or eBay. Tumblr sold for more than a billion, and Spotify is valued at much more. Others, no doubt, went for nothing except a handshake. Interestingly, none of these 50 were acquired by Google.

If I were to do this again, with hindsight, there'd be less focus on Twitter tools, but in 2010, one thought Twitter's platform was not just an interesting testbed, but potentially a big business. And I didn't even mention Uber.

Meanwhile, Symbaloo, who hosted my original list of fifty… they're still around - and found a niche.

How you will not uncover Satoshi

$
0
0

Computer forensics is the science of finding evidence in computers and digital documents, and when a hacker perform forensics, better be prepared for the unknown. Satoshi did many things forensicsin order to try to stay anonymous: he used Tor, he used anonymous e-mail servers, he did not disclose personal information in posts and probably he didn’t use the name Satoshi as his computer username. And here is when forensics come to play. In the Bitcoin original PDF paper (either the 2008 or the 2009 revisions) you will find PDF metadata. The PDF metadata holds no information for the “author” field, of course. Only we know from the metadata the paper was created with OpenOffice.org 2.4 Writer (which has a PDF export function), the date it was created, and the time-zone. If you look at the PDF with a text editor, you will see that there is a field not shown by the document property dialog:

/ID [ <CA1B0A44BD542453BEF918FFCD46DC04>
<CA1B0A44BD542453BEF918FFCD46DC04> ]

This is the ID of the PDF document. It turns out that the ID of the document was (in version 2.4 of OpenOffice.org) built as an MD5 digest of some fields, as shown by this code:

    OStringBuffer aID( 1024 );
    if( m_aDocInfo.Title.Len() )
        appendUnicodeTextString( m_aDocInfo.Title, aID );
    if( m_aDocInfo.Author.Len() )
        appendUnicodeTextString( m_aDocInfo.Author, aID );
    if( m_aDocInfo.Subject.Len() )
        appendUnicodeTextString( m_aDocInfo.Subject, aID );
    if( m_aDocInfo.Keywords.Len() )
        appendUnicodeTextString( m_aDocInfo.Keywords, aID );
    if( m_aDocInfo.Creator.Len() )
        appendUnicodeTextString( m_aDocInfo.Creator, aID );
    if( m_aDocInfo.Producer.Len() )
        appendUnicodeTextString( m_aDocInfo.Producer, aID );
...
    aID.append( m_aCreationDateString.getStr(), m_aCreationDateString.getLength() );
    aInfoValuesOut = aID.makeStringAndClear();
    osl_getSystemTime( &aGMT );            
    rtlDigestError nError = rtl_digest_updateMD5( m_aDigest, &aGMT, sizeof( aGMT ) );
    if( nError == rtl_Digest_E_None )
        nError = rtl_digest_updateMD5( m_aDigest, m_aContext.URL.getStr(), m_aContext.URL.getLength()*sizeof(sal_Unicode) );  /// OJO QUE ES UNICODE
    if( nError == rtl_Digest_E_None )
        nError = rtl_digest_updateMD5( m_aDigest, aInfoValuesOut.getStr(), aInfoValuesOut.getLength() );

The aGMT field can be re-created knowing the m_aCreationDateString field, which is stored on the PDF as:

/CreationDate(D:20090324113315-06'00')>>

Since we know Satoshi’s PC was a Windows XP, then we also know that aGMT has only millisecond precision. The CreationDate field does not store the milliseconds, but an attacker can easily brute-force the millisecond field and find the correct value.

The aInfoValuesOut field would contain Creator, Producer and CreationDate fields already present in the PDF, in their hexadecimal format:

<</Creator<FEFF005700720069007400650072>
/Producer<FEFF004F00700065006E004F00660066006900630065002E006F0072006700200032002E0034>

So aInfoValuesOut would be:

FEFF005700720069007400650072FEFF004F00700065006E004F00660066006900630065002E006F0072006700200032002E0034D:20090324113315-06'00'

The m_aContext.URL is the interesting part: it holds the path and name of the PDF where it was originally located, in Unicode format. I’m sure Satoshi did know about how products leak data, and probably he located the file in some innocent path like “c:\bitcoin\src\docs”. But while he has publishing one of the most extraordinary papers ever seen he may have been too exited to remember it. Then the URL could have been something like this:

file:///C:/Documents%20and%20Settings/JLewis/My%20Documents/Bitcoin/paper/Bitcoin.pdf

Here JLewis is just an example of a possible username.

Then somebody could try to uncover Satoshi by brute-forcing each possible 8 letter username, each possible “My Documents” folder (in the most common languages), each possible subdirectory (such as /Desktop or /Bitcoin), and each possible millisecond field.

But of course it is highly improbable that Satoshi had overlooked this, very improbable he did store the PDF under the directory of his username, quite improbable the username is found, and it is much more improbable somebody finds the exact path and name of the original PDF file. And still, I’m uneasy.

This entry was posted on June 19, 2014, 6:27 pm and is filed under Uncategorized. You can follow any responses to this entry through RSS 2.0. You can leave a response, or trackback from your own site.

Google’s Balloon Internet Experiment, One Year Later

$
0
0
A Loon balloon ascends to the stratosphere and heads toward Google's partner school, Linoca Gayoso Castelo Branco, where students wait for the arrival of the Internet. Photo: Courtesy of Google

A Loon balloon ascends to the stratosphere and heads toward Google’s partner school, Linoca Gayoso Castelo Branco, where students wait for the arrival of the Internet. Photo: Courtesy of Google

Earlier this month, Mike Cassidy, a project director at Google’s high-risk research division X, woke before dawn in the Northwest Brazilian state of Piauí. It was already warm and humid. He drove for an hour to a clearing in a rural area and helped his team launch several high-altitude balloons with a payload of Internet connectivity technology—the nub of the project he directs called Loon. Then he jumped into another car to race against the balloons’ flight path, speeding along an unpaved road, dodging chickens and pigs, and finally arriving at Agua Fria, a tiny community on the outskirts of the town Campo Maior.

Cassidy pulled up to a rural schoolhouse that had never been able to receive high-quality Internet signals. (Locals sometimes climb trees to try to get a signal for their mobile phones.) The principal, who doubles as the lunchroom cook, ushered him into a classroom filled with middle-school-age kids. Within minutes, one of the balloons he’d launched that morning was overhead, enabling a teacher to get a high-speed connection on his computer. The instructor was able to supplement that day’s lesson about Portugal with Google maps and Wikipedia. Students asked off-the-wall questions—and got answers courtesy of Google. Later when Cassidy spoke to the kids, they shared their goals: One wanted to be an engineer; another, a doctor.

Cassidy has always contended that by providing the Internet to unserved areas, his project could help make those dreams achievable. A year after the project’s public launch, he’s confident that Internet service enabled by high-altitude balloons is more than a possibility. “We’ve definitely crossed the point where there’s a greater than 50 percent chance that this will happen,” he says.

Project Loon team members install a Loon Internet antenna while the schoolchildren look on. Photo: Courtesy of Google

Project Loon team members install a Loon Internet antenna while schoolchildren look on. Photo: Courtesy of Google

When Google announced Project Loon on June 15 last year, a lot of people were skeptical. But Google reports that since then, it has been able to extend balloon flight times and add mobile connectivity to the service. As a result, Google’s expectations are flying even higher than the 60,000-foot strata where its balloons live.

“This is the poster child for Google X,” says Astro Teller, who heads the division. “The balloons are delivering 10x more bandwidth, 10x steer-ability, and are staying up 10x as long. That’s the kind of progress that can only happen a few more times until we’re in a problematically good place.” A year ago, balloons typically remained aloft for a few days at most, and download speeds averaged one or two megabits per second—comparable to the slowest wired Internet service.

Loon team members Chris and Cyrus set up the mobile ground station that will connect the Loon balloon signal to the Internet. Photo: Courtesy of Google

Loon team members Chris and Cyrus set up the mobile ground station that will connect the Loon balloon signal to the Internet. Photo: Courtesy of Google

Since the first public test flights in New Zealand, Google’s balloons have clocked over a million and half kilometers. Increasing the crafts’ endurance has been a key challenge. One balloon expert originally scoffed at the claim that Loon balloons would eventually keep going for an average of 100 days. “Absolutely impossible—even three weeks is rare,” said Per Lindstrand, known for his highly publicized forays with entrepreneur Richard Branson. Indeed, during the first New Zealand tests, the balloons generally lasted only a few days.

Google bumped up flight durations by extensively analyzing its failures. Using former military operations people, it took pains to recover nearly every downed balloon. Google’s testing procedures also got a boost from winter’s polar vortex: Ground temperatures in South Dakota, where some of the balloons are manufactured, went as low as -40 degrees Celsius, about the same as what balloons encounter at 60,000 feet. So Google could test the inflated materials at leisure. Ultimately, Loon engineers concluded that one of the biggest factors in failure were small, almost undetectable leaks in the polymer skins that must withstand huge atmospheric pressure and up to 100 mph winds. Even a pinhole can shorten a balloon’s lifespan to a few days.

The Loon crew not only strengthened the fragile seams where leaks often occurred but took fanatic care in handling the envelopes. They used to walk on the flattened polymer in stocking feet. Now only super-fluffy socks will do. Google, being Google, tested this protocol before implementing it. Teams were created, one wearing conventional socks and the other donning fuzzy footwear. Both groups performed a rigidly proscribed line dance, as if the spread-out balloon polymers were Urban Cowboy-style dance floors. The fluffy-footed team created significantly fewer pinholes. “We’re getting the next five billion online through a line dance!” Teller says.

Google also improved Loon flight times by dramatically upgrading the altitude control system, increasing the vertical range of the balloons so they can catch more favorable winds. (Its balloons “steer” their way around the world by placing themselves in wind currents headed in the right direction.) As a result, it’s not unusual for Google to keep balloons flying for 75 days. One craft, dubbed Ibis 152 (Google uses bird species to nickname its balloons), has been aloft over 100 days and is still flying. An earlier balloon, Ibis 162, circled the globe three times before descending. (It completed one circumnavigation in 22 days, a world record.)

Illustration: Courtesy of Google

Illustration: Courtesy of Google

The longer times aloft threatened to overwhelm the Loon software that adjusts the flight plans. “We didn’t have the infrastructure ready,” Cassidy says. When flights were shorter, Google could rely on data from the National Oceanic and Atmospheric Administration. But since NOAA only supplies forecasts for 16 days out, Google now has to make sophisticated guesses using a giant database of historical wind and weather data. To plot the optimal path—one that maximizes battery life and avoids crummy weather conditions—Google’s software recalculates as often as once a minute. (During the long, speedy flight of Ibis 162, Google recalculated 8 million times.)

Google made a different kind of advance with Loon when it added the capability to send data using the LTE spectrum—making it possible for people to connect directly to the Internet with their mobile phones. (Loon’s original Wi-Fi connection required a base station and a special antenna.) Using LTE also helped Google boost the capacity of its connections. Recent Loon payloads are providing as much as 22 MB/sec to a ground antenna and 5 MB/sec to a handset.

With the advances made over the last year, Google has a clearer idea of how it might eventually make money with Loon. In addition to connecting the last few billion (and often cash-poor) Internet users, the project might serve already-connected people with fat wallets by partnering with existing providers to deliver a super-roaming experience. “It’s not limited to rural areas,” Teller says. “Even in the middle of Silicon Valley you can lose connections while driving; large buildings and hills can block the signals. Balloons can fill in dead spots.”

Cyrus, a radio engineer for Google, pre-tests a balloon’s LTE subsystem from a hotel balcony in the Piauí state capital, Teresina. Photo: Courtesy of Google

Cyrus, a radio engineer for Project Loon, pre-tests a balloon’s LTE subsystem from a hotel balcony in the Piauí state capital, Teresina. Photo: Courtesy of Google

When Loon began, Teller’s biggest worry was that powerful telecommunications companies would view the project as a threat and attempt to snuff the project. But in part because LTE makes it possible for Google to interweave its service with existing mobile data networks—standard service in cities, Loon connectivity in more remote areas—the reaction has been the opposite. “Every telco wants to partner with us,” Cassidy says. Google is working with the regional giant Vivo and Telebras in its Brazil tests. It’s also working with Vodaphone in New Zealand. “They’re teaching us about what they need and how they can help,” Teller says.

Cassidy ticks off the goals for the next year: routine flights of 100 days, 100 balloons in the air at once (that’s four times the previous high), and then a full ring of between 300 to 400 balloons circling the globe to offer continuous service to a targeted area. Teller predicts that Loon may actually make enough progress to become operational, at least in the guise of a pilot program. Just where this will happen and how many people it will serve, he doesn’t say.

Not surprisingly, the Loon team is growing. Though Google won’t reveal headcounts, it allows that the muscle behind the balloon effort is comparable to other Google X projects like Glass or self-driving cars.

Still, Google seems to be hedging its bets on how to connect the world. Last April, it bought Titan Aerospace, a two-year-old company that makes high-altitude, solar powered drones that offer a non-inflatable approach to wireless Internet. (Facebook reportedly also bid on Titan; not long afterward it bought another drone company, Ascenta.). And earlier this month Google paid $500 million to acquire Skybox Imaging, a startup that makes low-cost satellites; though the orbiting payloads will be mainly used to augments its mapping operations, Google also said that the technology might eventually help improve Internet access.

Teller contends that the multi-pronged approach is not chaos but synergy. “The ethos of Google is to be loosely coupled,” he says. “If everyone is dependent on one approach, the whole system slows down.” He sees opportunities for collaboration. “Loon works with satellites as a backup system,” he says. “Titan Aerostar might need Loon’s wind data.”

Loon’s leaders acknowledge there are plenty of potential obstacles that may well pop their aspirations. But for now, Teller is optimistic. “On Loon’s two-year birthday, I would hope, instead of running experiments, we’ll have a more or less permanent set of balloons. In one or several countries, you will turn on your phone and talk to the balloons,” he says. “Yes, Loon will be offering service.”

The Project Loon team prepares for launch at dawn. Photo: Courtesy of Google

The Project Loon team prepares for launch at dawn. Photo: Courtesy of Google


GET /vehicles/{id}/command/honk_horn

$
0
0

never mind... the current version (5.8) of the response has that info: "charger_phases":3

here is the response of my car:

{ "charging_state":"Charging",

"charge_limit_soc":90, "charge_limit_soc_std":90, "charge_limit_soc_min":50, "charge_limit_soc_max":100, "charge_to_max_range":false, "battery_heater_on":false, "not_enough_power_to_heat":false, "max_range_charge_counter":0, "fast_charger_present":false, "battery_range":184.47, "est_battery_range":87.06, "ideal_battery_range":147.58, "battery_level":66, "battery_current":27.6, "charge_energy_added":10.7, "charge_miles_added_rated":41.5, "charge_miles_added_ideal":33.0, "charger_voltage":232, "charger_pilot_current":16, "charger_actual_current":16, "charger_power":4, "time_to_full_charge":2.03, "charge_rate":31.1, "charge_port_door_open":true, "scheduled_charging_start_time":null, "scheduled_charging_pending":false, "user_charge_enable_request":null, "charge_enable_request":true, "eu_vehicle":true, "charger_phases":3 }

RFC 7258 – Pervasive Monitoring Is an Attack

$
0
0
RFC 7258 - Pervasive Monitoring Is an Attack

[Docs] [txt|pdf] [draft-farrell-per...] [Diff1] [Diff2]

BEST CURRENT PRACTICE

Internet Engineering Task Force (IETF)                        S. Farrell
Request for Comments: 7258                        Trinity College Dublin
BCP: 188                                                   H. Tschofenig
Category: Best Current Practice                                 ARM Ltd.
ISSN: 2070-1721                                                 May 2014


                   Pervasive Monitoring Is an Attack

Abstract

   Pervasive monitoring is a technical attack that should be mitigated
   in the design of IETF protocols, where possible.

Status of This Memo

   This memo documents an Internet Best Current Practice.

   This document is a product of the Internet Engineering Task Force
   (IETF).  It represents the consensus of the IETF community.  It has
   received public review and has been approved for publication by the
   Internet Engineering Steering Group (IESG).  Further information on
   BCPs is available in Section 2 of RFC 5741.

   Information about the current status of this document, any errata,
   and how to provide feedback on it may be obtained at
   http://www.rfc-editor.org/info/rfc7258.

Copyright Notice

   Copyright (c) 2014 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents
   (http://trustee.ietf.org/license-info) in effect on the date of
   publication of this document.  Please review these documents
   carefully, as they describe your rights and restrictions with respect
   to this document.  Code Components extracted from this document must
   include Simplified BSD License text as described in Section 4.e of
   the Trust Legal Provisions and are provided without warranty as
   described in the Simplified BSD License.









Farrell & Tschofenig      Best Current Practice                 [Page 1]
RFC 7258            Pervasive Monitoring Is an Attack           May 20141.  Pervasive Monitoring Is a Widespread Attack on Privacy

   Pervasive Monitoring (PM) is widespread (and often covert)
   surveillance through intrusive gathering of protocol artefacts,
   including application content, or protocol metadata such as headers.
   Active or passive wiretaps and traffic analysis, (e.g., correlation,
   timing or measuring packet sizes), or subverting the cryptographic
   keys used to secure protocols can also be used as part of pervasive
   monitoring.  PM is distinguished by being indiscriminate and very
   large scale, rather than by introducing new types of technical
   compromise.

   The IETF community's technical assessment is that PM is an attack on
   the privacy of Internet users and organisations.  The IETF community
   has expressed strong agreement that PM is an attack that needs to be
   mitigated where possible, via the design of protocols that make PM
   significantly more expensive or infeasible.  Pervasive monitoring was
   discussed at the technical plenary of the November 2013 IETF meeting
   [IETF88Plenary] and then through extensive exchanges on IETF mailing
   lists.  This document records the IETF community's consensus and
   establishes the technical nature of PM.

   The term "attack" is used here in a technical sense that differs
   somewhat from common English usage.  In common English usage, an
   attack is an aggressive action perpetrated by an opponent, intended
   to enforce the opponent's will on the attacked party.  The term is
   used here to refer to behavior that subverts the intent of
   communicating parties without the agreement of those parties.  An
   attack may change the content of the communication, record the
   content or external characteristics of the communication, or through
   correlation with other communication events, reveal information the
   parties did not intend to be revealed.  It may also have other
   effects that similarly subvert the intent of a communicator.
   [RFC4949] contains a more complete definition for the term "attack".
   We also use the term in the singular here, even though PM in reality
   may consist of a multifaceted set of coordinated attacks.

   In particular, the term "attack", used technically, implies nothing
   about the motivation of the actor mounting the attack.  The
   motivation for PM can range from non-targeted nation-state
   surveillance, to legal but privacy-unfriendly purposes by commercial
   enterprises, to illegal actions by criminals.  The same techniques to
   achieve PM can be used regardless of motivation.  Thus, we cannot
   defend against the most nefarious actors while allowing monitoring by
   other actors no matter how benevolent some might consider them to be,
   since the actions required of the attacker are indistinguishable from
   other attacks.  The motivation for PM is, therefore, not relevant for
   how PM is mitigated in IETF protocols.



Farrell & Tschofenig      Best Current Practice                 [Page 2]
RFC 7258            Pervasive Monitoring Is an Attack           May 20142.  The IETF Will Work to Mitigate Pervasive Monitoring"Mitigation" is a technical term that does not imply an ability to
   completely prevent or thwart an attack.  Protocols that mitigate PM
   will not prevent the attack but can significantly change the threat.
   (See the diagram on page 24 of RFC 4949 for how the terms "attack"
   and "threat" are related.)  This can significantly increase the cost
   of attacking, force what was covert to be overt, or make the attack
   more likely to be detected, possibly later.

   IETF standards already provide mechanisms to protect Internet
   communications and there are guidelines [RFC3552] for applying these
   in protocol design.  But those standards generally do not address PM,
   the confidentiality of protocol metadata, countering traffic
   analysis, or data minimisation.  In all cases, there will remain some
   privacy-relevant information that is inevitably disclosed by
   protocols.  As technology advances, techniques that were once only
   available to extremely well-funded actors become more widely
   accessible.  Mitigating PM is therefore a protection against a wide
   range of similar attacks.

   It is therefore timely to revisit the security and privacy properties
   of our standards.  The IETF will work to mitigate the technical
   aspects of PM, just as we do for protocol vulnerabilities in general.
   The ways in which IETF protocols mitigate PM will change over time as
   mitigation and attack techniques evolve and so are not described
   here.

   Those developing IETF specifications need to be able to describe how
   they have considered PM, and, if the attack is relevant to the work
   to be published, be able to justify related design decisions.  This
   does not mean a new "pervasive monitoring considerations" section is
   needed in IETF documentation.  It means that, if asked, there needs
   to be a good answer to the question "Is pervasive monitoring relevant
   to this work and if so, how has it been considered?"

   In particular, architectural decisions, including which existing
   technology is reused, may significantly impact the vulnerability of a
   protocol to PM.  Those developing IETF specifications therefore need
   to consider mitigating PM when making architectural decisions.
   Getting adequate, early review of architectural decisions including
   whether appropriate mitigation of PM can be made is important.
   Revisiting these architectural decisions late in the process is very
   costly.

   While PM is an attack, other forms of monitoring that might fit the
   definition of PM can be beneficial and not part of any attack, e.g.,
   network management functions monitor packets or flows and anti-spam



Farrell & Tschofenig      Best Current Practice                 [Page 3]
RFC 7258            Pervasive Monitoring Is an Attack           May 2014


   mechanisms need to see mail message content.  Some monitoring can
   even be part of the mitigation for PM, for example, certificate
   transparency [RFC6962] involves monitoring Public Key Infrastructure
   in ways that could detect some PM attack techniques.  However, there
   is clear potential for monitoring mechanisms to be abused for PM, so
   this tension needs careful consideration in protocol design.  Making
   networks unmanageable to mitigate PM is not an acceptable outcome,
   but ignoring PM would go against the consensus documented here.  An
   appropriate balance will emerge over time as real instances of this
   tension are considered.

   Finally, the IETF, as a standards development organisation, does not
   control the implementation or deployment of our specifications
   (though IETF participants do develop many implementations), nor does
   the IETF standardise all layers of the protocol stack.  Moreover, the
   non-technical (e.g., legal and political) aspects of mitigating
   pervasive monitoring are outside of the scope of the IETF.  The
   broader Internet community will need to step forward to tackle PM, if
   it is to be fully addressed.

   To summarise: current capabilities permit some actors to monitor
   content and metadata across the Internet at a scale never before
   seen.  This pervasive monitoring is an attack on Internet privacy.
   The IETF will strive to produce specifications that mitigate
   pervasive monitoring attacks.

3.  Process Note

   In the past, architectural statements of this sort, e.g., [RFC1984]
   and [RFC2804], have been published as joint products of the Internet
   Engineering Steering Group (IESG) and the Internet Architecture Board
   (IAB).  However, since those documents were published, the IETF and
   IAB have separated their publication "streams" as described in
   [RFC4844] and [RFC5741].  This document was initiated after
   discussions in both the IESG and IAB, but is published as an IETF-
   stream consensus document, in order to ensure that it properly
   reflects the consensus of the IETF community as a whole.

4.  Security Considerations

   This document is entirely about privacy.  More information about the
   relationship between security and privacy threats can be found in
   [RFC6973].  Section 5.1.1 of [RFC6973] specifically addresses
   surveillance as a combined security-privacy threat.







Farrell & Tschofenig      Best Current Practice                 [Page 4]
RFC 7258            Pervasive Monitoring Is an Attack           May 20145.  Acknowledgements

   We would like to thank the participants of the IETF 88 technical
   plenary for their feedback.  Thanks in particular to the following
   for useful suggestions or comments: Jari Arkko, Fred Baker, Marc
   Blanchet, Tim Bray, Scott Brim, Randy Bush, Brian Carpenter, Benoit
   Claise, Alissa Cooper, Dave Crocker, Spencer Dawkins, Avri Doria,
   Wesley Eddy, Adrian Farrel, Joseph Lorenzo Hall, Phillip
   Hallam-Baker, Ted Hardie, Sam Hartmann, Paul Hoffman, Bjoern
   Hoehrmann, Russ Housley, Joel Jaeggli, Stephen Kent, Eliot Lear,
   Barry Leiba, Ted Lemon, Subramanian Moonesamy, Erik Nordmark, Pete
   Resnick, Peter Saint-Andre, Andrew Sullivan, Sean Turner, Nicholas
   Weaver, Stefan Winter, and Lloyd Wood.  Additionally, we would like
   to thank all those who contributed suggestions on how to improve
   Internet security and privacy or who commented on this on various
   IETF mailing lists, such as the ietf@ietf.org and the
   perpass@ietf.org lists.

6.  Informative References

   [IETF88Plenary]
              IETF, "IETF 88 Plenary Meeting Materials", November 2013,
              <http://www.ietf.org/proceedings/88/>.

   [RFC1984]  IAB, IESG, Carpenter, B., and F. Baker, "IAB and IESG
              Statement on Cryptographic Technology and the Internet",
              RFC 1984, August 1996.

   [RFC2804]  IAB and IESG, "IETF Policy on Wiretapping", RFC 2804, May
              2000.

   [RFC3552]  Rescorla, E. and B. Korver, "Guidelines for Writing RFC
              Text on Security Considerations", BCP 72, RFC 3552, July
              2003.

   [RFC4844]  Daigle, L. and Internet Architecture Board, "The RFC
              Series and RFC Editor", RFC 4844, July 2007.

   [RFC4949]  Shirey, R., "Internet Security Glossary, Version 2", RFC4949, August 2007.

   [RFC5741]  Daigle, L., Kolkman, O., and IAB, "RFC Streams, Headers,
              and Boilerplates", RFC 5741, December 2009.

   [RFC6962]  Laurie, B., Langley, A., and E. Kasper, "Certificate
              Transparency", RFC 6962, June 2013.





Farrell & Tschofenig      Best Current Practice                 [Page 5]
RFC 7258            Pervasive Monitoring Is an Attack           May 2014


   [RFC6973]  Cooper, A., Tschofenig, H., Aboba, B., Peterson, J.,
              Morris, J., Hansen, M., and R. Smith, "Privacy
              Considerations for Internet Protocols", RFC 6973, July
              2013.

Authors' Addresses

   Stephen Farrell
   Trinity College Dublin
   Dublin  2
   Ireland

   Phone: +353-1-896-2354
   EMail: stephen.farrell@cs.tcd.ie


   Hannes Tschofenig
   ARM Ltd.
   6060 Hall in Tirol
   Austria

   EMail: Hannes.tschofenig@gmx.net
   URI:   http://www.tschofenig.priv.at




























Farrell & Tschofenig      Best Current Practice                 [Page 6]


Html markup produced by rfcmarkup 1.107, available from http://tools.ietf.org/tools/rfcmarkup/

RFC 7258 - Pervasive Monitoring Is an Attack

[Docs] [txt|pdf] [draft-farrell-per...] [Diff1] [Diff2]

BEST CURRENT PRACTICE

Internet Engineering Task Force (IETF)                        S. Farrell
Request for Comments: 7258                        Trinity College Dublin
BCP: 188                                                   H. Tschofenig
Category: Best Current Practice                                 ARM Ltd.
ISSN: 2070-1721                                                 May 2014


                   Pervasive Monitoring Is an Attack

Abstract

   Pervasive monitoring is a technical attack that should be mitigated
   in the design of IETF protocols, where possible.

Status of This Memo

   This memo documents an Internet Best Current Practice.

   This document is a product of the Internet Engineering Task Force
   (IETF).  It represents the consensus of the IETF community.  It has
   received public review and has been approved for publication by the
   Internet Engineering Steering Group (IESG).  Further information on
   BCPs is available in Section 2 of RFC 5741.

   Information about the current status of this document, any errata,
   and how to provide feedback on it may be obtained at
   http://www.rfc-editor.org/info/rfc7258.

Copyright Notice

   Copyright (c) 2014 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents
   (http://trustee.ietf.org/license-info) in effect on the date of
   publication of this document.  Please review these documents
   carefully, as they describe your rights and restrictions with respect
   to this document.  Code Components extracted from this document must
   include Simplified BSD License text as described in Section 4.e of
   the Trust Legal Provisions and are provided without warranty as
   described in the Simplified BSD License.









Farrell & Tschofenig      Best Current Practice                 [Page 1]
RFC 7258            Pervasive Monitoring Is an Attack           May 20141.  Pervasive Monitoring Is a Widespread Attack on Privacy

   Pervasive Monitoring (PM) is widespread (and often covert)
   surveillance through intrusive gathering of protocol artefacts,
   including application content, or protocol metadata such as headers.
   Active or passive wiretaps and traffic analysis, (e.g., correlation,
   timing or measuring packet sizes), or subverting the cryptographic
   keys used to secure protocols can also be used as part of pervasive
   monitoring.  PM is distinguished by being indiscriminate and very
   large scale, rather than by introducing new types of technical
   compromise.

   The IETF community's technical assessment is that PM is an attack on
   the privacy of Internet users and organisations.  The IETF community
   has expressed strong agreement that PM is an attack that needs to be
   mitigated where possible, via the design of protocols that make PM
   significantly more expensive or infeasible.  Pervasive monitoring was
   discussed at the technical plenary of the November 2013 IETF meeting
   [IETF88Plenary] and then through extensive exchanges on IETF mailing
   lists.  This document records the IETF community's consensus and
   establishes the technical nature of PM.

   The term "attack" is used here in a technical sense that differs
   somewhat from common English usage.  In common English usage, an
   attack is an aggressive action perpetrated by an opponent, intended
   to enforce the opponent's will on the attacked party.  The term is
   used here to refer to behavior that subverts the intent of
   communicating parties without the agreement of those parties.  An
   attack may change the content of the communication, record the
   content or external characteristics of the communication, or through
   correlation with other communication events, reveal information the
   parties did not intend to be revealed.  It may also have other
   effects that similarly subvert the intent of a communicator.
   [RFC4949] contains a more complete definition for the term "attack".
   We also use the term in the singular here, even though PM in reality
   may consist of a multifaceted set of coordinated attacks.

   In particular, the term "attack", used technically, implies nothing
   about the motivation of the actor mounting the attack.  The
   motivation for PM can range from non-targeted nation-state
   surveillance, to legal but privacy-unfriendly purposes by commercial
   enterprises, to illegal actions by criminals.  The same techniques to
   achieve PM can be used regardless of motivation.  Thus, we cannot
   defend against the most nefarious actors while allowing monitoring by
   other actors no matter how benevolent some might consider them to be,
   since the actions required of the attacker are indistinguishable from
   other attacks.  The motivation for PM is, therefore, not relevant for
   how PM is mitigated in IETF protocols.



Farrell & Tschofenig      Best Current Practice                 [Page 2]
RFC 7258            Pervasive Monitoring Is an Attack           May 20142.  The IETF Will Work to Mitigate Pervasive Monitoring"Mitigation" is a technical term that does not imply an ability to
   completely prevent or thwart an attack.  Protocols that mitigate PM
   will not prevent the attack but can significantly change the threat.
   (See the diagram on page 24 of RFC 4949 for how the terms "attack"
   and "threat" are related.)  This can significantly increase the cost
   of attacking, force what was covert to be overt, or make the attack
   more likely to be detected, possibly later.

   IETF standards already provide mechanisms to protect Internet
   communications and there are guidelines [RFC3552] for applying these
   in protocol design.  But those standards generally do not address PM,
   the confidentiality of protocol metadata, countering traffic
   analysis, or data minimisation.  In all cases, there will remain some
   privacy-relevant information that is inevitably disclosed by
   protocols.  As technology advances, techniques that were once only
   available to extremely well-funded actors become more widely
   accessible.  Mitigating PM is therefore a protection against a wide
   range of similar attacks.

   It is therefore timely to revisit the security and privacy properties
   of our standards.  The IETF will work to mitigate the technical
   aspects of PM, just as we do for protocol vulnerabilities in general.
   The ways in which IETF protocols mitigate PM will change over time as
   mitigation and attack techniques evolve and so are not described
   here.

   Those developing IETF specifications need to be able to describe how
   they have considered PM, and, if the attack is relevant to the work
   to be published, be able to justify related design decisions.  This
   does not mean a new "pervasive monitoring considerations" section is
   needed in IETF documentation.  It means that, if asked, there needs
   to be a good answer to the question "Is pervasive monitoring relevant
   to this work and if so, how has it been considered?"

   In particular, architectural decisions, including which existing
   technology is reused, may significantly impact the vulnerability of a
   protocol to PM.  Those developing IETF specifications therefore need
   to consider mitigating PM when making architectural decisions.
   Getting adequate, early review of architectural decisions including
   whether appropriate mitigation of PM can be made is important.
   Revisiting these architectural decisions late in the process is very
   costly.

   While PM is an attack, other forms of monitoring that might fit the
   definition of PM can be beneficial and not part of any attack, e.g.,
   network management functions monitor packets or flows and anti-spam



Farrell & Tschofenig      Best Current Practice                 [Page 3]
RFC 7258            Pervasive Monitoring Is an Attack           May 2014


   mechanisms need to see mail message content.  Some monitoring can
   even be part of the mitigation for PM, for example, certificate
   transparency [RFC6962] involves monitoring Public Key Infrastructure
   in ways that could detect some PM attack techniques.  However, there
   is clear potential for monitoring mechanisms to be abused for PM, so
   this tension needs careful consideration in protocol design.  Making
   networks unmanageable to mitigate PM is not an acceptable outcome,
   but ignoring PM would go against the consensus documented here.  An
   appropriate balance will emerge over time as real instances of this
   tension are considered.

   Finally, the IETF, as a standards development organisation, does not
   control the implementation or deployment of our specifications
   (though IETF participants do develop many implementations), nor does
   the IETF standardise all layers of the protocol stack.  Moreover, the
   non-technical (e.g., legal and political) aspects of mitigating
   pervasive monitoring are outside of the scope of the IETF.  The
   broader Internet community will need to step forward to tackle PM, if
   it is to be fully addressed.

   To summarise: current capabilities permit some actors to monitor
   content and metadata across the Internet at a scale never before
   seen.  This pervasive monitoring is an attack on Internet privacy.
   The IETF will strive to produce specifications that mitigate
   pervasive monitoring attacks.

3.  Process Note

   In the past, architectural statements of this sort, e.g., [RFC1984]
   and [RFC2804], have been published as joint products of the Internet
   Engineering Steering Group (IESG) and the Internet Architecture Board
   (IAB).  However, since those documents were published, the IETF and
   IAB have separated their publication "streams" as described in
   [RFC4844] and [RFC5741].  This document was initiated after
   discussions in both the IESG and IAB, but is published as an IETF-
   stream consensus document, in order to ensure that it properly
   reflects the consensus of the IETF community as a whole.

4.  Security Considerations

   This document is entirely about privacy.  More information about the
   relationship between security and privacy threats can be found in
   [RFC6973].  Section 5.1.1 of [RFC6973] specifically addresses
   surveillance as a combined security-privacy threat.







Farrell & Tschofenig      Best Current Practice                 [Page 4]
RFC 7258            Pervasive Monitoring Is an Attack           May 20145.  Acknowledgements

   We would like to thank the participants of the IETF 88 technical
   plenary for their feedback.  Thanks in particular to the following
   for useful suggestions or comments: Jari Arkko, Fred Baker, Marc
   Blanchet, Tim Bray, Scott Brim, Randy Bush, Brian Carpenter, Benoit
   Claise, Alissa Cooper, Dave Crocker, Spencer Dawkins, Avri Doria,
   Wesley Eddy, Adrian Farrel, Joseph Lorenzo Hall, Phillip
   Hallam-Baker, Ted Hardie, Sam Hartmann, Paul Hoffman, Bjoern
   Hoehrmann, Russ Housley, Joel Jaeggli, Stephen Kent, Eliot Lear,
   Barry Leiba, Ted Lemon, Subramanian Moonesamy, Erik Nordmark, Pete
   Resnick, Peter Saint-Andre, Andrew Sullivan, Sean Turner, Nicholas
   Weaver, Stefan Winter, and Lloyd Wood.  Additionally, we would like
   to thank all those who contributed suggestions on how to improve
   Internet security and privacy or who commented on this on various
   IETF mailing lists, such as the ietf@ietf.org and the
   perpass@ietf.org lists.

6.  Informative References

   [IETF88Plenary]
              IETF, "IETF 88 Plenary Meeting Materials", November 2013,
              <http://www.ietf.org/proceedings/88/>.

   [RFC1984]  IAB, IESG, Carpenter, B., and F. Baker, "IAB and IESG
              Statement on Cryptographic Technology and the Internet",
              RFC 1984, August 1996.

   [RFC2804]  IAB and IESG, "IETF Policy on Wiretapping", RFC 2804, May
              2000.

   [RFC3552]  Rescorla, E. and B. Korver, "Guidelines for Writing RFC
              Text on Security Considerations", BCP 72, RFC 3552, July
              2003.

   [RFC4844]  Daigle, L. and Internet Architecture Board, "The RFC
              Series and RFC Editor", RFC 4844, July 2007.

   [RFC4949]  Shirey, R., "Internet Security Glossary, Version 2", RFC4949, August 2007.

   [RFC5741]  Daigle, L., Kolkman, O., and IAB, "RFC Streams, Headers,
              and Boilerplates", RFC 5741, December 2009.

   [RFC6962]  Laurie, B., Langley, A., and E. Kasper, "Certificate
              Transparency", RFC 6962, June 2013.





Farrell & Tschofenig      Best Current Practice                 [Page 5]
RFC 7258            Pervasive Monitoring Is an Attack           May 2014


   [RFC6973]  Cooper, A., Tschofenig, H., Aboba, B., Peterson, J.,
              Morris, J., Hansen, M., and R. Smith, "Privacy
              Considerations for Internet Protocols", RFC 6973, July
              2013.

Authors' Addresses

   Stephen Farrell
   Trinity College Dublin
   Dublin  2
   Ireland

   Phone: +353-1-896-2354
   EMail: stephen.farrell@cs.tcd.ie


   Hannes Tschofenig
   ARM Ltd.
   6060 Hall in Tirol
   Austria

   EMail: Hannes.tschofenig@gmx.net
   URI:   http://www.tschofenig.priv.at




























Farrell & Tschofenig      Best Current Practice                 [Page 6]


Html markup produced by rfcmarkup 1.107, available from http://tools.ietf.org/tools/rfcmarkup/

Google Trends: Hacker News vs. Slashdot

$
0
0

Arabic — العربية

Bengali — বাংলা

Bulgarian — български

Catalan — Català

Chinese (Hong Kong) — 中文 (香港)

Chinese (Simplified) — 中文(简体)

Chinese (Traditional) — 中文 (繁體)

Croatian — Hrvatski

Czech — Čeština

Danish — Dansk

Dutch — Nederlands

English (Australia)

English (UK)

English (US)

Estonian — Eesti keel

Filipino

Finnish — Suomi

French — Français

German — Deutsch

Greek — Ελληνικά

Hebrew — עברית

Hindi — हिन्दी

Hungarian — magyar

Indonesian — Indonesia

Italian — Italiano

Japanese — 日本語

Korean — 한국어

Latin American Spanish — Español latinoamericano

Latvian — Latviešu valoda

Lithuanian — Lietuvių

Malay — Bahasa Malaysia

Malayalam — മലയാളം

Norwegian — Norsk

Persian — فارسی

Polish — polski

Portuguese (Brazil) — Português (Brasil)

Portuguese (Portugal) — Português (Portugal)

Romanian — Română

Russian — Русский

Serbian — српски

Slovak — Slovenčina

Slovenian — slovenščina

Spanish — Español

Swedish — svenska

Thai — ไทย

Turkish — Türkçe

Ukrainian — Українська

Vietnamese — Tiếng Việt

Job interviews go both ways (2011)

$
0
0

Note: this is a post from 2011. It used to be on the IndexTank blog which no longer exists, so I’m putting it up here. 

When I interview a candidate here at IndexTank, I take it very seriously and try to be at the top of my game. I have to prove to this person that it’s worth choosing our company over others. Desirable candidates have many choices, so I’m competing with every hot tech company in the Bay Area.

Candidates often forget this fact. I expect them to bombard me with questions about where we are going, what I’m thinking, what it’s like to work hereMaybe even ask me a hard technical question, it’s only fair. I plan for ample interview time for this reason.

It turns out, the majority of the people don’t do this. They simply put on their best face, answer every question and try to sell themselves. Some ask questions everyone should ask, such as the financial situation of the company. Very rarely someone probes me to see if they would like to have me as their boss.

In a previous post I mentioned an interview I had at Netscape in 1998. I can freely talk about that one; Netscape has been effectively dead so long that younger generations may think it was a brand of milk chocolate.

It all started when a got a call from Netscape through a friend who had joined a few months before and recommended me. That was enough for them to fly me over to the Bay Area for an interview a week later. Arrived from Pittsburgh late at night, drove from SFO to a generic hotel in Mountain View where I spent the evening reading about how Netscape was doing. They had just announced that they would be releasing their source code to the public, which was very intriguing to me.

I remember arriving at Netscape, a gigantic campus that used to belong to HP. Maybe they had four thousand employees at the time. I was told that I was interviewing to replace employee #7 (everyone talked about their own employee number) who was leaving because he was fully vested that month (red flag).

At first glance I was impressed with the place. People with purple hair roller-skating around the office with their dogs. It was my first encounter with the “creative minds of Silicon Valley” in their natural environment.

During lunch came another red flag. One manager talked about how they were a bit bummed because Yahoo had just surpassed their market valuation. Both companies were public at the time, and it was right when the Nasdaq was starting to take off like a rocket (which turned out to be the Challenger if you pardon the bad taste of my pun).

What really sealed it for me where the technical interviews. The first guy who interviewed me was a C guru. He spent most of the interview talking about himself and asked me one trivia question: why is EOF in C defined as -1 (btw, this is platform dependent). Look it up if you’re interested. This was a prelude to explain a hideous bug he’d been fighting based on that behavior and how proud he was about it.

Another guy asked me a few “aha” questions which I got (I was really into puzzles and brainteasers at the time). They were unrelated to programming for the most part. The only hard programming question was how to traverse a binary tree with two pointers and without using a stack. Good luck figuring that one out during an interview.

If I ask you that question during an interview and you answer it correctly, there are three possibilities:

  • you’re super smart
  • you knew the answer beforehand and are a good actor
  • you lucked out into the solution and are reasonably smart

Not a lot of information. But most importantly, it says little about whether you’re capable of fixing horrendous bugs in the Mac version of Netscape Navigator (release 4, now with extra bloat!).

I had been a big fan of Netscape until then. I left the building that evening with mixed feelings. Nobody seemed excited about open-sourcing the code, the original people where leaving, the coder gurus projected strange attitudes to a lowly candidate. I didn’t want to work there. It turned out I never had to make a decision because they didn’t call me back. A few months later they were acquired by AOL, who proceeded to gut the company and turn netscape.com into yet-another-portal.

I still thank them for flying me over from Pittsburgh, rental car, hotel and meals paid. That’s how I came to the Bay Area for the first time and thirteen years later I’m still here.

If you liked this post, follow me on Twitter. If you didn’t, thanks for reading this far :)

. Bookmark the

.

New Y Combinator Website

$
0
0

Our website got a facelift.

The content is pretty much the same. Since the old site was mostly text, I did my best to just make that text easier to digest and hopefully entice people to get through more of it. A lot of the best content on the site like What Happens at Y Combinator and How to Apply Successfully went largely unread because a large number of people were either intimidated by the wall of text or didn't have the patience to read through it.

The new site is responsive, but if you're viewing it on a mobile phone right now, I want you to know my favorite way to go through it is on a  large monitor. For posterity, we preserved the old version of the site at http://old.ycombinator.com. If what you see makes you worried for Hacker News, I want you to know that I have very different design goals for HN

Many thanks to Nick Sivo for helping me dig through the server to find everything I need. We're still making tweaks and changes, so if you have feedback on things you think we should approve, please let us know!

Chumby is back

$
0
0

As you know, the chumby systems have been running in a very limited mode for the last year or so.  This followed the acquisition of the Chumby property and rights by Blue Octy, LLC, a company I formed for that purpose.

During that time, I've been spending evenings and weekends building a new system to restore the functionality that was lost when Chumby Industries closed.  I didn't want to just get the old system running, because it was built in a different time with different goals, and some of the technology was getting a bit timeworn, which is very common in this industry.

Today, we launched the result of that work.

For those of you that are familiar with the old system, the website's UI will look very much the same.

Unlike Chumby Industries, I don't have a bunch of venture capital investment to pay for the recurring costs of keeping these system and the associated company in operation.  Either this company operates in the black, or it goes away - I can't personally absorb the costs forever.  I know this is a pretty radical idea in this weird tech industry, but there you go.

What I've decided to to is to preserve the functionality we've all had for the last year (single clock, music, alarms, etc) for free, so nobody's losing anything they've had since Chumby closed, but have the access the full set of apps on your chumby devices through a $3 monthly subscription.

There are some things left to do - I have a list of apps that need to be updated that have not kept up with the changes made from their data feeds, and some apps will probably have to removed since they are not salvageable.  That will be the primary focus for the next few weeks.

I also have some ideas for new apps that have been percolating.

Very special thanks to chumby user "diamaunt" for his invaluable help in getting this new system up and running.  Thanks also for the testers that have put in the time to help track down the bugs.

JavaScript Modules

$
0
0
JavaScript Modules

The next version of JavaScript comes with a module system heavily inspired by Node.js modules.
Here’s how it works.

We’re going to build a simple asap module, which lets you schedule some work to happen as soon as possible, but asynchronously. In Node.js, you can do this via process.nextTick, but there are different approaches that work in various browsers. We’re going to build a module that works everywhere.1

We start by creating a new file for this module. We’ll call it asap.js. The module provides a single primary function, which JavaScript calls the default export. You export a default value from a module by using export default.

varasap;varisNode=typeofprocess!=="undefined"&&{}.toString.call(process)==="[object process]";if(isNode){asap=process.nextTick;}elseif(typeofsetImmediate!=="undefined"){asap=setImmediate;}else{asap=setTimeout;}exportdefaultasap;

To import asap in another module, we use the import syntax:

importasapfrom"asap";asap(function(){console.log("hello async world!");});

This syntax takes the default function exported from asap and stores it in the variable asap, which we can then use to call it.

Sometimes modules need multiple exports, which their consumers can refer to individually by name.

For example, jQuery has a single primary export, (the jQuery function), and several additional named exports (ajax, getJSON, animate, etc.). In Node.js, the mkdirp module has a single default export, which recursively creates a directory, and a named export called sync, which does the same thing, but synchronously.

In our case, in addition to the default export, the asap module might wish to provide a later function, which schedules a function to run later, after other network or UI work has a chance to occur.

Our module looks the same as before, except we add a new export declaration.

varasap;varisNode=typeofprocess!=="undefined"&&{}.toString.call(process)==="[object process]";if(isNode){asap=process.nextTick;}elseif(typeofsetImmediate!=="undefined"){asap=setImmediate;}else{asap=setTimeout;}exportdefaultasap;exportvarlater=isNode?process.setImmediate:asap;

Now that we’ve exported later, we can import it in another module.

import{later}from"asap";later(function(){console.log("Running after other network events");});

For the curious, you can import both the default export and a number of named exports in the same import:

importasap,{later}from"asap";

And that’s all there is to it!

Renaming named imports

Sometimes when importing a named export, you want to give it its own local name.

import{unlinkasrm}from"fs";rm(filename,function(err){/* check errors */});

Importing into a namespace

It can be convenient to import all of a module’s named exports into a single local namespace.

import*asfsfrom"fs";fs.unlink(filename,function(err){/* check errors */});

Shorter named exports

You can make any declaration in JavaScript (like var or function) a named export by prefixing it with export.

// exports this function as "requestAnimationFrame"exportfunctionrequestAnimationFrame(){// cross-browser requestAnimationFrame
}// exports document.location as "location"exportvarlocation=document.location;

This also works with new declarations, like class and let.

// exports this class as "File"exportclassFile(){/* implementation */}// exports "0.6.3" as "VERSION"exportletVERSION="0.6.3";

These names are also available in the module’s local scope, so you can use them in other functions.

Grouping named exports

You can export any number of local variables together.

export{getJSON,postJSON,animate};functiongetJSON(){// implementation
}functionpostJSON(){// implementation
}functionanimate(){// implementation
}

You can put the grouped export declaration anywhere in the file, so you can define your imports and exports next to each other at the top of your modules if you wish.

JavaScript modules have a number of nice features that make important use cases smooth and seamless, including refactoring and tooling.

  1. JavaScript modules support late bound cycles between modules for both the default export and named exports. It just works.
  2. JavaScript modules separate the names that exist on the default export (and their prototype chains) and other named exports, avoiding collisions.
  3. JavaScript modules make it easy to determine exactly what you are importing by just looking at the syntax. That improves error messages, but also makes it easier to build tools like browserify and JSHint that work reliably without caveats.

Compared to CommonJS

JavaScript Modules

The next version of JavaScript comes with a module system heavily inspired by Node.js modules.
Here’s how it works.

We’re going to build a simple asap module, which lets you schedule some work to happen as soon as possible, but asynchronously. In Node.js, you can do this via process.nextTick, but there are different approaches that work in various browsers. We’re going to build a module that works everywhere.1

We start by creating a new file for this module. We’ll call it asap.js. The module provides a single primary function, which JavaScript calls the default export. You export a default value from a module by using export default.

varasap;varisNode=typeofprocess!=="undefined"&&{}.toString.call(process)==="[object process]";if(isNode){asap=process.nextTick;}elseif(typeofsetImmediate!=="undefined"){asap=setImmediate;}else{asap=setTimeout;}exportdefaultasap;

To import asap in another module, we use the import syntax:

importasapfrom"asap";asap(function(){console.log("hello async world!");});

This syntax takes the default function exported from asap and stores it in the variable asap, which we can then use to call it.

Sometimes modules need multiple exports, which their consumers can refer to individually by name.

For example, jQuery has a single primary export, (the jQuery function), and several additional named exports (ajax, getJSON, animate, etc.). In Node.js, the mkdirp module has a single default export, which recursively creates a directory, and a named export called sync, which does the same thing, but synchronously.

In our case, in addition to the default export, the asap module might wish to provide a later function, which schedules a function to run later, after other network or UI work has a chance to occur.

Our module looks the same as before, except we add a new export declaration.

varasap;varisNode=typeofprocess!=="undefined"&&{}.toString.call(process)==="[object process]";if(isNode){asap=process.nextTick;}elseif(typeofsetImmediate!=="undefined"){asap=setImmediate;}else{asap=setTimeout;}exportdefaultasap;exportvarlater=isNode?process.setImmediate:asap;

Now that we’ve exported later, we can import it in another module.

import{later}from"asap";later(function(){console.log("Running after other network events");});

For the curious, you can import both the default export and a number of named exports in the same import:

importasap,{later}from"asap";

And that’s all there is to it!

Renaming named imports

Sometimes when importing a named export, you want to give it its own local name.

import{unlinkasrm}from"fs";rm(filename,function(err){/* check errors */});

Importing into a namespace

It can be convenient to import all of a module’s named exports into a single local namespace.

import*asfsfrom"fs";fs.unlink(filename,function(err){/* check errors */});

Shorter named exports

You can make any declaration in JavaScript (like var or function) a named export by prefixing it with export.

// exports this function as "requestAnimationFrame"exportfunctionrequestAnimationFrame(){// cross-browser requestAnimationFrame
}// exports document.location as "location"exportvarlocation=document.location;

This also works with new declarations, like class and let.

// exports this class as "File"exportclassFile(){/* implementation */}// exports "0.6.3" as "VERSION"exportletVERSION="0.6.3";

These names are also available in the module’s local scope, so you can use them in other functions.

Grouping named exports

You can export any number of local variables together.

export{getJSON,postJSON,animate};functiongetJSON(){// implementation
}functionpostJSON(){// implementation
}functionanimate(){// implementation
}

You can put the grouped export declaration anywhere in the file, so you can define your imports and exports next to each other at the top of your modules if you wish.

JavaScript modules have a number of nice features that make important use cases smooth and seamless, including refactoring and tooling.

  1. JavaScript modules support late bound cycles between modules for both the default export and named exports. It just works.
  2. JavaScript modules separate the names that exist on the default export (and their prototype chains) and other named exports, avoiding collisions.
  3. JavaScript modules make it easy to determine exactly what you are importing by just looking at the syntax. That improves error messages, but also makes it easier to build tools like browserify and JSHint that work reliably without caveats.

Compared to CommonJS


Things You Should Know About Tor

$
0
0

We posted last week about the Tor Challenge and why everyone should use Tor. Since we started our Tor Challenge two weeks ago we have signed up over 1000 new Tor relays. But it appears that there are still some popular misconceptions about Tor. We would like to take this opportunity to dispel some of these common myths and misconceptions.

1. Tor Still Works

One of the many things that we learned from the NSA leaks is that Tor still works. According to the NSA  slides revealed by the Guardian last year, the NSA is still not able to completely circumvent the anonymity provided by Tor. They have been able to compromise certain Tor users in specific situations. Historically this has been done by finding an exploit for the Tor Browser Bundle or by exploiting a user that has misconfigured Tor. The FBI—possibly in conjunction with the NSA—was able to find one serious exploit for Firefox that lead to the takedown of Freedom Hosting and exploit of its users, but it was patched quickly, and no major exploits for Firefox appear to have been found since.

There is another possible attack where someone with control of 51% or more of the Tor network could compromise the anonymity of anyone on the network. But it does not seem to be the case that anyone has that much control—even the NSA.

We can conclude from this that Tor has probably not been broken at a cryptographic level, and the best attacks on Tor are side-channel attacks on browser bugs or user misconfiguration.

2. Tor is Not Only Used by Criminals

One of the most common misconceptions we hear is that Tor is only used by criminals and pedophiles. This is simply not true! There are many types of people that use Tor. Activists use it to circumvent censorship and provide anonymity. The military uses it for secure communications and planning. Families use Tor to protect their children and preserve their privacy. Journalists use it to do research on stories and communicate securely with sources. The Tor Project website has an excellent explanation of why Tor doesn't help criminals very much. To paraphrase: Criminals can already do bad things since they will break laws they have much better tools at their disposal than what Tor offers, such as botnets made with malware, stolen devices, identity theft, etc. In fact using Tor may help you protect yourself against some of these tactics that criminals use such as identity theft or online stalking.

You are not helping criminals by using Tor any more than you are helping criminals by using the Internet.

3. Tor Does Not Have a Military Backdoor

Another common opinion that we hear is that Tor was created by the military and so it must have a military backdoor. There is no backdoor in the Tor software. It is true that initial development of Tor was funded by the US Navy. However, it has been audited by several very smart cryptographers and security professionals who have confirmed that there is no backdoor. Tor is open source, so any programmer can take a look at the code and verify that there is nothing fishy going on. It is worked on by a team of activists who are extremely dedicated to privacy and anonymity.

4. No One in the US Has Been Prosecuted For Running a Tor Relay

As far as EFF is aware, no one in the US has been sued or prosecuted for running a Tor relay. Furthermore we do not believe that running a Tor relay is illegal under US law. This is, of course, no guarantee that you won't be contacted by law enforcement, especially if you are running an exit relay. However EFF believes this fact so strongly that we are running our own Tor relay. You can find out more about the legalities of running a Tor relay at the Tor Challenge Legal FAQ. However, if you are going to use Tor for criminal activity (which the Tor project asks that you not do) you can create more problems for yourself if you get prosecuted. Criminal activity also brings more scrutiny on to Tor making it worse for the public as a whole.

5. Tor is Easy to Use

You might think that because it is privacy software Tor must be hard to use. This is simply not true. The easiest way to get started with Tor is to download the Tor Browser Bundle. This is a browser that comes pre-configured to use Tor in a secure manner. It is easy to use and is all you need to start browsing with Tor. Another easy way to use Tor is with Tails. Tails is a live operating system that runs on a DVD or thumb drive. Tails routes your entire Internet connection through Tor. And when you shut it down, Tails “forgets” everything that was done while it was running.

6. Tor is Not as Slow as You Think

It is true that Tor is slower than a regular Internet connection. However, the Tor developers have been doing a lot of hard work to make the Tor network faster. And it is faster today than ever before. One of the best things that can be done to speed up the Tor network is to create more relays. If you would like to contribute to making the Tor network faster, you can check out our Tor Challenge

7. Tor is Not Foolproof

Tor is not perfect; you can destroy your own anonymity with Tor if you use it incorrectly. That's why it is important to always use Tor Browser Bundle or Tails and make sure that you keep your software up to date. It is also important to remember that if you log into services like Google and Facebook over Tor, you will be sacrificing your anonymity to those services.

Tor is some of the strongest anonymity software that exists. We think that it is important to dispel misconceptions about it so that the public can be more informed and confident in its usefulness. There are many great reasons to use Tor and very few reasons not to. So get started with Tor, and take back your privacy online.

Why Everyone Should be Concerned By the Seizure of MyRedBook.com

$
0
0

Last week, an online community for sex workers disappeared from the Internet. Visit SFRedbook.com, MyPinkBook.com, or MyRedBook.com right now, and you’ll only find the seals of the law enforcement agencies—the FBI, the DOJ, and the IRS—that seized the sites as part of a prostitution and money laundering investigation.

The seizure is part of a disturbing trend of targeting sex workers, but more than that, it is an attack on the rights to free speech and free association exercised by a diverse group of people, many of whom have nothing to do with the alleged crimes.

MyRedBook and its companion sites served a large and diverse community of sex workers. The sites functioned as social media platforms, with discussion boards for users in topics from politics to financial tips. It also served as a resource guide with information ranging from explanations of the law as it pertains to sex work to health information. For archived versions of the forums sex workers no longer have access to, click here.

These sites were essential tools for First Amendment protected speech and association—especially important for a community that values its privacy for a variety of legitimate reasons. This platform has been pulled out from under the feet of this community. As the Bay Area Sex Worker Outreach Project  (SWOP) said in a statement:

Today we also lost extensive online forums for a community of sex workers to keep each other safe, screen clients, and blacklist predators. Myredbook also hosted resource guides for sex workers who were struggling and created a venue for community counseling for those in need. Many local outreach organizations used this forum to connect with vulnerable sex workers.

To compound the destruction of this indispensible forum, the users of these sites now have cause to worry that their private information, such as IP addresses, phone numbers, and email addresses, may be in the hands of the FBI. In fact, news reports specifically note: “[FBI]Agents seized several boxes of evidence … including business documents and computer hardware.”

SWOP spokesperson Kristina Dolgin put it mildly when she said,  “It’s a very scary thing.”

EFF has always supported freedom of association and free speech, no matter who is doing the talking. In fact, these rights are especially important for controversial groups. That’s why we are so concerned to see these sites shut down—especially on the heels of the bank account closures of sex workers nationwide.

It’s true that in many states, some forms of sex work are illegal. But sex workers have First Amendment rights to speak out about the issues that concern them, to advocate for changes in the law, to counsel each other, to discuss the issues that are important to them, and to advertise legally permissible services. And sex workers have First Amendment rights to associate with each other on Internet forums and elsewhere.

As society changes, its values and laws change as well. But the oppression of disfavored groups uses the same tactics. Today, sex workers are being oppressed, but it will be a different group tomorrow. When we allow any group to be silenced and targeted, we are paving the way for it to happen again.    

EFF is keeping an eye on what happens in the case, and the ripple effect in the sex worker community as the criminal charges associated with this seizure move forward. In the meantime, we’ve compiled a list of resources and strategies sex workers can use to protect their anonymity.

A Way to Reverse Coronary Artery Disease? [pdf]

$
0
0

%PDF-1.5 %âãÏÓ 104 0 obj <</Linearized 1/L 917439/O 106/E 54210/N 11/T 915243/H [ 1476 726]>> endobj xref 104 59 0000000016 00000 n 0000002202 00000 n 0000002321 00000 n 0000002831 00000 n 0000003441 00000 n 0000003959 00000 n 0000004615 00000 n 0000005333 00000 n 0000005613 00000 n 0000005872 00000 n 0000006320 00000 n 0000006357 00000 n 0000006669 00000 n 0000006783 00000 n 0000006895 00000 n 0000007549 00000 n 0000008233 00000 n 0000009236 00000 n 0000009669 00000 n 0000010292 00000 n 0000010981 00000 n 0000011691 00000 n 0000011826 00000 n 0000012905 00000 n 0000013837 00000 n 0000014760 00000 n 0000015706 00000 n 0000016674 00000 n 0000016701 00000 n 0000017001 00000 n 0000017141 00000 n 0000018042 00000 n 0000018341 00000 n 0000019264 00000 n 0000023743 00000 n 0000029137 00000 n 0000029307 00000 n 0000029584 00000 n 0000031980 00000 n 0000040176 00000 n 0000040256 00000 n 0000040326 00000 n 0000042975 00000 n 0000043045 00000 n 0000043125 00000 n 0000045678 00000 n 0000045950 00000 n 0000046115 00000 n 0000046142 00000 n 0000046443 00000 n 0000046591 00000 n 0000048668 00000 n 0000049024 00000 n 0000049452 00000 n 0000049584 00000 n 0000051418 00000 n 0000051765 00000 n 0000052160 00000 n 0000001476 00000 n trailer <</Size 163/Root 105 0 R/Info 103 0 R/ID[]/Prev 915233>> startxref 0 %%EOF 162 0 obj <</Filter/FlateDecode/I 790/L 774/Length 638/S 602>>stream hÞb```b``³f`c`™Ï ĀB@1vŽ@ËÝ–ö- ê ¬2L.¤HŸomiÊqN©›±°L<³Ḿ7`Ј¸ØÒ1ANFb‚Bï,cÑ×?üdT ~1÷KXâPË¥’¬®`£p±Å¹™‰cÂĤi“Ô?ëýŽy4ü’И¸Ôg^JgQ§ HIãÁFŽˆ‰þ]«å”_´›Èp©µWÅ¥áÝ7ö-°kU™)'qˆñ`#‹‹ÏÊIœÞbÎíù —tðŸô3È(Hpdʹ8ñ Ç$1 —äü=:¥BN:"af° ï´œ‹šOªèt®O:TÏûÅåC°ªÛD!Iõ¶Ýœ?•TØ[¤,”\»ÝJ-¿¬`ê)=#ÒÁ¿\ÁFBÀÅ(7¡2Xh­K9ß=µí<ý6<„–³Ðl˜ÊúG©K¡§íÎW†pNOÆ6Ö+™R,f²+X5ê $ &ÏD–EZàÜÀàÄ鼟güă4ÚÌ endstream endobj 105 0 obj <</Metadata 102 0 R/PageLabels 97 0 R/Pages 99 0 R/Type/Catalog/ViewerPreferences<</Direction/L2R>>>> endobj 106 0 obj <</ArtBox[0.0 0.0 567.0 774.0]/BleedBox[0.0 0.0 567.0 774.0]/Contents[120 0 R 126 0 R 127 0 R 128 0 R 129 0 R 130 0 R 134 0 R 136 0 R]/CropBox[0.0 0.0 567.0 774.0]/MediaBox[0.0 0.0 567.0 774.0]/Parent 100 0 R/Resources<</ColorSpace<</CS0 114 0 R>>/ExtGState<</GS0 116 0 R/GS1 117 0 R>>/Font<</C2_0 125 0 R/C2_1 133 0 R/T1_0 109 0 R/T1_1 110 0 R/T1_2 111 0 R/T1_3 112 0 R/T1_4 124 0 R>>/ProcSet[/PDF/Text]/XObject<</Fm0 161 0 R/Fm1 135 0 R>>>>/Rotate 0/TrimBox[0.0 0.0 567.0 774.0]/Type/Page>> endobj 107 0 obj <</Filter/FlateDecode/Length 540>>stream H‰\”K¢@…÷üŠZv/:P<«cBk›¸˜GÆ™€P:$#Ä…ÿ~êÜSÓ$c¢9È}|‡[—xw܇~Qñ÷ylOnQ—~èfwsëÔÙ]û!Ò©êúv WòÛÞš)Š}òéy_Üí8\Æh³Qñó¾ÌOõRwãÙ½Fñ·¹ss?\Õ˯ÝéUŧÇ4ýq77,*QÛ­êÜÅúÒL_››S±¤½;¿_žo>gøùœœJåZ¦;wŸšÖÍÍpuÑ&ñŸ­Úüg¹¡ûï~i™v¾´¿›Ù‡kœ$e¶õ:¥N¡3ÑU‹.$¦`Œ.©Ðµ…6¢ó ÚŠÎÞ¡kþŸC¿Sï¡w¢Óôž}…áƒ15ôõ?¼Ö cÐK“¿BMMþ œšü9ø5ùSÉ%Žúšüiø%žüø5ùK©Oþœšü¥†&.}ÉŸ•ÐäϤ&ù3ÄTÔúšd­iè%G®I×çl襃¡—Jré¥@}C/x½dðh襄¼”aN&ø‘~ô“I\˜fc觐ZôSIz¨0K9΁¥‡Ü6Ìõ-=”¨ié!ƒ $†*É àÓÒC6<»:YÏV­×:5ù3<÷z¿Î[ŽÌ¿“ãW,ì–Í¿Ôç&·yöK,/Ù^ìm?¸ÏwË4NÊgáý`a™Ø endstream endobj 108 0 obj <</Ascent 935/CapHeight 698/CharSet(/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/Y/Z/a/b/c/comma/d/e/eight/f/f_i/five/four/g/h/hyphen/i/j/k/l/m/n/nine/o/one/p/parenleft/parenright/percent/period/q/question/r/s/semicolon/seven/six/space/t/three/two/u/v/w/x/y/z/zero)/Descent -250/Flags 32/FontBBox[-166 -250 1000 935]/FontFamily(Frutiger LT Std 45 Light)/FontFile3 137 0 R/FontName/VWGNFM+FrutigerLTStd-Bold/FontStretch/Normal/FontWeight 700/ItalicAngle 0/StemV 136/Type/FontDescriptor/XHeight 515>> endobj 109 0 obj <</BaseFont/VWGNFM+FrutigerLTStd-Bold/Encoding 115 0 R/FirstChar 1/FontDescriptor 108 0 R/LastChar 173/Subtype/Type1/ToUnicode 107 0 R/Type/Font/Widths[444 611 611 556 611 611 278 722 278 722 944 278 389 389 611 556 389 444 556 278 611 278 556 889 611 278 556 611 556 556 556 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 556 500 500 722 556 611 722 556 556 611 667 389 556 333 611 611 500 778 556 556 889 556 667 556 556 1000 278 333 556 333 278 500 1000 722 667 556 0 0 0 0 0 0 0 0 0 0 722]>> endobj 110 0 obj <</BaseFont/VWGNFM+FrutigerLTStd-Roman/Encoding 113 0 R/FirstChar 1/FontDescriptor 118 0 R/LastChar 183/Subtype/Type1/ToUnicode 119 0 R/Type/Font/Widths[389 611 556 278 556 278 556 556 667 556 556 556 556 222 611 556 667 278 944 500 500 722 722 611 722 778 389 278 556 722 556 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 611 611 444 611 500 500 333 722 333 889 278 833 556 389 611 556 611 611 389 667 556 556 1000 278 1000 1000 500 611 611 611 667 722 389 278 500 800 278 556 556 600 556 278 556 556 600 278 278 600 556 800 500 278 600 556 600 667]>> endobj 111 0 obj <</BaseFont/VWGNFM+FrutigerLTStd-Light/Encoding 153 0 R/FirstChar 5/FontDescriptor 155 0 R/LastChar 31/Subtype/Type1/ToUnicode 156 0 R/Type/Font/Widths[833 278 800 722 333 444 444 278 444 556 500 444 667 333 556 556 222 333 222 389 556 222 944 278 500 556 500]>> endobj 112 0 obj <</BaseFont/VWGNFM+FrutigerLTStd-LightItalic/Encoding 157 0 R/FirstChar 12/FontDescriptor 159 0 R/LastChar 31/Subtype/Type1/ToUnicode 160 0 R/Type/Font/Widths[278 444 333 556 444 222 222 556 556 556 389 333 556 333 556 500 278 500 556 500]>> endobj 113 0 obj <</BaseEncoding/WinAnsiEncoding/Differences[1/t/n/a/l/seven/comma/three/six/V/four/one/zero/two/bar/C/P/Y/I/M/F/L/A/N/R/U/O/J/space/E/H/T 127/hyphen/o/b/c/h/v/y/parenleft/D/parenright/m/period/w/k/s/p/e/d/g/f/f_i/nine/eight/W/j/percent/emdash/x/q/B/u/f_l/G/r/colon/S/copyright/semicolon/asterisk/dagger/plusminus/five/slash/daggerdbl/section/less/i/quoteright/paragraph/numbersign/at/z/uni00A0/equal/dollar/plus/K]/Type/Encoding>> endobj 114 0 obj [/ICCBased 145 0 R] endobj 115 0 obj <</BaseEncoding/WinAnsiEncoding/Differences[1/c/b/u/S/h/o/i/G/semicolon/D/M/comma/r/J/n/y/t/s/E/period/B/space/e/w/d/l/a/C/six/five/three 127/P/L/F/H/T/p/U/one/two/g/f_i/f/seven/hyphen/R/q/z/O/eight/v/m/nine/V/x/zero/W/j/parenleft/k/parenright/I/question/percent/N/K/four 173/A]/Type/Encoding>> endobj 116 0 obj <</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>> endobj 117 0 obj <</AIS false/BM/Normal/CA 1.0/OP true/OPM 0/SA true/SMask/None/Type/ExtGState/ca 1.0/op true>> endobj 118 0 obj <</Ascent 935/CapHeight 698/CharSet(/t/n/a/l/seven/comma/three/six/V/four/one/zero/two/bar/C/P/Y/I/M/F/L/A/N/R/U/O/J/space/E/H/T/hyphen/o/b/c/h/v/y/parenleft/D/parenright/m/period/w/k/s/p/e/d/g/f/f_i/nine/eight/W/j/percent/emdash/x/q/B/u/f_l/G/r/colon/S/copyright/semicolon/asterisk/dagger/p\ lusminus/five/slash/daggerdbl/section/less/i/quoteright/paragraph/numbersign/at/z/uni00A0/equal/dollar/plus/K)/Descent -250/Flags 32/FontBBox[-169 -250 1000 935]/FontFamily(Frutiger LT Std 55 Roman)/FontFile3 138 0 R/FontName/VWGNFM+FrutigerLTStd-Roman/FontStretch/Normal/FontWeight 400/ItalicAngle 0/StemV 96/Type/FontDescriptor/XHeight 510>> endobj 119 0 obj <</Filter/FlateDecode/Length 614>>stream H‰\”Ë®›0†÷<…—ç,އ‹-E‘L.R½¨i 'Ej²ÈÛ×ÿÌôX*R¢¿ß3Lº=îŽC¿¨ôû<¶'¿¨k?t³ŒÏ¹õêâoýäZu}»Èý·÷ó”¤añéõXüý8\Çd½Véðò±Ì/õæºñâß“ôÛÜù¹nêí×öô®ÒÓsšþø»•©ÍFuþ}9O_Ïw¯RZöqìÂû~y}„51âçkòJÓ}Î0íØùÇtný|n>YgáÚ¨õ!\›ÄÝïåe—kûû<‡ð<†½ÔðbÊèÝH-(†½ØË°M16ž‰a/~ {©QSÃ^ªš½ÔÄ µ€Gsˆ­ðc/+üÈcu<Œ™0aªÏéÕ>ç9.–4±0«úÁÎÓiœTX…_òW€LAÔ endstream endobj 120 0 obj <</Filter/FlateDecode/Length 933>>stream H‰¤VÛj9}oÈ?èÑŒ¦ªtk1$c{!@˜~³—{w6„xdz$oùõTIjõÅÍdÉb¦[RKG§ªŽŽüЬÿØ‚úç±Y_݃ºøÜ¼m^vÍzÃw 4š O2éé•z¼ÛËLk:| U·kZü×*ãymUwߜ܀ üóüs§ÝÇæ²kÞl¼'{2f0ŸÀ¼Bãu+xÔ àuB<]!€´|m¹Ú²µej‹jkúU<ªx´„WQȎ¾þÙ½jÖÛ/ï÷ggëw‡ßêþþ~8»º¼º°þüü\½¼Ø¨&ê6rHÝ_MFl¼æqÐΛüázÊ¡ò'ójåOù,ÄVÑ0gleêuˆ¡RåtT½ó#ª4?Vˆœ$ÐÁs4´N”„UHI¥àšÅã¢&ËßÉé¶-2B/,~!Æ^4äQc08Ӎ]ÔÈѬ8Ç5Üð;Öì “sCEj#˜)c¤¡Oå„Â×òÞÕöÅÞÿïü0:Š¿Ÿ?N°ós÷4‡…³ñT·ýT™€ÿÏ'è²fÞik]ÒX—-Ñ(Ëô4‡àrQбm¶Kƶݼa,c¬ú¦¬z­š6#I ›§ÂE¶6oÙï•çÊÔÆzõ©Ù²‰X)üjAq½b¡e\Bšœ2N;ÃåöÆhB¶‰Z ‘®D*”/ù(}’c/…›)m#§µüÊ<</BaseEncoding/WinAnsiEncoding/Differences[1/nine/one/I/N/period/p/comma/l/i/d/m/n/c/h/g/u/T_h/question/D/C/s/v/e/r/o/t/y/a/w/space/A 127/eight/O/five/f_l/P/E/T/f/j/three/k/W/zero/q/hyphen/f_i/x/b/seven/four/z/H/six/S/M/equal/R/quoteright/B/J/parenleft/emdash/f_f/parenright/G/colon/L/V/percent/less/F/semicolon/slash/quotedblleft/quotedblright/greater/two/f_f_l/f_f_i/Y/U/K/X/Z/endash/quotesingle]/Type/Encoding>> endobj 122 0 obj <</Ascent 864/CapHeight 650/CharSet(/nine/one/I/N/period/p/comma/l/i/d/m/n/c/h/g/u/T_h/question/D/C/s/v/e/r/o/t/y/a/w/space/A/eight/O/five/f_l/P/E/T/f/j/three/k/W/zero/q/hyphen/f_i/x/b/seven/four/z/H/six/S/M/equal/R/quoteright/B/J/parenleft/emdash/f_f/parenright/G/colon/L/V/percent/less/F/s\ emicolon/slash/quotedblleft/quotedblright/greater/two/f_f_l/f_f_i/Y/U/K/X/Z/endash/quotesingle)/Descent -252/Flags 34/FontBBox[-150 -252 1061 864]/FontFamily(Utopia Std)/FontFile3 142 0 R/FontName/VWGNFM+UtopiaStd-Regular/FontStretch/Normal/FontWeight 400/ItalicAngle 0/StemV 92/Type/FontDescriptor/XHeight 461>> endobj 123 0 obj <</Filter/FlateDecode/Length 619>>stream H‰\”ËnÛ0E÷ú .“E ·D†Ê±/ú@Ý~€-Ñ©€Zdeá¿/ïÜIÒF€#i8œCRoöÏûqXLü}¾v¿˜ó0ö³¿]_çΛ“Æ(ÍL?t‹ÞÉw9NQî·Å_öãù­V&þ^Þ–ùn\=ùÇ(þ6÷~Æóðksx4ñáušþø‹“˜õÚôþ}9N_obö´ïÃûa¹?…1?ï“7™Ü§,¦»öþ6;?Ç­’p­Íj®uäÇþÓ{k9ìtî~瞆à$É›uàŒœ‚sáBžä-¸Î„+á:×|¾[áJ¸!KG.À-ù¼!KÎgrÞ’-xG®§ ç-Á¬¿,4.U‡X0_ªÈ›Ò¡V‡ L‡JòÒ¡ÎÀê 9éPKN:ÔpKÕk—Ò¡–ZéaR:ˆ©É9j¶ô)ßê~ K—ªÒµ´ô)‘˪Ä•ºàJǀÕǁé“ÃÙªO¦O‰Z-}rÉOŸµZúdØ+»ý¨ Þ–5˜ÛÑ!C.G‡NËé¹Âž8:”2V¿ 쉣C.1ê 1ꀵwtȰïN$¾%ÃÓÑ!Ç·áèÃÍý³oçÃíþ‡–>¥°~+¨¯¥O:Z=WX›V}àÙ–¬ûÐÒ'ÃZÈq~;Õ¡Åh/A³ =Ѽw²îužC“Æ)Ý}ký{o®“ £ð‹þ 0 3D. endstream endobj 124 0 obj <</BaseFont/VWGNFM+UtopiaStd-Regular/Encoding 121 0 R/FirstChar 1/FontDescriptor 122 0 R/LastChar 182/Subtype/Type1/ToUnicode 123 0 R/Type/Font/Widths[500 500 333 734 250 568 250 269 275 568 869 583 467 577 490 573 1080 422 739 655 411 474 490 369 543 310 470 498 722 206 635 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 725 500 568 577 577 589 287 268 500 497 896 500 561 368 568 458 561 500 500 452 756 500 512 894 543 615 262 614 331 357 940 586 357 710 250 548 626 758 538 548 250 423 424 424 538 500 868 868 582 706 643 620 587 470 224]>> endobj 125 0 obj <</BaseFont/VWGNFM+Wingdings3/DescendantFonts 151 0 R/Encoding/Identity-H/Subtype/Type0/ToUnicode 152 0 R/Type/Font>> endobj 126 0 obj <</Filter/FlateDecode/Length 1008>>stream H‰ŒV[kK~ð?ôcFØÙ®êÛ.„€Fsà€$óæŠ˜è b‚ƈ¾ù×OÝz¦ÇlbXvj¦/_]û«~s´óPzð$C2éÿu—ã˜E^Û(¨ô†VQ1,w{Ýu³œõ©;þÛùBqôÄ ÏìÜ÷ËënýÏ9¸Oß»õï‚7î»ì<ý²iHa“\Â2 äàÆ«Žµúg¶þ‘þ-`+mÜ“îÂ>è<¿óZLó­}b£ÑV ±?‹yñn&7¾à± !ª’m¢wD5ÁÀ¼© ,Çº/Šjú‚j ÎH‚Z Îu[2>Ꜯ½1½aÂVé›÷lò.By2[Ζޞ5½)YE’Ubäg ΝŸþG™ùéÀ»WŽÓæ9mß(eœ-pò°qÉç6îòªãÑ«.”< ½}éλ×ÝsAÎ[Âô”X*°* ì{Í>$L†˜q3$M=¢gûÖç_ß_¯Ÿ]ÞþxÿeüøëöøìåÙ•'žœœ¸ç/N/†$μүÜšK³õb¹q‡Ñï0‘ô^âhÐ÷ƒ%²%°l@%I^*­…OCÒ™ÃÒ­ZÂKv¥Zÿ~Æ¢F‹D™„Eٍò9a}b‘U¤~«çä3,&±ÏÊí ïQ ôQÉd£_6™å(õÐêFŒý p¶U¢1&.GL(Ïí䝔"]XéµxR™œ’ 5Èë±”˜™¯Žê™íWÅh0éiÛ÷2€z@O¿ č»[Ú)ÆÇÝ…QOÜíiBÏ\êÛ„6mÁVXB‘®:U_c„0¢C±ÎEñŒ˜y…•&²FpËFq¸©aÙ„ @ÝG± LþÌ1AKØÝu öw['–CIúÇì3Ǟ#[˜JXH ƒz}Qš¬¨Äæó"z+Ðr‡r7£&h‚¤#¦¥@©E˜)‹=æšRœ"#åÙÄR³{;™°Œ6Ó0š@Å9ã,¥`A—'Q¾¯zªSßuÕÊñºÿ#ÅV²‡ªEƒ6¥Kƒm§·4…<ÑT¡¹E €»§ånòlѽÙml©Uր•».`l¯"éA÷Òq„‰ŠÁŸv¾²!¬˜k£Jsï!eÀd;~PJBTK‰©[Žû Ûõµ8ˆ ÷ ž0)xÄåk+®lO’Þ¶~“¥8¹qùz“(´,êWË®—[…Ýè{}Š5ü#r–PÂࣇjÒ1áoN×ëÀnƒ/Û&^û°ç~LîxøMþpwEâiD½ ®¶ž[-ã{-îò^ïÓ¬Ò“‘e2ŠªÞ endstream endobj 127 0 obj <</Filter/FlateDecode/Length 862>>stream H‰œVKkA¾ï¯˜£]ðZÒ¼l0†6B §ì­.%¤(m($…Þò×;Ò¼×Nšö°¶W£‘>IŸ$OWÃʎڵÂÑ ©éÓð~q  ðÀÈ7„wÞí´Y®pcE €BBƒ(H¬ §V4äFþ]µÀ-?LWÃúúçÍÝn·~}ûðëæûôù÷ÃîòâòÀèðà~¿WoÎÏÔ<ó}rËéÛpñ.Hv€pž</8f¨½‡Ç08Q_ -Ù”GW¦Æ+FÙŒ‰&Hû…Ä,y+ѩ璬7ûÛ (i3véF‹ÏçjSò„8ú®k gébì:ÆQãYn‰±ºy@º‰ØwXu©jÆ¶ŠŽ{VIÄɺh•™Áé/‰ÅA¨^c†ŽåùN•k±+Oa®NlÖE¯°[[Éz.½œ10ñ#X}¯ÓT–c^qt¹ºh©ž‰zT;#Ÿ‹,!oèêˈê»dJ×lIQê8~§È† ?‚B5}áJÇÆ`FÒhM$ƒÕ¾´u$`¤À.ÑÃö:sp9€\,½¸êKO”ʉž¨÷ØE8³9Éüî´çZ”FF@«G©á)µw™6U_Ϥõ6£ÓhÂï+‘Î:¤áP´á쩁ãšDFd‰Ÿˆuhõš C²È=LÌã^/§œJE–½H療Žã™¹g¨Ûß»4 Sm£ñLNߏÈzƒKcB+Í)Ïm×,ÉJÛ®á ‚Ôœ\Ä'ÂêÙ²õ³\5“½® Ñbç®Åö¤Lö¨§m™#Ý^HV Ifoå—À΍Ð2€Ý͹áH)Äi°Î{ÃS`•¤µ#1ÒÌ)m™™5”‡H,Û`ÔV¡vaºo¬ÒZ«éÇ9Ä™ÁÙ´?ÂoŠ6N¯ªàɶ+½Yç0z܍¼Àˆ¨Ôýíݰ~{ êëý°>£Œi3ZAÅßèÝh5n3®]°¿ÙóöQ{¶CZ>]1‡b®™“#øm™“iY©…=à“Ó¬gªhµf¼ÿ­þ¦ykçõùÕ;ÆÑ_:¦ë/Ñîþºˆä_ˆ¯¼aóYÚ,¦nù¸—…‹y¼doy+»EÿPÆ–‘!¾ /!¦QS79ô”7<Ú¦tuëKTê-f—‰ endstream endobj 128 0 obj <</Filter/FlateDecode/Length 853>>stream H‰”VKkA¾/ô?ÌÑ.x-ifwm0†6B §î-.%MÚBiC!)ô–¿^4Ïõæ…YÛ;£Ç'éiÆ‹Ì [‡dÆÓærq ‚u݁Ð?ÃÀæÿÖ-W,ýòóxѬ?ý¹ºÝíÖï®ïÿ^ý¿ý»ßŸŸ8»ßïÍûÓÓ,€ÃrüÙœ}ä7öpÏêÛƒÂZq@&Ž ñƒ•€G”Öfâ‚H±–ÃoH,]ÐöqèzP$BQöáMR#* Î¬õ¨{^sÉ4ï?°V9‹è¼‚Ø·]Â4‡#˪òýhß׊†`“m‡Le™ `ê*òVÁÏǪ¦¬ÂŒ”`Sâ3)—d%ï¶R2*w©_Z©ü0ÑI …ïeé©ò"5¾S*¥œÖâÁSo\PÊÌÒ<¯¨È,LHYdW%Uº˜õ ´ª\8[X0Û3Y5HY+tËÁy}%‹aÓ䞙=Áƒ"§[bRÍ#¹Ì2ÍÁ›l"]*-gz=â0hÆïÍÖ¶mß›MgÈfüÝ,4ßÌ[ ¿å_îˆÄÆ|Wa]ÙU˜A±«@;ôì®ö-¢1w×·ÍúÃ'0?îšõ EL›¶Tþûm6ÁÚ±ùÍÞ“¥E^áo²òÝ'k(Ö8BTk·¿ó[|&ƏÙRÙ w:r5wŠU߉sL]±š(_ð3±9HÚÜg$×îÅ­]K{ÑÅc„ãõn[ìmbݍtLô;}’%™Ž„e!Ý›²óÜÁŒ4|:¼Ó2¼nèS|dËÚ¨³Ayî*€3­QÞ!»_ÛU6´)¸ùb¹n‘z¹ž¸IOðeCWÐ9òBì’¡7Ëû\SÏÌúÊgl"ˆÀ|¸ã[±sW=‹ç“‰n*QÎlY9: aõùxö¼rzÍ ÃLJÌì,!R¥—í+Ê¢Ò3D©m•S£Øñ!U–èðUÙc³árQLZLW!+i<</Filter/FlateDecode/Length 876>>stream H‰”VKkÜ@¾/ô?øè=¬WÒc׿nv»íÛ»§?·?†/Ÿv———¡²n¿ßWïÎϪè|T¾ø~AÓúºÄªz¼{Xmß_Cõíqµ=£Œ¯k#ŒOì\Ôvã.øïö±l š6ú!Ãÿ½ºCvÒÅäîR{®H±6–e¸gÐFAg¦ÅžfB à‚,á‚‘J=+tOã –´ÚÈB[¹$+Șy©³ sN™sÏÌ1l’aDÕÓ} pŒfOí§ìSsöOÁYΡÖIÔò:JLΉ°¢À”’qªÛF_H×J³’J_ËF6ŸD\$Ð]Ó¥‘éä|á÷‰vš4Ø$yö8_¸ÅºÍ*`ÚD ç´0Ñ’^h*åí›ä’c[q|úð!(´<ö¢XŽ^è—+†ù³²Žs.–-î\à™¬d©µ/¦JÔt-UÖ7®ët,qò¨á½_¢E¢‚¥f–§ïôL¸Â^:­ô).õ^;öŠ*{<</Filter/FlateDecode/Length 898>>stream H‰”VK‹Ô@¾Ï¯È1’­êgË‚ºîAðdnFdG݃è Coþu»ª©ÎκÈ0$]]]ϯ¾t»ènþv˜Û@øÑS›q½ÖÛÌ?Úåaíº~Ä6¼±þøgQ€RêÂ:´¤Ž]O2ôQ–M Þ¬ÁÁ–jY»¸ßyz(^)ßõº]NUIAÊ©¡2]oÚå­°Äu:ý8¿=´‹BK€¦ÇA9ÝÌ·”ð1ÅK~•´>w†’õ›‚¶¬PbPñ]qò1i:ºK)žÑËL`Ó eÝâÊRć²™_PìJAÖUªÂÔ& R¡ë}›»@mËMgå37ÒÄÇÊND<^ºN¡ßJ4))£È ¡:²kPÜje|Ž2 Í]iÙJ›â8ñq›[wÞ'ŽÎ¤\$@s1SŠ‹§Å‰:Ōʧ´OT?QøÇ½ÊŠO¸B¶MeÓ‹2 TÖÔ ÑakùOR®!¸zn8_@¾ÙD ØÁê1N|zÕÞÚÓh:Í“ÏþˆÆ  µk´õ‰r BA¦6"ü?¢ËŠ4>„b³3Ö'öºžëu¼¦`£ÙE1„ý‹à/äÙk×>^¹¸èwîM= üy#¤²§ÀúÝñ$o#H·uâ5Ö±rêCÕñG5¡Q¥p¼›Â‡Ø†#I«é„Ä­ÆLdV·òûP¼òÆóߙ̾GqjÝOAb[U}!£lcqœÖÕŒŸ Áf~8øÄbô4.\rƒ)R]¸ÂPÆWïÞŸ®¯¯^~^ÝŸ¿þ^¯ïÞÜÝ˜éææ¦yuûº9À`M)”æB½yÇrcÜà;Do _0½ŠÏ/"![¢51ZɹÌ`œÑ"Z`׏ÉÜ"JÃØhT‚ÌÃ'cOæ…M*÷| ïëž+T<æ7¯¥ÜŽI^-%‘(ÍóÆJ•°»Iv·¸(}¹Ï׋ݜîÙÖo—9j…$Œæ¯Ês‚T endstream endobj 131 0 obj [139 0 R] endobj 132 0 obj <</Filter/FlateDecode/Length 230>>stream H‰\ÁjÃ0†ï~ ÛCqZ(½„@iä°¶,Û8¶’Ù(Î!o?Å L`ƒüÿŸø-}©¯5ùúÁÁ6˜ óäÇ0±Eh±÷¤öpÞ¦µË·LTZàf5uA•%èÇÄ3lÎ.´¸UúÎÙS›¯K³ÝL1þà€” €ª‡z7ñf±]íD÷iÞ óçøœ#Â!÷ûgŽÑXdC=ª²ª |“ª’û§¯TÛÙoËûxwQœÎÙ½¾/œ|^¡ìÄ,yòr%‚'|­)†B-Gý 0­o½ endstream endobj 133 0 obj <</BaseFont/VWGNFM+ZapfDingbatsITC/DescendantFonts 131 0 R/Encoding/Identity-H/Subtype/Type0/ToUnicode 132 0 R/Type/Font>> endobj 134 0 obj <</Filter/FlateDecode/Length 831>>stream H‰”V=Û0ÝïWx´ Ø %ÓröN³»‡š!È~½iI”“æÚ!Ž-Qüxä£øÞ¯¦õÂOäŸ_ç|äwàßì†Yf‡"éb/bwºäÏ*È ¼x¯ÊÊ–ç­)ýG7È÷ìBŸ9¤ü^Tªr鯤íÁÞÍ‘F°­f»ÎÍ:ía½²®Ÿçoýê‘Üù×tŽ~ÝùûÛ{Uf‚dT.ª—%cu=¬Ô/“X¹ªÆcÁ-xØ]æì5ÙÃÀÏ‹ÀK9n}k“Ó1iH›…UDR€‡¸2Ò̦‚õzØ'ˆYóàkRöT¦T¯·£/r0xd¯ÉDÝ-u#Q™S5ßÛn ¤OÎÆA‰—1ΧºóGMå°¯æÀ?$pð.xß‹§Mkå]ÉN'lC¿g”]~‘Ãtú®(ÕଞRú­ñW©ôøEîçoi²‚At1ÛpÈ…/Î$§€äb¡Û_C¤1Qç'qԝ'xIà=*œþC\FôÓÒù“˜Ouçd3ݤ„ÍÆ^DsÄSåx.¾ŒD«!´ðèªÖMBgݱ4p§°‡i<…c‘4]/qå,  1·—ÍlÞ´àqÞ_‰R“*àRÓºò艸$¦¯Ò.¥V/DæðÅOÿK‘B‹Z¸¢Ž=EÔô…Ö' PïhH­FSi¿´ùà ?™NÖvËv€}Å\¹Oµð?üY7´z*Á·6äÕM¡Å¨î{ÀV¸8,³ÇJ(?M_H®ôG£¦nÔʳ—üÆE˜^1{:M#Àiê<÷@ËpuŠB)Œã2Ç/8E‹´Èòo„p˜Þ!ÚS^ê¥.г™$h¿£¯v²)"í£²æB«kÑ€`Pór°¨J¥jo™±9,\èa¶ Öî½–žì]uF(}îñ¦±Š¾Êø…´ø¤4_rØGêëô¥7ü‘k@åwê³.¹;}yo«ýÔ†H`֎wA0·¤ûc æ¦Ie60óc;’QNÓ%MoµÉì‚é0ÝU\“: endstream endobj 135 0 obj <</BBox[0.0 774.0 567.0 0.0]/Filter/FlateDecode/Length 92/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]/Resources<</ColorSpace<</CS0 114 0 R>>/ExtGState<</GS0 116 0 R>>>>/Subtype/Form>>stream H‰Œ1 €0û}ž 9ÉÅØ§¹'Xb ±ðû^ŠØÝXMXJ*ª9‘V7HÈü¨\)¼<</Filter/FlateDecode/Length 853>>stream H‰|Vß‹Ü8~Ï_áÇI!^Éò–…^w÷ pOÍÛÎQº½N¡Ü Ç6…þù•,'q2ÓeÙ±G–dé“ôyÆ÷ ˜­‹dÆûæép<§#¸ÐvþÀkj‘òµˆ¿Ç¶®—h1¨b'š.¶4+A¶e;§.ž©ý{|ߨø¯l=8K€½Á-F fü¯9síø­¬*Ëê!XHˆ¬I¢ôtØÄŽ€‘SxÉ—óv=|iƒrª„ÎAÛ¹‹¼æ¨]ΣKvéÅét<µªäÓ%›R\püG"§ ‘ߌøšñÔ¤’„¬DÞ†ƒA%SÀ¬ÿáÿOçÛÛ›·Ÿ§Ÿþ¿üœnüpwwgþ¸g°Á³Ÿúš‡¿²œÀ|À <ˆŒ€s¤Ôî¸~¡îJiEV¿û…1mû¡DÊKjó&¨õyaUmƒTû]ÐÇâ…Š›½rZ¹üyQJcm€Wlz%B™Zý®Hw¿Äzº¨ˆ$$2&¾ë˜%&êM¿!>eö £&°ƒ'4=VO˜›‡¾€X?·ù¬`.eÈ¥(˜Î…[=u±˜îž>í>‘å~„¸ícßb,^}ù8Ӟ¶ .³DW(@¥Ü€Sníê¡]Mª1.¿1ŽûvíÒ¥“y¦Ú9ŠŒP!:(¹.úŽÉ®tºÚ­?®ü²éOH¯ä)è<Œù%ÀOÎ? endstream endobj 137 0 obj <</Filter/FlateDecode/Length 4393/Subtype/Type1C>>stream H‰lT PgîáA¦mWg`ºEñˆ¨0¢"¬QAFX5¹fÐA`È0‚xA¢–dÍF£&ÆõZqÉZ^KØåP‘¨ˆGŠ¤¢k³åQc|=y³›ýД•TWÿÿÇûú{ï{ïÑ”JAÑ4­K[kŠIc_å°.·ØRSæ Q¶|³|*Hþ´4D%â1·þ´î§HFê+…û]öç³µ”’`P*zš›a¶•Ù­ËW8ÄÐéááÁdœÒ7†‹Æ£8Ûl˶ˆ)eÅKA±8¯0Çf/²Ù³óDqv~¾Øg\,Ú-Å{‰¼ù’”h-³D‡=Ël)Ȳ¯m¹b‚µÐæ(+²ˆÑd"±Yn%°v‹Y´ŠŽqáÄ”‰b/tˆY…f1õ•õ‚Ü\kŽ¥o³ «L$”^·Î±ØYd¶»˜·Ên-6[sV[añKð¬Ëo°°¦Ä|_Xl±ür[7qRLJª¼Í–\ŠŽ¦(–¢ ¾©~ì1É#ߣՓõ,ò¼ê5Æ+Æ«Ü븷Ò;Ôû-f Ú4¨×'ħÔç±æ M¢f›æ‚æŽo¤o™oóàáƒK7û‰~Ëüöù]Ó´‹µŸj/qo`aU£ôŸFšŒ£•U*©Ò•ä®da+^äñMØÎÀ#EláA^¸?T»Ùe}ßð&’5+5óòÊ+;AÇÊ{Àܳ^´?:Aëyäî» :ù´Šö††í--;L™™ï™Ò„HÕ‹¶Nð¤NQ4Å¢z´Ç¾¸fw:¼àó¬Gõ+î~¡;‰¿ÇJs\k˜é¬ÆÍ»*KéS¨„tW%? u8óŽx‚þàØ)àŸ#`¦Û@û-Ì X¶Ž"ÿü/\IíXrµl/\[€#¦0â6*`+},ʃ¨àÁ‹ýle0H&y  Á%4A ܃ 5±¨‘¾¢òúPAD‘Õ”;¥NrU„l²ußó£ª!ò»‡U0㙳 g„N®ÆÈ@a¤ –}K`*Ĺ·1“Ó0 £qt-Za¥ Ù_â2'öŒ;Òg|WxýÀ¸ƒè2á`µ¦ ÒB ~ ¤š¡„ÑI5° ‚qàcu0åŸU¶2Á°=˜ºÓ­‡Ûô.ÌÇ!ø.¾Ÿ  §ZS 0“7ZxN‘{ôÅN~]sׯv=QmüçÑ›qݸK¨QsOoÔ¶}ñoŒÃQuS¢ã6¬J1lGsèlËîóúŽ«æšLù„ù¨èd¹G®MŸc´%§.ÚýçtÙ!rB+Œ®*ÕBè¸n„ž{³¡•©ÁVύä၂8ÒBŒbñcw#Ó4–ÀB4Щý™ZXAîgj;™DÁeâÝAì&·7³»¾þO úžžüPãLk”)}ÿÇV[W‰~w¶âtÇ{çô÷ýð;˜‡ÜéqE%[*× [adá`‡si ä“XüƒÈ—ÜnwÍæ?MOß¾X%&4c2†7àHãí'0^àî}‡%e®JÏ3¼_Ã8·Õ|ô_ž,_{BÀxtð׎$Ä&%ÄÇØ.^í:|¹SŽ…ÔKÄk”Ò”R/—YÜåîe ˜…jéî4u"iI"á‘$С†0zÀÝ‚ið?ž{0-;cá‚"‰HnxFr¼'ëÒ¤CµšëîþìÔ­x¢² }‘NB?w+êtrW¾ëÞF¾µéHSËÑå‹2Íæõ†ô½‰µ—t܃ÍxŸo;õ·ÆC†‹«ÛòbtÉ+RR–Ô_4ô¥ÊX9Dô@p”wvókÎœÙØ¤‡’v’Eɞ S0 ³ÇàxäoNƒam ûÏjÞgFnÉFúè—ZvíÉ |œ­£órmÇ•ëG’çÍ}'1V(@(¨©×‹°Êù—5FºˆR®SÑ ~£¹Þv©ƒ?p¦eo‹ž{zñ‚}ޢ܂Ülayvî¢`ø²åDòøVu0™&TÇÅ­_=ßÀõ‚ß§¿BÝFR4ŒxY"ÉÑ®T®[ʀƒ@Dðƒ Š¤ˆ3Ôˆ"¾‚ˆbPFWßJ@ƒ D\Zh´øÀj|ÔúˆâZ-±û=íê>M»òƒa;÷ìùö>ß÷í}È@šÁ…¾2°|*…4°ïÄœ˜lmÀ ÂdÖ,äX›Á@ SE°²è;(Ð’ŸùXô1±BKL¿JöRO†<ó*…åŬ0G‚ÝÖBFÑnzR`-Ì’°rˆ.ç_!ëM„©‚6‚#„T"º3uÞù0{ÐY,ÁìŽýp¡ ýÝ G-èA­–oÔG£Œ}±o4È WyØE'“H©àäýuOæX-6]Xž¢MçqâzÝU/‚8Õ“Ž@­½5ù?ÈÚgá[ úÂP¤š„ÌËðK`]À-ùÙ9ÛUpAÛ˜Yùu°î„ö$¡Ü‰6ºí)ñJËÚ÷‡®þP›ÅÑzp´'+Åú]æi»µ;˜$À»ÁÁôâeeñ›ßΑXj¾½m€h]^*]º²¨#êãOä=(fJÞ$#!qŽÄ!~ õ5ø¶!|lrtTTÁÁêJÔˏ®¾n¤Qǹk°ëcÀÙpý›=§««3Ò*Ô®¾CfM“É<â!-IdÖc$œ™ÂcÏÌv×9fzå:ä*8éE„Bè‹0Ie‘”Ò âGº»Ç·€“Êp®Ædƒ*œáúííF96»ÁhVq[ÔDù†X+9ÿBY¥€^Dà/³¹3šXÍj·ÿ´@ށin0^”@OVCNzkãDãAz‹ò|“žPô=’]:u,Ýør€Ø¥0(ä¹rÑøËô1Oáïà”€ÃEȳ.]¦WÊÒt¥n,ÄõP„;ŒÎG´Î£r|+á-k­a&Èü+èZõ¥à s‰!o€£¼â)sPŽVÖî­5Þ<¶d¸ö8eüú”-&%ᣠƒ\5ðAÔà %µÅjŽ(/ßôivbn²½¼‚ÚÙgdzJ7–Ûo,ÛX~ÖpYï°¿àÐȐK§©ru>Rn>Ø~^­ç®KX–¤.1-úã㌄ \¿ÍçÜiƒ¥f}#ivPàc°(MGÝ»¿ßûñ)ƒü|“ž4«ò 4¢E7Q®¾˜#E•c®5‚o¸;úD€}Cf&MOвhà2©¢éçN›])Ÿ&ýØçJ~¼­Sèz%Ys<×R®­°:5.=Þ8ø£æž»üý‰ƒk2ö¿â<ÁKð÷ÿpÿÞQŸà1Iƒ}ýRž~Gð ï=“Œüt–X=wæ¾qFô ±õÑäj|·ÝÀ÷bÍî3Ç©‚t àöœ[íø¤«†Ã¥qkÙÙkÆk_L Û¢ýƒ”%±S–†‡GT}¿N&¸©ð&NÁa$›8òù@júzç¡j•Lœ¤àß }Û2ÈÆmÓ¨#7QphEê÷—¤ã;Ë+‹ 2ÖZh`ʧ¤åÇ[ÿŸ›h|7"ØCöø\rqÇ”6plƒ¦G>m/s¾'Û” „{WnÝyØr4ØÏ?qÌûšüŒˆí£È·B²¤ú„è}¡F|ï÷ä(=Q­£ÁÎûÚù²ŠZŽè»uè7nßÞ9jŠBò¥kÎañ×ð¸S/q÷a#xí8 â¨P{2@®xyϏÏîmúm¸Š‡iÝ"}ô=t ‰X›¨fA?iÞÔ˜ÅLWW»&ÚÙij¶Ð7OºŸŽl¯à,S‘©ýÛ[zzKN[¹r}Á¡ÏöÁ°tÍ;ƒk‰$§X¼A½Ý¾HéŠÐñyæ—¿›IÑ£q³A".†2jïËùÄ„ÃpސÅ&t!kÏüyçYÅ(ž,¯o… éøsí-W7ØÂŠ ù/Üȝ¡ây¾–^_S ¤ù÷Q—4a±z))æP°1v¢)<~g-åÊ_/fdêä8•v߸‚²ÄIß©°vJás=Ÿ£#Á¨çD,OB‡â`š—<0H÷?)7¾º~ÿo_}èŸìãÑ/ùñ]j'a‚é©—ö­FLàÝ›#FVU¥“~ý_Õo`Ì‚ØOxÏšÑU"Öåù(¯z÷íõÈ/ʼm¡io{¢mó˜,éÜ¢é%£Hñ6 vèÏ¿¶jgm‘Ùo”WÌ­u¨¨/Ø£=»£ ŒfYØN°%=={¥qDTÀŒu{-ÝPœ$n?­A&6¡5Ûf)û#rse¹Š|d[ÜœíáÆ>^ÓQ§áDHoìoˆº2qÖì{âTyñ|C¬¬>›I»†îLÄôi· 'w”V±&ý×;SK«Ðp¤£¥_]؏Nj·äV7¼2ÓS×/5Ƭ:Q¡ÁZpj¥¡½¿„†™sgc#Ì?S„•3‹BÖ•+Ž7õñòßx÷¢ ‡iÝ"¡ý9p¹RWræ·þ´ –tv;‹YoaEÔg»Á "™EàãÕ1ìIWWje®ÌI@Îùlºí &F—^³>¿ä4˜àƒEêZïðæØÍú޾"øò®¢\éníÅ#tc½"öíX‰|Õ§SŽvÛØ—:˜Èï3!¸O€"Ø“%Œ`˜ˆc`¼Yü}O쁶 ù[»³Ù.ŸëÀ§ì)B¬µLˆZ˜0uaÚæ­ËÕLO!³¸d}‰Ü‹éâ+žÔ`*Ë㛲êN(ø ÛçI#l´®Š,D‹;‘š¶Ý†»$Øhñ–x'W~®]¾ñTî×åRò×>…Oÿ½LyŲ¯½fÙ 6˾ö?–½ÊÒ>Ñ‚Ó,°Ô"BÑÖäY²HgZ ÍbO_äYÿcqP÷Œ™ÝÝ¡Õܝ6uwaç\Ûç(ÿ`Žé›¯ endstream endobj 138 0 obj <</Filter/FlateDecode/Length 5308/Subtype/Type1C>>stream H‰lT{TgŸI2“1@†Ik‚Éh)îŠd‘àƒú@|t!ˆÀª(` SIB“â£hR*GÛ‚íj«Ûª[±¨)n-Ëâc]j%±í_TŽ´gOöNúeÏÙZíölÿ˜û}÷»óûß½ß½Ž‰Žãª?,ž§Ÿ›“0×¾Úi®4Ù³òÆÄE6‹Áʇ5¬gG‹X”F3QÓë˜N°/G²ùџľØ'ǎabL†kñ饿ŠÒªÕVsRRzR†­ºÎn®\éd&¥N›6‘³©I#6e"“œ””̤me&&¿Îá4YÌk¹Í^m³œ&£–I¯ªbFÀÆnr˜ì5üá3ŒÙÁ§Ý`4YöUŒ­‚É6[mκj“Á‘h9L¥™£µ›ŒŒÙÊ8Wš˜Bm¾–YÈ‘[ŒÁjd ž£s+*Ì妑C‹¡Žá$ý]n²; ÜjãhìÌk«íf‡Ñ\î4Û¬ŽgäVƒÅô+*lœR.*ŽÞê0™~ϳ”Í×þnn~ï¤0FSÆ•Çø;‘(°±Q˜ŽÀ^Á°9£±bã‚Õ8æÀ0†íð0|›[Ê>Óc'ñ9xþ@ ä \‚ã‚/7O„a¶Ð,ì-}HD)D9–œKZÈf²C¼\¼K’tI½ääbXlXFXAØÖ°Ž°Káâðôð=ឈ õ{#¾”âÒithT樦QeSdëdO"ã#çE¾y.òJT|TyÔ‘hAtIôžè§r­Ü*ß'¤ÆQj7u,

%PDF-1.5 %âãÏÓ 104 0 obj <</Linearized 1/L 917439/O 106/E 54210/N 11/T 915243/H [ 1476 726]>> endobj xref 104 59 0000000016 00000 n 0000002202 00000 n 0000002321 00000 n 0000002831 00000 n 0000003441 00000 n 0000003959 00000 n 0000004615 00000 n 0000005333 00000 n 0000005613 00000 n 0000005872 00000 n 0000006320 00000 n 0000006357 00000 n 0000006669 00000 n 0000006783 00000 n 0000006895 00000 n 0000007549 00000 n 0000008233 00000 n 0000009236 00000 n 0000009669 00000 n 0000010292 00000 n 0000010981 00000 n 0000011691 00000 n 0000011826 00000 n 0000012905 00000 n 0000013837 00000 n 0000014760 00000 n 0000015706 00000 n 0000016674 00000 n 0000016701 00000 n 0000017001 00000 n 0000017141 00000 n 0000018042 00000 n 0000018341 00000 n 0000019264 00000 n 0000023743 00000 n 0000029137 00000 n 0000029307 00000 n 0000029584 00000 n 0000031980 00000 n 0000040176 00000 n 0000040256 00000 n 0000040326 00000 n 0000042975 00000 n 0000043045 00000 n 0000043125 00000 n 0000045678 00000 n 0000045950 00000 n 0000046115 00000 n 0000046142 00000 n 0000046443 00000 n 0000046591 00000 n 0000048668 00000 n 0000049024 00000 n 0000049452 00000 n 0000049584 00000 n 0000051418 00000 n 0000051765 00000 n 0000052160 00000 n 0000001476 00000 n trailer <</Size 163/Root 105 0 R/Info 103 0 R/ID[]/Prev 915233>> startxref 0 %%EOF 162 0 obj <</Filter/FlateDecode/I 790/L 774/Length 638/S 602>>stream hÞb```b``³f`c`™Ï ĀB@1vŽ@ËÝ–ö- ê ¬2L.¤HŸomiÊqN©›±°L<³Ḿ7`Ј¸ØÒ1ANFb‚Bï,cÑ×?üdT ~1÷KXâPË¥’¬®`£p±Å¹™‰cÂĤi“Ô?ëýŽy4ü’И¸Ôg^JgQ§ HIãÁFŽˆ‰þ]«å”_´›Èp©µWÅ¥áÝ7ö-°kU™)'qˆñ`#‹‹ÏÊIœÞbÎíù —tðŸô3È(Hpdʹ8ñ Ç$1 —äü=:¥BN:"af° ï´œ‹šOªèt®O:TÏûÅåC°ªÛD!Iõ¶Ýœ?•TØ[¤,”\»ÝJ-¿¬`ê)=#ÒÁ¿\ÁFBÀÅ(7¡2Xh­K9ß=µí<ý6<„–³Ðl˜ÊúG©K¡§íÎW†pNOÆ6Ö+™R,f²+X5ê $ &ÏD–EZàÜÀàÄ鼟güă4ÚÌ endstream endobj 105 0 obj <</Metadata 102 0 R/PageLabels 97 0 R/Pages 99 0 R/Type/Catalog/ViewerPreferences<</Direction/L2R>>>> endobj 106 0 obj <</ArtBox[0.0 0.0 567.0 774.0]/BleedBox[0.0 0.0 567.0 774.0]/Contents[120 0 R 126 0 R 127 0 R 128 0 R 129 0 R 130 0 R 134 0 R 136 0 R]/CropBox[0.0 0.0 567.0 774.0]/MediaBox[0.0 0.0 567.0 774.0]/Parent 100 0 R/Resources<</ColorSpace<</CS0 114 0 R>>/ExtGState<</GS0 116 0 R/GS1 117 0 R>>/Font<</C2_0 125 0 R/C2_1 133 0 R/T1_0 109 0 R/T1_1 110 0 R/T1_2 111 0 R/T1_3 112 0 R/T1_4 124 0 R>>/ProcSet[/PDF/Text]/XObject<</Fm0 161 0 R/Fm1 135 0 R>>>>/Rotate 0/TrimBox[0.0 0.0 567.0 774.0]/Type/Page>> endobj 107 0 obj <</Filter/FlateDecode/Length 540>>stream H‰\”K¢@…÷üŠZv/:P<«cBk›¸˜GÆ™€P:$#Ä…ÿ~êÜSÓ$c¢9È}|‡[—xw܇~Qñ÷ylOnQ—~èfwsëÔÙ]û!Ò©êúv WòÛÞš)Š}òéy_Üí8\Æh³Qñó¾ÌOõRwãÙ½Fñ·¹ss?\Õ˯ÝéUŧÇ4ýq77,*QÛ­êÜÅúÒL_››S±¤½;¿_žo>gøùœœJåZ¦;wŸšÖÍÍpuÑ&ñŸ­Úüg¹¡ûï~i™v¾´¿›Ù‡kœ$e¶õ:¥N¡3ÑU‹.$¦`Œ.©Ðµ…6¢ó ÚŠÎÞ¡kþŸC¿Sï¡w¢Óôž}…áƒ15ôõ?¼Ö cÐK“¿BMMþ œšü9ø5ùSÉ%Žúšüiø%žüø5ùK©Oþœšü¥†&.}ÉŸ•ÐäϤ&ù3ÄTÔúšd­iè%G®I×çl襃¡—Jré¥@}C/x½dðh襄¼”aN&ø‘~ô“I\˜fc觐ZôSIz¨0K9΁¥‡Ü6Ìõ-=”¨ié!ƒ $†*É àÓÒC6<»:YÏV­×:5ù3<÷z¿Î[ŽÌ¿“ãW,ì–Í¿Ôç&·yöK,/Ù^ìm?¸ÏwË4NÊgáý`a™Ø endstream endobj 108 0 obj <</Ascent 935/CapHeight 698/CharSet(/A/B/C/D/E/F/G/H/I/J/K/L/M/N/O/P/Q/R/S/T/U/V/W/Y/Z/a/b/c/comma/d/e/eight/f/f_i/five/four/g/h/hyphen/i/j/k/l/m/n/nine/o/one/p/parenleft/parenright/percent/period/q/question/r/s/semicolon/seven/six/space/t/three/two/u/v/w/x/y/z/zero)/Descent -250/Flags 32/FontBBox[-166 -250 1000 935]/FontFamily(Frutiger LT Std 45 Light)/FontFile3 137 0 R/FontName/VWGNFM+FrutigerLTStd-Bold/FontStretch/Normal/FontWeight 700/ItalicAngle 0/StemV 136/Type/FontDescriptor/XHeight 515>> endobj 109 0 obj <</BaseFont/VWGNFM+FrutigerLTStd-Bold/Encoding 115 0 R/FirstChar 1/FontDescriptor 108 0 R/LastChar 173/Subtype/Type1/ToUnicode 107 0 R/Type/Font/Widths[444 611 611 556 611 611 278 722 278 722 944 278 389 389 611 556 389 444 556 278 611 278 556 889 611 278 556 611 556 556 556 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 556 500 500 722 556 611 722 556 556 611 667 389 556 333 611 611 500 778 556 556 889 556 667 556 556 1000 278 333 556 333 278 500 1000 722 667 556 0 0 0 0 0 0 0 0 0 0 722]>> endobj 110 0 obj <</BaseFont/VWGNFM+FrutigerLTStd-Roman/Encoding 113 0 R/FirstChar 1/FontDescriptor 118 0 R/LastChar 183/Subtype/Type1/ToUnicode 119 0 R/Type/Font/Widths[389 611 556 278 556 278 556 556 667 556 556 556 556 222 611 556 667 278 944 500 500 722 722 611 722 778 389 278 556 722 556 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 333 611 611 444 611 500 500 333 722 333 889 278 833 556 389 611 556 611 611 389 667 556 556 1000 278 1000 1000 500 611 611 611 667 722 389 278 500 800 278 556 556 600 556 278 556 556 600 278 278 600 556 800 500 278 600 556 600 667]>> endobj 111 0 obj <</BaseFont/VWGNFM+FrutigerLTStd-Light/Encoding 153 0 R/FirstChar 5/FontDescriptor 155 0 R/LastChar 31/Subtype/Type1/ToUnicode 156 0 R/Type/Font/Widths[833 278 800 722 333 444 444 278 444 556 500 444 667 333 556 556 222 333 222 389 556 222 944 278 500 556 500]>> endobj 112 0 obj <</BaseFont/VWGNFM+FrutigerLTStd-LightItalic/Encoding 157 0 R/FirstChar 12/FontDescriptor 159 0 R/LastChar 31/Subtype/Type1/ToUnicode 160 0 R/Type/Font/Widths[278 444 333 556 444 222 222 556 556 556 389 333 556 333 556 500 278 500 556 500]>> endobj 113 0 obj <</BaseEncoding/WinAnsiEncoding/Differences[1/t/n/a/l/seven/comma/three/six/V/four/one/zero/two/bar/C/P/Y/I/M/F/L/A/N/R/U/O/J/space/E/H/T 127/hyphen/o/b/c/h/v/y/parenleft/D/parenright/m/period/w/k/s/p/e/d/g/f/f_i/nine/eight/W/j/percent/emdash/x/q/B/u/f_l/G/r/colon/S/copyright/semicolon/asterisk/dagger/plusminus/five/slash/daggerdbl/section/less/i/quoteright/paragraph/numbersign/at/z/uni00A0/equal/dollar/plus/K]/Type/Encoding>> endobj 114 0 obj [/ICCBased 145 0 R] endobj 115 0 obj <</BaseEncoding/WinAnsiEncoding/Differences[1/c/b/u/S/h/o/i/G/semicolon/D/M/comma/r/J/n/y/t/s/E/period/B/space/e/w/d/l/a/C/six/five/three 127/P/L/F/H/T/p/U/one/two/g/f_i/f/seven/hyphen/R/q/z/O/eight/v/m/nine/V/x/zero/W/j/parenleft/k/parenright/I/question/percent/N/K/four 173/A]/Type/Encoding>> endobj 116 0 obj <</AIS false/BM/Normal/CA 1.0/OP false/OPM 1/SA true/SMask/None/Type/ExtGState/ca 1.0/op false>> endobj 117 0 obj <</AIS false/BM/Normal/CA 1.0/OP true/OPM 0/SA true/SMask/None/Type/ExtGState/ca 1.0/op true>> endobj 118 0 obj <</Ascent 935/CapHeight 698/CharSet(/t/n/a/l/seven/comma/three/six/V/four/one/zero/two/bar/C/P/Y/I/M/F/L/A/N/R/U/O/J/space/E/H/T/hyphen/o/b/c/h/v/y/parenleft/D/parenright/m/period/w/k/s/p/e/d/g/f/f_i/nine/eight/W/j/percent/emdash/x/q/B/u/f_l/G/r/colon/S/copyright/semicolon/asterisk/dagger/p\ lusminus/five/slash/daggerdbl/section/less/i/quoteright/paragraph/numbersign/at/z/uni00A0/equal/dollar/plus/K)/Descent -250/Flags 32/FontBBox[-169 -250 1000 935]/FontFamily(Frutiger LT Std 55 Roman)/FontFile3 138 0 R/FontName/VWGNFM+FrutigerLTStd-Roman/FontStretch/Normal/FontWeight 400/ItalicAngle 0/StemV 96/Type/FontDescriptor/XHeight 510>> endobj 119 0 obj <</Filter/FlateDecode/Length 614>>stream H‰\”Ë®›0†÷<…—ç,އ‹-E‘L.R½¨i 'Ej²ÈÛ×ÿÌôX*R¢¿ß3Lº=îŽC¿¨ôû<¶'¿¨k?t³ŒÏ¹õêâoýäZu}»Èý·÷ó”¤añéõXüý8\Çd½Véðò±Ì/õæºñâß“ôÛÜù¹nêí×öô®ÒÓsšþø»•©ÍFuþ}9O_Ïw¯RZöqìÂû~y}„51âçkòJÓ}Î0íØùÇtný|n>YgáÚ¨õ!\›ÄÝïåe—kûû<‡ð<†½ÔðbÊèÝH-(†½ØË°M16ž‰a/~ {©QSÃ^ªš½ÔÄ µ€Gsˆ­ðc/+üÈcu<Œ™0aªÏéÕ>ç9.–4±0«úÁÎÓiœTX…_òW€LAÔ endstream endobj 120 0 obj <</Filter/FlateDecode/Length 933>>stream H‰¤VÛj9}oÈ?èÑŒ¦ªtk1$c{!@˜~³—{w6„xdz$oùõTIjõÅÍdÉb¦[RKG§ªŽŽüЬÿØ‚úç±Y_݃ºøÜ¼m^vÍzÃw 4š O2éé•z¼ÛËLk:| U·kZü×*ãymUwߜ܀ üóüs§ÝÇæ²kÞl¼'{2f0ŸÀ¼Bãu+xÔ àuB<]!€´|m¹Ú²µej‹jkúU<ªx´„WQȎ¾þÙ½jÖÛ/ï÷ggëw‡ßêþþ~8»º¼º°þüü\½¼Ø¨&ê6rHÝ_MFl¼æqÐΛüázÊ¡ò'ójåOù,ÄVÑ0gleêuˆ¡RåtT½ó#ª4?Vˆœ$ÐÁs4´N”„UHI¥àšÅã¢&ËßÉé¶-2B/,~!Æ^4äQc08Ӎ]ÔÈѬ8Ç5Üð;Öì “sCEj#˜)c¤¡Oå„Â×òÞÕöÅÞÿïü0:Š¿Ÿ?N°ós÷4‡…³ñT·ýT™€ÿÏ'è²fÞik]ÒX—-Ñ(Ëô4‡àrQбm¶Kƶݼa,c¬ú¦¬z­š6#I ›§ÂE¶6oÙï•çÊÔÆzõ©Ù²‰X)üjAq½b¡e\Bšœ2N;ÃåöÆhB¶‰Z ‘®D*”/ù(}’c/…›)m#§µüÊ<</BaseEncoding/WinAnsiEncoding/Differences[1/nine/one/I/N/period/p/comma/l/i/d/m/n/c/h/g/u/T_h/question/D/C/s/v/e/r/o/t/y/a/w/space/A 127/eight/O/five/f_l/P/E/T/f/j/three/k/W/zero/q/hyphen/f_i/x/b/seven/four/z/H/six/S/M/equal/R/quoteright/B/J/parenleft/emdash/f_f/parenright/G/colon/L/V/percent/less/F/semicolon/slash/quotedblleft/quotedblright/greater/two/f_f_l/f_f_i/Y/U/K/X/Z/endash/quotesingle]/Type/Encoding>> endobj 122 0 obj <</Ascent 864/CapHeight 650/CharSet(/nine/one/I/N/period/p/comma/l/i/d/m/n/c/h/g/u/T_h/question/D/C/s/v/e/r/o/t/y/a/w/space/A/eight/O/five/f_l/P/E/T/f/j/three/k/W/zero/q/hyphen/f_i/x/b/seven/four/z/H/six/S/M/equal/R/quoteright/B/J/parenleft/emdash/f_f/parenright/G/colon/L/V/percent/less/F/s\ emicolon/slash/quotedblleft/quotedblright/greater/two/f_f_l/f_f_i/Y/U/K/X/Z/endash/quotesingle)/Descent -252/Flags 34/FontBBox[-150 -252 1061 864]/FontFamily(Utopia Std)/FontFile3 142 0 R/FontName/VWGNFM+UtopiaStd-Regular/FontStretch/Normal/FontWeight 400/ItalicAngle 0/StemV 92/Type/FontDescriptor/XHeight 461>> endobj 123 0 obj <</Filter/FlateDecode/Length 619>>stream H‰\”ËnÛ0E÷ú .“E ·D†Ê±/ú@Ý~€-Ñ©€Zdeá¿/ïÜIÒF€#i8œCRoöÏûqXLü}¾v¿˜ó0ö³¿]_çΛ“Æ(ÍL?t‹ÞÉw9NQî·Å_öãù­V&þ^Þ–ùn\=ùÇ(þ6÷~Æóðksx4ñáušþø‹“˜õÚôþ}9N_obö´ïÃûa¹?…1?ï“7™Ü§,¦»öþ6;?Ç­’p­Íj®uäÇþÓ{k9ìtî~瞆à$É›uàŒœ‚sáBžä-¸Î„+á:×|¾[áJ¸!KG.À-ù¼!KÎgrÞ’-xG®§ ç-Á¬¿,4.U‡X0_ªÈ›Ò¡V‡ L‡JòÒ¡ÎÀê 9éPKN:ÔpKÕk—Ò¡–ZéaR:ˆ©É9j¶ô)ßê~ K—ªÒµ´ô)‘˪Ä•ºàJǀÕǁé“ÃÙªO¦O‰Z-}rÉOŸµZúdØ+»ý¨ Þ–5˜ÛÑ!C.G‡NËé¹Âž8:”2V¿ 쉣C.1ê 1ꀵwtȰïN$¾%ÃÓÑ!Ç·áèÃÍý³oçÃíþ‡–>¥°~+¨¯¥O:Z=WX›V}àÙ–¬ûÐÒ'ÃZÈq~;Õ¡Åh/A³ =Ѽw²îužC“Æ)Ý}ký{o®“ £ð‹þ 0 3D. endstream endobj 124 0 obj <</BaseFont/VWGNFM+UtopiaStd-Regular/Encoding 121 0 R/FirstChar 1/FontDescriptor 122 0 R/LastChar 182/Subtype/Type1/ToUnicode 123 0 R/Type/Font/Widths[500 500 333 734 250 568 250 269 275 568 869 583 467 577 490 573 1080 422 739 655 411 474 490 369 543 310 470 498 722 206 635 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 500 725 500 568 577 577 589 287 268 500 497 896 500 561 368 568 458 561 500 500 452 756 500 512 894 543 615 262 614 331 357 940 586 357 710 250 548 626 758 538 548 250 423 424 424 538 500 868 868 582 706 643 620 587 470 224]>> endobj 125 0 obj <</BaseFont/VWGNFM+Wingdings3/DescendantFonts 151 0 R/Encoding/Identity-H/Subtype/Type0/ToUnicode 152 0 R/Type/Font>> endobj 126 0 obj <</Filter/FlateDecode/Length 1008>>stream H‰ŒV[kK~ð?ôcFØÙ®êÛ.„€Fsà€$óæŠ˜è b‚ƈ¾ù×OÝz¦ÇlbXvj¦/_]û«~s´óPzð$C2éÿu—ã˜E^Û(¨ô†VQ1,w{Ýu³œõ©;þÛùBqôÄ ÏìÜ÷ËënýÏ9¸Oß»õï‚7î»ì<ý²iHa“\Â2 äàÆ«Žµúg¶þ‘þ-`+mÜ“îÂ>è<¿óZLó­}b£ÑV ±?‹yñn&7¾à± !ª’m¢wD5ÁÀ¼© ,Çº/Šjú‚j ÎH‚Z Îu[2>Ꜯ½1½aÂVé›÷lò.By2[Ζޞ5½)YE’Ubäg ΝŸþG™ùéÀ»WŽÓæ9mß(eœ-pò°qÉç6îòªãÑ«.”< ½}éλ×ÝsAÎ[Âô”X*°* ì{Í>$L†˜q3$M=¢gûÖç_ß_¯Ÿ]ÞþxÿeüøëöøìåÙ•'žœœ¸ç/N/†$μүÜšK³õb¹q‡Ñï0‘ô^âhÐ÷ƒ%²%°l@%I^*­…OCÒ™ÃÒ­ZÂKv¥Zÿ~Æ¢F‹D™„Eٍò9a}b‘U¤~«çä3,&±ÏÊí ïQ ôQÉd£_6™å(õÐêFŒý p¶U¢1&.GL(Ïí䝔"]XéµxR™œ’ 5Èë±”˜™¯Žê™íWÅh0éiÛ÷2€z@O¿ č»[Ú)ÆÇÝ…QOÜíiBÏ\êÛ„6mÁVXB‘®:U_c„0¢C±ÎEñŒ˜y…•&²FpËFq¸©aÙ„ @ÝG± LþÌ1AKØÝu öw['–CIúÇì3Ǟ#[˜JXH ƒz}Qš¬¨Äæó"z+Ðr‡r7£&h‚¤#¦¥@©E˜)‹=æšRœ"#åÙÄR³{;™°Œ6Ó0š@Å9ã,¥`A—'Q¾¯zªSßuÕÊñºÿ#ÅV²‡ªEƒ6¥Kƒm§·4…<ÑT¡¹E €»§ånòlѽÙml©Uր•».`l¯"éA÷Òq„‰ŠÁŸv¾²!¬˜k£Jsï!eÀd;~PJBTK‰©[Žû Ûõµ8ˆ ÷ ž0)xÄåk+®lO’Þ¶~“¥8¹qùz“(´,êWË®—[…Ýè{}Š5ü#r–PÂࣇjÒ1áoN×ëÀnƒ/Û&^û°ç~LîxøMþpwEâiD½ ®¶ž[-ã{-îò^ïÓ¬Ò“‘e2ŠªÞ endstream endobj 127 0 obj <</Filter/FlateDecode/Length 862>>stream H‰œVKkA¾ï¯˜£]ðZÒ¼l0†6B §ì­.%¤(m($…Þò×;Ò¼×Nšö°¶W£‘>IŸ$OWÃʎڵÂÑ ©éÓð~q  ðÀÈ7„wÞí´Y®pcE €BBƒ(H¬ §V4äFþ]µÀ-?LWÃúúçÍÝn·~}ûðëæûôù÷ÃîòâòÀèðà~¿WoÎÏÔ<ó}rËéÛpñ.Hv€pž</8f¨½‡Ç08Q_ -Ù”GW¦Æ+FÙŒ‰&Hû…Ä,y+ѩ璬7ûÛ (i3véF‹ÏçjSò„8ú®k gébì:ÆQãYn‰±ºy@º‰ØwXu©jÆ¶ŠŽ{VIÄɺh•™Áé/‰ÅA¨^c†ŽåùN•k±+Oa®NlÖE¯°[[Éz.½œ10ñ#X}¯ÓT–c^qt¹ºh©ž‰zT;#Ÿ‹,!oèêˈê»dJ×lIQê8~§È† ?‚B5}áJÇÆ`FÒhM$ƒÕ¾´u$`¤À.ÑÃö:sp9€\,½¸êKO”ʉž¨÷ØE8³9Éüî´çZ”FF@«G©á)µw™6U_Ϥõ6£ÓhÂï+‘Î:¤áP´á쩁ãšDFd‰Ÿˆuhõš C²È=LÌã^/§œJE–½H療Žã™¹g¨Ûß»4 Sm£ñLNߏÈzƒKcB+Í)Ïm×,ÉJÛ®á ‚Ôœ\Ä'ÂêÙ²õ³\5“½® Ñbç®Åö¤Lö¨§m™#Ý^HV Ifoå—À΍Ð2€Ý͹áH)Äi°Î{ÃS`•¤µ#1ÒÌ)m™™5”‡H,Û`ÔV¡vaºo¬ÒZ«éÇ9Ä™ÁÙ´?ÂoŠ6N¯ªàɶ+½Yç0z܍¼Àˆ¨Ôýíݰ~{ êëý°>£Œi3ZAÅßèÝh5n3®]°¿ÙóöQ{¶CZ>]1‡b®™“#øm™“iY©…=à“Ó¬gªhµf¼ÿ­þ¦ykçõùÕ;ÆÑ_:¦ë/Ñîþºˆä_ˆ¯¼aóYÚ,¦nù¸—…‹y¼doy+»EÿPÆ–‘!¾ /!¦QS79ô”7<Ú¦tuëKTê-f—‰ endstream endobj 128 0 obj <</Filter/FlateDecode/Length 853>>stream H‰”VKkA¾/ô?ÌÑ.x-ifwm0†6B §î-.%MÚBiC!)ô–¿^4Ïõæ…YÛ;£Ç'éiÆ‹Ì [‡dÆÓærq ‚u݁Ð?ÃÀæÿÖ-W,ýòóxѬ?ý¹ºÝíÖï®ïÿ^ý¿ý»ßŸŸ8»ßïÍûÓÓ,€ÃrüÙœ}ä7öpÏêÛƒÂZq@&Ž ñƒ•€G”Öfâ‚H±–ÃoH,]ÐöqèzP$BQöáMR#* Î¬õ¨{^sÉ4ï?°V9‹è¼‚Ø·]Â4‡#˪òýhß׊†`“m‡Le™ `ê*òVÁÏǪ¦¬ÂŒ”`Sâ3)—d%ï¶R2*w©_Z©ü0ÑI …ïeé©ò"5¾S*¥œÖâÁSo\PÊÌÒ<¯¨È,LHYdW%Uº˜õ ´ª\8[X0Û3Y5HY+tËÁy}%‹aÓ䞙=Áƒ"§[bRÍ#¹Ì2ÍÁ›l"]*-gz=â0hÆïÍÖ¶mß›MgÈfüÝ,4ßÌ[ ¿å_îˆÄÆ|Wa]ÙU˜A±«@;ôì®ö-¢1w×·ÍúÃ'0?îšõ EL›¶Tþûm6ÁÚ±ùÍÞ“¥E^áo²òÝ'k(Ö8BTk·¿ó[|&ƏÙRÙ w:r5wŠU߉sL]±š(_ð3±9HÚÜg$×îÅ­]K{ÑÅc„ãõn[ìmbݍtLô;}’%™Ž„e!Ý›²óÜÁŒ4|:¼Ó2¼nèS|dËÚ¨³Ayî*€3­QÞ!»_ÛU6´)¸ùb¹n‘z¹ž¸IOðeCWÐ9òBì’¡7Ëû\SÏÌúÊgl"ˆÀ|¸ã[±sW=‹ç“‰n*QÎlY9: aõùxö¼rzÍ ÃLJÌì,!R¥—í+Ê¢Ò3D©m•S£Øñ!U–èðUÙc³árQLZLW!+i<</Filter/FlateDecode/Length 876>>stream H‰”VKkÜ@¾/ô?øè=¬WÒc׿nv»íÛ»§?·?†/Ÿv———¡²n¿ßWïÎϪè|T¾ø~AÓúºÄªz¼{Xmß_Cõíqµ=£Œ¯k#ŒOì\Ôvã.øïö±l š6ú!Ãÿ½ºCvÒÅäîR{®H±6–e¸gÐFAg¦ÅžfB à‚,á‚‘J=+tOã –´ÚÈB[¹$+Șy©³ sN™sÏÌ1l’aDÕÓ} pŒfOí§ìSsöOÁYΡÖIÔò:JLΉ°¢À”’qªÛF_H×J³’J_ËF6ŸD\$Ð]Ó¥‘éä|á÷‰vš4Ø$yö8_¸ÅºÍ*`ÚD ç´0Ñ’^h*åí›ä’c[q|úð!(´<ö¢XŽ^è—+†ù³²Žs.–-î\à™¬d©µ/¦JÔt-UÖ7®ët,qò¨á½_¢E¢‚¥f–§ïôL¸Â^:­ô).õ^;öŠ*{<</Filter/FlateDecode/Length 898>>stream H‰”VK‹Ô@¾Ï¯È1’­êgË‚ºîAðdnFdG݃è Coþu»ª©ÎκÈ0$]]]ϯ¾t»ènþv˜Û@øÑS›q½ÖÛÌ?Úåaíº~Ä6¼±þøgQ€RêÂ:´¤Ž]O2ôQ–M Þ¬ÁÁ–jY»¸ßyz(^)ßõº]NUIAÊ©¡2]oÚå­°Äu:ý8¿=´‹BK€¦ÇA9ÝÌ·”ð1ÅK~•´>w†’õ›‚¶¬PbPñ]qò1i:ºK)žÑËL`Ó eÝâÊRć²™_PìJAÖUªÂÔ& R¡ë}›»@mËMgå37ÒÄÇÊND<^ºN¡ßJ4))£È ¡:²kPÜje|Ž2 Í]iÙJ›â8ñq›[wÞ'ŽÎ¤\$@s1SŠ‹§Å‰:Ōʧ´OT?QøÇ½ÊŠO¸B¶MeÓ‹2 TÖÔ ÑakùOR®!¸zn8_@¾ÙD ØÁê1N|zÕÞÚÓh:Í“ÏþˆÆ  µk´õ‰r BA¦6"ü?¢ËŠ4>„b³3Ö'öºžëu¼¦`£ÙE1„ý‹à/äÙk×>^¹¸èwîM= üy#¤²§ÀúÝñ$o#H·uâ5Ö±rêCÕñG5¡Q¥p¼›Â‡Ø†#I«é„Ä­ÆLdV·òûP¼òÆóߙ̾GqjÝOAb[U}!£lcqœÖÕŒŸ Áf~8øÄbô4.\rƒ)R]¸ÂPÆWïÞŸ®¯¯^~^ÝŸ¿þ^¯ïÞÜÝ˜éææ¦yuûº9À`M)”æB½yÇrcÜà;Do _0½ŠÏ/"![¢51ZɹÌ`œÑ"Z`׏ÉÜ"JÃØhT‚ÌÃ'cOæ…M*÷| ïëž+T<æ7¯¥ÜŽI^-%‘(ÍóÆJ•°»Iv·¸(}¹Ï׋ݜîÙÖo—9j…$Œæ¯Ês‚T endstream endobj 131 0 obj [139 0 R] endobj 132 0 obj <</Filter/FlateDecode/Length 230>>stream H‰\ÁjÃ0†ï~ ÛCqZ(½„@iä°¶,Û8¶’Ù(Î!o?Å L`ƒüÿŸø-}©¯5ùúÁÁ6˜ óäÇ0±Eh±÷¤öpÞ¦µË·LTZàf5uA•%èÇÄ3lÎ.´¸UúÎÙS›¯K³ÝL1þà€” €ª‡z7ñf±]íD÷iÞ óçøœ#Â!÷ûgŽÑXdC=ª²ª |“ª’û§¯TÛÙoËûxwQœÎÙ½¾/œ|^¡ìÄ,yòr%‚'|­)†B-Gý 0­o½ endstream endobj 133 0 obj <</BaseFont/VWGNFM+ZapfDingbatsITC/DescendantFonts 131 0 R/Encoding/Identity-H/Subtype/Type0/ToUnicode 132 0 R/Type/Font>> endobj 134 0 obj <</Filter/FlateDecode/Length 831>>stream H‰”V=Û0ÝïWx´ Ø %ÓröN³»‡š!È~½iI”“æÚ!Ž-Qüxä£øÞ¯¦õÂOäŸ_ç|äwàßì†Yf‡"éb/bwºäÏ*È ¼x¯ÊÊ–ç­)ýG7È÷ìBŸ9¤ü^Tªr鯤íÁÞÍ‘F°­f»ÎÍ:ía½²®Ÿçoýê‘Üù×tŽ~ÝùûÛ{Uf‚dT.ª—%cu=¬Ô/“X¹ªÆcÁ-xØ]æì5ÙÃÀÏ‹ÀK9n}k“Ó1iH›…UDR€‡¸2Ò̦‚õzØ'ˆYóàkRöT¦T¯·£/r0xd¯ÉDÝ-u#Q™S5ßÛn ¤OÎÆA‰—1ΧºóGMå°¯æÀ?$pð.xß‹§Mkå]ÉN'lC¿g”]~‘Ãtú®(ÕଞRú­ñW©ôøEîçoi²‚At1ÛpÈ…/Î$§€äb¡Û_C¤1Qç'qԝ'xIà=*œþC\FôÓÒù“˜Ouçd3ݤ„ÍÆ^DsÄSåx.¾ŒD«!´ðèªÖMBgݱ4p§°‡i<…c‘4]/qå,  1·—ÍlÞ´àqÞ_‰R“*àRÓºò艸$¦¯Ò.¥V/DæðÅOÿK‘B‹Z¸¢Ž=EÔô…Ö' PïhH­FSi¿´ùà ?™NÖvËv€}Å\¹Oµð?üY7´z*Á·6äÕM¡Å¨î{ÀV¸8,³ÇJ(?M_H®ôG£¦nÔʳ—üÆE˜^1{:M#Àiê<÷@ËpuŠB)Œã2Ç/8E‹´Èòo„p˜Þ!ÚS^ê¥.г™$h¿£¯v²)"í£²æB«kÑ€`Pór°¨J¥jo™±9,\èa¶ Öî½–žì]uF(}îñ¦±Š¾Êø…´ø¤4_rØGêëô¥7ü‘k@åwê³.¹;}yo«ýÔ†H`֎wA0·¤ûc æ¦Ie60óc;’QNÓ%MoµÉì‚é0ÝU\“: endstream endobj 135 0 obj <</BBox[0.0 774.0 567.0 0.0]/Filter/FlateDecode/Length 92/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]/Resources<</ColorSpace<</CS0 114 0 R>>/ExtGState<</GS0 116 0 R>>>>/Subtype/Form>>stream H‰Œ1 €0û}ž 9ÉÅØ§¹'Xb ±ðû^ŠØÝXMXJ*ª9‘V7HÈü¨\)¼<</Filter/FlateDecode/Length 853>>stream H‰|Vß‹Ü8~Ï_áÇI!^Éò–…^w÷ pOÍÛÎQº½N¡Ü Ç6…þù•,'q2ÓeÙ±G–dé“ôyÆ÷ ˜­‹dÆûæép<§#¸ÐvþÀkj‘òµˆ¿Ç¶®—h1¨b'š.¶4+A¶e;§.ž©ý{|ߨø¯l=8K€½Á-F fü¯9síø­¬*Ëê!XHˆ¬I¢ôtØÄŽ€‘SxÉ—óv=|iƒrª„ÎAÛ¹‹¼æ¨]ΣKvéÅét<µªäÓ%›R\püG"§ ‘ߌøšñÔ¤’„¬DÞ†ƒA%SÀ¬ÿáÿOçÛÛ›·Ÿ§Ÿþ¿üœnüpwwgþ¸g°Á³Ÿúš‡¿²œÀ|À <ˆŒ€s¤Ôî¸~¡îJiEV¿û…1mû¡DÊKjó&¨õyaUmƒTû]ÐÇâ…Š›½rZ¹üyQJcm€Wlz%B™Zý®Hw¿Äzº¨ˆ$$2&¾ë˜%&êM¿!>eö £&°ƒ'4=VO˜›‡¾€X?·ù¬`.eÈ¥(˜Î…[=u±˜îž>í>‘å~„¸ícßb,^}ù8Ӟ¶ .³DW(@¥Ü€Sníê¡]Mª1.¿1ŽûvíÒ¥“y¦Ú9ŠŒP!:(¹.úŽÉ®tºÚ­?®ü²éOH¯ä)è<Œù%ÀOÎ? endstream endobj 137 0 obj <</Filter/FlateDecode/Length 4393/Subtype/Type1C>>stream H‰lT PgîáA¦mWg`ºEñˆ¨0¢"¬QAFX5¹fÐA`È0‚xA¢–dÍF£&ÆõZqÉZ^KØåP‘¨ˆGŠ¤¢k³åQc|=y³›ýД•TWÿÿÇûú{ï{ïÑ”JAÑ4­K[kŠIc_å°.·ØRSæ Q¶|³|*Hþ´4D%â1·þ´î§HFê+…û]öç³µ”’`P*zš›a¶•Ù­ËW8ÄÐéááÁdœÒ7†‹Æ£8Ûl˶ˆ)eÅKA±8¯0Çf/²Ù³óDqv~¾Øg\,Ú-Å{‰¼ù’”h-³D‡=Ël)Ȳ¯m¹b‚µÐæ(+²ˆÑd"±Yn%°v‹Y´ŠŽqáÄ”‰b/tˆY…f1õ•õ‚Ü\kŽ¥o³ «L$”^·Î±ØYd¶»˜·Ên-6[sV[añKð¬Ëo°°¦Ä|_Xl±ür[7qRLJª¼Í–\ŠŽ¦(–¢ ¾©~ì1É#ߣՓõ,ò¼ê5Æ+Æ«Ü븷Ò;Ôû-f Ú4¨×'ħÔç±æ M¢f›æ‚æŽo¤o™oóàáƒK7û‰~Ëüöù]Ó´‹µŸj/qo`aU£ôŸFšŒ£•U*©Ò•ä®da+^äñMØÎÀ#EláA^¸?T»Ùe}ßð&’5+5óòÊ+;AÇÊ{Àܳ^´?:Aëyäî» :ù´Šö††í--;L™™ï™Ò„HÕ‹¶Nð¤NQ4Å¢z´Ç¾¸fw:¼àó¬Gõ+î~¡;‰¿ÇJs\k˜é¬ÆÍ»*KéS¨„tW%? u8óŽx‚þàØ)àŸ#`¦Û@û-Ì X¶Ž"ÿü/\IíXrµl/\[€#¦0â6*`+},ʃ¨àÁ‹ýle0H&y  Á%4A ܃ 5±¨‘¾¢òúPAD‘Õ”;¥NrU„l²ußó£ª!ò»‡U0㙳 g„N®ÆÈ@a¤ –}K`*Ĺ·1“Ó0 £qt-Za¥ Ù_â2'öŒ;Òg|WxýÀ¸ƒè2á`µ¦ ÒB ~ ¤š¡„ÑI5° ‚qàcu0åŸU¶2Á°=˜ºÓ­‡Ûô.ÌÇ!ø.¾Ÿ  §ZS 0“7ZxN‘{ôÅN~]sׯv=QmüçÑ›qݸK¨QsOoÔ¶}ñoŒÃQuS¢ã6¬J1lGsèlËîóúŽ«æšLù„ù¨èd¹G®MŸc´%§.ÚýçtÙ!rB+Œ®*ÕBè¸n„ž{³¡•©ÁVύä၂8ÒBŒbñcw#Ó4–ÀB4Щý™ZXAîgj;™DÁeâÝAì&·7³»¾þO úžžüPãLk”)}ÿÇV[W‰~w¶âtÇ{çô÷ýð;˜‡ÜéqE%[*× [adá`‡si ä“XüƒÈ—ÜnwÍæ?MOß¾X%&4c2†7àHãí'0^àî}‡%e®JÏ3¼_Ã8·Õ|ô_ž,_{BÀxtð׎$Ä&%ÄÇØ.^í:|¹SŽ…ÔKÄk”Ò”R/—YÜåîe ˜…jéî4u"iI"á‘$С†0zÀÝ‚ið?ž{0-;cá‚"‰HnxFr¼'ëÒ¤CµšëîþìÔ­x¢² }‘NB?w+êtrW¾ëÞF¾µéHSËÑå‹2Íæõ†ô½‰µ—t܃ÍxŸo;õ·ÆC†‹«ÛòbtÉ+RR–Ô_4ô¥ÊX9Dô@p”wvókÎœÙØ¤‡’v’Eɞ S0 ³ÇàxäoNƒam ûÏjÞgFnÉFúè—ZvíÉ |œ­£órmÇ•ëG’çÍ}'1V(@(¨©×‹°Êù—5FºˆR®SÑ ~£¹Þv©ƒ?p¦eo‹ž{zñ‚}ޢ܂Ülayvî¢`ø²åDòøVu0™&TÇÅ­_=ßÀõ‚ß§¿BÝFR4ŒxY"ÉÑ®T®[ʀƒ@Dðƒ Š¤ˆ3Ôˆ"¾‚ˆbPFWßJ@ƒ D\Zh´øÀj|ÔúˆâZ-±û=íê>M»òƒa;÷ìùö>ß÷í}È@šÁ…¾2°|*…4°ïÄœ˜lmÀ ÂdÖ,äX›Á@ SE°²è;(Ð’ŸùXô1±BKL¿JöRO†<ó*…åŬ0G‚ÝÖBFÑnzR`-Ì’°rˆ.ç_!ëM„©‚6‚#„T"º3uÞù0{ÐY,ÁìŽýp¡ ýÝ G-èA­–oÔG£Œ}±o4È WyØE'“H©àäýuOæX-6]Xž¢MçqâzÝU/‚8Õ“Ž@­½5ù?ÈÚgá[ úÂP¤š„ÌËðK`]À-ùÙ9ÛUpAÛ˜Yùu°î„ö$¡Ü‰6ºí)ñJËÚ÷‡®þP›ÅÑzp´'+Åú]æi»µ;˜$À»ÁÁôâeeñ›ßΑXj¾½m€h]^*]º²¨#êãOä=(fJÞ$#!qŽÄ!~ õ5ø¶!|lrtTTÁÁêJÔˏ®¾n¤Qǹk°ëcÀÙpý›=§««3Ò*Ô®¾CfM“É<â!-IdÖc$œ™ÂcÏÌv×9fzå:ä*8éE„Bè‹0Ie‘”Ò âGº»Ç·€“Êp®Ædƒ*œáúííF96»ÁhVq[ÔDù†X+9ÿBY¥€^Dà/³¹3šXÍj·ÿ´@ށin0^”@OVCNzkãDãAz‹ò|“žPô=’]:u,Ýør€Ø¥0(ä¹rÑøËô1Oáïà”€ÃEȳ.]¦WÊÒt¥n,ÄõP„;ŒÎG´Î£r|+á-k­a&Èü+èZõ¥à s‰!o€£¼â)sPŽVÖî­5Þ<¶d¸ö8eüú”-&%ᣠƒ\5ðAÔà %µÅjŽ(/ßôivbn²½¼‚ÚÙgdzJ7–Ûo,ÛX~ÖpYï°¿àÐȐK§©ru>Rn>Ø~^­ç®KX–¤.1-úã㌄ \¿ÍçÜiƒ¥f}#ivPàc°(MGÝ»¿ßûñ)ƒü|“ž4«ò 4¢E7Q®¾˜#E•c®5‚o¸;úD€}Cf&MOвhà2©¢éçN›])Ÿ&ýØçJ~¼­Sèz%Ys<×R®­°:5.=Þ8ø£æž»üý‰ƒk2ö¿â<ÁKð÷ÿpÿÞQŸà1Iƒ}ýRž~Gð ï=“Œüt–X=wæ¾qFô ±õÑäj|·ÝÀ÷bÍî3Ç©‚t àöœ[íø¤«†Ã¥qkÙÙkÆk_L Û¢ýƒ”%±S–†‡GT}¿N&¸©ð&NÁa$›8òù@júzç¡j•Lœ¤àß }Û2ÈÆmÓ¨#7QphEê÷—¤ã;Ë+‹ 2ÖZh`ʧ¤åÇ[ÿŸ›h|7"ØCöø\rqÇ”6plƒ¦G>m/s¾'Û” „{WnÝyØr4ØÏ?qÌûšüŒˆí£È·B²¤ú„è}¡F|ï÷ä(=Q­£ÁÎûÚù²ŠZŽè»uè7nßÞ9jŠBò¥kÎañ×ð¸S/q÷a#xí8 â¨P{2@®xyϏÏîmúm¸Š‡iÝ"}ô=t ‰X›¨fA?iÞÔ˜ÅLWW»&ÚÙij¶Ð7OºŸŽl¯à,S‘©ýÛ[zzKN[¹r}Á¡ÏöÁ°tÍ;ƒk‰$§X¼A½Ý¾HéŠÐñyæ—¿›IÑ£q³A".†2jïËùÄ„ÃpސÅ&t!kÏüyçYÅ(ž,¯o… éøsí-W7ØÂŠ ù/Üȝ¡ây¾–^_S ¤ù÷Q—4a±z))æP°1v¢)<~g-åÊ_/fdêä8•v߸‚²ÄIß©°vJás=Ÿ£#Á¨çD,OB‡â`š—<0H÷?)7¾º~ÿo_}èŸìãÑ/ùñ]j'a‚é©—ö­FLàÝ›#FVU¥“~ý_Õo`Ì‚ØOxÏšÑU"Öåù(¯z÷íõÈ/ʼm¡io{¢mó˜,éÜ¢é%£Hñ6 vèÏ¿¶jgm‘Ùo”WÌ­u¨¨/Ø£=»£ ŒfYØN°%=={¥qDTÀŒu{-ÝPœ$n?­A&6¡5Ûf)û#rse¹Š|d[ÜœíáÆ>^ÓQ§áDHoìoˆº2qÖì{âTyñ|C¬¬>›I»†îLÄôi· 'w”V±&ý×;SK«Ðp¤£¥_]؏Nj·äV7¼2ÓS×/5Ƭ:Q¡ÁZpj¥¡½¿„†™sgc#Ì?S„•3‹BÖ•+Ž7õñòßx÷¢ ‡iÝ"¡ý9p¹RWræ·þ´ –tv;‹YoaEÔg»Á "™EàãÕ1ìIWWje®ÌI@Îùlºí &F—^³>¿ä4˜àƒEêZïðæØÍú޾"øò®¢\éníÅ#tc½"öíX‰|Õ§SŽvÛØ—:˜Èï3!¸O€"Ø“%Œ`˜ˆc`¼Yü}O쁶 ù[»³Ù.ŸëÀ§ì)B¬µLˆZ˜0uaÚæ­ËÕLO!³¸d}‰Ü‹éâ+žÔ`*Ë㛲êN(ø ÛçI#l´®Š,D‹;‘š¶Ý†»$Øhñ–x'W~®]¾ñTî×åRò×>…Oÿ½LyŲ¯½fÙ 6˾ö?–½ÊÒ>Ñ‚Ó,°Ô"BÑÖäY²HgZ ÍbO_äYÿcqP÷Œ™ÝÝ¡Õܝ6uwaç\Ûç(ÿ`Žé›¯ endstream endobj 138 0 obj <</Filter/FlateDecode/Length 5308/Subtype/Type1C>>stream H‰lT{TgŸI2“1@†Ik‚Éh)îŠd‘àƒú@|t!ˆÀª(` SIB“â£hR*GÛ‚íj«Ûª[±¨)n-Ëâc]j%±í_TŽ´gOöNúeÏÙZíölÿ˜û}÷»óûß½ß½Ž‰Žãª?,ž§Ÿ›“0×¾Úi®4Ù³òÆÄE6‹Áʇ5¬gG‹X”F3QÓë˜N°/G²ùџľØ'ǎabL†kñ饿ŠÒªÕVsRRzR†­ºÎn®\éd&¥N›6‘³©I#6e"“œ””̤me&&¿Îá4YÌk¹Í^m³œ&£–I¯ªbFÀÆnr˜ì5üá3ŒÙÁ§Ý`4YöUŒ­‚É6[mκj“Á‘h9L¥™£µ›ŒŒÙÊ8Wš˜Bm¾–YÈ‘[ŒÁjd ž£s+*Ì妑C‹¡Žá$ý]n²; ÜjãhìÌk«íf‡Ñ\î4Û¬ŽgäVƒÅô+*lœR.*ŽÞê0™~ϳ”Í×þnn~ï¤0FSÆ•Çø;‘(°±Q˜ŽÀ^Á°9£±bã‚Õ8æÀ0†íð0|›[Ê>Óc'ñ9xþ@ ä \‚ã‚/7O„a¶Ð,ì-}HD)D9–œKZÈf²C¼\¼K’tI½ääbXlXFXAØÖ°Ž°Káâðôð=ឈ õ{#¾”âÒithT樦QeSdëdO"ã#çE¾y.òJT|TyÔ‘hAtIôžè§r­Ü*ß'¤ÆQj7u,

Java vs. Scala: Divided We Fail

$
0
0

The discussion in that particular StackOverflow thread dates back a few questions, so instead of digging there, we will just take the latest benchmark code, and wrap it up with JMH. JMH already has the bindings for Java and Scala, which somewhat alleviates the difference in testing methodology. You can find full benchmark code here (warning, it contains spoilers).

The original benchmark may be expressed with the help of JMH as follows:

@State(Scope.Benchmark)classScalaBench{@Param(Array("1","5","10","15","20"))varlim:Int=_@tailrecprivatedefisEvenlyDivisible(v:Int,div:Int,lim:Int):Boolean={if(div>lim)trueelse(v%div==0)&&isEvenlyDivisible(v,div+1,lim)}@Benchmarkdeftest():Int={varv=10while(!isEvenlyDivisible(v,2,lim))v+=2v}}

What does this thing do? This code tries to find the first even integer past 10, which is evenly divisible by all integers in [2..lim). isEvenlyDivisible is the tail-recursive implementation of the search through div.

The straight rewrite of the same benchmark in Java yields:

@State(Scope.Benchmark)publicclassJavaBench{@Param({"1","5","10","15","20"})intlim;privatebooleanisEvenlyDivisible(intval,intdiv,intlim){if(div>lim)returntrue;elsereturn(val%div==0)&&isEvenlyDivisible(val,div+1,lim);}@Benchmarkpublicinttest(){intval=10;while(!isEvenlyDivisible(val,2,lim))val+=2;returnval;}}

Okay, now we have two seemingly similar benchmarks, let’s run them! Shall we? But before we do that, let us try our intuition and make some predictions. Most people would predict that since JVMs do not have tail recursion elimination yet and also are rather pessimistic with recursive inlining, the @tailrec variant exploded by scalac itself would bring in the performance of ordinary looping. Therefore, one would conclude Scala benchmark should win big time over Java benchmark.

Good, let’s see. Running this on my laptop (2x2 i5-2520M, 2.0 GHz, Linux x86_64, JDK 8 GA) yields:

Benchmark             (lim)   Mode   Samples        Score  Score error    Units
n.s.ScalaBench.test       1   avgt        15        0.002        0.000    us/op
n.s.ScalaBench.test       5   avgt        15        0.494        0.005    us/op
n.s.ScalaBench.test      10   avgt        15       24.228        0.268    us/op
n.s.ScalaBench.test      15   avgt        15     3457.733       33.070    us/op
n.s.ScalaBench.test      20   avgt        15  2505634.259    15366.665    us/op

Benchmark             (lim)   Mode   Samples        Score  Score error    Units
n.s.JavaBench.test        1   avgt        15        0.002        0.000    us/op
n.s.JavaBench.test        5   avgt        15        0.252        0.001    us/op
n.s.JavaBench.test       10   avgt        15       12.782        0.325    us/op
n.s.JavaBench.test       15   avgt        15     1615.890        7.647    us/op
n.s.JavaBench.test       20   avgt        15  1053187.731    20502.217    us/op

That’s odd: Scala benchmark is actually twice as slow. Consistently. At this point, people try to muck the benchmark into showing what they want it to show. The obvious thing to consider is inhibiting tail recursion elimination altogether:

--- ScalaBench.scala+++ ScalaBenchNoTailrec.scala@@ -10,12 +12,12 @@
 @State(Scope.Benchmark)
-class ScalaBench {+class ScalaBenchNoTailrec {

   @Param(Array("1", "5", "10", "15", "20"))
   var lim: Int = _

-  @tailrec private def isEvenlyDivisible(v: Int, div: Int, lim: Int): Boolean = {+  def isEvenlyDivisible(v: Int, div: Int, lim: Int): Boolean = {
     if (div > lim) true
     else (v % div == 0) && isEvenlyDivisible(v, div + 1, lim)
   }

This gets the performance back to Java level:

Benchmark                      (lim)  Mode  Samples        Score  Score error  Units
n.s.ScalaBenchNoTailrec.test       1  avgt       15        0.002        0.000  us/op
n.s.ScalaBenchNoTailrec.test       5  avgt       15        0.253        0.002  us/op
n.s.ScalaBenchNoTailrec.test      10  avgt       15       12.482        0.056  us/op
n.s.ScalaBenchNoTailrec.test      15  avgt       15     1615.506       11.100  us/op
n.s.ScalaBenchNoTailrec.test      20  avgt       15  1055345.330    10848.845  us/op

Everyone is happy, except for everyone else who is sad. "Why would such a nice scalac optimization turn the code into slowish nightmare?", they would ask themselves.

Call me maybe: MongoDB (2013)

$
0
0

Previously in Jepsen, we discussed Redis. In this post, we'll see MongoDB drop a phenomenal amount of data.

MongoDB is a document-oriented database with a similar distribution design to Redis. In a replica set, there exists a single writable primary node which accepts writes, and asynchronously replicates those writes as an oplog to N secondaries. However, there are a few key differences.

First, Mongo builds in its leader election and replicated state machine. There's no separate system which tries to observe a replica set in order to make decisions about what it should do. The replica set decides among itself which node should be primary, when to step down, how to replicate, etc. This is operationally simpler and eliminates whole classes of topology problems.

Second, Mongo allows you to ask that the primary confirm successful replication of a write by its disk log, or by secondary nodes. At the cost of latency, we can get stronger guarantees about whether or not a write was successful.

What happens when a primary becomes inaccessible?

-046.jpg

-047.jpg

The remaining secondaries will gradually detect the failed connection and attempt to come to a consensus about what to do. If they have a majority (and remember, there can be only one majority in a cluster, so this suggests we're heading towards a CP system), they'll select the node with the highest optime (a monotonic clock maintained by each node) and promote it to be a new primary. Simultaneously, the minority nodes will detect that they no longer have a quorum, and demote the primary to a secondary so it can't accept writes.

-045.jpg

-048.jpg

If our primary is on n1, and we cut off n1 and n2 from the rest of the cluster, we expect either n3, n4, or n5 to become the new primary. Because this architecture demotes the original primary on n1, we won't find ourselves in the same split-brain problem we saw with Redis.

Consistency

So is MongoDB CP? There'sapopularnotionthatMongoDBisaCPsystem, including exchanges like this, where all kinds of nuanced technical assertions about strong consistency are thrown around. At the same time, Mongo's documentation for replica sets explains carefully that Mongo may “revert operations”:

In some failover situations primaries will have accepted write operations that have not replicated to the secondaries after a failover occurs. This case is rare and typically occurs as a result of a network partition with replication lag. When this member (the former primary) rejoins the replica set and attempts to continue replication as a secondary the former primary must revert these operations or “roll back” these operations to maintain database consistency across the replica set.

“Revert” certainly doesn't sound like linearizability to me, but that bit about “maintain[ing] database consistency” doesn't sound so bad. What actually happens? Let's find out!

For this example, we'll be adding integers to a list in a MongoDB document by using the update command in a CaS loop–just like you'd use with any transactionally isolated database. Yes, we could use $addInSet, but I'm using this app as an example of atomic updates in general, and they have different oplog dynamics.

Unacknowledged

-050.jpg

Up until recently, clients for MongoDB didn't bother to check whether or not their writes succeeded, by default: they just sent them and assumed everything went fine. This goes about as well as you'd expect.

lein run mongo-unsafe -n 6000 salticid jepsen.partition

For a while, writes continue to complete against n1. Then we see errors as the replica set fails over, like

3186 No replica set members available in [ { address:'n3/10.10.3.101:27017', ok:true, ping:0.8954104, isMaster:false, isSecondary:true, setName:rs0, maxBsonObjectSize:16777216, },{ address:'n4/10.10.3.95:27017', ok:true, ping:0.681164, isMaster:false, isSecondary:true, setName:rs0, maxBsonObjectSize:16777216, },{ address:'n5/10.10.3.32:27017', ok:true, ping:0.6231328, isMaster:false, isSecondary:true, setName:rs0, maxBsonObjectSize:16777216, },{ address:'n2/10.10.3.52:27017', ok:true, ping:0.51316977, isMaster:false, isSecondary:true, setName:rs0, maxBsonObjectSize:16777216, },{ address:'n1/10.10.3.242:27017', ok:true, ping:0.37008655, isMaster:false, isSecondary:true, setName:rs0, maxBsonObjectSize:16777216, } ] for { "mode" : "primary"}

During this time, the majority nodes (n3, n4, n5) are still secondaries, but they've agreed that the old primary is inaccessible. They compare optimes and race to elect a leader:

$ salticid mongo.rs_stat 22:09:08 Starting... 22:09:08 MongoDB shell version: 2.4.1 22:09:08 connecting to: test 22:09:08 n1:27017 (not reachable/healthy) 1368940104/56 22:09:08 n2:27017 (not reachable/healthy) 1368940103/458 22:09:08 n3:27017 SECONDARY 1368940104/89 22:09:08 n4:27017 SECONDARY 1368940104/89 22:09:08 n5:27017 SECONDARY 1368940104/102 22:09:08 true 22:09:08 Finished22:09:23 n1:27017 (not reachable/healthy) 1368941926/66 22:09:23 n2:27017 (not reachable/healthy) 1368941961/70 22:09:23 n3:27017 SECONDARY 1368941962/9 22:09:23 n4:27017 SECONDARY 1368941961/45 22:09:23 n5:27017 PRIMARY 1368941963/11

N5 wins the race, and proceeds to accept writes. If we heal the partition with salticid jepsen.heal, and wait a few seconds, the nodes will detect the fully connected cluster and the new primary will step down, to allow n1 to resume its place. Now that the cluster has stabilized, we hit enter to check how many of our writes survived:

Hit enter when ready to collect results. Writes completed in 93.608 seconds 6000 total 5700 acknowledged 3319 survivors 2381 acknowledged writes lost! (╯°□°)╯︵ ┻━┻ 469 474 479 484 489 494 ... 3166 3168 3171 3173 3178 3183 0.95 ack rate 0.4177193 loss rate 0.0 unacknowledged but successful rate

42% write loss. Well, to some extent, this shouldn't be surprising, because we weren't checking to see whether the server was successful in applying our writes. Those 300 errors only came about when we tried to write to a secondary. But we never actually crashed a node, and we didn't see any signs of a split-brain condition with two simultaneous primaries–so why did Mongo drop data?

Remember those writes that completed on n1 just after the partition started? Those writes are still on n1, but never made it to n5. N5 proceeded without them. Now n1 and n5 are comparing notes, and n1 realizes that n5's optime is higher. N1 figures out the last point where the two agreed on the oplog, and rolls back to that point.

22:09:33 Sun May 19 05:09:33.032 [rsHealthPoll] replSet member n5:27017 is now in state PRIMARY 22:09:33 Sun May 19 05:09:33.207 [initandlisten] connection accepted from 10.10.3.95:37718 #6154 (23 connections now open) 22:09:33 Sun May 19 05:09:33.417 [rsBackgroundSync] replSet syncing to: n5:27017 22:09:33 Sun May 19 05:09:33.438 [rsBackgroundSync] replSet our last op time fetched: May 19 05:08:37:2 22:09:33 Sun May 19 05:09:33.438 [rsBackgroundSync] replset source's GTE: May 19 05:09:26:1 22:09:33 Sun May 19 05:09:33.438 [rsBackgroundSync] replSet rollback 0 22:09:33 Sun May 19 05:09:33.438 [rsBackgroundSync] replSet ROLLBACK 22:09:33 Sun May 19 05:09:33.439 [rsBackgroundSync] replSet rollback 1 22:09:33 Sun May 19 05:09:33.439 [rsBackgroundSync] replSet rollback 2 FindCommonPoint 22:09:33 Sun May 19 05:09:33.439 [rsBackgroundSync] replSet info rollback our last optime: May 19 05:08:37:2 22:09:33 Sun May 19 05:09:33.439 [rsBackgroundSync] replSet info rollback their last optime: May 19 05:09:33:32 22:09:33 Sun May 19 05:09:33.439 [rsBackgroundSync] replSet info rollback diff in end of log times: -56 seconds 22:09:35 Sun May 19 05:09:33.621 [initandlisten] connection accepted from 10.10.3.32:59066 #6155 (24 connections now open) 22:09:35 Sun May 19 05:09:35.221 [rsBackgroundSync] replSet rollback found matching events at May 19 05:08:24:66 22:09:35 Sun May 19 05:09:35.221 [rsBackgroundSync] replSet rollback findcommonpoint scanned : 3798 22:09:35 Sun May 19 05:09:35.221 [rsBackgroundSync] replSet replSet rollback 3 fixup 22:09:35 Sun May 19 05:09:35.222 [rsBackgroundSync] replSet rollback 3.5 22:09:35 Sun May 19 05:09:35.222 [rsBackgroundSync] replSet rollback 4 n:1 22:09:35 Sun May 19 05:09:35.222 [rsBackgroundSync] replSet minvalid=May 19 05:09:35 51985e8f:19 22:09:35 Sun May 19 05:09:35.222 [rsBackgroundSync] replSet rollback 4.6 22:09:35 Sun May 19 05:09:35.223 [rsBackgroundSync] replSet rollback 4.7 22:09:35 Sun May 19 05:09:35.223 [rsBackgroundSync] replSet rollback 5 d:0 u:1 22:09:35 Sun May 19 05:09:35.224 [rsBackgroundSync] replSet rollback 6 22:09:35 Sun May 19 05:09:35.236 [rsBackgroundSync] replSet rollback 7 22:09:35 Sun May 19 05:09:35.238 [rsBackgroundSync] replSet rollback done 22:09:35 Sun May 19 05:09:35.238 [rsBackgroundSync] replSet RECOVERING

During a rollback, all the writes the old primary accepted after the common point in the oplog are removed from the database and written to a BSON file in Mongo's rollbacks directory. If you're a sysadmin, you could go look at the rollback files to try and reconstruct the writes that the database dropped.

Well, theoretically. In my tests, it only does this in 1 out of 5 runs or so. Mostly, it just throws those writes away entirely: no rollback files, no nothing. I don't really know why.

-054.jpg

-055.jpg

This leads to an important discovery: it doesn't matter whether or not there were two primaries at the same time. We can still get conflicting writes if the old primary's state is causally unconnected from the new primary. A primary/secondary system, by itself, is not sufficient. We have to actually track causality on the writes themselves in order to be CP. Otherwise, newly elected primaries could diverge from the old one.

Safe

Aha! But that was with the old “unsafe” write concern! We should use the Safe write concern!

lein run mongo-safe -n 6000 ... 6000 total 5900 acknowledged 3692 survivors 2208 acknowledged writes lost! (╯°□°)╯︵ ┻━┻ 458 463 468 473 478 483 ... 3075 3080 3085 3090 3095 3100 0.98333335 ack rate 0.3742373 loss rate 0.0 unacknowledged but successful rate

-059.jpg

-066.jpg

Replicas-safe

WriteConcern.SAFE only verifies that the write was accepted by the primary. We need to make sure that the replicas have received our write before considering it a success.

lein run mongo-replicas-safe -n 6000 ... 6000 total 5695 acknowledged 3768 survivors 1927 acknowledged writes lost! (╯°□°)╯︵ ┻━┻ 712 717 722 727 732 737 ... 2794 2799 2804 2809 2814 2819 0.94916666 ack rate 0.338367 loss rate 0.0 unacknowledged but successful rate

Mongo still rolled back our writes. Why? Because REPLICAS_SAFE only checks to see if the write took place against two replicas. Our cluster has five nodes, so it's possible for writes to exist only on n1 and n2. A new primary can be elected without having seen our write. We need to wait until our write has been acknowledged by a majority of nodes.

Majority

lein run mongo -n 6000

Using WriteConcern.MAJORITY, we notice an improvement! When we cause the partition, writes pause immediately. The clients are blocked, waiting for the primary to confirm acknowledgement on nodes which will never respond. Eventually they time out. This is a hallmark of a CP system: we shouldn't be able to make progress without talking to a majority of nodes.

Writes completed in 157.425 seconds 6000 total 5700 acknowledged 5701 survivors 2 acknowledged writes lost! (╯°□°)╯︵ ┻━┻ (596 598) 3 unacknowledged writes found! ヽ(´ー`)ノ (562 653 3818) 0.95 ack rate 1.754386E-4 loss rate 5.2631577E-4 unacknowledged but successful rate

So 3 writes which supposedly failed actually succeeded. That's not so bad. On the other hand, Mongo still dropped two “successful” writes. Writes which were supposedly acknowledged by a majority of nodes.

-069.jpg

I've been talking with 10gen, and they think this is a bug. When the network partitions, the server just checks off the “OK” field for the client's WriteConcern request, and sends it back. The client sees the “OK” message and… sensibly presumes the write was OK. This should be fixed in master, but is still present in 2.4.3, the most recent release.

Even if this bug is fixed, Mongo still isn't consistent. Those three writes which “failed” but showed up in the result set? Those are writes which were replicated to a majority node just prior to the partition, but never had the chance to acknowledge. Single writes are not atomic without a proper consensus protocol: those failed writes could materialize never, now, or some time in the future; potentially overwriting valid data.

Strategies for working with Mongo

On the one hand, Mongo advocates usually tell me “but network partitions are exceedingly rare in practice.” Then I talk to Mongo users who report their cluster fails over on a weekly basis. One thing to keep in mind is that heavy load–like seasonal writes, recovering from a crash, or performing a rollback–can slow a node down to the point where other nodes declare it dead. This is a partition. I've seen my test cluster perform dozens of rollbacks as nodes go unavailable attempting to elect a new primary. You should probably instrument your cluster to watch for these events in production.

As we've discussed before, one option is simply to accept data loss. Not all applications need consistency.

At the same time, you should watch those rollback files. Sometimes they don't appear even though they're supposed to, and not all data types will actually be rolled back. Conflicts in capped collections, for example, appear to simply discard all data in the collection past the conflict point by design.

People use capped collections for distributed queues. Think about that for a minute.

Moreover, a rollback file doesn't give you enough information to actually reconstruct the correct state of the system–at least in general. It's just a snapshot of “some state” the database had to discard. Because there's no well-defined ordering for these writes, you'll have to decide what that means for your particular data structures. If you can structure your documents as CRDTs and write a merge function, you'll be able to safely merge. If there's no conflicting copy of the document in the database, and you never delete those kinds of documents, you can restore it automatically. Immutable records can always be recovered, too.

Finally, you can drastically reduce the probability of write loss by using WriteConcern.MAJORITY. This is gonna impose a big performance hit. That's another hallmark of more-available CP systems.

To recap: MongoDB is neither AP nor CP. The defaults can cause significant loss of acknowledged writes. The strongest consistency offered has bugs which cause false acknowledgements, and even if they're fixed, doesn't prevent false failures.

In the next post, we'll talk about a database which emphasizes availability and partition tolerance: Riak.

Viewing all 737 articles
Browse latest View live