diff options
author | Loïc Hoguin <[email protected]> | 2016-03-28 15:36:42 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2016-03-28 15:36:42 +0200 |
commit | fe3492a98de29942477b061cd02c92246f4bf85a (patch) | |
tree | 2255b796a657e6e4dfb72beec1141258d17f1220 /talks/bed | |
download | ninenines.eu-fe3492a98de29942477b061cd02c92246f4bf85a.tar.gz ninenines.eu-fe3492a98de29942477b061cd02c92246f4bf85a.tar.bz2 ninenines.eu-fe3492a98de29942477b061cd02c92246f4bf85a.zip |
Initial commit, new website system
Diffstat (limited to 'talks/bed')
27 files changed, 2674 insertions, 0 deletions
diff --git a/talks/bed/bed.ezdoc b/talks/bed/bed.ezdoc new file mode 100644 index 00000000..0b36513d --- /dev/null +++ b/talks/bed/bed.ezdoc @@ -0,0 +1,432 @@ +::: The last REST client you will ever need + +It's better to REST in BED. + +:: Author + +* Loïc Hoguin +* @lhoguin +* Nine Nines +* Erlang Cowboy and Nine Nines founder + +:: Conference + +* EUC 2014 +* 20140609 + +:: Why this talk? + +: REST is great + +^!rest.jpg + +: The family business + +^!family_business.jpg + +: Open your mind + +^!mind_blown.jpg + +:: REST constraints + +: Client-server architecture + +* Different set of concerns +* Client cares about processing or rendering +* Server cares about storing and making information available efficiently +* Keeping concerns separate allow client and server to evolve independently + +: Stateless + +* Messages always contain all data needed to process the request +* Including authentication information if required +** That doesn't mean you can't use cookies! +** That means you must use them responsibly +* The server keeps no session state around +** The client may + +: Cacheable + +* Resources may be cached by any component, including the client, + the server and any intermediary +* All resources are explicitly or implicitly marked as (not) cacheable + +: Uniform interface + +* All components use the same rules to speak to each other +* Makes it easy to understand the interactions +* A number of constraints are required to achieve this +** We will see them in a few minutes! + +: Layered system + +* Components only know about the components they talk to +* For example a proxy completely hides what's behind it +** This is true for both directions +** There may be more proxies in one way or another + + perhaps use the picture here + +: Code on demand (optional) + +* Code may be downloaded to extend the client functionality +* This is optional, you can't assume the client will receive + or be able to execute the code +* Javascript is a common example of this + +:: Uniform interface in details + +: Resources and resource identifiers + +* Any information that can be named can be a resource +* A resource is a conceptual mapping to a set of entities +** For example one user or a group of users +* A resource is identified by a URI +* Typically we talk about resources and resource collections + +: Resource representations + +* Sequence of bytes + metadata +* Representation metadata (media type, modification time...) +* Resource metadata (related resources, additional representations...) +* Control data (parameterized requests, handling instructions...) + +: Self-descriptive messages + +* Messages contain everything needed to decipher them +* All representations must have a media type in the message +* The media type must be agreed upon by both endpoints +* Negotiating the appropriate media type is a big part of REST + +: Hypermedia as the engine of the application state + +* Interactions must be entirely driven by hypermedia +* A client only needs an entry point and basic understanding + of the media types being used by the service +* Resources and functionality can be discovered at runtime + +:: What media type should we use? + +: Not just one media type + +* Each resource should have at least one media type +* The media type defines the structure and accepted values +* It's pretty much what you do when you document your API +** So why not give them a name and use that in the protocol? +* We still need a basic type to extend upon + +: Why not JSON? + +* No concept of links or link relations +* Unable to deal with binary data +* Not very good with the map datatype +* Very slow and very expensive to parse +* Stop using JSON, save the planet! + +: Why not msgpack? + +* No concept of links or link relations +* No bignums +* No decimals +* Not very good with the map datatype + +: Why not HTML? + +* Everything is a string +* Unable to deal with binary data +* No easy mapping of types onto HTML +* Different use case than what we are looking for really + +: Why not XML? + +* Everything is a string +* Unable to deal with binary data +* No easy mapping of types onto XML +** You can, but it's damn verbose +* XML is probably slower and more expensive to parse than JSON +** The planet is doomed! + +: What then? + +^!wondering.jpg + +:: BED + +: Goals + +* Hyperlinks and link relations +* Binary, explicit sizes, efficient to parse +* Small, exponentially smaller the larger the data gets +* Good type coverage, extensible +* No NULL value +* Fully specified + +: Media types 1/2 + +* application/x-bed +* application/x-bed-stream +** Great with Websockets + +: Media types 2/2 + +* Again, don't be shy, define your own media types! +* Make sure to advertise both your custom type and the basic type +* This way you can process the data even if you don't know its structure + +: Hyperlink 1/2 + +* Link without link relation +* Link with link relation +** Better for automated processing +* Link relations are standard but you may use custom relations + +: Hyperlink 2/2 + +* Link is a string +* Link relation is a symbol +* Highly recommended to only use fully qualified links +** The client should not build links unless strictly required +** This is true with any media type + +: Symbol 1/9 + +``` js +{ + "firstName": "John", + "lastName": "Smith", + "isAlive": true, + "age": 25, + "phoneNumbers": [ + { "type": "home", "number": "212 555-1234" }, + { "type": "office", "number": "646 555-4567" } + ] +} +``` + +: Symbol 2/9 + +* A lot of data is sent as maps +* A lot of maps share the same keys +* Repeating these keys over and over is madness +* There's a better way + +: Symbol 3/9 + +* Keep track of symbols already sent +* Replace repeated symbols with a numerical value +* Continue doing that until the end of the message +** Or the end of the stream! +* It's just like atoms, isn't it? + +: Symbol 4/9 + +* Symbol dictionary starts with `false` (0) and `true` (1) +* You can create a custom content-type that has more pre-defined + +: Symbol 5/9 + +* First message +* JSON: `{"compact":true,"schema":0}` (27 bytes) +* MsgPack: `82 A7 compact C3 A6 schema 00` (18 bytes) +* BED: `C2 27 compact 41 26 schema 80` (18 bytes) + +: Symbol 6/9 + +* Subsequent messages +* JSON: `{"compact":true,"schema":0}` (27 bytes) +* MsgPack: `82 A7 compact C3 A6 schema 00` (18 bytes) +* BED: `C2 42 41 43 80` (5 bytes) + +: Symbol 7/9 + +* We sacrifice a little CPU power for a large size gain +** Especially for collections and large streams +* We don't sacrifice too much +** Even streams tend to use a limited number of symbols +** That means the lookup time is not significant + +: Symbol 8/9 + +* All this without compression +* All this without schemas +* Just call the encode function and you're done! +** Okay some languages might need a little more wrapping than others... + +: Symbol 9/9 + +* The symbol string is limited to 255 bytes (not characters!) +* The first 32 symbols cost exactly 1 byte +** This never changes, so choose these 32 symbols well! +* Subsequent symbols cost 2 or 3 bytes +** 2 bytes when there are less than 8192 symbols defined total +** 3 bytes when there are more + +: Binary + +* Size followed by sequence of bytes +* Size may be encoded as 16-bit, 32-bit or 64-bit unsigned integer +* Minimal binary size: 3 bytes + +: String + +* Must be valid UTF-8 +** Decoding validates UTF-8 by default (optionally can be disabled) +* Size followed by sequence of bytes +** Character-terminated strings are the devil! +* Size may be encoded as 8-bit, 16-bit or 32-bit unsigned integer +* Minimal string size: 2 bytes + +: RFC 3339 date + +* Why? +* Because they are a lot more common than you think +* By standardizing we avoid having tons of different formats +** That means less bugs, especially when converting +* RFC 3339 includes time, date and timezone information +** It's a subset of ISO 8601 +* 2 bytes followed by the date as a sequence of bytes + +: Integer + +* 6-bit, 8-bit, 16-bit, 32-bit and 64-bit signed integer +* Positive and negative bignum integer +** Same encoding as Erlang +* Minimal integer size: 1 byte (-32 to 31) + +: Floating-point + +* IEEE 754 binary64 (double) +* IEEE 754 decimal64 +* Both take 9 bytes + +: Map + +* Size followed by unordered list of pairs of key/values +** If any duplicate, only the last key/value is kept +* Size may be encoded as 5-bit, 16-bit or 32-bit unsigned integer +* Minimal map size: 1 byte +** Maps smaller than 32 keys take 1 byte + the size of pairs + +: Array + +* Size followed by list of values +* Size may be encoded as 5-bit, 16-bit or 32-bit unsigned integer +* Minimal array size: 1 byte +** Arrays smaller than 32 values take 1 byte + the size of the values + +: List + +* 1 byte to indicate the start of a list +* 1 byte to indicate the end +* For special cases only + +: Extensions + +* Define up to 256 additional types +** You can do that through custom media types +* 8-bit, 16-bit, 32-bit or 64-bit value +* Blob of 8-bit, 16-bit, 32-bit or 64-bit unsigned size + +: Wrap-up + +* BED is... +* Great for REST (hypertext) +* Great for Websockets (exponentially smaller as time goes on) +* Comfy! + +: But wait... + +* Doesn't binary make it harder to debug things? +* No +* A large enough JSON is as indecipherable as a large enough binary +* When debugging you can just add a well placed decode call +* Plus nothing is stopping you from providing JSON at the same time! + +:: Writing a REST client + +: Warning + +* This part has no code written for it at this point +* Sorry! +* The BED format was just too interesting to work on +* And we're probably running out of time anyway + +: Goals + +* Manipulate resources +** Only use URIs +** Don't look into or validate representations +** Don't parse representations (with exceptions) +* Automatic caching +** Provide a default but replaceable implementation +** Again, URI based! +* Automatic discovery of service capabilities + +: HTTP client + +* Use `gun` as the client +* Always connected, so great for automation +* What do you call a `gun` based REST client? + +: HTTP client + +* Use `gun` as the client +* Always connected, so great for automation +* What do you call a `gun` based REST client? +* `gunr` of course! + +: Service map 1/2 + +* We don't want to hardcode URIs +* We want to obtain them directly from the service +* We can generate a wrapper using this information +* We could use "crawling" but it's impractical +* RSDL specifications do what we want + +: Service map 2/2 + +* RSDL is ugly XML though :( +* RSDL includes way more information than we need +** It literally describes everything +** It's good, but life is too short +* A subset of RSDL generated from a simpler DSL might be workable +** Or just send that simpler DSL + +: Interface + +``` erlang +my_generated_api_users:get_all(). +my_generated_api_users:get(Key, MediaType). +my_generated_api_users:put(Key, MediaType, Representation). +... +``` + +: Cache + +* A `get` call first looks into the cache +* It builds a request based on cache contents +** In some cases it may not +* The server dictates the client how cache should be used +* So we can safely rely on it + +: Going further + +* We could go further with RSDL +* Is it worth it, though? +* Would people really use this stuff to its full potential? +* I'm not so sure... +* Sounds like too much work for too little reward + +:: Putting it to rest + +: Let's be lazy now! + +* BED: ^https://github.com/bed-project/ +** Help welcome! +* gun: ^https://github.com/extend/gun +** Yes, I promise, I'll add Websockets support soon +* gunr: help welcome! +* Me +** Twitter: @lhoguin +** ^http://ninenines.eu diff --git a/talks/bed/bed.html b/talks/bed/bed.html new file mode 100644 index 00000000..7609b765 --- /dev/null +++ b/talks/bed/bed.html @@ -0,0 +1,767 @@ + +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> +<title>D3 + Websocket for live Web applications</title> +<!-- metadata --> +<meta charset="utf8" /> +<meta name="generator" content="S5" /> +<meta name="version" content="S5 1.1" /> +<meta name="presdate" content="20140609" /> +<meta name="author" content="Loïc Hoguin" /> +<meta name="company" content="Nine Nines" /> +<!-- configuration parameters --> +<meta name="defaultView" content="slideshow" /> +<meta name="controlVis" content="visible" /> +<!-- style sheet links --> +<link rel="stylesheet" href="ui/default/slides.css" type="text/css" media="projection" id="slideProj" /> +<link rel="stylesheet" href="ui/default/outline.css" type="text/css" media="screen" id="outlineStyle" /> +<link rel="stylesheet" href="ui/default/print.css" type="text/css" media="print" id="slidePrint" /> +<link rel="stylesheet" href="ui/default/opera.css" type="text/css" media="projection" id="operaFix" /> +<link href="ui/sh/sh99s.css" rel="stylesheet"/> +<!-- S5 JS --> +<script src="ui/default/slides.js" type="text/javascript"></script> +<!-- syntax highlighter JS --> +<script type="text/javascript" src="ui/sh/shCore.js"></script> +<script type="text/javascript" src="ui/sh/shBrushErlang.js"></script> +<script type="text/javascript" src="ui/sh/shBrushJScript.js"></script> +<script type="text/javascript" src="ui/sh/shBrushXml.js"></script> +</head> +<body> + +<div class="layout"> +<div id="controls"><!-- DO NOT EDIT --></div> +<div id="currentSlide"><!-- DO NOT EDIT --></div> +<div id="header"> + <div id="sub_header"></div> + <div id="logo"><img src="ui/img/logo.svg"/></div> +</div> +<div id="footer"> +<div id="footer_shadow"></div> +<h1>EUC 2014</h1> +<h2>The last REST client you will ever need, Nine Nines</h2> +</div> + +</div> + + +<div class="presentation"> + +<div class="slide"> +<h1>The last REST client you will ever need</h1> +<h2>It's better to REST in BED.</h2> +<h3>Loïc Hoguin - @lhoguin</h3> +<h4>Erlang Cowboy and Nine Nines founder</h4> +</div> + + +<div class="slide"> +<h1>Why this talk?</h1> +</div> + + +<div class="slide"> +<h1>REST is great</h1> +<p><img src="pics/rest.jpg"/></p> +</div> + + +<div class="slide"> +<h1>The family business</h1> +<p><img src="pics/family_business.jpg"/></p> +</div> + + +<div class="slide"> +<h1>Open your mind</h1> +<p><img src="pics/mind_blown.jpg"/></p> +</div> + + +<div class="slide"> +<h1>REST constraints</h1> +</div> + + +<div class="slide"> +<h1>Client-server architecture</h1> +<ul> +<li>Different set of concerns</li> +<li>Client cares about processing or rendering</li> +<li>Server cares about storing and making information available efficiently</li> +<li>Keeping concerns separate allow client and server to evolve independently</li> +</ul> +</div> + + +<div class="slide"> +<h1>Stateless</h1> +<ul> +<li>Messages always contain all data needed to process the request</li> +<li>Including authentication information if required<ul> +<li>That doesn't mean you can't use cookies!</li> +<li>That means you must use them responsibly</li> +</ul> +</li> +<li>The server keeps no session state around<ul> +<li>The client may</li> +</ul> +</li> +</ul> +</div> + + +<div class="slide"> +<h1>Cacheable</h1> +<ul> +<li>Resources may be cached by any component, including the client, the server and any intermediary</li> +<li>All resources are explicitly or implicitly marked as (not) cacheable</li> +</ul> +</div> + + +<div class="slide"> +<h1>Uniform interface</h1> +<ul> +<li>All components use the same rules to speak to each other</li> +<li>Makes it easy to understand the interactions</li> +<li>A number of constraints are required to achieve this<ul> +<li>We will see them in a few minutes!</li> +</ul> +</li> +</ul> +</div> + + +<div class="slide"> +<h1>Layered system</h1> +<ul> +<li>Components only know about the components they talk to</li> +<li>For example a proxy completely hides what's behind it<ul> +<li>This is true for both directions</li> +<li>There may be more proxies in one way or another</li> +</ul> +</li> +</ul> +</div> + + +<div class="slide"> +<h1>Code on demand (optional)</h1> +<ul> +<li>Code may be downloaded to extend the client functionality</li> +<li>This is optional, you can't assume the client will receive or be able to execute the code</li> +<li>Javascript is a common example of this</li> +</ul> +</div> + + +<div class="slide"> +<h1>Uniform interface in details</h1> +</div> + + +<div class="slide"> +<h1>Resources and resource identifiers</h1> +<ul> +<li>Any information that can be named can be a resource</li> +<li>A resource is a conceptual mapping to a set of entities<ul> +<li>For example one user or a group of users</li> +</ul> +</li> +<li>A resource is identified by a URI</li> +<li>Typically we talk about resources and resource collections</li> +</ul> +</div> + + +<div class="slide"> +<h1>Resource representations</h1> +<ul> +<li>Sequence of bytes + metadata</li> +<li>Representation metadata (media type, modification time...)</li> +<li>Resource metadata (related resources, additional representations...)</li> +<li>Control data (parameterized requests, handling instructions...)</li> +</ul> +</div> + + +<div class="slide"> +<h1>Self-descriptive messages</h1> +<ul> +<li>Messages contain everything needed to decipher them</li> +<li>All representations must have a media type in the message</li> +<li>The media type must be agreed upon by both endpoints</li> +<li>Negotiating the appropriate media type is a big part of REST</li> +</ul> +</div> + + +<div class="slide"> +<h1>Hypermedia as the engine of the application state</h1> +<ul> +<li>Interactions must be entirely driven by hypermedia</li> +<li>A client only needs an entry point and basic understanding of the media types being used by the service</li> +<li>Resources and functionality can be discovered at runtime</li> +</ul> +</div> + + +<div class="slide"> +<h1>What media type should we use?</h1> +</div> + + +<div class="slide"> +<h1>Not just one media type</h1> +<ul> +<li>Each resource should have at least one media type</li> +<li>The media type defines the structure and accepted values</li> +<li>It's pretty much what you do when you document your API<ul> +<li>So why not give them a name and use that in the protocol?</li> +</ul> +</li> +<li>We still need a basic type to extend upon</li> +</ul> +</div> + + +<div class="slide"> +<h1>Why not JSON?</h1> +<ul> +<li>No concept of links or link relations</li> +<li>Unable to deal with binary data</li> +<li>Not very good with the map datatype</li> +<li>Very slow and very expensive to parse</li> +<li>Stop using JSON, save the planet!</li> +</ul> +</div> + + +<div class="slide"> +<h1>Why not msgpack?</h1> +<ul> +<li>No concept of links or link relations</li> +<li>No bignums</li> +<li>No decimals</li> +<li>Not very good with the map datatype</li> +</ul> +</div> + + +<div class="slide"> +<h1>Why not HTML?</h1> +<ul> +<li>Everything is a string</li> +<li>Unable to deal with binary data</li> +<li>No easy mapping of types onto HTML</li> +<li>Different use case than what we are looking for really</li> +</ul> +</div> + + +<div class="slide"> +<h1>Why not XML?</h1> +<ul> +<li>Everything is a string</li> +<li>Unable to deal with binary data</li> +<li>No easy mapping of types onto XML<ul> +<li>You can, but it's damn verbose</li> +</ul> +</li> +<li>XML is probably slower and more expensive to parse than JSON<ul> +<li>The planet is doomed!</li> +</ul> +</li> +</ul> +</div> + + +<div class="slide"> +<h1>What then?</h1> +<p><img src="pics/wondering.jpg"/></p> +</div> + + +<div class="slide"> +<h1>BED</h1> +</div> + + +<div class="slide"> +<h1>Goals</h1> +<ul> +<li>Hyperlinks and link relations</li> +<li>Binary, explicit sizes, efficient to parse</li> +<li>Small, exponentially smaller the larger the data gets</li> +<li>Good type coverage, extensible</li> +<li>No NULL value</li> +<li>Fully specified</li> +</ul> +</div> + + +<div class="slide"> +<h1>Media types 1/2</h1> +<ul> +<li>application/x-bed</li> +<li>application/x-bed-stream<ul> +<li>Great with Websockets</li> +</ul> +</li> +</ul> +</div> + + +<div class="slide"> +<h1>Media types 2/2</h1> +<ul> +<li>Again, don't be shy, define your own media types!</li> +<li>Make sure to advertise both your custom type and the basic type</li> +<li>This way you can process the data even if you don't know its structure</li> +</ul> +</div> + + +<div class="slide"> +<h1>Hyperlink 1/2</h1> +<ul> +<li>Link without link relation</li> +<li>Link with link relation<ul> +<li>Better for automated processing</li> +</ul> +</li> +<li>Link relations are standard but you may use custom relations</li> +</ul> +</div> + + +<div class="slide"> +<h1>Hyperlink 2/2</h1> +<ul> +<li>Link is a string</li> +<li>Link relation is a symbol</li> +<li>Highly recommended to only use fully qualified links<ul> +<li>The client should not build links unless strictly required</li> +<li>This is true with any media type</li> +</ul> +</li> +</ul> +</div> + + +<div class="slide"> +<h1>Symbol 1/9</h1> +<div><script type="syntaxhighlighter" class="brush: js"><![CDATA[ +{ + "firstName": "John", + "lastName": "Smith", + "isAlive": true, + "age": 25, + "phoneNumbers": [ + { "type": "home", "number": "212 555-1234" }, + { "type": "office", "number": "646 555-4567" } + ] +} +]]></script></div></div> + + +<div class="slide"> +<h1>Symbol 2/9</h1> +<ul> +<li>A lot of data is sent as maps</li> +<li>A lot of maps share the same keys</li> +<li>Repeating these keys over and over is madness</li> +<li>There's a better way</li> +</ul> +</div> + + +<div class="slide"> +<h1>Symbol 3/9</h1> +<ul> +<li>Keep track of symbols already sent</li> +<li>Replace repeated symbols with a numerical value</li> +<li>Continue doing that until the end of the message<ul> +<li>Or the end of the stream!</li> +</ul> +</li> +<li>It's just like atoms, isn't it?</li> +</ul> +</div> + + +<div class="slide"> +<h1>Symbol 4/9</h1> +<ul> +<li>Symbol dictionary starts with <code>false</code> (0) and <code>true</code> (1)</li> +<li>You can create a custom content-type that has more pre-defined</li> +</ul> +</div> + + +<div class="slide"> +<h1>Symbol 5/9</h1> +<ul> +<li>First message</li> +<li>JSON: <code>{"compact":true,"schema":0}</code> (27 bytes)</li> +<li>MsgPack: <code>82 A7 compact C3 A6 schema 00</code> (18 bytes)</li> +<li>BED: <code>C2 27 compact 41 26 schema 80</code> (18 bytes)</li> +</ul> +</div> + + +<div class="slide"> +<h1>Symbol 6/9</h1> +<ul> +<li>Subsequent messages</li> +<li>JSON: <code>{"compact":true,"schema":0}</code> (27 bytes)</li> +<li>MsgPack: <code>82 A7 compact C3 A6 schema 00</code> (18 bytes)</li> +<li>BED: <code>C2 42 41 43 80</code> (5 bytes)</li> +</ul> +</div> + + +<div class="slide"> +<h1>Symbol 7/9</h1> +<ul> +<li>We sacrifice a little CPU power for a large size gain<ul> +<li>Especially for collections and large streams</li> +</ul> +</li> +<li>We don't sacrifice too much<ul> +<li>Even streams tend to use a limited number of symbols</li> +<li>That means the lookup time is not significant</li> +</ul> +</li> +</ul> +</div> + + +<div class="slide"> +<h1>Symbol 8/9</h1> +<ul> +<li>All this without compression</li> +<li>All this without schemas</li> +<li>Just call the encode function and you're done!<ul> +<li>Okay some languages might need a little more wrapping than others...</li> +</ul> +</li> +</ul> +</div> + + +<div class="slide"> +<h1>Symbol 9/9</h1> +<ul> +<li>The symbol string is limited to 255 bytes (not characters!)</li> +<li>The first 32 symbols cost exactly 1 byte<ul> +<li>This never changes, so choose these 32 symbols well!</li> +</ul> +</li> +<li>Subsequent symbols cost 2 or 3 bytes<ul> +<li>2 bytes when there are less than 8192 symbols defined total</li> +<li>3 bytes when there are more</li> +</ul> +</li> +</ul> +</div> + + +<div class="slide"> +<h1>Binary</h1> +<ul> +<li>Size followed by sequence of bytes</li> +<li>Size may be encoded as 16-bit, 32-bit or 64-bit unsigned integer</li> +<li>Minimal binary size: 3 bytes</li> +</ul> +</div> + + +<div class="slide"> +<h1>String</h1> +<ul> +<li>Must be valid UTF-8<ul> +<li>Decoding validates UTF-8 by default (optionally can be disabled)</li> +</ul> +</li> +<li>Size followed by sequence of bytes<ul> +<li>Character-terminated strings are the devil!</li> +</ul> +</li> +<li>Size may be encoded as 8-bit, 16-bit or 32-bit unsigned integer</li> +<li>Minimal string size: 2 bytes</li> +</ul> +</div> + + +<div class="slide"> +<h1>RFC 3339 date</h1> +<ul> +<li>Why?</li> +<li>Because they are a lot more common than you think</li> +<li>By standardizing we avoid having tons of different formats<ul> +<li>That means less bugs, especially when converting</li> +</ul> +</li> +<li>RFC 3339 includes time, date and timezone information<ul> +<li>It's a subset of ISO 8601</li> +</ul> +</li> +<li>2 bytes followed by the date as a sequence of bytes</li> +</ul> +</div> + + +<div class="slide"> +<h1>Integer</h1> +<ul> +<li>6-bit, 8-bit, 16-bit, 32-bit and 64-bit signed integer</li> +<li>Positive and negative bignum integer<ul> +<li>Same encoding as Erlang</li> +</ul> +</li> +<li>Minimal integer size: 1 byte (-32 to 31)</li> +</ul> +</div> + + +<div class="slide"> +<h1>Floating-point</h1> +<ul> +<li>IEEE 754 binary64 (double)</li> +<li>IEEE 754 decimal64</li> +<li>Both take 9 bytes</li> +</ul> +</div> + + +<div class="slide"> +<h1>Map</h1> +<ul> +<li>Size followed by unordered list of pairs of key/values<ul> +<li>If any duplicate, only the last key/value is kept</li> +</ul> +</li> +<li>Size may be encoded as 5-bit, 16-bit or 32-bit unsigned integer</li> +<li>Minimal map size: 1 byte<ul> +<li>Maps smaller than 32 keys take 1 byte + the size of pairs</li> +</ul> +</li> +</ul> +</div> + + +<div class="slide"> +<h1>Array</h1> +<ul> +<li>Size followed by list of values</li> +<li>Size may be encoded as 5-bit, 16-bit or 32-bit unsigned integer</li> +<li>Minimal array size: 1 byte<ul> +<li>Arrays smaller than 32 values take 1 byte + the size of the values</li> +</ul> +</li> +</ul> +</div> + + +<div class="slide"> +<h1>List</h1> +<ul> +<li>1 byte to indicate the start of a list</li> +<li>1 byte to indicate the end</li> +<li>For special cases only</li> +</ul> +</div> + + +<div class="slide"> +<h1>Extensions</h1> +<ul> +<li>Define up to 256 additional types<ul> +<li>You can do that through custom media types</li> +</ul> +</li> +<li>8-bit, 16-bit, 32-bit or 64-bit value</li> +<li>Blob of 8-bit, 16-bit, 32-bit or 64-bit unsigned size</li> +</ul> +</div> + + +<div class="slide"> +<h1>Wrap-up</h1> +<ul> +<li>BED is...</li> +<li>Great for REST (hypertext)</li> +<li>Great for Websockets (exponentially smaller as time goes on)</li> +<li>Comfy!</li> +</ul> +</div> + + +<div class="slide"> +<h1>But wait...</h1> +<ul> +<li>Doesn't binary make it harder to debug things?</li> +<li>No</li> +<li>A large enough JSON is as indecipherable as a large enough binary</li> +<li>When debugging you can just add a well placed decode call</li> +<li>Plus nothing is stopping you from providing JSON at the same time!</li> +</ul> +</div> + + +<div class="slide"> +<h1>Writing a REST client</h1> +</div> + + +<div class="slide"> +<h1>Warning</h1> +<ul> +<li>This part has no code written for it at this point</li> +<li>Sorry!</li> +<li>The BED format was just too interesting to work on</li> +<li>And we're probably running out of time anyway</li> +</ul> +</div> + + +<div class="slide"> +<h1>Goals</h1> +<ul> +<li>Manipulate resources<ul> +<li>Only use URIs</li> +<li>Don't look into or validate representations</li> +<li>Don't parse representations (with exceptions)</li> +</ul> +</li> +<li>Automatic caching<ul> +<li>Provide a default but replaceable implementation</li> +<li>Again, URI based!</li> +</ul> +</li> +<li>Automatic discovery of service capabilities</li> +</ul> +</div> + + +<div class="slide"> +<h1>HTTP client</h1> +<ul> +<li>Use <code>gun</code> as the client</li> +<li>Always connected, so great for automation</li> +<li>What do you call a <code>gun</code> based REST client?</li> +</ul> +</div> + + +<div class="slide"> +<h1>HTTP client</h1> +<ul> +<li>Use <code>gun</code> as the client</li> +<li>Always connected, so great for automation</li> +<li>What do you call a <code>gun</code> based REST client?</li> +<li><code>gunr</code> of course!</li> +</ul> +</div> + + +<div class="slide"> +<h1>Service map 1/2</h1> +<ul> +<li>We don't want to hardcode URIs</li> +<li>We want to obtain them directly from the service</li> +<li>We can generate a wrapper using this information</li> +<li>We could use "crawling" but it's impractical</li> +<li>RSDL specifications do what we want</li> +</ul> +</div> + + +<div class="slide"> +<h1>Service map 2/2</h1> +<ul> +<li>RSDL is ugly XML though :(</li> +<li>RSDL includes way more information than we need<ul> +<li>It literally describes everything</li> +<li>It's good, but life is too short</li> +</ul> +</li> +<li>A subset of RSDL generated from a simpler DSL might be workable<ul> +<li>Or just send that simpler DSL</li> +</ul> +</li> +</ul> +</div> + + +<div class="slide"> +<h1>Interface</h1> +<div><script type="syntaxhighlighter" class="brush: erlang"><![CDATA[ +my_generated_api_users:get_all(). +my_generated_api_users:get(Key, MediaType). +my_generated_api_users:put(Key, MediaType, Representation). +... +]]></script></div></div> + + +<div class="slide"> +<h1>Cache</h1> +<ul> +<li>A <code>get</code> call first looks into the cache</li> +<li>It builds a request based on cache contents<ul> +<li>In some cases it may not</li> +</ul> +</li> +<li>The server dictates the client how cache should be used</li> +<li>So we can safely rely on it</li> +</ul> +</div> + + +<div class="slide"> +<h1>Going further</h1> +<ul> +<li>We could go further with RSDL</li> +<li>Is it worth it, though?</li> +<li>Would people really use this stuff to its full potential?</li> +<li>I'm not so sure...</li> +<li>Sounds like too much work for too little reward</li> +</ul> +</div> + + +<div class="slide"> +<h1>Putting it to rest</h1> +</div> + + +<div class="slide"> +<h1>Let's be lazy now!</h1> +<ul> +<li>BED: <a href="https://github.com/bed-project/">https://github.com/bed-project/</a><ul> +<li>Help welcome!</li> +</ul> +</li> +<li>gun: <a href="https://github.com/extend/gun">https://github.com/extend/gun</a><ul> +<li>Yes, I promise, I'll add Websockets support soon</li> +</ul> +</li> +<li>gunr: help welcome!</li> +<li>Me<ul> +<li>Twitter: @lhoguin</li> +<li><a href="http://ninenines.eu">http://ninenines.eu</a></li> +</ul> +</li> +</ul> +</div> + + +</div> + +<script type="text/javascript">SyntaxHighlighter.all();</script> + +</body> +</html> diff --git a/talks/bed/pics/family_business.jpg b/talks/bed/pics/family_business.jpg Binary files differnew file mode 100644 index 00000000..96f58e1b --- /dev/null +++ b/talks/bed/pics/family_business.jpg diff --git a/talks/bed/pics/mind_blown.jpg b/talks/bed/pics/mind_blown.jpg Binary files differnew file mode 100644 index 00000000..2a679719 --- /dev/null +++ b/talks/bed/pics/mind_blown.jpg diff --git a/talks/bed/pics/rest.jpg b/talks/bed/pics/rest.jpg Binary files differnew file mode 100644 index 00000000..ef029965 --- /dev/null +++ b/talks/bed/pics/rest.jpg diff --git a/talks/bed/pics/wondering.jpg b/talks/bed/pics/wondering.jpg Binary files differnew file mode 100644 index 00000000..9a017654 --- /dev/null +++ b/talks/bed/pics/wondering.jpg diff --git a/talks/bed/ui/default/blank.gif b/talks/bed/ui/default/blank.gif Binary files differnew file mode 100644 index 00000000..75b945d2 --- /dev/null +++ b/talks/bed/ui/default/blank.gif diff --git a/talks/bed/ui/default/bodybg.gif b/talks/bed/ui/default/bodybg.gif Binary files differnew file mode 100755 index 00000000..5f448a16 --- /dev/null +++ b/talks/bed/ui/default/bodybg.gif diff --git a/talks/bed/ui/default/framing.css b/talks/bed/ui/default/framing.css new file mode 100644 index 00000000..14d8509e --- /dev/null +++ b/talks/bed/ui/default/framing.css @@ -0,0 +1,23 @@ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#header {top: 0; height: 3em; z-index: 1;} +div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;} +.slide {top: 0; width: 92%; padding: 3.5em 4% 4%; z-index: 2; list-style: none;} +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/talks/bed/ui/default/iepngfix.htc b/talks/bed/ui/default/iepngfix.htc new file mode 100644 index 00000000..bba2db75 --- /dev/null +++ b/talks/bed/ui/default/iepngfix.htc @@ -0,0 +1,42 @@ +<public:component>
+<public:attach event="onpropertychange" onevent="doFix()" />
+
+<script>
+
+// IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull http://www.twinhelix.com
+// Free usage permitted as long as this notice remains intact.
+
+// This must be a path to a blank image. That's all the configuration you need here.
+var blankImg = 'ui/default/blank.gif';
+
+var f = 'DXImageTransform.Microsoft.AlphaImageLoader';
+
+function filt(s, m) {
+ if (filters[f]) {
+ filters[f].enabled = s ? true : false;
+ if (s) with (filters[f]) { src = s; sizingMethod = m }
+ } else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")';
+}
+
+function doFix() {
+ if ((parseFloat(navigator.userAgent.match(/MSIE (\S+)/)[1]) < 5.5) ||
+ (event && !/(background|src)/.test(event.propertyName))) return;
+
+ if (tagName == 'IMG') {
+ if ((/\.png$/i).test(src)) {
+ filt(src, 'image'); // was 'scale'
+ src = blankImg;
+ } else if (src.indexOf(blankImg) < 0) filt();
+ } else if (style.backgroundImage) {
+ if (style.backgroundImage.match(/^url[("']+(.*\.png)[)"']+$/i)) {
+ var s = RegExp.$1;
+ style.backgroundImage = '';
+ filt(s, 'crop');
+ } else filt();
+ }
+}
+
+doFix();
+
+</script>
+</public:component>
\ No newline at end of file diff --git a/talks/bed/ui/default/opera.css b/talks/bed/ui/default/opera.css new file mode 100644 index 00000000..9e9d2a3c --- /dev/null +++ b/talks/bed/ui/default/opera.css @@ -0,0 +1,7 @@ +/* DO NOT CHANGE THESE unless you really want to break Opera Show */ +.slide { + visibility: visible !important; + position: static !important; + page-break-before: always; +} +#slide0 {page-break-before: avoid;} diff --git a/talks/bed/ui/default/outline.css b/talks/bed/ui/default/outline.css new file mode 100644 index 00000000..62db519e --- /dev/null +++ b/talks/bed/ui/default/outline.css @@ -0,0 +1,15 @@ +/* don't change this unless you want the layout stuff to show up in the outline view! */ + +.layout div, #footer *, #controlForm * {display: none;} +#footer, #controls, #controlForm, #navLinks, #toggle { + display: block; visibility: visible; margin: 0; padding: 0;} +#toggle {float: right; padding: 0.5em;} +html>body #toggle {position: fixed; top: 0; right: 0;} + +/* making the outline look pretty-ish */ + +#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;} +#slide0 h1 {padding-top: 1.5em;} +.slide h1 {margin: 1.5em 0 0; padding-top: 0.25em; + border-top: 1px solid #888; border-bottom: 1px solid #AAA;} +#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;} diff --git a/talks/bed/ui/default/pretty.css b/talks/bed/ui/default/pretty.css new file mode 100644 index 00000000..1d9b8a8c --- /dev/null +++ b/talks/bed/ui/default/pretty.css @@ -0,0 +1,255 @@ +/* Following are the presentation styles -- edit away! */ + +body {background: #FFF -16px 0 no-repeat; color: #000; font-size: 2em;} +:link, :visited {text-decoration: none; color: #00C;} +#controls :active {color: #88A !important;} +#controls :focus {outline: 1px dotted #227;} +h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;} +ul, ol, pre {margin: 0; line-height: 1em;} +html, body {margin: 0; padding: 0;} + +blockquote, q {font-style: italic;} +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em; text-align: center; font-size: 1em;} +blockquote p {margin: 0;} +blockquote i {font-style: normal;} +blockquote b {display: block; margin-top: 0.5em; font-weight: normal; font-size: smaller; font-style: normal;} +blockquote b i {font-style: italic;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide code {padding: 2px 0.25em; font-weight: bold; color: #533;} +.slide code.bad, code del {color: red;} +.slide code.old {color: silver;} +.slide pre {padding: 0; margin: 0.25em 0 0.5em 0.5em; color: #533; font-size: 90%;} +.slide pre code {display: block;} +.slide ul {margin-left: 5%; margin-right: 7%; list-style: disc;} +.slide ol {margin-left: 5%; margin-right: 7%;} +.slide li {margin-top: 0.75em; margin-right: 0;} +.slide ul ul {line-height: 1;} +.slide ul ul li {margin: .2em; font-size: 85%; list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} + +div#header, div#footer {color: #ccc; + font-family: Verdana, Helvetica, sans-serif; background: url("../img/footer_bg.png") repeat scroll 0 0 transparent; + +} +div#header { + +background-image: linear-gradient(bottom, rgb(234,234,234) 26%, rgb(246,246,246) 49%, rgb(252,252,252) 83%); +background-image: -o-linear-gradient(bottom, rgb(234,234,234) 26%, rgb(246,246,246) 49%, rgb(252,252,252) 83%); +background-image: -moz-linear-gradient(bottom, rgb(234,234,234) 26%, rgb(246,246,246) 49%, rgb(252,252,252) 83%); +background-image: -webkit-linear-gradient(bottom, rgb(234,234,234) 26%, rgb(246,246,246) 49%, rgb(252,252,252) 83%); +background-image: -ms-linear-gradient(bottom, rgb(234,234,234) 26%, rgb(246,246,246) 49%, rgb(252,252,252) 83%); +line-height: 1px; +border-bottom: 1px solid #ccc; +} + +div#sub_header { + display: block; z-index: 2; top: 0pt; background: none repeat scroll 0% 0% rgba(255, 255, 255, 0.4); left: 50%; position: fixed; border-radius: 100em 100em 100em 100em; height: 80em; width: 80em; margin-top: -77.3em; margin-left: -40em; +} + +div#footer {font-size: 0.5em; font-weight: bold; padding: 0 0 1em; height: 5em;} +#footer h1, #footer h2 {display: block; padding: 0 1em;} +#footer h2 {font-style: italic;} + +#footer_shadow { + background: url("../img/footer_shadow.png") repeat scroll 0 0 transparent; + width: 100%; + height: 7px; + margin-bottom: 1em; +} + + +div.long {font-size: 0.75em;} +.slide h1 {position: absolute; top: 0.3em; left: 87px; z-index: 1; + margin: 0; padding: 0.3em 0 0 15px; white-space: nowrap; + font: bold 150%/1em Helvetica, sans-serif; text-transform: capitalize; + color: #333;} +.slide h3 {font-size: 130%;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; + text-align: right; font: bold 0.9em Verdana, Helvetica, sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; + top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + border: none; color: #ccc; + cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; background: #DDD; color: #227;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #ccc;} + +#logo {text-align: right; position: fixed; width: 100%; bottom: 0pt;} +#logo img { height: 18em; width: 24em; margin-right: 0em; } + +#slide0 {padding-top: 3.5em; font-size: 90%;} +#slide0 h1 {position: static; margin: 1em 0 0; padding: 0; + font: bold 2em Helvetica, sans-serif; white-space: normal; + color: #000; background: transparent;} +#slide0 h2 {font: bold italic 1em Helvetica, sans-serif; margin: 0.25em;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.note {display: none;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #77B;} + +.incremental, .incremental *, .incremental *:after {color: #DDE; visibility: visible;} +img.incremental {visibility: hidden;} +.slide .current {color: #B02;} + +button.btn, input[type="submit"].btn { + *padding-top: 2px; + *padding-bottom: 2px; +} +button.btn::-moz-focus-inner, input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} +button.btn.large, input[type="submit"].btn.large { + *padding-top: 7px; + *padding-bottom: 7px; +} +button.btn.small, input[type="submit"].btn.small { + *padding-top: 3px; + *padding-bottom: 3px; +} +.btn-group { + position: relative; + *zoom: 1; + *margin-left: .3em; +} +.btn-group:before, .btn-group:after { + display: table; + content: ""; +} +.btn-group:after { + clear: both; +} +.btn-group:first-child { + *margin-left: 0; +} +.btn-group + .btn-group { + margin-left: 5px; +} +.btn-toolbar { + margin-top: 9px; + margin-bottom: 9px; +} +.btn-toolbar .btn-group { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} +.btn-group .btn { + position: relative; + float: left; + margin-left: -1px; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.btn-group .btn:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; + border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + border-bottom-left-radius: 4px; +} +.btn-group .btn:last-child, .btn-group .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; + border-bottom-right-radius: 4px; +} +.btn-group .btn.large:first-child { + margin-left: 0; + -webkit-border-top-left-radius: 6px; + -moz-border-radius-topleft: 6px; + border-top-left-radius: 6px; + -webkit-border-bottom-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + border-bottom-left-radius: 6px; +} +.btn-group .btn.large:last-child, .btn-group .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + -moz-border-radius-topright: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + -moz-border-radius-bottomright: 6px; + border-bottom-right-radius: 6px; +} +.btn-group .btn:hover, +.btn-group .btn:focus, +.btn-group .btn:active, +.btn-group .btn.active { + z-index: 2; +} +.btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + *padding-top: 5px; + *padding-bottom: 5px; +} +.btn-group.open { + *z-index: 1000; +} +.btn-group.open .dropdown-menu { + display: block; + margin-top: 1px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 6px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} +.btn .caret { + margin-top: 7px; + margin-left: 0; +} +.btn:hover .caret, .open.btn-group .caret { + opacity: 1; + filter: alpha(opacity=100); +} +.btn-primary .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + opacity: 0.75; + filter: alpha(opacity=75); +} +.btn-small .caret { + margin-top: 4px; +} + + +/* diagnostics + +li:after {content: " [" attr(class) "]"; color: #F88;} + */ diff --git a/talks/bed/ui/default/print.css b/talks/bed/ui/default/print.css new file mode 100644 index 00000000..e7a71d14 --- /dev/null +++ b/talks/bed/ui/default/print.css @@ -0,0 +1 @@ +/* The following rule is necessary to have all slides appear in print! DO NOT REMOVE IT! */
.slide, ul {page-break-inside: avoid; visibility: visible !important;}
h1 {page-break-after: avoid;}
body {font-size: 12pt; background: white;}
* {color: black;}
#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;}
#slide0 h3 {margin: 0; padding: 0;}
#slide0 h4 {margin: 0 0 0.5em; padding: 0;}
#slide0 {margin-bottom: 3em;}
h1 {border-top: 2pt solid gray; border-bottom: 1px dotted silver;}
.extra {background: transparent !important;}
div.extra, pre.extra, .example {font-size: 10pt; color: #333;}
ul.extra a {font-weight: bold;}
p.example {display: none;}
#header {display: none;}
#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; font-style: italic;}
#footer h2, #controls {display: none;}
/* The following rule keeps the layout stuff out of print. Remove at your own risk! */
.layout, .layout * {display: none !important;}
\ No newline at end of file diff --git a/talks/bed/ui/default/s5-core.css b/talks/bed/ui/default/s5-core.css new file mode 100644 index 00000000..86444e04 --- /dev/null +++ b/talks/bed/ui/default/s5-core.css @@ -0,0 +1,9 @@ +/* Do not edit or override these styles! The system will likely break if you do. */ + +div#header, div#footer, div#controls, .slide {position: absolute;} +html>body div#header, html>body div#footer, + html>body div#controls, html>body .slide {position: fixed;} +.handout {display: none;} +.layout {display: block;} +.slide, .hideme, .incremental {visibility: hidden;} +#slide0 {visibility: visible;} diff --git a/talks/bed/ui/default/slides.css b/talks/bed/ui/default/slides.css new file mode 100644 index 00000000..0786d7db --- /dev/null +++ b/talks/bed/ui/default/slides.css @@ -0,0 +1,3 @@ +@import url(s5-core.css); /* required to make the slide show run at all */ +@import url(framing.css); /* sets basic placement and size of slide components */ +@import url(pretty.css); /* stuff that makes the slides look better than blah */
\ No newline at end of file diff --git a/talks/bed/ui/default/slides.js b/talks/bed/ui/default/slides.js new file mode 100644 index 00000000..3d9ad756 --- /dev/null +++ b/talks/bed/ui/default/slides.js @@ -0,0 +1,545 @@ +// S5 v1.1 slides.js -- released into the Public Domain +// +// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for information +// about all the wonderful and talented contributors to this code! + +var undef; +var slideCSS = ''; +var snum = 0; +var smax = 1; +var incpos = 0; +var number = undef; +var s5mode = true; +var defaultView = 'slideshow'; +var controlVis = 'visible'; + +var isIE = navigator.appName == 'Microsoft Internet Explorer' && navigator.userAgent.indexOf('Opera') < 1 ? 1 : 0; +var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0; +var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0; + +function hasClass(object, className) { + if (!object.className) return false; + return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1); +} + +function hasValue(object, value) { + if (!object) return false; + return (object.search('(^|\\s)' + value + '(\\s|$)') != -1); +} + +function removeClass(object,className) { + if (!object) return; + object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2); +} + +function addClass(object,className) { + if (!object || hasClass(object, className)) return; + if (object.className) { + object.className += ' '+className; + } else { + object.className = className; + } +} + +function GetElementsWithClassName(elementName,className) { + var allElements = document.getElementsByTagName(elementName); + var elemColl = new Array(); + for (var i = 0; i< allElements.length; i++) { + if (hasClass(allElements[i], className)) { + elemColl[elemColl.length] = allElements[i]; + } + } + return elemColl; +} + +function isParentOrSelf(element, id) { + if (element == null || element.nodeName=='BODY') return false; + else if (element.id == id) return true; + else return isParentOrSelf(element.parentNode, id); +} + +function nodeValue(node) { + var result = ""; + if (node.nodeType == 1) { + var children = node.childNodes; + for (var i = 0; i < children.length; ++i) { + result += nodeValue(children[i]); + } + } + else if (node.nodeType == 3) { + result = node.nodeValue; + } + return(result); +} + +function slideLabel() { + var slideColl = GetElementsWithClassName('*','slide'); + var list = document.getElementById('jumplist'); + smax = slideColl.length; + for (var n = 0; n < smax; n++) { + var obj = slideColl[n]; + + var did = 'slide' + n.toString(); + obj.setAttribute('id',did); + if (isOp) continue; + + var otext = ''; + var menu = obj.firstChild; + if (!menu) continue; // to cope with empty slides + while (menu && menu.nodeType == 3) { + menu = menu.nextSibling; + } + if (!menu) continue; // to cope with slides with only text nodes + + var menunodes = menu.childNodes; + for (var o = 0; o < menunodes.length; o++) { + otext += nodeValue(menunodes[o]); + } + list.options[list.length] = new Option(n + ' : ' + otext, n); + } +} + +function currentSlide() { + var cs; + if (document.getElementById) { + cs = document.getElementById('currentSlide'); + } else { + cs = document.currentSlide; + } + cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' + + '<span id="csSep">\/<\/span> ' + + '<span id="csTotal">' + (smax-1) + '<\/span>'; + if (snum == 0) { + cs.style.visibility = 'hidden'; + } else { + cs.style.visibility = 'visible'; + } +} + +function go(step) { + if (document.getElementById('slideProj').disabled || step == 0) return; + var jl = document.getElementById('jumplist'); + var cid = 'slide' + snum; + var ce = document.getElementById(cid); + if (incrementals[snum].length > 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + removeClass(incrementals[snum][i], 'current'); + removeClass(incrementals[snum][i], 'incremental'); + } + } + if (step != 'j') { + snum += step; + lmax = smax - 1; + if (snum > lmax) snum = lmax; + if (snum < 0) snum = 0; + } else + snum = parseInt(jl.value); + var nid = 'slide' + snum; + var ne = document.getElementById(nid); + if (!ne) { + ne = document.getElementById('slide0'); + snum = 0; + } + if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;} + if (incrementals[snum].length > 0 && incpos == 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + if (hasClass(incrementals[snum][i], 'current')) + incpos = i + 1; + else + addClass(incrementals[snum][i], 'incremental'); + } + } + if (incrementals[snum].length > 0 && incpos > 0) + addClass(incrementals[snum][incpos - 1], 'current'); + ce.style.visibility = 'hidden'; + ne.style.visibility = 'visible'; + jl.selectedIndex = snum; + currentSlide(); + number = 0; +} + +function goTo(target) { + if (target >= smax || target == snum) return; + go(target - snum); +} + +function subgo(step) { + if (step > 0) { + removeClass(incrementals[snum][incpos - 1],'current'); + removeClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos],'current'); + incpos++; + } else { + incpos--; + removeClass(incrementals[snum][incpos],'current'); + addClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos - 1],'current'); + } +} + +function toggle() { + var slideColl = GetElementsWithClassName('*','slide'); + var slides = document.getElementById('slideProj'); + var outline = document.getElementById('outlineStyle'); + if (!slides.disabled) { + slides.disabled = true; + outline.disabled = false; + s5mode = false; + fontSize('1em'); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'visible'; + } + } else { + slides.disabled = false; + outline.disabled = true; + s5mode = true; + fontScale(); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'hidden'; + } + slideColl[snum].style.visibility = 'visible'; + } +} + +function showHide(action) { + var obj = GetElementsWithClassName('*','hideme')[0]; + switch (action) { + case 's': obj.style.visibility = 'visible'; break; + case 'h': obj.style.visibility = 'hidden'; break; + case 'k': + if (obj.style.visibility != 'visible') { + obj.style.visibility = 'visible'; + } else { + obj.style.visibility = 'hidden'; + } + break; + } +} + +// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/) +function keys(key) { + if (!key) { + key = event; + key.which = key.keyCode; + } + if (key.which == 84) { + toggle(); + return; + } + if (s5mode) { + switch (key.which) { + case 10: // return + case 13: // enter + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + if(number != undef) { + goTo(number); + break; + } + case 32: // spacebar + case 34: // page down + case 39: // rightkey + case 40: // downkey + if(number != undef) { + go(number); + } else if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + break; + case 33: // page up + case 37: // leftkey + case 38: // upkey + if(number != undef) { + go(-1 * number); + } else if (!incrementals[snum] || incpos <= 0) { + go(-1); + } else { + subgo(-1); + } + break; + case 36: // home + goTo(0); + break; + case 35: // end + goTo(smax-1); + break; + case 67: // c + showHide('k'); + break; + } + if (key.which < 48 || key.which > 57) { + number = undef; + } else { + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + number = (((number != undef) ? number : 0) * 10) + (key.which - 48); + } + } + return false; +} + +function clicker(e) { + number = undef; + var target; + if (window.event) { + target = window.event.srcElement; + e = window.event; + } else target = e.target; + if (target.getAttribute('href') != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target,'object')) return true; + if (!e.which || e.which == 1) { + if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + } +} + +function findSlide(hash) { + var target = null; + var slides = GetElementsWithClassName('*','slide'); + for (var i = 0; i < slides.length; i++) { + var targetSlide = slides[i]; + if ( (targetSlide.name && targetSlide.name == hash) + || (targetSlide.id && targetSlide.id == hash) ) { + target = targetSlide; + break; + } + } + while(target != null && target.nodeName != 'BODY') { + if (hasClass(target, 'slide')) { + return parseInt(target.id.slice(5)); + } + target = target.parentNode; + } + return null; +} + +function slideJump() { + if (window.location.hash == null) return; + var sregex = /^#slide(\d+)$/; + var matches = sregex.exec(window.location.hash); + var dest = null; + if (matches != null) { + dest = parseInt(matches[1]); + } else { + dest = findSlide(window.location.hash.slice(1)); + } + if (dest != null) + go(dest - snum); +} + +function fixLinks() { + var thisUri = window.location.href; + thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length); + var aelements = document.getElementsByTagName('A'); + for (var i = 0; i < aelements.length; i++) { + var a = aelements[i].href; + var slideID = a.match('\#slide[0-9]{1,2}'); + if ((slideID) && (slideID[0].slice(0,1) == '#')) { + var dest = findSlide(slideID[0].slice(1)); + if (dest != null) { + if (aelements[i].addEventListener) { + aelements[i].addEventListener("click", new Function("e", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "if (e.preventDefault) e.preventDefault();"), true); + } else if (aelements[i].attachEvent) { + aelements[i].attachEvent("onclick", new Function("", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "event.returnValue = false;")); + } + } + } + } +} + +function externalLinks() { + if (!document.getElementsByTagName) return; + var anchors = document.getElementsByTagName('a'); + for (var i=0; i<anchors.length; i++) { + var anchor = anchors[i]; + if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) { + anchor.target = '_blank'; + addClass(anchor,'external'); + } + } +} + +function createControls() { + var controlsDiv = document.getElementById("controls"); + if (!controlsDiv) return; + var hider = ' onmouseover="showHide(\'s\');" onmouseout="showHide(\'h\');"'; + var hideDiv, hideList = ''; + if (controlVis == 'hidden') { + hideDiv = hider; + } + controlsDiv.innerHTML = '<form action="#" id="controlForm"' + hideDiv + '>' + + '<div id="navLinks">' + + '<a accesskey="t" id="toggle" href="javascript:toggle();">Ø<\/a>' + + '<a accesskey="z" id="prev" href="javascript:go(-1);">«<\/a>' + + '<a accesskey="x" id="next" href="javascript:go(1);">»<\/a>' + + '<div id="navList"><select id="jumplist" onchange="go(\'j\');"><\/select><\/div>' + + '<\/div><\/form>'; +} + +function fontScale() { // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers + if (!s5mode) return false; + var vScale = 22; // both yield 32 (after rounding) at 1024x768 + var hScale = 32; // perhaps should auto-calculate based on theme's declared value? + if (window.innerHeight) { + var vSize = window.innerHeight; + var hSize = window.innerWidth; + } else if (document.documentElement.clientHeight) { + var vSize = document.documentElement.clientHeight; + var hSize = document.documentElement.clientWidth; + } else if (document.body.clientHeight) { + var vSize = document.body.clientHeight; + var hSize = document.body.clientWidth; + } else { + var vSize = 700; // assuming 1024x768, minus chrome and such + var hSize = 1024; // these do not account for kiosk mode or Opera Show + } + var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale)); + fontSize(newSize + 'px'); + if (isGe) { // hack to counter incremental reflow bugs + var obj = document.getElementsByTagName('body')[0]; + obj.style.display = 'none'; + obj.style.display = 'block'; + } +} + +function fontSize(value) { + if (!(s5ss = document.getElementById('s5ss'))) { + if (!isIE) { + document.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style')); + s5ss.setAttribute('media','screen, projection'); + s5ss.setAttribute('id','s5ss'); + } else { + document.createStyleSheet(); + document.s5ss = document.styleSheets[document.styleSheets.length - 1]; + } + } + if (!isIE) { + while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild); + s5ss.appendChild(document.createTextNode('body {font-size: ' + value + ' !important;}')); + } else { + document.s5ss.addRule('body','font-size: ' + value + ' !important;'); + } +} + +function notOperaFix() { + slideCSS = document.getElementById('slideProj').href; + var slides = document.getElementById('slideProj'); + var outline = document.getElementById('outlineStyle'); + slides.setAttribute('media','screen'); + outline.disabled = true; + if (isGe) { + slides.setAttribute('href','null'); // Gecko fix + slides.setAttribute('href',slideCSS); // Gecko fix + } + if (isIE && document.styleSheets && document.styleSheets[0]) { + document.styleSheets[0].addRule('img', 'behavior: url(ui/default/iepngfix.htc)'); + document.styleSheets[0].addRule('div', 'behavior: url(ui/default/iepngfix.htc)'); + document.styleSheets[0].addRule('.slide', 'behavior: url(ui/default/iepngfix.htc)'); + } +} + +function getIncrementals(obj) { + var incrementals = new Array(); + if (!obj) + return incrementals; + var children = obj.childNodes; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (hasClass(child, 'incremental')) { + if (child.nodeName == 'OL' || child.nodeName == 'UL') { + removeClass(child, 'incremental'); + for (var j = 0; j < child.childNodes.length; j++) { + if (child.childNodes[j].nodeType == 1) { + addClass(child.childNodes[j], 'incremental'); + } + } + } else { + incrementals[incrementals.length] = child; + removeClass(child,'incremental'); + } + } + if (hasClass(child, 'show-first')) { + if (child.nodeName == 'OL' || child.nodeName == 'UL') { + removeClass(child, 'show-first'); + if (child.childNodes[isGe].nodeType == 1) { + removeClass(child.childNodes[isGe], 'incremental'); + } + } else { + incrementals[incrementals.length] = child; + } + } + incrementals = incrementals.concat(getIncrementals(child)); + } + return incrementals; +} + +function createIncrementals() { + var incrementals = new Array(); + for (var i = 0; i < smax; i++) { + incrementals[i] = getIncrementals(document.getElementById('slide'+i)); + } + return incrementals; +} + +function defaultCheck() { + var allMetas = document.getElementsByTagName('meta'); + for (var i = 0; i< allMetas.length; i++) { + if (allMetas[i].name == 'defaultView') { + defaultView = allMetas[i].content; + } + if (allMetas[i].name == 'controlVis') { + controlVis = allMetas[i].content; + } + } +} + +// Key trap fix, new function body for trap() +function trap(e) { + if (!e) { + e = event; + e.which = e.keyCode; + } + try { + modifierKey = e.ctrlKey || e.altKey || e.metaKey; + } + catch(e) { + modifierKey = false; + } + return modifierKey || e.which == 0; +} + +function startup() { + defaultCheck(); + if (!isOp) + createControls(); + slideLabel(); + fixLinks(); + externalLinks(); + fontScale(); + if (!isOp) { + notOperaFix(); + incrementals = createIncrementals(); + slideJump(); + if (defaultView == 'outline') { + toggle(); + } + document.onkeyup = keys; + document.onkeypress = trap; + document.onclick = clicker; + } +} + +window.onload = startup; +window.onresize = function(){setTimeout('fontScale()', 50);} diff --git a/talks/bed/ui/img/footer_bg.png b/talks/bed/ui/img/footer_bg.png Binary files differnew file mode 100644 index 00000000..bf08c6c7 --- /dev/null +++ b/talks/bed/ui/img/footer_bg.png diff --git a/talks/bed/ui/img/footer_logo.png b/talks/bed/ui/img/footer_logo.png Binary files differnew file mode 100644 index 00000000..9887afd7 --- /dev/null +++ b/talks/bed/ui/img/footer_logo.png diff --git a/talks/bed/ui/img/footer_shadow.png b/talks/bed/ui/img/footer_shadow.png Binary files differnew file mode 100644 index 00000000..27fd93db --- /dev/null +++ b/talks/bed/ui/img/footer_shadow.png diff --git a/talks/bed/ui/img/logo.png b/talks/bed/ui/img/logo.png Binary files differnew file mode 100644 index 00000000..ffd0fcf9 --- /dev/null +++ b/talks/bed/ui/img/logo.png diff --git a/talks/bed/ui/img/logo.svg b/talks/bed/ui/img/logo.svg new file mode 100644 index 00000000..833a691a --- /dev/null +++ b/talks/bed/ui/img/logo.svg @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="498.5px" height="336px" viewBox="0 0 498.5 336" enable-background="new 0 0 498.5 336" xml:space="preserve">
+<g opacity="0.2">
+ <path fill="#5195AA" d="M170.314,115.788c0,17.162-7.237,40.448-21.685,69.856l-55.483,113.25H41.331l54.38-108.102
+ c-5.396,2.21-11.875,3.312-19.468,3.312c-18.623,0-34.536-6.857-47.777-20.592c-14.205-14.704-21.31-33.699-21.31-56.989
+ c0-25.245,7.834-45.345,23.509-60.296C45.609,42.012,64.97,34.902,88.738,34.902c23.758,0,43.115,6.985,58.049,20.955
+ C162.469,70.562,170.314,90.544,170.314,115.788z M122.172,116.159c0-11.77-3.097-21.083-9.272-27.944
+ c-6.18-6.864-14.246-10.299-24.164-10.299c-9.933,0-17.995,3.435-24.173,10.299c-6.185,6.861-9.267,16.175-9.267,27.944
+ c0,11.525,3.082,20.772,9.267,27.757c6.178,6.986,14.24,10.479,24.173,10.479c9.918,0,17.984-3.43,24.164-10.295
+ C119.074,137.239,122.172,127.923,122.172,116.159z"/>
+ <path fill="#FC9DB5" d="M340.007,115.788c0,17.162-7.224,40.448-21.682,69.856l-55.489,113.25h-51.808l54.387-108.102
+ c-5.397,2.21-11.89,3.312-19.479,3.312c-18.618,0-34.538-6.857-47.766-20.592c-14.208-14.707-21.316-33.701-21.316-56.991
+ c0-25.245,7.834-45.345,23.52-60.296C215.308,42.01,234.662,34.9,258.431,34.9c23.761,0,43.12,6.985,58.067,20.955
+ C332.168,70.562,340.007,90.544,340.007,115.788z M291.871,116.159c0-11.77-3.096-21.083-9.277-27.944
+ c-6.179-6.864-14.231-10.299-24.166-10.299c-9.933,0-17.993,3.435-24.176,10.299c-6.173,6.861-9.264,16.175-9.264,27.944
+ c0,11.525,3.091,20.772,9.264,27.757c6.183,6.986,14.243,10.479,24.176,10.479c9.935,0,17.987-3.43,24.166-10.295
+ C288.778,137.239,291.871,127.923,291.871,116.159z"/>
+ <path fill="#C6D673" d="M491.156,238.598c0,20.346-7.847,36.029-23.514,47.062c-14.7,10.294-33.93,15.441-57.695,15.441
+ c-17.888,0-32.465-1.602-43.725-4.779c-14.21-4.166-26.822-11.768-37.849-22.795l31.229-31.256
+ c12,12.015,29.032,18.014,51.068,18.014c22.543,0,33.814-6.617,33.814-19.852c0-10.535-6.752-16.426-20.216-17.649l-30.136-2.943
+ c-37.229-3.678-55.854-21.567-55.854-53.679c0-19.116,7.473-34.314,22.414-45.593c13.725-10.295,30.871-15.441,51.452-15.441
+ c32.821,0,57.198,7.482,73.12,22.429l-29.396,29.781c-9.552-8.583-24.375-12.872-44.466-12.872
+ c-18.13,0-27.191,6.129-27.191,18.385c0,9.808,6.61,15.326,19.854,16.549l30.129,2.94
+ C472.178,186.018,491.156,204.77,491.156,238.598z"/>
+ <path fill="#43A3BA" d="M146.787,55.854c-14.934-13.971-34.291-20.957-58.049-20.957c-10.371,0-19.843,1.435-28.542,4.143
+ c8.149,5.549,15.888,11.744,23.214,18.592c8.055,7.558,15.274,15.672,21.736,24.297c2.848,1.608,5.434,3.703,7.756,6.279
+ c4.783,5.315,7.699,12.12,8.778,20.38c12.84,25.312,20.201,54.312,22.088,86.977l4.859-9.924
+ c14.452-29.407,21.685-52.691,21.685-69.857C170.314,90.544,162.469,70.562,146.787,55.854z"/>
+ <path fill="#E8809E" d="M191.529,66.489c8.312,18.707,19.499,35.677,33.506,50.944c-0.006-0.432-0.047-0.84-0.047-1.274
+ c0-11.77,3.091-21.083,9.264-27.944c6.183-6.864,14.243-10.299,24.178-10.299c9.933,0,17.985,3.435,24.165,10.299
+ c6.184,6.861,9.276,16.175,9.276,27.944c0,11.764-3.096,21.08-9.276,27.944c-3.867,4.299-8.479,7.248-13.824,8.856
+ c17.236,9.888,35.812,16.361,55.727,19.428c10.301-23.211,15.51-42.109,15.51-56.595c0-25.242-7.843-45.227-23.515-59.936
+ c-14.945-13.97-34.308-20.955-58.068-20.955c-23.767,0-43.12,7.11-58.055,21.327C197.044,59.399,194.149,62.854,191.529,66.489z"/>
+ <g>
+ <path fill="#ACB75C" d="M386.362,170.945c-1.382-2.271-2.142-4.938-2.142-8.095c0-12.252,9.062-18.385,27.189-18.385
+ c20.091,0,34.918,4.289,44.466,12.87l29.396-29.779c-15.922-14.949-40.298-22.431-73.117-22.431
+ c-20.584,0-37.731,5.148-51.455,15.443c-14.942,11.278-22.414,26.475-22.414,45.593c0,2.708,0.185,5.278,0.448,7.785
+ c4.417,0.312,8.867,0.524,13.402,0.524C364.728,174.473,376.118,173.291,386.362,170.945z"/>
+ </g>
+</g>
+</svg>
diff --git a/talks/bed/ui/sh/sh99s.css b/talks/bed/ui/sh/sh99s.css new file mode 100644 index 00000000..ba2cd2ea --- /dev/null +++ b/talks/bed/ui/sh/sh99s.css @@ -0,0 +1,341 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +.syntaxhighlighter a, +.syntaxhighlighter div, +.syntaxhighlighter code, +.syntaxhighlighter table, +.syntaxhighlighter table td, +.syntaxhighlighter table tr, +.syntaxhighlighter table tbody, +.syntaxhighlighter table thead, +.syntaxhighlighter table caption, +.syntaxhighlighter textarea { + -moz-border-radius: 0 0 0 0 !important; + -webkit-border-radius: 0 0 0 0 !important; + background: none !important; + border: 0 !important; + bottom: auto !important; + float: none !important; + height: auto !important; + left: auto !important; + line-height: 1.1em !important; + margin: 0 !important; + outline: 0 !important; + overflow: visible !important; + padding: 0 !important; + position: static !important; + right: auto !important; + text-align: left !important; + top: auto !important; + vertical-align: baseline !important; + width: auto !important; + box-sizing: content-box !important; + font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important; + font-weight: normal !important; + font-style: normal !important; + font-size: 1em !important; + min-height: inherit !important; + min-height: auto !important; +} + +.syntaxhighlighter { + margin: 1em 0 1em 0 !important; + position: relative !important; + overflow: auto !important; + font-size: 0.8em !important; +} +.syntaxhighlighter.source { + overflow: hidden !important; +} +.syntaxhighlighter .bold { + font-weight: bold !important; +} +.syntaxhighlighter .italic { + font-style: italic !important; +} +.syntaxhighlighter .line { + white-space: pre !important; +} +.syntaxhighlighter table { + width: 100% !important; +} +.syntaxhighlighter table caption { + text-align: left !important; + padding: .5em 0 0.5em 1em !important; +} +.syntaxhighlighter table td.code { + width: 100% !important; +} +.syntaxhighlighter table td.code .container { + position: relative !important; +} +.syntaxhighlighter table td.code .container textarea { + box-sizing: border-box !important; + position: absolute !important; + left: 0 !important; + top: 0 !important; + width: 100% !important; + height: 100% !important; + border: none !important; + background: white !important; + padding-left: 1em !important; + overflow: hidden !important; + white-space: pre !important; +} +.syntaxhighlighter table td.gutter .line { + text-align: right !important; + padding: 0 0.5em 0 1em !important; +} +.syntaxhighlighter table td.code .line { + padding: 0 1em !important; +} +.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line { + padding-left: 0em !important; +} +.syntaxhighlighter.show { + display: block !important; +} +.syntaxhighlighter.collapsed table { + display: none !important; +} +.syntaxhighlighter.collapsed .toolbar { + padding: 0.1em 0.8em 0em 0.8em !important; + font-size: 1em !important; + position: static !important; + width: auto !important; + height: auto !important; +} +.syntaxhighlighter.collapsed .toolbar span { + display: inline !important; + margin-right: 1em !important; +} +.syntaxhighlighter.collapsed .toolbar span a { + padding: 0 !important; + display: none !important; +} +.syntaxhighlighter.collapsed .toolbar span a.expandSource { + display: inline !important; +} +.syntaxhighlighter .toolbar { + position: absolute !important; + right: 1px !important; + top: 1px !important; + width: 11px !important; + height: 11px !important; + font-size: 10px !important; + z-index: 10 !important; +} +.syntaxhighlighter .toolbar span.title { + display: inline !important; +} +.syntaxhighlighter .toolbar a { + display: block !important; + text-align: center !important; + text-decoration: none !important; + padding-top: 1px !important; +} +.syntaxhighlighter .toolbar a.expandSource { + display: none !important; +} +.syntaxhighlighter.ie { + font-size: .9em !important; + padding: 1px 0 1px 0 !important; +} +.syntaxhighlighter.ie .toolbar { + line-height: 8px !important; +} +.syntaxhighlighter.ie .toolbar a { + padding-top: 0px !important; +} +.syntaxhighlighter.printing .line.alt1 .content, +.syntaxhighlighter.printing .line.alt2 .content, +.syntaxhighlighter.printing .line.highlighted .number, +.syntaxhighlighter.printing .line.highlighted.alt1 .content, +.syntaxhighlighter.printing .line.highlighted.alt2 .content { + background: none !important; +} +.syntaxhighlighter.printing .line .number { + color: #bbbbbb !important; +} +.syntaxhighlighter.printing .line .content { + color: black !important; +} +.syntaxhighlighter.printing .toolbar { + display: none !important; +} +.syntaxhighlighter.printing a { + text-decoration: none !important; +} +.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a { + color: black !important; +} +.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a { + color: #008200 !important; +} +.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a { + color: blue !important; +} +.syntaxhighlighter.printing .keyword { + color: #006699 !important; + font-weight: bold !important; +} +.syntaxhighlighter.printing .preprocessor { + color: gray !important; +} +.syntaxhighlighter.printing .variable { + color: #aa7700 !important; +} +.syntaxhighlighter.printing .value { + color: #009900 !important; +} +.syntaxhighlighter.printing .functions { + color: #ff1493 !important; +} +.syntaxhighlighter.printing .constants { + color: #0066cc !important; +} +.syntaxhighlighter.printing .script { + font-weight: bold !important; +} +.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a { + color: gray !important; +} +.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a { + color: #ff1493 !important; +} +.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a { + color: red !important; +} +.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a { + color: black !important; +} + +.syntaxhighlighter { + background-color: #f8f8f8 !important; + border: 1px solid #ccc; + border-radius: 5px; + padding: 10px; +} +.syntaxhighlighter .line.alt1 { + background-color: #f8f8f8 !important; +} +.syntaxhighlighter .line.alt2 { + background-color: #f8f8f8 !important; +} +.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 { + background-color: #c3defe !important; +} +.syntaxhighlighter .line.highlighted.number { + color: white !important; +} +.syntaxhighlighter table caption { + color: black !important; +} +.syntaxhighlighter .gutter { + color: #787878 !important; +} +.syntaxhighlighter .gutter .line { + border-right: 1px solid #d4d0c8 !important; +} +.syntaxhighlighter .gutter .line.highlighted { + background-color: #d4d0c8 !important; + color: white !important; +} +.syntaxhighlighter.printing .line .content { + border: none !important; +} +.syntaxhighlighter.collapsed { + overflow: visible !important; +} +.syntaxhighlighter.collapsed .toolbar { + color: #3f5fbf !important; + background: white !important; + border: 1px solid #d4d0c8 !important; +} +.syntaxhighlighter.collapsed .toolbar a { + color: #3f5fbf !important; +} +.syntaxhighlighter.collapsed .toolbar a:hover { + color: #aa7700 !important; +} +.syntaxhighlighter .toolbar { + color: #a0a0a0 !important; + border: none !important; + font-size: 14px !important; +} +.syntaxhighlighter .toolbar a { + color: #a0a0a0 !important; +} +.syntaxhighlighter .toolbar a:hover { + color: red !important; +} +.syntaxhighlighter .plain, .syntaxhighlighter .plain a { + color: black !important; +} +.syntaxhighlighter .comments, .syntaxhighlighter .comments a { + color: #3f5fbf !important; +} +.syntaxhighlighter .string, .syntaxhighlighter .string a { + color: #2a00ff !important; +} +.syntaxhighlighter .keyword { + color: #7f0055 !important; +} +.syntaxhighlighter .preprocessor { + color: #646464 !important; +} +.syntaxhighlighter .variable { + color: #aa7700 !important; +} +.syntaxhighlighter .value { + color: #009900 !important; +} +.syntaxhighlighter .functions { + color: #ff1493 !important; +} +.syntaxhighlighter .constants { + color: #0066cc !important; +} +.syntaxhighlighter .script { + font-weight: bold !important; + color: #7f0055 !important; + background-color: none !important; +} +.syntaxhighlighter .color1, .syntaxhighlighter .color1 a { + color: gray !important; +} +.syntaxhighlighter .color2, .syntaxhighlighter .color2 a { + color: #ff1493 !important; +} +.syntaxhighlighter .color3, .syntaxhighlighter .color3 a { + color: red !important; +} + +.syntaxhighlighter .keyword { + font-weight: bold !important; +} +.syntaxhighlighter .xml .keyword { + color: #3f7f7f !important; + font-weight: normal !important; +} +.syntaxhighlighter .xml .color1, .syntaxhighlighter .xml .color1 a { + color: #7f007f !important; +} +.syntaxhighlighter .xml .string { + font-style: italic !important; + color: #2a00ff !important; +} diff --git a/talks/bed/ui/sh/shBrushErlang.js b/talks/bed/ui/sh/shBrushErlang.js new file mode 100644 index 00000000..6ba7d9da --- /dev/null +++ b/talks/bed/ui/sh/shBrushErlang.js @@ -0,0 +1,52 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + // Contributed by Jean-Lou Dupont + // http://jldupont.blogspot.com/2009/06/erlang-syntax-highlighter.html + + // According to: http://erlang.org/doc/reference_manual/introduction.html#1.5 + var keywords = 'after and andalso band begin bnot bor bsl bsr bxor '+ + 'case catch cond div end fun if let not of or orelse '+ + 'query receive rem try when xor'+ + // additional + ' module export import define'; + + this.regexList = [ + { regex: new RegExp("[A-Z][A-Za-z0-9_]+", 'g'), css: 'constants' }, + { regex: new RegExp("\\%.+", 'gm'), css: 'comments' }, + { regex: new RegExp("\\?[A-Za-z0-9_]+", 'g'), css: 'preprocessor' }, + { regex: new RegExp("[a-z0-9_]+:[a-z0-9_]+", 'g'), css: 'functions' }, + { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, + { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } + ]; + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['erl', 'erlang']; + + SyntaxHighlighter.brushes.Erland = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/talks/bed/ui/sh/shBrushJScript.js b/talks/bed/ui/sh/shBrushJScript.js new file mode 100644 index 00000000..ff98daba --- /dev/null +++ b/talks/bed/ui/sh/shBrushJScript.js @@ -0,0 +1,52 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + var keywords = 'break case catch continue ' + + 'default delete do else false ' + + 'for function if in instanceof ' + + 'new null return super switch ' + + 'this throw true try typeof var while with' + ; + + var r = SyntaxHighlighter.regexLib; + + this.regexList = [ + { regex: r.multiLineDoubleQuotedString, css: 'string' }, // double quoted strings + { regex: r.multiLineSingleQuotedString, css: 'string' }, // single quoted strings + { regex: r.singleLineCComments, css: 'comments' }, // one line comments + { regex: r.multiLineCComments, css: 'comments' }, // multiline comments + { regex: /\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion + { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // keywords + ]; + + this.forHtmlScript(r.scriptScriptTags); + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['js', 'jscript', 'javascript']; + + SyntaxHighlighter.brushes.JScript = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/talks/bed/ui/sh/shBrushXml.js b/talks/bed/ui/sh/shBrushXml.js new file mode 100644 index 00000000..69d9fd0b --- /dev/null +++ b/talks/bed/ui/sh/shBrushXml.js @@ -0,0 +1,69 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +;(function() +{ + // CommonJS + typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null; + + function Brush() + { + function process(match, regexInfo) + { + var constructor = SyntaxHighlighter.Match, + code = match[0], + tag = new XRegExp('(<|<)[\\s\\/\\?]*(?<name>[:\\w-\\.]+)', 'xg').exec(code), + result = [] + ; + + if (match.attributes != null) + { + var attributes, + regex = new XRegExp('(?<name> [\\w:\\-\\.]+)' + + '\\s*=\\s*' + + '(?<value> ".*?"|\'.*?\'|\\w+)', + 'xg'); + + while ((attributes = regex.exec(code)) != null) + { + result.push(new constructor(attributes.name, match.index + attributes.index, 'color1')); + result.push(new constructor(attributes.value, match.index + attributes.index + attributes[0].indexOf(attributes.value), 'string')); + } + } + + if (tag != null) + result.push( + new constructor(tag.name, match.index + tag[0].indexOf(tag.name), 'keyword') + ); + + return result; + } + + this.regexList = [ + { regex: new XRegExp('(\\<|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](\\>|>)', 'gm'), css: 'color2' }, // <![ ... [ ... ]]> + { regex: SyntaxHighlighter.regexLib.xmlComments, css: 'comments' }, // <!-- ... --> + { regex: new XRegExp('(<|<)[\\s\\/\\?]*(\\w+)(?<attributes>.*?)[\\s\\/\\?]*(>|>)', 'sg'), func: process } + ]; + }; + + Brush.prototype = new SyntaxHighlighter.Highlighter(); + Brush.aliases = ['xml', 'xhtml', 'xslt', 'html']; + + SyntaxHighlighter.brushes.Xml = Brush; + + // CommonJS + typeof(exports) != 'undefined' ? exports.Brush = Brush : null; +})(); diff --git a/talks/bed/ui/sh/shCore.js b/talks/bed/ui/sh/shCore.js new file mode 100644 index 00000000..b47b6454 --- /dev/null +++ b/talks/bed/ui/sh/shCore.js @@ -0,0 +1,17 @@ +/** + * SyntaxHighlighter + * http://alexgorbatchev.com/SyntaxHighlighter + * + * SyntaxHighlighter is donationware. If you are using it, please donate. + * http://alexgorbatchev.com/SyntaxHighlighter/donate.html + * + * @version + * 3.0.83 (July 02 2010) + * + * @copyright + * Copyright (C) 2004-2010 Alex Gorbatchev. + * + * @license + * Dual licensed under the MIT and GPL licenses. + */ +eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('K M;I(M)1S 2U("2a\'t 4k M 4K 2g 3l 4G 4H");(6(){6 r(f,e){I(!M.1R(f))1S 3m("3s 15 4R");K a=f.1w;f=M(f.1m,t(f)+(e||""));I(a)f.1w={1m:a.1m,19:a.19?a.19.1a(0):N};H f}6 t(f){H(f.1J?"g":"")+(f.4s?"i":"")+(f.4p?"m":"")+(f.4v?"x":"")+(f.3n?"y":"")}6 B(f,e,a,b){K c=u.L,d,h,g;v=R;5K{O(;c--;){g=u[c];I(a&g.3r&&(!g.2p||g.2p.W(b))){g.2q.12=e;I((h=g.2q.X(f))&&h.P===e){d={3k:g.2b.W(b,h,a),1C:h};1N}}}}5v(i){1S i}5q{v=11}H d}6 p(f,e,a){I(3b.Z.1i)H f.1i(e,a);O(a=a||0;a<f.L;a++)I(f[a]===e)H a;H-1}M=6(f,e){K a=[],b=M.1B,c=0,d,h;I(M.1R(f)){I(e!==1d)1S 3m("2a\'t 5r 5I 5F 5B 5C 15 5E 5p");H r(f)}I(v)1S 2U("2a\'t W 3l M 59 5m 5g 5x 5i");e=e||"";O(d={2N:11,19:[],2K:6(g){H e.1i(g)>-1},3d:6(g){e+=g}};c<f.L;)I(h=B(f,c,b,d)){a.U(h.3k);c+=h.1C[0].L||1}Y I(h=n.X.W(z[b],f.1a(c))){a.U(h[0]);c+=h[0].L}Y{h=f.3a(c);I(h==="[")b=M.2I;Y I(h==="]")b=M.1B;a.U(h);c++}a=15(a.1K(""),n.Q.W(e,w,""));a.1w={1m:f,19:d.2N?d.19:N};H a};M.3v="1.5.0";M.2I=1;M.1B=2;K C=/\\$(?:(\\d\\d?|[$&`\'])|{([$\\w]+)})/g,w=/[^5h]+|([\\s\\S])(?=[\\s\\S]*\\1)/g,A=/^(?:[?*+]|{\\d+(?:,\\d*)?})\\??/,v=11,u=[],n={X:15.Z.X,1A:15.Z.1A,1C:1r.Z.1C,Q:1r.Z.Q,1e:1r.Z.1e},x=n.X.W(/()??/,"")[1]===1d,D=6(){K f=/^/g;n.1A.W(f,"");H!f.12}(),y=6(){K f=/x/g;n.Q.W("x",f,"");H!f.12}(),E=15.Z.3n!==1d,z={};z[M.2I]=/^(?:\\\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\\29-26-f]{2}|u[\\29-26-f]{4}|c[A-3o-z]|[\\s\\S]))/;z[M.1B]=/^(?:\\\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\\d*|x[\\29-26-f]{2}|u[\\29-26-f]{4}|c[A-3o-z]|[\\s\\S])|\\(\\?[:=!]|[?*+]\\?|{\\d+(?:,\\d*)?}\\??)/;M.1h=6(f,e,a,b){u.U({2q:r(f,"g"+(E?"y":"")),2b:e,3r:a||M.1B,2p:b||N})};M.2n=6(f,e){K a=f+"/"+(e||"");H M.2n[a]||(M.2n[a]=M(f,e))};M.3c=6(f){H r(f,"g")};M.5l=6(f){H f.Q(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g,"\\\\$&")};M.5e=6(f,e,a,b){e=r(e,"g"+(b&&E?"y":""));e.12=a=a||0;f=e.X(f);H b?f&&f.P===a?f:N:f};M.3q=6(){M.1h=6(){1S 2U("2a\'t 55 1h 54 3q")}};M.1R=6(f){H 53.Z.1q.W(f)==="[2m 15]"};M.3p=6(f,e,a,b){O(K c=r(e,"g"),d=-1,h;h=c.X(f);){a.W(b,h,++d,f,c);c.12===h.P&&c.12++}I(e.1J)e.12=0};M.57=6(f,e){H 6 a(b,c){K d=e[c].1I?e[c]:{1I:e[c]},h=r(d.1I,"g"),g=[],i;O(i=0;i<b.L;i++)M.3p(b[i],h,6(k){g.U(d.3j?k[d.3j]||"":k[0])});H c===e.L-1||!g.L?g:a(g,c+1)}([f],0)};15.Z.1p=6(f,e){H J.X(e[0])};15.Z.W=6(f,e){H J.X(e)};15.Z.X=6(f){K e=n.X.1p(J,14),a;I(e){I(!x&&e.L>1&&p(e,"")>-1){a=15(J.1m,n.Q.W(t(J),"g",""));n.Q.W(f.1a(e.P),a,6(){O(K c=1;c<14.L-2;c++)I(14[c]===1d)e[c]=1d})}I(J.1w&&J.1w.19)O(K b=1;b<e.L;b++)I(a=J.1w.19[b-1])e[a]=e[b];!D&&J.1J&&!e[0].L&&J.12>e.P&&J.12--}H e};I(!D)15.Z.1A=6(f){(f=n.X.W(J,f))&&J.1J&&!f[0].L&&J.12>f.P&&J.12--;H!!f};1r.Z.1C=6(f){M.1R(f)||(f=15(f));I(f.1J){K e=n.1C.1p(J,14);f.12=0;H e}H f.X(J)};1r.Z.Q=6(f,e){K a=M.1R(f),b,c;I(a&&1j e.58()==="3f"&&e.1i("${")===-1&&y)H n.Q.1p(J,14);I(a){I(f.1w)b=f.1w.19}Y f+="";I(1j e==="6")c=n.Q.W(J,f,6(){I(b){14[0]=1f 1r(14[0]);O(K d=0;d<b.L;d++)I(b[d])14[0][b[d]]=14[d+1]}I(a&&f.1J)f.12=14[14.L-2]+14[0].L;H e.1p(N,14)});Y{c=J+"";c=n.Q.W(c,f,6(){K d=14;H n.Q.W(e,C,6(h,g,i){I(g)5b(g){24"$":H"$";24"&":H d[0];24"`":H d[d.L-1].1a(0,d[d.L-2]);24"\'":H d[d.L-1].1a(d[d.L-2]+d[0].L);5a:i="";g=+g;I(!g)H h;O(;g>d.L-3;){i=1r.Z.1a.W(g,-1)+i;g=1Q.3i(g/10)}H(g?d[g]||"":"$")+i}Y{g=+i;I(g<=d.L-3)H d[g];g=b?p(b,i):-1;H g>-1?d[g+1]:h}})})}I(a&&f.1J)f.12=0;H c};1r.Z.1e=6(f,e){I(!M.1R(f))H n.1e.1p(J,14);K a=J+"",b=[],c=0,d,h;I(e===1d||+e<0)e=5D;Y{e=1Q.3i(+e);I(!e)H[]}O(f=M.3c(f);d=f.X(a);){I(f.12>c){b.U(a.1a(c,d.P));d.L>1&&d.P<a.L&&3b.Z.U.1p(b,d.1a(1));h=d[0].L;c=f.12;I(b.L>=e)1N}f.12===d.P&&f.12++}I(c===a.L){I(!n.1A.W(f,"")||h)b.U("")}Y b.U(a.1a(c));H b.L>e?b.1a(0,e):b};M.1h(/\\(\\?#[^)]*\\)/,6(f){H n.1A.W(A,f.2S.1a(f.P+f[0].L))?"":"(?:)"});M.1h(/\\((?!\\?)/,6(){J.19.U(N);H"("});M.1h(/\\(\\?<([$\\w]+)>/,6(f){J.19.U(f[1]);J.2N=R;H"("});M.1h(/\\\\k<([\\w$]+)>/,6(f){K e=p(J.19,f[1]);H e>-1?"\\\\"+(e+1)+(3R(f.2S.3a(f.P+f[0].L))?"":"(?:)"):f[0]});M.1h(/\\[\\^?]/,6(f){H f[0]==="[]"?"\\\\b\\\\B":"[\\\\s\\\\S]"});M.1h(/^\\(\\?([5A]+)\\)/,6(f){J.3d(f[1]);H""});M.1h(/(?:\\s+|#.*)+/,6(f){H n.1A.W(A,f.2S.1a(f.P+f[0].L))?"":"(?:)"},M.1B,6(){H J.2K("x")});M.1h(/\\./,6(){H"[\\\\s\\\\S]"},M.1B,6(){H J.2K("s")})})();1j 2e!="1d"&&(2e.M=M);K 1v=6(){6 r(a,b){a.1l.1i(b)!=-1||(a.1l+=" "+b)}6 t(a){H a.1i("3e")==0?a:"3e"+a}6 B(a){H e.1Y.2A[t(a)]}6 p(a,b,c){I(a==N)H N;K d=c!=R?a.3G:[a.2G],h={"#":"1c",".":"1l"}[b.1o(0,1)]||"3h",g,i;g=h!="3h"?b.1o(1):b.5u();I((a[h]||"").1i(g)!=-1)H a;O(a=0;d&&a<d.L&&i==N;a++)i=p(d[a],b,c);H i}6 C(a,b){K c={},d;O(d 2g a)c[d]=a[d];O(d 2g b)c[d]=b[d];H c}6 w(a,b,c,d){6 h(g){g=g||1P.5y;I(!g.1F){g.1F=g.52;g.3N=6(){J.5w=11}}c.W(d||1P,g)}a.3g?a.3g("4U"+b,h):a.4y(b,h,11)}6 A(a,b){K c=e.1Y.2j,d=N;I(c==N){c={};O(K h 2g e.1U){K g=e.1U[h];d=g.4x;I(d!=N){g.1V=h.4w();O(g=0;g<d.L;g++)c[d[g]]=h}}e.1Y.2j=c}d=e.1U[c[a]];d==N&&b!=11&&1P.1X(e.13.1x.1X+(e.13.1x.3E+a));H d}6 v(a,b){O(K c=a.1e("\\n"),d=0;d<c.L;d++)c[d]=b(c[d],d);H c.1K("\\n")}6 u(a,b){I(a==N||a.L==0||a=="\\n")H a;a=a.Q(/</g,"&1y;");a=a.Q(/ {2,}/g,6(c){O(K d="",h=0;h<c.L-1;h++)d+=e.13.1W;H d+" "});I(b!=N)a=v(a,6(c){I(c.L==0)H"";K d="";c=c.Q(/^(&2s;| )+/,6(h){d=h;H""});I(c.L==0)H d;H d+\'<17 1g="\'+b+\'">\'+c+"</17>"});H a}6 n(a,b){a.1e("\\n");O(K c="",d=0;d<50;d++)c+=" ";H a=v(a,6(h){I(h.1i("\\t")==-1)H h;O(K g=0;(g=h.1i("\\t"))!=-1;)h=h.1o(0,g)+c.1o(0,b-g%b)+h.1o(g+1,h.L);H h})}6 x(a){H a.Q(/^\\s+|\\s+$/g,"")}6 D(a,b){I(a.P<b.P)H-1;Y I(a.P>b.P)H 1;Y I(a.L<b.L)H-1;Y I(a.L>b.L)H 1;H 0}6 y(a,b){6 c(k){H k[0]}O(K d=N,h=[],g=b.2D?b.2D:c;(d=b.1I.X(a))!=N;){K i=g(d,b);I(1j i=="3f")i=[1f e.2L(i,d.P,b.23)];h=h.1O(i)}H h}6 E(a){K b=/(.*)((&1G;|&1y;).*)/;H a.Q(e.3A.3M,6(c){K d="",h=N;I(h=b.X(c)){c=h[1];d=h[2]}H\'<a 2h="\'+c+\'">\'+c+"</a>"+d})}6 z(){O(K a=1E.36("1k"),b=[],c=0;c<a.L;c++)a[c].3s=="20"&&b.U(a[c]);H b}6 f(a){a=a.1F;K b=p(a,".20",R);a=p(a,".3O",R);K c=1E.4i("3t");I(!(!a||!b||p(a,"3t"))){B(b.1c);r(b,"1m");O(K d=a.3G,h=[],g=0;g<d.L;g++)h.U(d[g].4z||d[g].4A);h=h.1K("\\r");c.39(1E.4D(h));a.39(c);c.2C();c.4C();w(c,"4u",6(){c.2G.4E(c);b.1l=b.1l.Q("1m","")})}}I(1j 3F!="1d"&&1j M=="1d")M=3F("M").M;K e={2v:{"1g-27":"","2i-1s":1,"2z-1s-2t":11,1M:N,1t:N,"42-45":R,"43-22":4,1u:R,16:R,"3V-17":R,2l:11,"41-40":R,2k:11,"1z-1k":11},13:{1W:"&2s;",2M:R,46:11,44:11,34:"4n",1x:{21:"4o 1m",2P:"?",1X:"1v\\n\\n",3E:"4r\'t 4t 1D O: ",4g:"4m 4B\'t 51 O 1z-1k 4F: ",37:\'<!4T 1z 4S "-//4V//3H 4W 1.0 4Z//4Y" "1Z://2y.3L.3K/4X/3I/3H/3I-4P.4J"><1z 4I="1Z://2y.3L.3K/4L/5L"><3J><4N 1Z-4M="5G-5M" 6K="2O/1z; 6J=6I-8" /><1t>6L 1v</1t></3J><3B 1L="25-6M:6Q,6P,6O,6N-6F;6y-2f:#6x;2f:#6w;25-22:6v;2O-3D:3C;"><T 1L="2O-3D:3C;3w-32:1.6z;"><T 1L="25-22:6A-6E;">1v</T><T 1L="25-22:.6C;3w-6B:6R;"><T>3v 3.0.76 (72 73 3x)</T><T><a 2h="1Z://3u.2w/1v" 1F="38" 1L="2f:#3y">1Z://3u.2w/1v</a></T><T>70 17 6U 71.</T><T>6T 6X-3x 6Y 6D.</T></T><T>6t 61 60 J 1k, 5Z <a 2h="6u://2y.62.2w/63-66/65?64=5X-5W&5P=5O" 1L="2f:#3y">5R</a> 5V <2R/>5U 5T 5S!</T></T></3B></1z>\'}},1Y:{2j:N,2A:{}},1U:{},3A:{6n:/\\/\\*[\\s\\S]*?\\*\\//2c,6m:/\\/\\/.*$/2c,6l:/#.*$/2c,6k:/"([^\\\\"\\n]|\\\\.)*"/g,6o:/\'([^\\\\\'\\n]|\\\\.)*\'/g,6p:1f M(\'"([^\\\\\\\\"]|\\\\\\\\.)*"\',"3z"),6s:1f M("\'([^\\\\\\\\\']|\\\\\\\\.)*\'","3z"),6q:/(&1y;|<)!--[\\s\\S]*?--(&1G;|>)/2c,3M:/\\w+:\\/\\/[\\w-.\\/?%&=:@;]*/g,6a:{18:/(&1y;|<)\\?=?/g,1b:/\\?(&1G;|>)/g},69:{18:/(&1y;|<)%=?/g,1b:/%(&1G;|>)/g},6d:{18:/(&1y;|<)\\s*1k.*?(&1G;|>)/2T,1b:/(&1y;|<)\\/\\s*1k\\s*(&1G;|>)/2T}},16:{1H:6(a){6 b(i,k){H e.16.2o(i,k,e.13.1x[k])}O(K c=\'<T 1g="16">\',d=e.16.2x,h=d.2X,g=0;g<h.L;g++)c+=(d[h[g]].1H||b)(a,h[g]);c+="</T>";H c},2o:6(a,b,c){H\'<2W><a 2h="#" 1g="6e 6h\'+b+" "+b+\'">\'+c+"</a></2W>"},2b:6(a){K b=a.1F,c=b.1l||"";b=B(p(b,".20",R).1c);K d=6(h){H(h=15(h+"6f(\\\\w+)").X(c))?h[1]:N}("6g");b&&d&&e.16.2x[d].2B(b);a.3N()},2x:{2X:["21","2P"],21:{1H:6(a){I(a.V("2l")!=R)H"";K b=a.V("1t");H e.16.2o(a,"21",b?b:e.13.1x.21)},2B:6(a){a=1E.6j(t(a.1c));a.1l=a.1l.Q("47","")}},2P:{2B:6(){K a="68=0";a+=", 18="+(31.30-33)/2+", 32="+(31.2Z-2Y)/2+", 30=33, 2Z=2Y";a=a.Q(/^,/,"");a=1P.6Z("","38",a);a.2C();K b=a.1E;b.6W(e.13.1x.37);b.6V();a.2C()}}}},35:6(a,b){K c;I(b)c=[b];Y{c=1E.36(e.13.34);O(K d=[],h=0;h<c.L;h++)d.U(c[h]);c=d}c=c;d=[];I(e.13.2M)c=c.1O(z());I(c.L===0)H d;O(h=0;h<c.L;h++){O(K g=c[h],i=a,k=c[h].1l,j=3W 0,l={},m=1f M("^\\\\[(?<2V>(.*?))\\\\]$"),s=1f M("(?<27>[\\\\w-]+)\\\\s*:\\\\s*(?<1T>[\\\\w-%#]+|\\\\[.*?\\\\]|\\".*?\\"|\'.*?\')\\\\s*;?","g");(j=s.X(k))!=N;){K o=j.1T.Q(/^[\'"]|[\'"]$/g,"");I(o!=N&&m.1A(o)){o=m.X(o);o=o.2V.L>0?o.2V.1e(/\\s*,\\s*/):[]}l[j.27]=o}g={1F:g,1n:C(i,l)};g.1n.1D!=N&&d.U(g)}H d},1M:6(a,b){K c=J.35(a,b),d=N,h=e.13;I(c.L!==0)O(K g=0;g<c.L;g++){b=c[g];K i=b.1F,k=b.1n,j=k.1D,l;I(j!=N){I(k["1z-1k"]=="R"||e.2v["1z-1k"]==R){d=1f e.4l(j);j="4O"}Y I(d=A(j))d=1f d;Y 6H;l=i.3X;I(h.2M){l=l;K m=x(l),s=11;I(m.1i("<![6G[")==0){m=m.4h(9);s=R}K o=m.L;I(m.1i("]]\\>")==o-3){m=m.4h(0,o-3);s=R}l=s?m:l}I((i.1t||"")!="")k.1t=i.1t;k.1D=j;d.2Q(k);b=d.2F(l);I((i.1c||"")!="")b.1c=i.1c;i.2G.74(b,i)}}},2E:6(a){w(1P,"4k",6(){e.1M(a)})}};e.2E=e.2E;e.1M=e.1M;e.2L=6(a,b,c){J.1T=a;J.P=b;J.L=a.L;J.23=c;J.1V=N};e.2L.Z.1q=6(){H J.1T};e.4l=6(a){6 b(j,l){O(K m=0;m<j.L;m++)j[m].P+=l}K c=A(a),d,h=1f e.1U.5Y,g=J,i="2F 1H 2Q".1e(" ");I(c!=N){d=1f c;O(K k=0;k<i.L;k++)(6(){K j=i[k];g[j]=6(){H h[j].1p(h,14)}})();d.28==N?1P.1X(e.13.1x.1X+(e.13.1x.4g+a)):h.2J.U({1I:d.28.17,2D:6(j){O(K l=j.17,m=[],s=d.2J,o=j.P+j.18.L,F=d.28,q,G=0;G<s.L;G++){q=y(l,s[G]);b(q,o);m=m.1O(q)}I(F.18!=N&&j.18!=N){q=y(j.18,F.18);b(q,j.P);m=m.1O(q)}I(F.1b!=N&&j.1b!=N){q=y(j.1b,F.1b);b(q,j.P+j[0].5Q(j.1b));m=m.1O(q)}O(j=0;j<m.L;j++)m[j].1V=c.1V;H m}})}};e.4j=6(){};e.4j.Z={V:6(a,b){K c=J.1n[a];c=c==N?b:c;K d={"R":R,"11":11}[c];H d==N?c:d},3Y:6(a){H 1E.4i(a)},4c:6(a,b){K c=[];I(a!=N)O(K d=0;d<a.L;d++)I(1j a[d]=="2m")c=c.1O(y(b,a[d]));H J.4e(c.6b(D))},4e:6(a){O(K b=0;b<a.L;b++)I(a[b]!==N)O(K c=a[b],d=c.P+c.L,h=b+1;h<a.L&&a[b]!==N;h++){K g=a[h];I(g!==N)I(g.P>d)1N;Y I(g.P==c.P&&g.L>c.L)a[b]=N;Y I(g.P>=c.P&&g.P<d)a[h]=N}H a},4d:6(a){K b=[],c=2u(J.V("2i-1s"));v(a,6(d,h){b.U(h+c)});H b},3U:6(a){K b=J.V("1M",[]);I(1j b!="2m"&&b.U==N)b=[b];a:{a=a.1q();K c=3W 0;O(c=c=1Q.6c(c||0,0);c<b.L;c++)I(b[c]==a){b=c;1N a}b=-1}H b!=-1},2r:6(a,b,c){a=["1s","6i"+b,"P"+a,"6r"+(b%2==0?1:2).1q()];J.3U(b)&&a.U("67");b==0&&a.U("1N");H\'<T 1g="\'+a.1K(" ")+\'">\'+c+"</T>"},3Q:6(a,b){K c="",d=a.1e("\\n").L,h=2u(J.V("2i-1s")),g=J.V("2z-1s-2t");I(g==R)g=(h+d-1).1q().L;Y I(3R(g)==R)g=0;O(K i=0;i<d;i++){K k=b?b[i]:h+i,j;I(k==0)j=e.13.1W;Y{j=g;O(K l=k.1q();l.L<j;)l="0"+l;j=l}a=j;c+=J.2r(i,k,a)}H c},49:6(a,b){a=x(a);K c=a.1e("\\n");J.V("2z-1s-2t");K d=2u(J.V("2i-1s"));a="";O(K h=J.V("1D"),g=0;g<c.L;g++){K i=c[g],k=/^(&2s;|\\s)+/.X(i),j=N,l=b?b[g]:d+g;I(k!=N){j=k[0].1q();i=i.1o(j.L);j=j.Q(" ",e.13.1W)}i=x(i);I(i.L==0)i=e.13.1W;a+=J.2r(g,l,(j!=N?\'<17 1g="\'+h+\' 5N">\'+j+"</17>":"")+i)}H a},4f:6(a){H a?"<4a>"+a+"</4a>":""},4b:6(a,b){6 c(l){H(l=l?l.1V||g:g)?l+" ":""}O(K d=0,h="",g=J.V("1D",""),i=0;i<b.L;i++){K k=b[i],j;I(!(k===N||k.L===0)){j=c(k);h+=u(a.1o(d,k.P-d),j+"48")+u(k.1T,j+k.23);d=k.P+k.L+(k.75||0)}}h+=u(a.1o(d),c()+"48");H h},1H:6(a){K b="",c=["20"],d;I(J.V("2k")==R)J.1n.16=J.1n.1u=11;1l="20";J.V("2l")==R&&c.U("47");I((1u=J.V("1u"))==11)c.U("6S");c.U(J.V("1g-27"));c.U(J.V("1D"));a=a.Q(/^[ ]*[\\n]+|[\\n]*[ ]*$/g,"").Q(/\\r/g," ");b=J.V("43-22");I(J.V("42-45")==R)a=n(a,b);Y{O(K h="",g=0;g<b;g++)h+=" ";a=a.Q(/\\t/g,h)}a=a;a:{b=a=a;h=/<2R\\s*\\/?>|&1y;2R\\s*\\/?&1G;/2T;I(e.13.46==R)b=b.Q(h,"\\n");I(e.13.44==R)b=b.Q(h,"");b=b.1e("\\n");h=/^\\s*/;g=4Q;O(K i=0;i<b.L&&g>0;i++){K k=b[i];I(x(k).L!=0){k=h.X(k);I(k==N){a=a;1N a}g=1Q.4q(k[0].L,g)}}I(g>0)O(i=0;i<b.L;i++)b[i]=b[i].1o(g);a=b.1K("\\n")}I(1u)d=J.4d(a);b=J.4c(J.2J,a);b=J.4b(a,b);b=J.49(b,d);I(J.V("41-40"))b=E(b);1j 2H!="1d"&&2H.3S&&2H.3S.1C(/5s/)&&c.U("5t");H b=\'<T 1c="\'+t(J.1c)+\'" 1g="\'+c.1K(" ")+\'">\'+(J.V("16")?e.16.1H(J):"")+\'<3Z 5z="0" 5H="0" 5J="0">\'+J.4f(J.V("1t"))+"<3T><3P>"+(1u?\'<2d 1g="1u">\'+J.3Q(a)+"</2d>":"")+\'<2d 1g="17"><T 1g="3O">\'+b+"</T></2d></3P></3T></3Z></T>"},2F:6(a){I(a===N)a="";J.17=a;K b=J.3Y("T");b.3X=J.1H(a);J.V("16")&&w(p(b,".16"),"5c",e.16.2b);J.V("3V-17")&&w(p(b,".17"),"56",f);H b},2Q:6(a){J.1c=""+1Q.5d(1Q.5n()*5k).1q();e.1Y.2A[t(J.1c)]=J;J.1n=C(e.2v,a||{});I(J.V("2k")==R)J.1n.16=J.1n.1u=11},5j:6(a){a=a.Q(/^\\s+|\\s+$/g,"").Q(/\\s+/g,"|");H"\\\\b(?:"+a+")\\\\b"},5f:6(a){J.28={18:{1I:a.18,23:"1k"},1b:{1I:a.1b,23:"1k"},17:1f M("(?<18>"+a.18.1m+")(?<17>.*?)(?<1b>"+a.1b.1m+")","5o")}}};H e}();1j 2e!="1d"&&(2e.1v=1v);',62,441,'||||||function|||||||||||||||||||||||||||||||||||||return|if|this|var|length|XRegExp|null|for|index|replace|true||div|push|getParam|call|exec|else|prototype||false|lastIndex|config|arguments|RegExp|toolbar|code|left|captureNames|slice|right|id|undefined|split|new|class|addToken|indexOf|typeof|script|className|source|params|substr|apply|toString|String|line|title|gutter|SyntaxHighlighter|_xregexp|strings|lt|html|test|OUTSIDE_CLASS|match|brush|document|target|gt|getHtml|regex|global|join|style|highlight|break|concat|window|Math|isRegExp|throw|value|brushes|brushName|space|alert|vars|http|syntaxhighlighter|expandSource|size|css|case|font|Fa|name|htmlScript|dA|can|handler|gm|td|exports|color|in|href|first|discoveredBrushes|light|collapse|object|cache|getButtonHtml|trigger|pattern|getLineHtml|nbsp|numbers|parseInt|defaults|com|items|www|pad|highlighters|execute|focus|func|all|getDiv|parentNode|navigator|INSIDE_CLASS|regexList|hasFlag|Match|useScriptTags|hasNamedCapture|text|help|init|br|input|gi|Error|values|span|list|250|height|width|screen|top|500|tagName|findElements|getElementsByTagName|aboutDialog|_blank|appendChild|charAt|Array|copyAsGlobal|setFlag|highlighter_|string|attachEvent|nodeName|floor|backref|output|the|TypeError|sticky|Za|iterate|freezeTokens|scope|type|textarea|alexgorbatchev|version|margin|2010|005896|gs|regexLib|body|center|align|noBrush|require|childNodes|DTD|xhtml1|head|org|w3|url|preventDefault|container|tr|getLineNumbersHtml|isNaN|userAgent|tbody|isLineHighlighted|quick|void|innerHTML|create|table|links|auto|smart|tab|stripBrs|tabs|bloggerMode|collapsed|plain|getCodeLinesHtml|caption|getMatchesHtml|findMatches|figureOutLineNumbers|removeNestedMatches|getTitleHtml|brushNotHtmlScript|substring|createElement|Highlighter|load|HtmlScript|Brush|pre|expand|multiline|min|Can|ignoreCase|find|blur|extended|toLowerCase|aliases|addEventListener|innerText|textContent|wasn|select|createTextNode|removeChild|option|same|frame|xmlns|dtd|twice|1999|equiv|meta|htmlscript|transitional|1E3|expected|PUBLIC|DOCTYPE|on|W3C|XHTML|TR|EN|Transitional||configured|srcElement|Object|after|run|dblclick|matchChain|valueOf|constructor|default|switch|click|round|execAt|forHtmlScript|token|gimy|functions|getKeywords|1E6|escape|within|random|sgi|another|finally|supply|MSIE|ie|toUpperCase|catch|returnValue|definition|event|border|imsx|constructing|one|Infinity|from|when|Content|cellpadding|flags|cellspacing|try|xhtml|Type|spaces|2930402|hosted_button_id|lastIndexOf|donate|active|development|keep|to|xclick|_s|Xml|please|like|you|paypal|cgi|cmd|webscr|bin|highlighted|scrollbars|aspScriptTags|phpScriptTags|sort|max|scriptScriptTags|toolbar_item|_|command|command_|number|getElementById|doubleQuotedString|singleLinePerlComments|singleLineCComments|multiLineCComments|singleQuotedString|multiLineDoubleQuotedString|xmlComments|alt|multiLineSingleQuotedString|If|https|1em|000|fff|background|5em|xx|bottom|75em|Gorbatchev|large|serif|CDATA|continue|utf|charset|content|About|family|sans|Helvetica|Arial|Geneva|3em|nogutter|Copyright|syntax|close|write|2004|Alex|open|JavaScript|highlighter|July|02|replaceChild|offset|83'.split('|'),0,{})) |