From c1b4760e568b786c36346cd0902d425d74868149 Mon Sep 17 00:00:00 2001 From: Marcos Lilljedahl Date: Fri, 20 Jan 2017 11:51:48 -0300 Subject: [PATCH] Initial commit --- .gitignore | 4 + .gitmodules | 0 CNAME | 1 + README.md | 37 + _config.yml | 54 + _includes/analytics.html | 11 + _includes/footer.html | 22 + _includes/head.html | 21 + _includes/header.html | 24 + _includes/main.scss | 46 + _includes/sidebar.html | 29 + _layouts/compress.html | 10 + _layouts/default.html | 50 + _layouts/page.html | 19 + _layouts/post.html | 51 + _posts/2016-09-09-go-docker.markdown | 483 ++ _posts/2017-01-15-webapps.markdown | 480 ++ _posts/2017-01-16-alpine.markdown | 114 + _posts/2017-01-17-setup.markdown | 39 + .../2017-01-19-how-to-write-go-code.markdown | 403 + _sass/_bootstrap-readable.scss | 6871 +++++++++++++++++ _sass/_custom.scss | 2 + _sass/_layout.scss | 142 + _sass/_syntax-highlighting.scss | 72 + _sass/component/_tag.scss | 63 + about.md | 10 + css/bootstrap.min.scss | 51 + css/syntax-highlighting.scss | 51 + css/xterm.css | 2206 ++++++ feed.xml | 30 + images/create-gh-pages-branch.JPG | Bin 0 -> 9503 bytes images/delete-github-branch-2.png | Bin 0 -> 6202 bytes images/delete-github-branch.png | Bin 0 -> 6165 bytes images/docker-go.png | Bin 0 -> 42218 bytes images/docker-logo.png | Bin 0 -> 47520 bytes images/facebook.svg | 1 + images/github.svg | 1 + images/gopher.png | Bin 0 -> 34156 bytes images/simple-logo.png | Bin 0 -> 17608 bytes images/twitter.svg | 1 + index.html | 73 + js/bootstrap.min.js | 7 + js/fit.js | 59 + js/sdk.js | 220 + js/xterm.js | 5160 +++++++++++++ tags.md | 29 + 46 files changed, 16947 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 CNAME create mode 100644 README.md create mode 100644 _config.yml create mode 100644 _includes/analytics.html create mode 100644 _includes/footer.html create mode 100644 _includes/head.html create mode 100644 _includes/header.html create mode 100644 _includes/main.scss create mode 100644 _includes/sidebar.html create mode 100644 _layouts/compress.html create mode 100644 _layouts/default.html create mode 100644 _layouts/page.html create mode 100644 _layouts/post.html create mode 100644 _posts/2016-09-09-go-docker.markdown create mode 100644 _posts/2017-01-15-webapps.markdown create mode 100644 _posts/2017-01-16-alpine.markdown create mode 100644 _posts/2017-01-17-setup.markdown create mode 100644 _posts/2017-01-19-how-to-write-go-code.markdown create mode 100644 _sass/_bootstrap-readable.scss create mode 100644 _sass/_custom.scss create mode 100644 _sass/_layout.scss create mode 100644 _sass/_syntax-highlighting.scss create mode 100644 _sass/component/_tag.scss create mode 100644 about.md create mode 100644 css/bootstrap.min.scss create mode 100644 css/syntax-highlighting.scss create mode 100644 css/xterm.css create mode 100644 feed.xml create mode 100644 images/create-gh-pages-branch.JPG create mode 100644 images/delete-github-branch-2.png create mode 100644 images/delete-github-branch.png create mode 100644 images/docker-go.png create mode 100644 images/docker-logo.png create mode 100644 images/facebook.svg create mode 100644 images/github.svg create mode 100644 images/gopher.png create mode 100644 images/simple-logo.png create mode 100644 images/twitter.svg create mode 100644 index.html create mode 100644 js/bootstrap.min.js create mode 100644 js/fit.js create mode 100644 js/sdk.js create mode 100644 js/xterm.js create mode 100644 tags.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0605938 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.vscode/ +_site/ +.sass-cache/ +.jekyll-metadata diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..e69de29 diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..f97610b --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +training.play-with-docker.com \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..da0eb5c --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +# Docker Tutorials and Labs + +This repo contains [Docker](https://docker.com) labs and tutorials authored both by Docker, and by members of the community. We welcome contributions and want to grow the repo. + +#### Docker tutorials: +* [Docker for beginners] (beginner/readme.md) +* [Docker Swarm Mode](swarm-mode/README.md) +* [Configuring developer tools and programming languages](developer-tools/README.md) + * Java + * [Live Debugging Java with Docker](developer-tools/java-debugging) + * [Docker for Java Developers](developer-tools/java/) + * Node.js + * [Live Debugging a Node.js application in Docker](developer-tools/nodejs-debugging) + * [Dockerizing a Node.js application](developer-tools/nodejs/porting/) +* [Docker for ASP.NET and Windows containers](windows/readme.md) +* [Building a 12 Factor app with Docker](12factor/README.md) +* [Docker Security](security/README.md) +* [Docker Networking](networking/) + + +#### Community tutorials +* [Docker Tutorials from the Community](https://github.com/docker/community/tree/master/Docker-Meetup-Content) - links to a different repository +* [Advanced Docker orchestration workshop] (https://github.com/docker/labs/tree/master/Docker-Orchestration) - links to a different repository + +For more information on Docker, see the Official [Docker documentation](https://docs.docker.com). + +#### Contributing + +We want to see this repo grow, so if you have a tutorial to submit, or contributions to existing tutorials, please see this guide: + +[Guide to submitting your own tutorial](contribute.md) + +# Running trainings site + +Clone the repo and run the following docker container: `docker run --rm --label=jekyll --volume=$(pwd):/srv/jekyll -it -p 4000:4000 jekyll/jekyll` + +Browser the site by visiting http://localhost:4000 diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..eee2b81 --- /dev/null +++ b/_config.yml @@ -0,0 +1,54 @@ +# Welcome to Jekyll! +# +# This config file is meant for settings that affect your whole blog, values +# which you are expected to set up once and rarely need to edit after that. +# For technical reasons, this file is *NOT* reloaded automatically when you use +# 'jekyll serve'. If you change this file, please restart the server process. + +# Site settings +title: PlayWithDocker class-room +email: +description: > # this means to ignore newlines until "baseurl:" + Play with docker class-room environment + + + +baseurl: # the subpath of your site, e.g. /blog +url: "http://marcosnils.github.io" # the base hostname & protocol for your site + +#sidebar +default-image: docker-logo.png # If there is no featured image in a post then this image will be showed. Also on all pages this image will be showed. Use a 500x250 image. + +#footer +built-by: PWD Team +copyright: + name: PWD + link: 'http://play-with-docker.com' + +# Build settings +markdown: kramdown +permalink: /:title/ +paginate: 6 +paginate_path: /page:num/ + +# Tracker +analytics: UA-83979019-1 + + +#social +facebook: https://www.facebook.com/docker.run +twitter: https://twitter.com/@docker +github: https://www.github.com/docker/labs + +#facebook like box +fb-app-id: 549480635219583 +fb-page-url: https://www.facebook.com/docker.run/ +fb-page-title: Docker + +# Sass style +sass: + style: compressed + +# Ruby Gems +gems: [jekyll-paginate] + diff --git a/_includes/analytics.html b/_includes/analytics.html new file mode 100644 index 0000000..a061f41 --- /dev/null +++ b/_includes/analytics.html @@ -0,0 +1,11 @@ + + \ No newline at end of file diff --git a/_includes/footer.html b/_includes/footer.html new file mode 100644 index 0000000..5e54626 --- /dev/null +++ b/_includes/footer.html @@ -0,0 +1,22 @@ + + diff --git a/_includes/head.html b/_includes/head.html new file mode 100644 index 0000000..3848764 --- /dev/null +++ b/_includes/head.html @@ -0,0 +1,21 @@ + + + + + +{% comment %} +{% seo %} +{% endcomment %} + + + + + + + + diff --git a/_includes/header.html b/_includes/header.html new file mode 100644 index 0000000..a63b2d4 --- /dev/null +++ b/_includes/header.html @@ -0,0 +1,24 @@ + diff --git a/_includes/main.scss b/_includes/main.scss new file mode 100644 index 0000000..d6a3f5e --- /dev/null +++ b/_includes/main.scss @@ -0,0 +1,46 @@ +// Our variables +$base-font-family: Georgia, "Times New Roman", Times, serif; +$base-font-size: 16px; +$base-font-weight: 400; +$small-font-size: $base-font-size * 0.875; +$base-line-height: 1.5; + +$spacing-unit: 30px; + +$text-color: #111; +$background-color: #fdfdfd; +$brand-color: #2a7ae2; + +$grey-color: #828282; +$grey-color-light: lighten($grey-color, 40%); +$grey-color-dark: darken($grey-color, 25%); + +// Width of the content area +$content-width: 800px; + +$on-palm: 600px; +$on-laptop: 800px; + + + +// Use media queries like this: +// @include media-query($on-palm) { +// .wrapper { +// padding-right: $spacing-unit / 2; +// padding-left: $spacing-unit / 2; +// } +// } +@mixin media-query($device) { + @media screen and (max-width: $device) { + @content; + } +} + + + +// Import partials from `sass_dir` (defaults to `_sass`) +@import + "layout", + "component/tag", + "custom" +; diff --git a/_includes/sidebar.html b/_includes/sidebar.html new file mode 100644 index 0000000..fa42a8a --- /dev/null +++ b/_includes/sidebar.html @@ -0,0 +1,29 @@ +
+
+ {% if page.img %} + {{page.title}} + {% else %} + Docker + {% endif %} +
+ + +
+

Recent articles

+
    + {% for post in site.posts limit:3 %} + +
  • +

    {{ post.title }}  {{ post.date | date_to_string }}

    +
  • + + {% endfor %} +
+
+ +
+ + +
+ +
diff --git a/_layouts/compress.html b/_layouts/compress.html new file mode 100644 index 0000000..3db753a --- /dev/null +++ b/_layouts/compress.html @@ -0,0 +1,10 @@ +--- +# Jekyll layout that compresses HTML +# v3.0.1 +# http://jch.penibelst.de/ +# © 2014–2015 Anatol Broder +# MIT License +--- + +{% capture _LINE_FEED %} +{% endcapture %}{% if site.compress_html.ignore.envs contains jekyll.environment %}{{ content }}{% else %}{% capture _content %}{{ content }}{% endcapture %}{% assign _profile = site.compress_html.profile %}{% if site.compress_html.endings == "all" %}{% assign _endings = "html head body li dt dd p rt rp optgroup option colgroup caption thead tbody tfoot tr td th" | split: " " %}{% else %}{% assign _endings = site.compress_html.endings %}{% endif %}{% for _element in _endings %}{% capture _end %}{% endcapture %}{% assign _content = _content | remove: _end %}{% endfor %}{% if _profile and _endings %}{% assign _profile_endings = _content | size | plus: 1 %}{% endif %}{% for _element in site.compress_html.startings %}{% capture _start %}<{{ _element }}>{% endcapture %}{% assign _content = _content | remove: _start %}{% endfor %}{% if _profile and site.compress_html.startings %}{% assign _profile_startings = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.comments == "all" %}{% assign _comments = "" | split: " " %}{% else %}{% assign _comments = site.compress_html.comments %}{% endif %}{% if _comments.size == 2 %}{% capture _comment_befores %}.{{ _content }}{% endcapture %}{% assign _comment_befores = _comment_befores | split: _comments.first %}{% for _comment_before in _comment_befores %}{% if forloop.first %}{% continue %}{% endif %}{% capture _comment_outside %}{% if _carry %}{{ _comments.first }}{% endif %}{{ _comment_before }}{% endcapture %}{% capture _comment %}{% unless _carry %}{{ _comments.first }}{% endunless %}{{ _comment_outside | split: _comments.last | first }}{% if _comment_outside contains _comments.last %}{{ _comments.last }}{% assign _carry = false %}{% else %}{% assign _carry = true %}{% endif %}{% endcapture %}{% assign _content = _content | remove_first: _comment %}{% endfor %}{% if _profile %}{% assign _profile_comments = _content | size | plus: 1 %}{% endif %}{% endif %}{% assign _pre_befores = _content | split: "" %}{% assign _pres_after = "" %}{% if _pres.size != 0 %}{% if site.compress_html.blanklines %}{% assign _lines = _pres.last | split: _LINE_FEED %}{% assign _lastchar = _pres.last | split: "" | last %}{% assign _outerloop = forloop %}{% capture _pres_after %}{% for _line in _lines %}{% assign _trimmed = _line | split: " " | join: " " %}{% if forloop.last and _lastchar == _LINE_FEED %}{% unless _outerloop.last %}{{ _LINE_FEED }}{% endunless %}{% continue %}{% endif %}{% if _trimmed != empty or forloop.last %}{% unless forloop.first %}{{ _LINE_FEED }}{% endunless %}{{ _line }}{% endif %}{% endfor %}{% endcapture %}{% else %}{% assign _pres_after = _pres.last | split: " " | join: " " %}{% endif %}{% endif %}{% capture _content %}{{ _content }}{% if _pre_before contains "" %}{% endif %}{% unless _pre_before contains "" and _pres.size == 1 %}{{ _pres_after }}{% endunless %}{% endcapture %}{% endfor %}{% if _profile %}{% assign _profile_collapse = _content | size | plus: 1 %}{% endif %}{% if site.compress_html.clippings == "all" %}{% assign _clippings = "html head title base link meta style body article section nav aside h1 h2 h3 h4 h5 h6 hgroup header footer address p hr blockquote ol ul li dl dt dd figure figcaption main div table caption colgroup col tbody thead tfoot tr td th" | split: " " %}{% else %}{% assign _clippings = site.compress_html.clippings %}{% endif %}{% for _element in _clippings %}{% assign _edges = " ;; ;" | replace: "e", _element | split: ";" %}{% assign _content = _content | replace: _edges[0], _edges[1] | replace: _edges[2], _edges[3] | replace: _edges[4], _edges[5] %}{% endfor %}{% if _profile and _clippings %}{% assign _profile_clippings = _content | size | plus: 1 %}{% endif %}{{ _content }}{% if _profile %}
Step Bytes
raw {{ content | size }}{% if _profile_endings %}
endings {{ _profile_endings }}{% endif %}{% if _profile_startings %}
startings {{ _profile_startings }}{% endif %}{% if _profile_comments %}
comments {{ _profile_comments }}{% endif %}{% if _profile_collapse %}
collapse {{ _profile_collapse }}{% endif %}{% if _profile_clippings %}
clippings {{ _profile_clippings }}{% endif %}
{% endif %}{% endif %} diff --git a/_layouts/default.html b/_layouts/default.html new file mode 100644 index 0000000..58e3912 --- /dev/null +++ b/_layouts/default.html @@ -0,0 +1,50 @@ + + + + + {% include head.html %} + + + + {% include header.html %} + + {{ content }} + + {% include footer.html %} + + + + + + + + + + + + {% if site.analytics %}{% include analytics.html %}{% endif %} + + + diff --git a/_layouts/page.html b/_layouts/page.html new file mode 100644 index 0000000..daa814a --- /dev/null +++ b/_layouts/page.html @@ -0,0 +1,19 @@ +--- +layout: default +--- +
+
+
+ +
+

{{ page.title }}

+
+ +
+ {{ content }} +
+ +
+
+{% include sidebar.html %} +
diff --git a/_layouts/post.html b/_layouts/post.html new file mode 100644 index 0000000..605d27e --- /dev/null +++ b/_layouts/post.html @@ -0,0 +1,51 @@ +--- +layout: default +--- +
+ +
+
+ +
+

{{ page.title }}

+ + +
+ +
+ {{ content }} +
+ +
+ +
+ +
+ +
+ +
+
+ +
+
+
+ + + diff --git a/_posts/2016-09-09-go-docker.markdown b/_posts/2016-09-09-go-docker.markdown new file mode 100644 index 0000000..710589a --- /dev/null +++ b/_posts/2016-09-09-go-docker.markdown @@ -0,0 +1,483 @@ +--- +layout: post +title: "Go + Docker = ♥" +date: 2016-09-09 10:51:47 +0530 +author: "Jérôme Petazzoni (jpetazzo)" +tags: [docker, golang] +categories: docker go +img: "docker-go.png" +--- + +This is a short collection of tips and tricks showing how Docker +can be useful when working with Go code. For instance, I'll show +you how to compile Go code with different versions of the Go +toolchain, how to cross-compile to a different platform (and test +the result!), or how to produce really small container images. + +The following article assumes that you have Docker installed on +your system. It doesn't have to be a recent version (we're not +going to use any fancy feature here). + + +## Go without `go` + +*... And by that, we mean "Go without installing `go`".* + +If you write Go code, or if you have even the slightest interest +into the Go language, you certainly have the Go compiler and toolchain installed, +so you might be wondering "what's the point?"; but there are +a few scenarios where you want to compile Go without installing Go. + +* You still have this old Go 1.2 on your machine (that you can't + or won't upgrade), and you have to work on this codebase that + requires a newer version of the toolchain. +* You want to play with cross compilation features of Go 1.5 + (for instance, to make sure that you can create OS X binaries + from a Linux system). +* You want to have multiple versions of Go side-by-side, but don't + want to completely litter your system. +* You want to be 100% sure that your project and all its dependencies + download, build, and run fine on a clean system. + +If any of this is relevant to you, then let's call Docker to the rescue! + + +### Compiling a program in a container + +When you have installed Go, you can do `go get -v github.com/user/repo` +to download, build, and install a library. (The `-v` flag is just +here for verbosity, you can remove it if you prefer your +toolchain to be swift and silent!) + +You can also do `go get github.com/user/repo/...` (yes, that's +three dots) to download, build, and install all the things in +that repo (including libraries and binaries). + +We can do that in a container! + +Try this: + +```.term +docker run golang go get -v github.com/golang/example/hello/... +``` + +This will pull the `golang` image (unless you have it already; +then it will start right away), and create a container based on +that image. In that container, `go` will download a little +"hello world" example, build it, and install it. But it will +install it in the container ... So how do we run that program now? + + +### Running our program in a container + +One solution is to *commit* the container that we just built, +i.e. "freeze" it into a new image: + +```.term +docker commit $(docker ps -lq) awesomeness +``` + +Note: `docker ps -lq` outputs the ID (and only the ID!) of +the last container that was executed. If you are the only +uesr on your machine, and if you haven't created another +container since the previous command, that container +should be the one in which we just built the "hello world" +example. + +Now, we can run our program in a container based on +the image that we just built: + +```.term +docker run awesomeness hello +``` + +The output should be `Hello, Go examples!`. + + +#### Bonus points + +When creating the image with `docker commit`, you can +use the `--change` flag to specify arbitrary [Dockerfile]( +https://docs.docker.com/engine/reference/builder/) commands. +For instance, you could use a `CMD` or `ENTRYPOINT` command +so that `docker run awesomeness` automatically executes +`hello`. + + +### Running in a throwaway container + +What if we don't want to create an extra image just to +run this Go program? + +We got you covered: + +```.term +docker run --rm golang sh -c \ + "go get github.com/golang/example/hello/... && exec hello" +``` + +Wait a minute, what are all those bells and whistles? + +* `--rm` tells to the Docker CLI to automatically issue a + `docker rm` command once the container exits. That way, + we don't leave anything behind ourselves. +* We chain together the build step (`go get`) and the + execution step (`exec hello`) using the shell logical + operator `&&`. If you're not a shell aficionado, `&&` + means "and". It will run the first part `go get...`, + and if (and only if!) that part is successful, it will run + the second part (`exec hello`). If you wonder why this + is like that: it works like a lazy `and` evaluator, + which needs to evaluate the right hand side + only if the left hand side evaluates to `true`. +* We pass our commands to `sh -c`, because if we were to + simply do `docker run golang "go get ... && hello"`, + Docker would try to execute the program named `go SPACE get + SPACE etc.` and that wouldn't work. So instead, we start + a shell and instruct the shell to execute the command + sequence. +* We use `exec hello` instead of `hello`: this will replace + the current process (the shell that we started) with the + `hello` program. This ensures that `hello` will be PID 1 + in the container, instead of having the shell as PID 1 + and `hello` as a child process. This is totally useless + for this tiny example, but when we will run more useful + programs, this will allow them to receive external signals + properly, since external signals are delivered to PID 1 of + the container. What kind of signal, you might be wondering? + A good example is `docker stop`, which sends `SIGTERM` to + PID 1 in the container. + + +### Using a different version of Go + +When you use the `golang` image, Docker expands that to +`golang:latest`, which (as you might guess) will map to +the latest version available on the Docker Hub. + +If you want to use a specific version of Go, that's very +easy: specify that version as a *tag* after the image name. + +For instance, to use Go 1.5, change the example above +to replace `golang` with `golang:1.5`: + +```.term +docker run --rm golang:1.5 sh -c \ + "go get github.com/golang/example/hello/... && exec hello" +``` + +You can see all the versions (and variants) available on the +[Golang image page](https://hub.docker.com/r/library/golang/tags/) +on the Docker Hub. + + +### Installing on our system + +OK, so what if we want to run the compiled program on our +system, instead of in a container? + +We could copy the compiled binary out of the container. +Note, however, that this will work only if our container +architecture matches our host architecture; in other words, +if we run Docker on Linux. (I'm leaving out people who +might be running Windows Containers!) + +The easiest way to get the binary out of the container +is to map the `$GOPATH/bin` directory to a local directory. +In the `golang` container, `$GOPATH` is `/go`. So we can do +the following: + +```.term +docker run -v /tmp/bin:/go/bin \ + golang go get github.com/golang/example/hello/... +/tmp/bin/hello +``` + +If you are on Linux, you should see the `Hello, Go examples!` message. +But if you are, for instance, on a Mac, you will probably see: + +```.term +/tmp/test/hello: cannot execute binary file +``` + +What can we do about it? + + +### Cross-compilation + +Go 1.5 comes with [outstanding out-of-the-box cross-compilation abilities]( +http://dave.cheney.net/2015/08/22/cross-compilation-with-go-1-5), so if your +container operating system and/or architecture doesn't match your system's, +it's no problem at all! + +To enable cross-compilation, you need to set `GOOS` and/or `GOARCH`. + +For instance, assuming that you are on a 64 bits Mac: + +```.term +docker run -e GOOS=darwin -e GOARCH=amd64 -v /tmp/crosstest:/go/bin \ + golang go get github.com/golang/example/hello/... +``` + +The output of cross-compilation is not directly in `$GOPATH/bin`, +but in `$GOPATH/bin/$GOOS_$GOARCH`. In other words, to run the +program, you have to execute `/tmp/crosstest/darwin_amd64/hello`. + + +### Installing straight to the `$PATH` + +If you are on Linux, you can even install directly to your system +`bin` directories: + +```.term +docker run -v /usr/local/bin:/go/bin \ + golang get github.com/golang/example/hello/... +``` + +However, on a Mac, trying to use `/usr` as a volume will not +mount your Mac's filesystem to the container. It will mount +the `/usr` directory of the Moby VM (the small Linux VM +hidden behind the Docker whale icon in your toolbar). + +You can, however, use `/tmp` or something in your home +directory, and then copy it from there. + + +## Building lean images + +The Go binaries that we produced with this technique are +*statically linked*. This means that they embed all the code +that they need to run, including all dependencies. This +contrasts with *dynamically linked* programs, which don't +contain some basic libraries (like the "libc") and use a system-wide +copy which is resolved at run time. + +This means that we can drop our Go compiled program in +a container, *without anything else*, and it should work. + +Let's try this! + + +### The `scratch` image + +There is a special image in the Docker ecosystem: `scratch`. +This is an empty image. It doesn't need to be created or +downloaded, since by definition, it is empty. + +Let's create a new, empty directory for our new Go lean image. + +In this new directory, create the following Dockerfile: + +```dockerfile +FROM scratch +COPY ./hello /hello +ENTRYPOINT ["/hello"] +``` + +This means: +* start *from scratch* (an empty image), +* add the `hello` file to the root of the image, +* define this `hello` program to be the default thing to execute + when starting this container. + +Then, produce our `hello` binary as follows: + +```.term +docker run -v $(pwd):/go/bin --rm \ + golang go get github.com/golang/example/hello/... +``` + +Note: we don't need to set `GOOS` and `GOARCH` here, because +precisely, we want a binary that will run *in a Docker container*, +not on our host system. So leave those variables alone! + +Then, we can build the image: + +```.term +docker build -t hello . +``` + +And test it: + +```.term +docker run hello +``` + +(This should display `Hello, Go examples!`.) + +Last but not least, check the image's size: + +```.term +docker images hello +``` + +If we did everything right, this image should be about 2 MB. Not bad! + + +### Building something without pushing to GitHub + +Of course, if we had to push to GitHub each time we wanted to compile, +we would waste a lot of time. + +When you want to work on a piece of code and build it within a container, +you can mount a local directory to `/go` in the `golang` container, so that the +`$GOPATH` is persisted across invocations: `docker run -v $HOME/go:/go golang ...`. + +But you can also mount local directories to specific paths, to "override" some +packages (the ones that you have edited locally). Here is a complete example: + +```.term +# Adapt the two following environment variables if you are not running on a Mac +export GOOS=darwin GOARCH=amd64 +mkdir go-and-docker-is-love +cd go-and-docker-is-love +git clone git://github.com/golang/example +cat example/hello/hello.go +sed -i .bak s/olleH/eyB/ example/hello/hello.go +docker run --rm \ + -v $(pwd)/example:/go/src/github.com/golang/example \ + -v $(pwd):/go/bin/${GOOS}_${GOARCH} \ + -e GOOS -e GOARCH \ + golang go get github.com/golang/example/hello/... +./hello +# Should display "Bye, Go examples!" +``` + + +## The special case of the `net` package and CGo + +Before diving into real-world Go code, we have to confess something: +we lied a little bit about the static binaries. If you are using CGo, +or if you are using the `net` package, the Go linker will generate +a dynamic binary. In the case of the `net` package (which a *lot* +of useful Go programs out there are using indeed!), the main culprit +is the DNS resolver. Most systems out there have a fancy, modular name +resolution system (like the *Name Service Switch*) which relies on +plugins which are, technically, dynamic libraries. By default, +Go will try to use that; and to do so, it will produce dynamic +libraries. + +How do we work around that? + + +### Re-using another distro's libc + +One solution is to use a base image that *has* the essential +libraries needed by those Go programs to function. Almost any +"regular" Linux distro based on the GNU libc will do the trick. +So instead of `FROM scratch`, you would use `FROM debian` or +`FROM fedora`, for instance. The resulting image will be much +bigger now; but at least, the bigger bits will be shared with +other images on your system. + +Note: you *cannot* use Alpine +in that case, since Alpine is using the musl library instead +of the GNU libc. + + +### Bring your own libc + +Another solution is to surgically extract the files needed, +and place them in your container with `COPY`. The resulting +container will be small. However, this extraction process +leaves the author with the uneasy impression of a really +dirty job, and they would rather not go into more details. + +If you want to see for yourself, look around `ldd` and the +Name Service Switch plugins mentioned earlier. + + +### Producing static binaries with `netgo` + +We can also instruct Go to *not* use the system's libc, and +substitute Go's `netgo` library, which comes with a native +DNS resolver. + +To use it, just add `-tags netgo -installsuffix netgo` to +the `go get` options. + +- `-tags netgo` instructs the toolchain to use netgo. +* `-installsuffix netgo` will make sure that the resulting + libraries (if any) are placed in a different, non-default + directory. This will avoid conflicts between code built + with and without netgo, if you do multiple `go get` + (or `go build`) invocations. If you build in containers + like we have shown so far, this is not strictly necessary, + since there will be no other Go code compiled in this + container, ever; but it's a good idea to get used to it, + or at least know that this flag exists. + + +## The special case of SSL certificates + +There is one more thing that you have to worry about if +your code has to validate SSL certificates; for instance +if it will connect to external APIs over HTTPS. In that +case, you need to put the root certificates in your +container too, because Go won't bundle those into your +binary. + + +### Installing the SSL certificates + +Three again, there are multiple options available, but +the easiest one is to use a package from an existing +distribution. + +Alpine is a good candidate here because it's so tiny. +The following `Dockerfile` will give you a base image +that is small, but has an up-to-date bundle of root +certificates: + +```dockerfile +FROM alpine:3.4 +RUN apk add --no-cache ca-certificates apache2-utils +``` + +Check it out; the resulting image is only 6 MB! + +Note: the `--no-cache` option tells `apk` (the Alpine +package manager) to get the list of available packages +from Alpine's distribution mirrors, without saving it +to disk. You might have seen Dockerfiles doing something +like `apt-get update && apt-get install ... && rm -rf /var/cache/apt/*`; +this achieves something equivalent (i.e. not leave package +caches in the final image) with a single flag. + +*As an added bonus,* putting your application in a container +based on the Alpine image gives you access to a ton of really +useful tools: now you can drop a shell into your container +and poke around while it's running, if you need to! + + +## Wrapping it up + +We saw how Docker can help us to compile Go code in a clean, +isolated environment; how to use different versions of the +Go toolchain; and how to cross-compile between different +operating systems and platforms. + +We also saw how Go can help us to build small, lean container +images for Docker, and described a number of associated +subtleties linked (no pun intended) to static libraries +and network dependencies. + +Beyond the fact that Go is really good fit for a project +that Docker, we hope that we showed you how Go and Docker +can benefit from each other and work really well together! + + +### Acknowledgements + +This was initially presented during the hack day at GopherCon 2016. + +I would like to thank all the people who proofread this material +and gave ideas and suggestions to make it better; including but +not limited to: + +- Aaron Lehmann +- Stephen Day +- AJ Bowen + +All mistakes and typos are my own; all the good stuff is theirs! ☺ + diff --git a/_posts/2017-01-15-webapps.markdown b/_posts/2017-01-15-webapps.markdown new file mode 100644 index 0000000..5814923 --- /dev/null +++ b/_posts/2017-01-15-webapps.markdown @@ -0,0 +1,480 @@ +--- +layout: post +title: "WebApps" +date: 2017-01-15 10:51:47 +0530 +categories: webapps +tags: [docker, webapp] +--- +## 2.0 Webapps with Docker +Great! So you have now looked at `docker run`, played with a Docker container and also got the hang of some terminology. Armed with all this knowledge, you are now ready to get to the real stuff — deploying web applications with Docker. + +### 2.1 Run a static website in a container +>**Note:** Code for this section is in this repo in the [static-site directory](https://github.com/docker/labs/tree/master/beginner/static-site). + +Let's start by taking baby-steps. First, we'll use Docker to run a static website in a container. The website is based on an existing image. We'll pull a Docker image from Docker Hub, run the container, and see how easy it is to set up a web server. + +The image that you are going to use is a single-page website that was already created for this demo and is available on the Docker Hub as [`seqvence/static-site`](https://hub.docker.com/r/seqvence/static-site/). You can download and run the image directly in one go using `docker run` as follows. + +```.term +docker run -d seqvence/static-site +``` + +>**Note:** The current version of this image doesn't run without the `-d` flag. The `-d` flag enables **detached mode**, which detaches the running container from the terminal/shell and returns your prompt after the container starts. We are debugging the problem with this image but for now, use `-d` even for this first example. + +So, what happens when you run this command? + +Since the image doesn't exist on your Docker host, the Docker daemon first fetches it from the registry and then runs it as a container. + +Now that the server is running, do you see the website? What port is it running on? And more importantly, how do you access the container directly from our host machine? + +Actually, you probably won't be able to answer any of these questions yet! ☺ In this case, the client didn't tell the Docker Engine to publish any of the ports, so you need to re-run the `docker run` command to add this instruction. + +Let's re-run the command with some new flags to publish ports and pass your name to the container to customize the message displayed. We'll use the *-d* option again to run the container in detached mode. + +First, stop the container that you have just launched. In order to do this, we need the container ID. + +Since we ran the container in detached mode, we don't have to launch another terminal to do this. Run `docker ps` to view the running containers. + +```.term +docker ps +``` +``` +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +a7a0e504ca3e seqvence/static-site "/bin/sh -c 'cd /usr/" 28 seconds ago Up 26 seconds 80/tcp, 443/tcp stupefied_mahavira +``` + +Check out the `CONTAINER ID` column. You will need to use this `CONTAINER ID` value, a long sequence of characters, to identify the container you want to stop, and then to remove it. The example below provides the `CONTAINER ID` on our system; you should use the value that you see in your terminal. +``` +$ docker stop a7a0e504ca3e +$ docker rm a7a0e504ca3e +``` + +>**Note:** A cool feature is that you do not need to specify the entire `CONTAINER ID`. You can just specify a few starting characters and if it is unique among all the containers that you have launched, the Docker client will intelligently pick it up. + +Now, let's launch a container in **detached** mode as shown below: + +```.term +docker run --name static-site -e AUTHOR="Your Name" -d -P seqvence/static-site +``` +``` +e61d12292d69556eabe2a44c16cbd54486b2527e2ce4f95438e504afb7b02810 +``` + +In the above command: + +* `-d` will create a container with the process detached from our terminal +* `-P` will publish all the exposed container ports to random ports on the Docker host +* `-e` is how you pass environment variables to the container +* `--name` allows you to specify a container name +* `AUTHOR` is the environment variable name and `Your Name` is the value that you can pass + +Now you can see the ports by running the `docker port` command. + +```.term +docker port static-site +``` +``` +443/tcp -> 0.0.0.0:32772 +80/tcp -> 0.0.0.0:32773 +``` + +If you are running [Docker for Mac](https://docs.docker.com/docker-for-mac/), [Docker for Windows](https://docs.docker.com/docker-for-windows/), or Docker on Linux, you can open `http://localhost:[YOUR_PORT_FOR 80/tcp]`. For our example this is `http://localhost:32773`. + +If you are using Docker Machine on Mac or Windows, you can find the hostname on the command line using `docker-machine` as follows (assuming you are using the `default` machine). + +``` +$ docker-machine ip default +192.168.99.100 +``` +You can now open `http://:[YOUR_PORT_FOR 80/tcp]` to see your site live! For our example, this is: `http://192.168.99.100:32773`. + +You can also run a second webserver at the same time, specifying a custom host port mapping to the container's webserver. + +```.term +docker run --name static-site-2 -e AUTHOR="Your Name" -d -p 8888:80 seqvence/static-site +``` + + +To deploy this on a real server you would just need to install Docker, and run the above `docker` command(as in this case you can see the `AUTHOR` is Docker which we passed as an environment variable). + +Now that you've seen how to run a webserver inside a Docker container, how do you create your own Docker image? This is the question we'll explore in the next section. + +But first, let's stop and remove the containers since you won't be using them anymore. + +```.term +docker stop static-site +``` +```.term +docker rm static-site +``` + +Let's use a shortcut to remove the second site: + +```.term +docker rm -f static-site-2 +``` + +Run `docker ps` to make sure the containers are gone. +```.term +docker ps +``` +``` +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +``` + +### 2.2 Docker Images + +In this section, let's dive deeper into what Docker images are. You will build your own image, use that image to run an application locally, and finally, push some of your own images to Docker Hub. + +Docker images are the basis of containers. In the previous example, you **pulled** the *seqvence/static-site* image from the registry and asked the Docker client to run a container **based** on that image. To see the list of images that are available locally on your system, run the `docker images` command. + +```.term +docker images +``` +``` +REPOSITORY TAG IMAGE ID CREATED SIZE +seqvence/static-site latest 92a386b6e686 2 hours ago 190.5 MB +nginx latest af4b3d7d5401 3 hours ago 190.5 MB +python 2.7 1c32174fd534 14 hours ago 676.8 MB +postgres 9.4 88d845ac7a88 14 hours ago 263.6 MB +containous/traefik latest 27b4e0c6b2fd 4 days ago 20.75 MB +node 0.10 42426a5cba5f 6 days ago 633.7 MB +redis latest 4f5f397d4b7c 7 days ago 177.5 MB +mongo latest 467eb21035a8 7 days ago 309.7 MB +alpine 3.3 70c557e50ed6 8 days ago 4.794 MB +java 7 21f6ce84e43c 8 days ago 587.7 MB +``` + +Above is a list of images that I've pulled from the registry and those I've created myself (we'll shortly see how). You will have a different list of images on your machine. The `TAG` refers to a particular snapshot of the image and the `ID` is the corresponding unique identifier for that image. + +For simplicity, you can think of an image akin to a git repository - images can be [committed](https://docs.docker.com/engine/reference/commandline/commit/) with changes and have multiple versions. When you do not provide a specific version number, the client defaults to `latest`. + +For example you could pull a specific version of `ubuntu` image as follows: + +```.term +docker pull ubuntu:12.04 +``` + +If you do not specify the version number of the image then, as mentioned, the Docker client will default to a version named `latest`. + +So for example, the `docker pull` command given below will pull an image named `ubuntu:latest`: + +```.term +docker pull ubuntu +``` + +To get a new Docker image you can either get it from a registry (such as the Docker Hub) or create your own. There are hundreds of thousands of images available on [Docker hub](https://hub.docker.com). You can also search for images directly from the command line using `docker search`. + +An important distinction with regard to images is between _base images_ and _child images_. + +- **Base images** are images that have no parent images, usually images with an OS like ubuntu, alpine or debian. + +- **Child images** are images that build on base images and add additional functionality. + +Another key concept is the idea of _official images_ and _user images_. (Both of which can be base images or child images.) + +- **Official images** are Docker sanctioned images. Docker, Inc. sponsors a dedicated team that is responsible for reviewing and publishing all Official Repositories content. This team works in collaboration with upstream software maintainers, security experts, and the broader Docker community. These are not prefixed by an organization or user name. In the list of images above, the `python`, `node`, `alpine` and `nginx` images are official (base) images. To find out more about them, check out the [Official Images Documentation](https://docs.docker.com/docker-hub/official_repos/). + +- **User images** are images created and shared by users like you. They build on base images and add additional functionality. Typically these are formatted as `user/image-name`. The `user` value in the image name is your Docker Hub user or organization name. + +### 2.3 Create your first image +>**Note:** The code for this section is in this repository in the [flask-app](https://github.com/docker/labs/tree/master/beginner/flask-app) directory. + +Now that you have a better understanding of images, it's time to create your own. Our goal here is to create an image that sandboxes a small [Flask](http://flask.pocoo.org) application. + +**The goal of this exercise is to create a Docker image which will run a Flask app.** + +We'll do this by first pulling together the components for a random cat picture generator built with Python Flask, then _dockerizing_ it by writing a _Dockerfile_. Finally, we'll build the image, and then run it. + +- [Create a Python Flask app that displays random cat pix](#231-create-a-python-flask-app-that-displays-random-cat-pix) +- [Write a Dockerfile](#232-write-a-dockerfile) +- [Build the image](#233-build-the-image) +- [Run your image](#234-run-your-image) +- [Dockerfile commands summary](#235-dockerfile-commands-summary) + +### 2.3.1 Create a Python Flask app that displays random cat pix + +For the purposes of this workshop, we've created a fun little Python Flask app that displays a random cat `.gif` every time it is loaded - because, you know, who doesn't like cats? + +Start by creating a directory called ```flask-app``` where we'll create the following files: + +- [app.py](#apppy) +- [requirements.txt](#requirementstxt) +- [templates/index.html](#templatesindexhtml) +- [Dockerfile](#dockerfile) + +Make sure to ```cd flask-app``` before you start creating the files, because you don't want to start adding a whole bunch of other random files to your image. + +#### app.py +Create the **app.py** with the following content: + +``` +from flask import Flask, render_template +import random + +app = Flask(__name__) + +# list of cat images +images = [ + "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26388-1381844103-11.gif", + "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr01/15/9/anigif_enhanced-buzz-31540-1381844535-8.gif", + "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26390-1381844163-18.gif", + "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/10/anigif_enhanced-buzz-1376-1381846217-0.gif", + "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr03/15/9/anigif_enhanced-buzz-3391-1381844336-26.gif", + "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/10/anigif_enhanced-buzz-29111-1381845968-0.gif", + "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr03/15/9/anigif_enhanced-buzz-3409-1381844582-13.gif", + "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr02/15/9/anigif_enhanced-buzz-19667-1381844937-10.gif", + "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr05/15/9/anigif_enhanced-buzz-26358-1381845043-13.gif", + "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/9/anigif_enhanced-buzz-18774-1381844645-6.gif", + "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr06/15/9/anigif_enhanced-buzz-25158-1381844793-0.gif", + "http://ak-hdl.buzzfed.com/static/2013-10/enhanced/webdr03/15/10/anigif_enhanced-buzz-11980-1381846269-1.gif" +] + +@app.route('/') +def index(): + url = random.choice(images) + return render_template('index.html', url=url) + +if __name__ == "__main__": + app.run(host="0.0.0.0") +``` +#### requirements.txt +In order to install the Python modules required for our app, we need to create a file called **requirements.txt** and add the following line to that file: + +``` +Flask==0.10.1 +``` +#### templates/index.html +Create a directory called `templates` and create an **index.html** file in that directory with the following content in it: + +``` + + + + + +
+

Cat Gif of the day

+ +

Courtesy: Buzzfeed

+
+ + +``` +### 2.3.2 Write a Dockerfile +We want to create a Docker image with this web app. As mentioned above, all user images are based on a _base image_. Since our application is written in Python, we will build our own Python image based on [Alpine](https://hub.docker.com/_/alpine/). We'll do that using a **Dockerfile**. + +A [Dockerfile](https://docs.docker.com/engine/reference/builder/) is a text file that contains a list of commands that the Docker daemon calls while creating an image. The Dockerfile contains all the information that Docker needs to know to run the app — a base Docker image to run from, location of your project code, any dependencies it has, and what commands to run at start-up. It is simple way to automate the image creation process. The best part is that the [commands](https://docs.docker.com/engine/reference/builder/) you write in a Dockerfile are *almost* identical to their equivalent Linux commands. This means you don't really have to learn new syntax to create your own Dockerfiles. + + +1. Create a file called **Dockerfile**, and add content to it as described below. + + We'll start by specifying our base image, using the `FROM` keyword: + + ``` + FROM alpine:latest + ``` + +2. The next step usually is to write the commands of copying the files and installing the dependencies. But first we will install the Python pip package to the alpine linux distribution. This will not just install the pip package but any other dependencies too, which includes the python interpreter. Add the following [RUN](https://docs.docker.com/engine/reference/builder/#run) command next: + ``` + RUN apk add --update py2-pip + ``` + +3. Let's add the files that make up the Flask Application. + + Install all Python requirements for our app to run. This will be accomplished by adding the lines: + + ``` + COPY requirements.txt /usr/src/app/ + RUN pip install --no-cache-dir -r /usr/src/app/requirements.txt + ``` + + Copy the files you have created earlier into our image by using [COPY](https://docs.docker.com/engine/reference/builder/#copy) command. + + ``` + COPY app.py /usr/src/app/ + COPY templates/index.html /usr/src/app/templates/ + ``` + +4. Specify the port number which needs to be exposed. Since our flask app is running on `5000` that's what we'll expose. + ``` + EXPOSE 5000 + ``` + +5. The last step is the command for running the application which is simply - `python ./app.py`. Use the [CMD](https://docs.docker.com/engine/reference/builder/#cmd) command to do that: + + ``` + CMD ["python", "/usr/src/app/app.py"] + ``` + + The primary purpose of `CMD` is to tell the container which command it should run by default when it is started. + +6. Verify your Dockerfile. + + Our `Dockerfile` is now ready. This is how it looks: + + ``` + # our base image + FROM alpine:latest + + # Install python and pip + RUN apk add --update py2-pip + + # install Python modules needed by the Python app + COPY requirements.txt /usr/src/app/ + RUN pip install --no-cache-dir -r /usr/src/app/requirements.txt + + # copy files required for the app to run + COPY app.py /usr/src/app/ + COPY templates/index.html /usr/src/app/templates/ + + # tell the port number the container should expose + EXPOSE 5000 + + # run the application + CMD ["python", "/usr/src/app/app.py"] + ``` + +### 2.3.3 Build the image + +Now that you have your `Dockerfile`, you can build your image. The `docker build` command does the heavy-lifting of creating a docker image from a `Dockerfile`. + +When you run the `docker build` command given below, make sure to replace `` with your username. This username should be the same one you created when registering on [Docker hub](https://hub.docker.com). If you haven't done that yet, please go ahead and create an account. + +The `docker build` command is quite simple - it takes an optional tag name with the `-t` flag, and the location of the directory containing the `Dockerfile` - the `.` indicates the current directory: + +``` +$ docker build -t /myfirstapp . +Sending build context to Docker daemon 9.728 kB +Step 1 : FROM alpine:latest + ---> 0d81fc72e790 +Step 2 : RUN apk add --update py-pip + ---> Running in 8abd4091b5f5 +fetch http://dl-4.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz +fetch http://dl-4.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz +(1/12) Installing libbz2 (1.0.6-r4) +(2/12) Installing expat (2.1.0-r2) +(3/12) Installing libffi (3.2.1-r2) +(4/12) Installing gdbm (1.11-r1) +(5/12) Installing ncurses-terminfo-base (6.0-r6) +(6/12) Installing ncurses-terminfo (6.0-r6) +(7/12) Installing ncurses-libs (6.0-r6) +(8/12) Installing readline (6.3.008-r4) +(9/12) Installing sqlite-libs (3.9.2-r0) +(10/12) Installing python (2.7.11-r3) +(11/12) Installing py-setuptools (18.8-r0) +(12/12) Installing py-pip (7.1.2-r0) +Executing busybox-1.24.1-r7.trigger +OK: 59 MiB in 23 packages + ---> 976a232ac4ad +Removing intermediate container 8abd4091b5f5 +Step 3 : COPY requirements.txt /usr/src/app/ + ---> 65b4be05340c +Removing intermediate container 29ef53b58e0f +Step 4 : RUN pip install --no-cache-dir -r /usr/src/app/requirements.txt + ---> Running in a1f26ded28e7 +Collecting Flask==0.10.1 (from -r /usr/src/app/requirements.txt (line 1)) + Downloading Flask-0.10.1.tar.gz (544kB) +Collecting Werkzeug>=0.7 (from Flask==0.10.1->-r /usr/src/app/requirements.txt (line 1)) + Downloading Werkzeug-0.11.4-py2.py3-none-any.whl (305kB) +Collecting Jinja2>=2.4 (from Flask==0.10.1->-r /usr/src/app/requirements.txt (line 1)) + Downloading Jinja2-2.8-py2.py3-none-any.whl (263kB) +Collecting itsdangerous>=0.21 (from Flask==0.10.1->-r /usr/src/app/requirements.txt (line 1)) + Downloading itsdangerous-0.24.tar.gz (46kB) +Collecting MarkupSafe (from Jinja2>=2.4->Flask==0.10.1->-r /usr/src/app/requirements.txt (line 1)) + Downloading MarkupSafe-0.23.tar.gz +Installing collected packages: Werkzeug, MarkupSafe, Jinja2, itsdangerous, Flask + Running setup.py install for MarkupSafe + Running setup.py install for itsdangerous + Running setup.py install for Flask +Successfully installed Flask-0.10.1 Jinja2-2.8 MarkupSafe-0.23 Werkzeug-0.11.4 itsdangerous-0.24 +You are using pip version 7.1.2, however version 8.1.1 is available. +You should consider upgrading via the 'pip install --upgrade pip' command. + ---> 8de73b0730c2 +Removing intermediate container a1f26ded28e7 +Step 5 : COPY app.py /usr/src/app/ + ---> 6a3436fca83e +Removing intermediate container d51b81a8b698 +Step 6 : COPY templates/index.html /usr/src/app/templates/ + ---> 8098386bee99 +Removing intermediate container b783d7646f83 +Step 7 : EXPOSE 5000 + ---> Running in 31401b7dea40 + ---> 5e9988d87da7 +Removing intermediate container 31401b7dea40 +Step 8 : CMD python /usr/src/app/app.py + ---> Running in 78e324d26576 + ---> 2f7357a0805d +Removing intermediate container 78e324d26576 +Successfully built 2f7357a0805d +``` + +If you don't have the `alpine:latest` image, the client will first pull the image and then create your image. Therefore, your output on running the command will look different from mine. If everything went well, your image should be ready! Run `docker images` and see if your image (`/myfirstapp`) shows. + +### 2.3.4 Run your image +The last step in this section is to run the image and see if it actually works. + +``` +$ docker run -p 8888:5000 --name myfirstapp YOUR_USERNAME/myfirstapp + * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) +``` + +Head over to `http://localhost:8888` and your app should be live. **Note** If you are using Docker Machine, you may need to open up another terminal and determine the container ip address using `docker-machine ip default`. + + + +Hit the Refresh button in the web browser to see a few more cat images. + +OK, now that you are done with this container, stop and remove it since you won't be using it again. + +Open another terminal window and execute the following commands: + +``` +$ docker stop myfirstapp +$ docker rm myfirstapp +``` + +or + +```.term +docker rm -f myfirstapp +``` + +### 2.3.5 Dockerfile commands summary + +Here's a quick summary of the few basic commands we used in our Dockerfile. + +* `FROM` starts the Dockerfile. It is a requirement that the Dockerfile must start with the `FROM` command. Images are created in layers, which means you can use another image as the base image for your own. The `FROM` command defines your base layer. As arguments, it takes the name of the image. Optionally, you can add the Docker Hub username of the maintainer and image version, in the format `username/imagename:version`. + +* `RUN` is used to build up the Image you're creating. For each `RUN` command, Docker will run the command then create a new layer of the image. This way you can roll back your image to previous states easily. The syntax for a `RUN` instruction is to place the full text of the shell command after the `RUN` (e.g., `RUN mkdir /user/local/foo`). This will automatically run in a `/bin/sh` shell. You can define a different shell like this: `RUN /bin/bash -c 'mkdir /user/local/foo'` + +* `COPY` copies local files into the container. + +* `CMD` defines the commands that will run on the Image at start-up. Unlike a `RUN`, this does not create a new layer for the Image, but simply runs the command. There can only be one `CMD` per a Dockerfile/Image. If you need to run multiple commands, the best way to do that is to have the `CMD` run a script. `CMD` requires that you tell it where to run the command, unlike `RUN`. So example `CMD` commands would be: +``` + CMD ["python", "./app.py"] + + CMD ["/bin/bash", "echo", "Hello World"] +``` + +* `EXPOSE` opens ports in your image to allow communication to the outside world when it runs in a container. + +>**Note:** If you want to learn more about Dockerfiles, check out [Best practices for writing Dockerfiles](https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/). + +## Next Steps +For the next step in the tutorial head over to [3.0 Run a multi-container app with Docker Compose](./votingapp.md) diff --git a/_posts/2017-01-16-alpine.markdown b/_posts/2017-01-16-alpine.markdown new file mode 100644 index 0000000..a68cb40 --- /dev/null +++ b/_posts/2017-01-16-alpine.markdown @@ -0,0 +1,114 @@ +--- +layout: post +title: "Alpine" +date: 2017-01-16 10:51:47 +0530 +categories: alpine beginner +tags: [docker, alpine] +--- +## 1.0 Running your first container +Now that you have everything setup, it's time to get our hands dirty. In this section, you are going to run an [Alpine Linux](http://www.alpinelinux.org/) container (a lightweight linux distribution) on your system and get a taste of the `docker run` command. + +To get started, let's run the following in our terminal: + +```.term +docker pull alpine +``` + +> **Note:** Depending on how you've installed docker on your system, you might see a `permission denied` error after running the above command. Try the commands from the Getting Started tutorial to [verify your installation](https://docs.docker.com/engine/getstarted/step_one/#/step-3-verify-your-installation). If you're on Linux, you may need to prefix your `docker` commands with `sudo`. Alternatively you can [create a docker group](https://docs.docker.com/engine/installation/linux/ubuntulinux/#/create-a-docker-group) to get rid of this issue. + +The `pull` command fetches the alpine **image** from the **Docker registry** and saves it in our system. You can use the `docker images` command to see a list of all images on your system. + +```.term +docker images +``` +``` +REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE +alpine latest c51f86c28340 4 weeks ago 1.109 MB +hello-world latest 690ed74de00f 5 months ago 960 B +``` + +### 1.1 Docker Run +Great! Let's now run a Docker **container** based on this image. To do that you are going to use the `docker run` command. + +```.term +docker run alpine ls -l +``` +``` +total 48 +drwxr-xr-x 2 root root 4096 Mar 2 16:20 bin +drwxr-xr-x 5 root root 360 Mar 18 09:47 dev +drwxr-xr-x 13 root root 4096 Mar 18 09:47 etc +drwxr-xr-x 2 root root 4096 Mar 2 16:20 home +drwxr-xr-x 5 root root 4096 Mar 2 16:20 lib +...... +...... +``` +What happened? Behind the scenes, a lot of stuff happened. When you call `run`, the Docker client finds the image (alpine in this case), creates the container and then runs a command in that container. When you run `docker run alpine`, you provided a command (`ls -l`), so Docker started the command specified and you saw the listing. + +Let's try something more exciting. + +```.term +docker run alpine echo "hello from alpine" +``` +``` +hello from alpine +``` +OK, that's some actual output. In this case, the Docker client dutifully ran the `echo` command in our alpine container and then exited it. If you've noticed, all of that happened pretty quickly. Imagine booting up a virtual machine, running a command and then killing it. Now you know why they say containers are fast! + +Try another command. +```.term +docker run alpine /bin/sh +``` + +Wait, nothing happened! Is that a bug? Well, no. These interactive shells will exit after running any scripted commands, unless they are run in an interactive terminal - so for this example to not exit, you need to `docker run -it alpine /bin/sh`. + +You are now inside the container shell and you can try out a few commands like `ls -l`, `uname -a` and others. Exit out of the container by giving the `exit` command. + + +Ok, now it's time to see the `docker ps` command. The `docker ps` command shows you all containers that are currently running. + +```.term +docker ps +``` +``` +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +``` + +Since no containers are running, you see a blank line. Let's try a more useful variant: `docker ps -a` + +```.term +docker ps -a +``` +``` +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +36171a5da744 alpine "/bin/sh" 5 minutes ago Exited (0) 2 minutes ago fervent_newton +a6a9d46d0b2f alpine "echo 'hello from alp" 6 minutes ago Exited (0) 6 minutes ago lonely_kilby +ff0a5c3750b9 alpine "ls -l" 8 minutes ago Exited (0) 8 minutes ago elated_ramanujan +c317d0a9e3d2 hello-world "/hello" 34 seconds ago Exited (0) 12 minutes ago stupefied_mcclintock +``` + +What you see above is a list of all containers that you ran. Notice that the `STATUS` column shows that these containers exited a few minutes ago. You're probably wondering if there is a way to run more than just one command in a container. Let's try that now: + +```.term +docker run -it alpine /bin/sh +``` +``` +/ # ls +bin dev etc home lib linuxrc media mnt proc root run sbin sys tmp usr var +/ # uname -a +Linux 97916e8cb5dc 4.4.27-moby #1 SMP Wed Oct 26 14:01:48 UTC 2016 x86_64 Linux +``` +Running the `run` command with the `-it` flags attaches us to an interactive tty in the container. Now you can run as many commands in the container as you want. Take some time to run your favorite commands. + +That concludes a whirlwind tour of the `docker run` command which would most likely be the command you'll use most often. It makes sense to spend some time getting comfortable with it. To find out more about `run`, use `docker run --help` to see a list of all flags it supports. As you proceed further, we'll see a few more variants of `docker run`. +### 1.2 Terminology +In the last section, you saw a lot of Docker-specific jargon which might be confusing to some. So before you go further, let's clarify some terminology that is used frequently in the Docker ecosystem. + +- *Images* - The file system and configuration of our application which are used to create containers. To find out more about a Docker image, run `docker inspect alpine`. In the demo above, you used the `docker pull` command to download the **alpine** image. When you executed the command `docker run hello-world`, it also did a `docker pull` behind the scenes to download the **hello-world** image. +- *Containers* - Running instances of Docker images — containers run the actual applications. A container includes an application and all of its dependencies. It shares the kernel with other containers, and runs as an isolated process in user space on the host OS. You created a container using `docker run` which you did using the alpine image that you downloaded. A list of running containers can be seen using the `docker ps` command. +- *Docker daemon* - The background service running on the host that manages building, running and distributing Docker containers. +- *Docker client* - The command line tool that allows the user to interact with the Docker daemon. +- *Docker Hub* - A [registry](https://hub.docker.com/explore/) of Docker images. You can think of the registry as a directory of all available Docker images. You'll be using this later in this tutorial. + +## Next Steps +For the next step in the tutorial, head over to [2.0 Webapps with Docker](./webapps.md)- diff --git a/_posts/2017-01-17-setup.markdown b/_posts/2017-01-17-setup.markdown new file mode 100644 index 0000000..4d479bd --- /dev/null +++ b/_posts/2017-01-17-setup.markdown @@ -0,0 +1,39 @@ +--- +layout: post +title: "Setup" +date: 2017-01-17 +tags: [docker] +categories: setup +--- +## Prerequisites +There are no specific skills needed for this tutorial beyond a basic comfort with the command line and using a text editor. Prior experience in developing web applications will be helpful but is not required. As you proceed further along the tutorial, we'll make use of [Docker Hub](https://hub.docker.com/). + +## Setting up your computer +Getting all the tooling setup on your computer can be a daunting task, but getting Docker up and running on your favorite OS has become very easy. + +The *getting started* guide on Docker has detailed instructions for setting up Docker on [Mac](https://docs.docker.com/docker-for-mac/), [Linux](https://docs.docker.com/engine/installation/linux/) and [Windows](https://docs.docker.com/docker-for-windows/). + +*If you're using Docker for Windows* make sure you have [shared your drive](https://docs.docker.com/docker-for-windows/#/shared-drives). + +*Important note* If you're using an older version of Windows or MacOS you may need to use [Docker Machine](https://docs.docker.com/machine/overview/) instead. + +*All commands work in either bash or Powershell on Windows* + +Once you are done installing Docker, test your Docker installation by running the following: + +```.term +docker run hello-world +``` +``` +Unable to find image 'hello-world:latest' locally +latest: Pulling from library/hello-world +03f4658f8b78: Pull complete +a3ed95caeb02: Pull complete +Digest: sha256:8be990ef2aeb16dbcb9271ddfe2610fa6658d13f6dfb8bc72074cc1ca36966a7 +Status: Downloaded newer image for hello-world:latest + +Hello from Docker. +This message shows that your installation appears to be working correctly. +``` +## Next Steps +For the next step in the tutorial, head over to [1.0 Running your first container](alpine.md)` diff --git a/_posts/2017-01-19-how-to-write-go-code.markdown b/_posts/2017-01-19-how-to-write-go-code.markdown new file mode 100644 index 0000000..d2cb7f7 --- /dev/null +++ b/_posts/2017-01-19-how-to-write-go-code.markdown @@ -0,0 +1,403 @@ +--- +layout: post +title: "How to write Go code" +date: 2017-01-19 10:51:47 +0530 +author: "Golang" +tags: [golang] +categories: golang +img: "gopher.png" +--- + +## Introduction + +This document demonstrates the development of a simple Go package and introduces the [go tool](/cmd/go/), the standard way to fetch, build, and install Go packages and commands. + +The `go` tool requires you to organize your code in a specific way. Please read this document carefully. It explains the simplest way to get up and running with your Go installation. + +A similar explanation is available as a [screencast](//www.youtube.com/watch?v=XCsL89YtqCs). + +## Code organization + +### Overview + +* Go programmers typically keep all their Go code in a single _workspace_. +* A workspace contains many version control _repositories_ (managed by Git, for example). +* Each repository contains one or more _packages_. +* Each package consists of one or more Go source files in a single directory. +* The path to a package's directory determines its _import path_. + +Note that this differs from other programming environments in which every project has a separate workspace and workspaces are closely tied to version control repositories. + +### Workspaces + +A workspace is a directory hierarchy with three directories at its root: + +* `src` contains Go source files, +* `pkg` contains package objects, and +* `bin` contains executable commands. + +The `go` tool builds source packages and installs the resulting binaries to the `pkg` and `bin` directories. + +The `src` subdirectory typically contains multiple version control repositories (such as for Git or Mercurial) that track the development of one or more source packages. + +To give you an idea of how a workspace looks in practice, here's an example: + +
bin/
+    hello                          # command executable
+    outyet                         # command executable
+pkg/
+    linux_amd64/
+        github.com/golang/example/
+            stringutil.a           # package object
+src/
+    [github.com/golang/example/](https://github.com/golang/example/)
+        .git/                      # Git repository metadata
+	hello/
+	    hello.go               # command source
+	outyet/
+	    main.go                # command source
+	    main_test.go           # test source
+	stringutil/
+	    reverse.go             # package source
+	    reverse_test.go        # test source
+    [golang.org/x/image/](https://golang.org/x/image/)
+        .git/                      # Git repository metadata
+	bmp/
+	    reader.go              # package source
+	    writer.go              # package source
+    ... (many more repositories and packages omitted) ...
+
+ +The tree above shows a workspace containing two repositories (`example` and `image`). The `example` repository contains two commands (`hello` and `outyet`) and one library (`stringutil`). The `image` repository contains the `bmp` package and [several others](https://godoc.org/golang.org/x/image). + +A typical workspace contains many source repositories containing many packages and commands. Most Go programmers keep _all_ their Go source code and dependencies in a single workspace. + +Commands and libraries are built from different kinds of source packages. We will discuss the distinction [later](#PackageNames). + + +### Installing go + +Before moving forward it's necessary to install Go and set your GOPATH. You can do so by running the command below. + +```.term1 +apk add --no-cache go +export GOPATH=$HOME/go +``` + + +### The `GOPATH` environment variable + +The `GOPATH` environment variable specifies the location of your workspace. It defaults to a directory named `go` inside your home directory, so `$HOME/go` on Unix, `$home/go` on Plan 9, and `%USERPROFILE%\go` (usually `C:\Users\YourName\go`) on Windows. If you would like to work in a different location, you will need to set `GOPATH` to the path to that directory. (Another common setup is to set `GOPATH=$HOME`.) Note that `GOPATH` must **not** be the same path as your Go installation. + +The command `go` `env` `GOPATH` prints the effective current `GOPATH`; it prints the default location if the environment variable is unset. + +For convenience, add the workspace's `bin` subdirectory to your `PATH`: + +```.term1 +export PATH=$PATH:$(go env GOPATH)/bin +``` + +The scripts in the rest of this document use `$GOPATH` instead of `$(go env GOPATH)` for brevity. To make the scripts run as written if you have not set GOPATH, you can substitute $HOME/go in those commands or else run: + +```.term1 +export GOPATH=$(go env GOPATH) +``` + +To learn more about the `GOPATH` environment variable, see [`'go help gopath'`](/cmd/go/#hdr-GOPATH_environment_variable). + +To use a custom workspace location, [set the `GOPATH` environment variable](https://golang.org/wiki/SettingGOPATH). + +### Import paths + +An _import path_ is a string that uniquely identifies a package. A package's import path corresponds to its location inside a workspace or in a remote repository (explained below). + +The packages from the standard library are given short import paths such as `"fmt"` and `"net/http"`. For your own packages, you must choose a base path that is unlikely to collide with future additions to the standard library or other external libraries. + +If you keep your code in a source repository somewhere, then you should use the root of that source repository as your base path. For instance, if you have a [GitHub](https://github.com/) account at `github.com/user`, that should be your base path. + +Note that you don't need to publish your code to a remote repository before you can build it. It's just a good habit to organize your code as if you will publish it someday. In practice you can choose any arbitrary path name, as long as it is unique to the standard library and greater Go ecosystem. + +We'll use `github.com/user` as our base path. Create a directory inside your workspace in which to keep source code: + +```.term1 +mkdir -p $GOPATH/src/github.com/user +``` + +### Your first program + +To compile and run a simple program, first choose a package path (we'll use `github.com/user/hello`) and create a corresponding package directory inside your workspace: + +```.term1 +mkdir $GOPATH/src/github.com/user/hello +cd $GOPATH/src/github.com/user/hello +``` + +Next, create a file named `hello.go` inside that directory, containing the following Go code. + +
package main
+
+import "fmt"
+
+func main() {
+	fmt.Printf("Hello, world.\n")
+}
+
+ +Now you can build and install that program with the `go` tool: + +```.term1 +go install github.com/user/hello +``` + +Note that you can run this command from anywhere on your system. The `go` tool finds the source code by looking for the `github.com/user/hello` package inside the workspace specified by `GOPATH`. + +You can also omit the package path if you run `go install` from the package directory: + +```.term1 +cd $GOPATH/src/github.com/user/hello +go install +``` + +This command builds the `hello` command, producing an executable binary. It then installs that binary to the workspace's `bin` directory as `hello` (or, under Windows, `hello.exe`). In our example, that will be `$GOPATH/bin/hello`, which is `$HOME/work/bin/hello`. + +The `go` tool will only print output when an error occurs, so if these commands produce no output they have executed successfully. + +You can now run the program by typing its full path at the command line: + +```.term1 +$GOPATH/bin/hello +``` + +Or, as you have added `$GOPATH/bin` to your `PATH`, just type the binary name: + +```.term1 +hello +``` + +If you're using a source control system, now would be a good time to initialize a repository, add the files, and commit your first change. Again, this step is optional: you do not need to use source control to write Go code. + +```.term1 +cd $GOPATH/src/github.com/user/hello +git init +git add hello.go +git commit -m "initial commit" +``` + +Pushing the code to a remote repository is left as an exercise for the reader. + +### Your first library + +Let's write a library and use it from the `hello` program. + +Again, the first step is to choose a package path (we'll use `github.com/user/stringutil`) and create the package directory: + + +```.term1 +mkdir $GOPATH/src/github.com/user/stringutil +``` + +Next, create a file named `reverse.go` in that directory with the following contents. + +
// Package stringutil contains utility functions for working with strings.
+package stringutil
+
+// Reverse returns its argument string reversed rune-wise left to right.
+func Reverse(s string) string {
+	r := []rune(s)
+	for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
+		r[i], r[j] = r[j], r[i]
+	}
+	return string(r)
+}
+
+ +Now, test that the package compiles with `go build`: + +```.term1 +go build github.com/user/stringutil +``` + +Or, if you are working in the package's source directory, just: + +```.term1 +go build +``` + +This won't produce an output file. To do that, you must use `go install`, which places the package object inside the `pkg` directory of the workspace. + +After confirming that the `stringutil` package builds, modify your original `hello.go` (which is in `$GOPATH/src/github.com/user/hello`) to use it: + +
package main
+
+import (
+	"fmt"
+
+	**"github.com/user/stringutil"**
+)
+
+func main() {
+	fmt.Printf(stringutil.Reverse("!oG ,olleH"))
+}
+
+ +Whenever the `go` tool installs a package or binary, it also installs whatever dependencies it has. So when you install the `hello` program + + +```.term1 +go install github.com/user/hello +``` + + +the `stringutil` package will be installed as well, automatically. + +Running the new version of the program, you should see a new, reversed message: + + +```.term1 +hello +``` + +After the steps above, your workspace should look like this: + +
bin/
+    hello                 # command executable
+pkg/
+    linux_amd64/          # this will reflect your OS and architecture
+        github.com/user/
+            stringutil.a  # package object
+src/
+    github.com/user/
+        hello/
+            hello.go      # command source
+        stringutil/
+            reverse.go    # package source
+
+ +Note that `go install` placed the `stringutil.a` object in a directory inside `pkg/linux_amd64` that mirrors its source directory. This is so that future invocations of the `go` tool can find the package object and avoid recompiling the package unnecessarily. The `linux_amd64` part is there to aid in cross-compilation, and will reflect the operating system and architecture of your system. + +Go command executables are statically linked; the package objects need not be present to run Go programs. + +### Package names + +The first statement in a Go source file must be + +
package _name_
+
+ +where `_name_` is the package's default name for imports. (All files in a package must use the same `_name_`.) + +Go's convention is that the package name is the last element of the import path: the package imported as "`crypto/rot13`" should be named `rot13`. + +Executable commands must always use `package main`. + +There is no requirement that package names be unique across all packages linked into a single binary, only that the import paths (their full file names) be unique. + +See [Effective Go](/doc/effective_go.html#names) to learn more about Go's naming conventions. + +## Testing + +Go has a lightweight test framework composed of the `go test` command and the `testing` package. + +You write a test by creating a file with a name ending in `_test.go` that contains functions named `TestXXX` with signature `func (t *testing.T)`. The test framework runs each such function; if the function calls a failure function such as `t.Error` or `t.Fail`, the test is considered to have failed. + +Add a test to the `stringutil` package by creating the file `$GOPATH/src/github.com/user/stringutil/reverse_test.go` containing the following Go code. + +
package stringutil
+
+import "testing"
+
+func TestReverse(t *testing.T) {
+	cases := []struct {
+		in, want string
+	}{
+		{"Hello, world", "dlrow ,olleH"},
+		{"Hello, 世界", "界世 ,olleH"},
+		{"", ""},
+	}
+	for _, c := range cases {
+		got := Reverse(c.in)
+		if got != c.want {
+			t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
+		}
+	}
+}
+
+ +Then run the test with `go test`: + + +```.term1 +go test github.com/user/stringutil +``` + +As always, if you are running the `go` tool from the package directory, you can omit the package path: + + +```.term1 +go test +``` + +Run `[go help test](/cmd/go/#hdr-Test_packages)` and see the [testing package documentation](/pkg/testing/) for more detail. + +## Remote packages + +An import path can describe how to obtain the package source code using a revision control system such as Git or Mercurial. The `go` tool uses this property to automatically fetch packages from remote repositories. For instance, the examples described in this document are also kept in a Git repository hosted at GitHub `[github.com/golang/example](https://github.com/golang/example)`. If you include the repository URL in the package's import path, `go get` will fetch, build, and install it automatically: + +```.term1 +go get github.com/golang/example/hello +``` + +If the specified package is not present in a workspace, `go get` will place it inside the first workspace specified by `GOPATH`. (If the package does already exist, `go get` skips the remote fetch and behaves the same as `go install`.) + +After issuing the above `go get` command, the workspace directory tree should now look like this: + +
bin/
+    hello                           # command executable
+pkg/
+    linux_amd64/
+        github.com/golang/example/
+            stringutil.a            # package object
+        github.com/user/
+            stringutil.a            # package object
+src/
+    github.com/golang/example/
+	.git/                       # Git repository metadata
+        hello/
+            hello.go                # command source
+        stringutil/
+            reverse.go              # package source
+            reverse_test.go         # test source
+    github.com/user/
+        hello/
+            hello.go                # command source
+        stringutil/
+            reverse.go              # package source
+            reverse_test.go         # test source
+
+ +The `hello` command hosted at GitHub depends on the `stringutil` package within the same repository. The imports in `hello.go` file use the same import path convention, so the `go get` command is able to locate and install the dependent package, too. + +
import "github.com/golang/example/stringutil"
+
+ +This convention is the easiest way to make your Go packages available for others to use. The [Go Wiki](//golang.org/wiki/Projects) and [godoc.org](//godoc.org/) provide lists of external Go projects. + +For more information on using remote repositories with the `go` tool, see `[go help importpath](/cmd/go/#hdr-Remote_import_paths)`. + +## What's next + +Subscribe to the [golang-announce](//groups.google.com/group/golang-announce) mailing list to be notified when a new stable version of Go is released. + +See [Effective Go](/doc/effective_go.html) for tips on writing clear, idiomatic Go code. + +Take [A Tour of Go](//tour.golang.org/) to learn the language proper. + +Visit the [documentation page](/doc/#articles) for a set of in-depth articles about the Go language and its libraries and tools. + +## Getting help + +For real-time help, ask the helpful gophers in `#go-nuts` on the [Freenode](http://freenode.net/) IRC server. + +The official mailing list for discussion of the Go language is [Go Nuts](//groups.google.com/group/golang-nuts). + +Report bugs using the [Go issue tracker](//golang.org/issue). diff --git a/_sass/_bootstrap-readable.scss b/_sass/_bootstrap-readable.scss new file mode 100644 index 0000000..1cad0db --- /dev/null +++ b/_sass/_bootstrap-readable.scss @@ -0,0 +1,6871 @@ +/* @import url("https://fonts.googleapis.com/css?family=Raleway:400,700"); */ +/*! + * bootswatch v3.3.6 + * Homepage: http://bootswatch.com + * Copyright 2012-2016 Thomas Park + * Licensed under MIT + * Based on Bootstrap +*/ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +html { + font-family: sans-serif; + -ms-text-size-adjust: 100%; + -webkit-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +menu, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background-color: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + font-size: 2em; + margin: 0.67em 0; +} +mark { + background: #ff0; + color: #000; +} +small { + font-size: 80%; +} +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} +sup { + top: -0.5em; +} +sub { + bottom: -0.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + height: 0; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + color: inherit; + font: inherit; + margin: 0; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-appearance: textfield; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + border: 1px solid #c0c0c0; + margin: 0 2px; + padding: 0.35em 0.625em 0.75em; +} +legend { + border: 0; + padding: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +td, +th { + padding: 0; +} +/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ +@media print { + *, + *:before, + *:after { + background: transparent !important; + color: #000 !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + text-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="#"]:after, + a[href^="javascript:"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + .navbar { + display: none; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\002a"; +} +.glyphicon-plus:before { + content: "\002b"; +} +.glyphicon-euro:before, +.glyphicon-eur:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +.glyphicon-cd:before { + content: "\e201"; +} +.glyphicon-save-file:before { + content: "\e202"; +} +.glyphicon-open-file:before { + content: "\e203"; +} +.glyphicon-level-up:before { + content: "\e204"; +} +.glyphicon-copy:before { + content: "\e205"; +} +.glyphicon-paste:before { + content: "\e206"; +} +.glyphicon-alert:before { + content: "\e209"; +} +.glyphicon-equalizer:before { + content: "\e210"; +} +.glyphicon-king:before { + content: "\e211"; +} +.glyphicon-queen:before { + content: "\e212"; +} +.glyphicon-pawn:before { + content: "\e213"; +} +.glyphicon-bishop:before { + content: "\e214"; +} +.glyphicon-knight:before { + content: "\e215"; +} +.glyphicon-baby-formula:before { + content: "\e216"; +} +.glyphicon-tent:before { + content: "\26fa"; +} +.glyphicon-blackboard:before { + content: "\e218"; +} +.glyphicon-bed:before { + content: "\e219"; +} +.glyphicon-apple:before { + content: "\f8ff"; +} +.glyphicon-erase:before { + content: "\e221"; +} +.glyphicon-hourglass:before { + content: "\231b"; +} +.glyphicon-lamp:before { + content: "\e223"; +} +.glyphicon-duplicate:before { + content: "\e224"; +} +.glyphicon-piggy-bank:before { + content: "\e225"; +} +.glyphicon-scissors:before { + content: "\e226"; +} +.glyphicon-bitcoin:before { + content: "\e227"; +} +.glyphicon-btc:before { + content: "\e227"; +} +.glyphicon-xbt:before { + content: "\e227"; +} +.glyphicon-yen:before { + content: "\00a5"; +} +.glyphicon-jpy:before { + content: "\00a5"; +} +.glyphicon-ruble:before { + content: "\20bd"; +} +.glyphicon-rub:before { + content: "\20bd"; +} +.glyphicon-scale:before { + content: "\e230"; +} +.glyphicon-ice-lolly:before { + content: "\e231"; +} +.glyphicon-ice-lolly-tasted:before { + content: "\e232"; +} +.glyphicon-education:before { + content: "\e233"; +} +.glyphicon-option-horizontal:before { + content: "\e234"; +} +.glyphicon-option-vertical:before { + content: "\e235"; +} +.glyphicon-menu-hamburger:before { + content: "\e236"; +} +.glyphicon-modal-window:before { + content: "\e237"; +} +.glyphicon-oil:before { + content: "\e238"; +} +.glyphicon-grain:before { + content: "\e239"; +} +.glyphicon-sunglasses:before { + content: "\e240"; +} +.glyphicon-text-size:before { + content: "\e241"; +} +.glyphicon-text-color:before { + content: "\e242"; +} +.glyphicon-text-background:before { + content: "\e243"; +} +.glyphicon-object-align-top:before { + content: "\e244"; +} +.glyphicon-object-align-bottom:before { + content: "\e245"; +} +.glyphicon-object-align-horizontal:before { + content: "\e246"; +} +.glyphicon-object-align-left:before { + content: "\e247"; +} +.glyphicon-object-align-vertical:before { + content: "\e248"; +} +.glyphicon-object-align-right:before { + content: "\e249"; +} +.glyphicon-triangle-right:before { + content: "\e250"; +} +.glyphicon-triangle-left:before { + content: "\e251"; +} +.glyphicon-triangle-bottom:before { + content: "\e252"; +} +.glyphicon-triangle-top:before { + content: "\e253"; +} +.glyphicon-console:before { + content: "\e254"; +} +.glyphicon-superscript:before { + content: "\e255"; +} +.glyphicon-subscript:before { + content: "\e256"; +} +.glyphicon-menu-left:before { + content: "\e257"; +} +.glyphicon-menu-right:before { + content: "\e258"; +} +.glyphicon-menu-down:before { + content: "\e259"; +} +.glyphicon-menu-up:before { + content: "\e260"; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: Georgia, "Times New Roman", Times, serif; + font-size: 20px; + line-height: 1.6; + color: #333333; + background-color: #ffffff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #4582ec; + text-decoration: none; +} +a:hover, +a:focus { + color: #134fb8; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + padding: 4px; + line-height: 1.42857143; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; + display: inline-block; + max-width: 100%; + height: auto; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 22px; + margin-bottom: 22px; + border: 0; + border-top: 1px solid #eeeeee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + margin: -1px; + padding: 0; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +[role="button"] { + cursor: pointer; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: bold; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #b3b3b3; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 22px; + margin-bottom: 11px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 11px; + margin-bottom: 11px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 41px; +} +h2, +.h2 { + font-size: 34px; +} +h3, +.h3 { + font-size: 28px; +} +h4, +.h4 { + font-size: 20px; +} +h5, +.h5 { + font-size: 16px; +} +h6, +.h6 { + font-size: 14px; +} +p { + margin: 0 0 20px; +} +.lead { + margin-bottom: 22px; + font-size: 18px; + font-weight: 300; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 24px; + } +} +small, +.small { + font-size: 87%; +} +mark, +.mark { + background-color: #fcf8e3; + padding: .2em; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-nowrap { + white-space: nowrap; +} +.text-lowercase { + text-transform: lowercase; +} +.text-uppercase { + text-transform: uppercase; +} +.text-capitalize { + text-transform: capitalize; +} +.text-muted { + color: #b3b3b3; +} +.text-primary { + color: #4582ec; +} +a.text-primary:hover, +a.text-primary:focus { + color: #1863e6; +} +.text-success { + color: #3fad46; +} +a.text-success:hover, +a.text-success:focus { + color: #318837; +} +.text-info { + color: #5bc0de; +} +a.text-info:hover, +a.text-info:focus { + color: #31b0d5; +} +.text-warning { + color: #f0ad4e; +} +a.text-warning:hover, +a.text-warning:focus { + color: #ec971f; +} +.text-danger { + color: #d9534f; +} +a.text-danger:hover, +a.text-danger:focus { + color: #c9302c; +} +.bg-primary { + color: #fff; + background-color: #4582ec; +} +a.bg-primary:hover, +a.bg-primary:focus { + background-color: #1863e6; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover, +a.bg-success:focus { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover, +a.bg-info:focus { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover, +a.bg-warning:focus { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover, +a.bg-danger:focus { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 10px; + margin: 44px 0 22px; + border-bottom: 1px solid #dddddd; +} +ul, +ol { + margin-top: 0; + margin-bottom: 11px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + list-style: none; + margin-left: -5px; +} +.list-inline > li { + display: inline-block; + padding-left: 5px; + padding-right: 5px; +} +dl { + margin-top: 0; + margin-bottom: 22px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + clear: left; + text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #b3b3b3; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 11px 22px; + margin: 0 0 22px; + font-size: 20px; + border-left: 5px solid #4582ec; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #333333; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #4582ec; + border-left: 0; + text-align: right; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +address { + margin-bottom: 22px; + font-style: normal; + line-height: 1.42857143; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #ffffff; + background-color: #333333; + border-radius: 3px; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: bold; + -webkit-box-shadow: none; + box-shadow: none; +} +pre { + display: block; + padding: 10.5px; + margin: 0 0 11px; + font-size: 15px; + line-height: 1.42857143; + word-break: break-all; + word-wrap: break-word; + color: #333333; + background-color: #f5f5f5; + border: 1px solid #cccccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + margin-right: auto; + margin-left: auto; + padding-left: 20px; + padding-right: 20px; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + margin-right: auto; + margin-left: auto; + padding-left: 15px; + padding-right: 15px; +} +.row { + margin-left: -15px; + margin-right: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-left: 15px; + padding-right: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0%; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0%; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0%; + } +} +table { + background-color: transparent; +} +caption { + padding-top: 8px; + padding-bottom: 8px; + color: #b3b3b3; + text-align: left; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 22px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #dddddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #dddddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #dddddd; +} +.table .table { + background-color: #ffffff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #dddddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #dddddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-of-type(odd) { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + float: none; + display: table-column; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + float: none; + display: table-cell; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +.table-responsive { + overflow-x: auto; + min-height: 0.01%; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 16.5px; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #dddddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + padding: 0; + margin: 0; + border: 0; + min-width: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 22px; + font-size: 24px; + line-height: inherit; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 9px; + font-size: 16px; + line-height: 1.42857143; + color: #333333; +} +.form-control { + display: block; + width: 100%; + height: 40px; + padding: 8px 12px; + font-size: 16px; + line-height: 1.42857143; + color: #333333; + background-color: #ffffff; + background-image: none; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6); +} +.form-control::-moz-placeholder { + color: #b3b3b3; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #b3b3b3; +} +.form-control::-webkit-input-placeholder { + color: #b3b3b3; +} +.form-control::-ms-expand { + border: 0; + background-color: transparent; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + background-color: #eeeeee; + opacity: 1; +} +.form-control[disabled], +fieldset[disabled] .form-control { + cursor: not-allowed; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +@media screen and (-webkit-min-device-pixel-ratio: 0) { + input[type="date"].form-control, + input[type="time"].form-control, + input[type="datetime-local"].form-control, + input[type="month"].form-control { + line-height: 40px; + } + input[type="date"].input-sm, + input[type="time"].input-sm, + input[type="datetime-local"].input-sm, + input[type="month"].input-sm, + .input-group-sm input[type="date"], + .input-group-sm input[type="time"], + .input-group-sm input[type="datetime-local"], + .input-group-sm input[type="month"] { + line-height: 33px; + } + input[type="date"].input-lg, + input[type="time"].input-lg, + input[type="datetime-local"].input-lg, + input[type="month"].input-lg, + .input-group-lg input[type="date"], + .input-group-lg input[type="time"], + .input-group-lg input[type="datetime-local"], + .input-group-lg input[type="month"] { + line-height: 57px; + } +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + min-height: 22px; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-left: -20px; + margin-top: 4px \9; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + position: relative; + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + vertical-align: middle; + font-weight: normal; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + padding-top: 9px; + padding-bottom: 9px; + margin-bottom: 0; + min-height: 38px; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-left: 0; + padding-right: 0; +} +.input-sm { + height: 33px; + padding: 5px 10px; + font-size: 14px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 33px; + line-height: 33px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.form-group-sm .form-control { + height: 33px; + padding: 5px 10px; + font-size: 14px; + line-height: 1.5; + border-radius: 3px; +} +.form-group-sm select.form-control { + height: 33px; + line-height: 33px; +} +.form-group-sm textarea.form-control, +.form-group-sm select[multiple].form-control { + height: auto; +} +.form-group-sm .form-control-static { + height: 33px; + min-height: 36px; + padding: 6px 10px; + font-size: 14px; + line-height: 1.5; +} +.input-lg { + height: 57px; + padding: 14px 16px; + font-size: 20px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-lg { + height: 57px; + line-height: 57px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.form-group-lg .form-control { + height: 57px; + padding: 14px 16px; + font-size: 20px; + line-height: 1.3333333; + border-radius: 6px; +} +.form-group-lg select.form-control { + height: 57px; + line-height: 57px; +} +.form-group-lg textarea.form-control, +.form-group-lg select[multiple].form-control { + height: auto; +} +.form-group-lg .form-control-static { + height: 57px; + min-height: 42px; + padding: 15px 16px; + font-size: 20px; + line-height: 1.3333333; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 50px; +} +.form-control-feedback { + position: absolute; + top: 0; + right: 0; + z-index: 2; + display: block; + width: 40px; + height: 40px; + line-height: 40px; + text-align: center; + pointer-events: none; +} +.input-lg + .form-control-feedback, +.input-group-lg + .form-control-feedback, +.form-group-lg .form-control + .form-control-feedback { + width: 57px; + height: 57px; + line-height: 57px; +} +.input-sm + .form-control-feedback, +.input-group-sm + .form-control-feedback, +.form-group-sm .form-control + .form-control-feedback { + width: 33px; + height: 33px; + line-height: 33px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline, +.has-success.radio label, +.has-success.checkbox label, +.has-success.radio-inline label, +.has-success.checkbox-inline label { + color: #3fad46; +} +.has-success .form-control { + border-color: #3fad46; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-success .form-control:focus { + border-color: #318837; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #81d186; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #81d186; +} +.has-success .input-group-addon { + color: #3fad46; + border-color: #3fad46; + background-color: #dff0d8; +} +.has-success .form-control-feedback { + color: #3fad46; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline, +.has-warning.radio label, +.has-warning.checkbox label, +.has-warning.radio-inline label, +.has-warning.checkbox-inline label { + color: #f0ad4e; +} +.has-warning .form-control { + border-color: #f0ad4e; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-warning .form-control:focus { + border-color: #ec971f; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f8d9ac; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #f8d9ac; +} +.has-warning .input-group-addon { + color: #f0ad4e; + border-color: #f0ad4e; + background-color: #fcf8e3; +} +.has-warning .form-control-feedback { + color: #f0ad4e; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline, +.has-error.radio label, +.has-error.checkbox label, +.has-error.radio-inline label, +.has-error.checkbox-inline label { + color: #d9534f; +} +.has-error .form-control { + border-color: #d9534f; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} +.has-error .form-control:focus { + border-color: #c9302c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #eba5a3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #eba5a3; +} +.has-error .input-group-addon { + color: #d9534f; + border-color: #d9534f; + background-color: #f2dede; +} +.has-error .form-control-feedback { + color: #d9534f; +} +.has-feedback label ~ .form-control-feedback { + top: 27px; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-static { + display: inline-block; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + margin-top: 0; + margin-bottom: 0; + padding-top: 9px; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 31px; +} +.form-horizontal .form-group { + margin-left: -15px; + margin-right: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + text-align: right; + margin-bottom: 0; + padding-top: 9px; + } +} +.form-horizontal .has-feedback .form-control-feedback { + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 15px; + font-size: 20px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + font-size: 14px; + } +} +.btn { + display: inline-block; + margin-bottom: 0; + font-weight: normal; + text-align: center; + vertical-align: middle; + -ms-touch-action: manipulation; + touch-action: manipulation; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + padding: 8px 12px; + font-size: 16px; + line-height: 1.42857143; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus, +.btn.focus, +.btn:active.focus, +.btn.active.focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus, +.btn.focus { + color: #333333; + text-decoration: none; +} +.btn:active, +.btn.active { + outline: 0; + background-image: none; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + cursor: not-allowed; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; +} +a.btn.disabled, +fieldset[disabled] a.btn { + pointer-events: none; +} +.btn-default { + color: #333333; + background-color: #ffffff; + border-color: #dddddd; +} +.btn-default:focus, +.btn-default.focus { + color: #333333; + background-color: #e6e6e6; + border-color: #9d9d9d; +} +.btn-default:hover { + color: #333333; + background-color: #e6e6e6; + border-color: #bebebe; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333333; + background-color: #e6e6e6; + border-color: #bebebe; +} +.btn-default:active:hover, +.btn-default.active:hover, +.open > .dropdown-toggle.btn-default:hover, +.btn-default:active:focus, +.btn-default.active:focus, +.open > .dropdown-toggle.btn-default:focus, +.btn-default:active.focus, +.btn-default.active.focus, +.open > .dropdown-toggle.btn-default.focus { + color: #333333; + background-color: #d4d4d4; + border-color: #9d9d9d; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled.focus, +.btn-default[disabled].focus, +fieldset[disabled] .btn-default.focus { + background-color: #ffffff; + border-color: #dddddd; +} +.btn-default .badge { + color: #ffffff; + background-color: #333333; +} +.btn-primary { + color: #ffffff; + background-color: #4582ec; + border-color: #4582ec; +} +.btn-primary:focus, +.btn-primary.focus { + color: #ffffff; + background-color: #1863e6; + border-color: #1045a1; +} +.btn-primary:hover { + color: #ffffff; + background-color: #1863e6; + border-color: #175fdd; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #ffffff; + background-color: #1863e6; + border-color: #175fdd; +} +.btn-primary:active:hover, +.btn-primary.active:hover, +.open > .dropdown-toggle.btn-primary:hover, +.btn-primary:active:focus, +.btn-primary.active:focus, +.open > .dropdown-toggle.btn-primary:focus, +.btn-primary:active.focus, +.btn-primary.active.focus, +.open > .dropdown-toggle.btn-primary.focus { + color: #ffffff; + background-color: #1455c6; + border-color: #1045a1; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled.focus, +.btn-primary[disabled].focus, +fieldset[disabled] .btn-primary.focus { + background-color: #4582ec; + border-color: #4582ec; +} +.btn-primary .badge { + color: #4582ec; + background-color: #ffffff; +} +.btn-success { + color: #ffffff; + background-color: #3fad46; + border-color: #3fad46; +} +.btn-success:focus, +.btn-success.focus { + color: #ffffff; + background-color: #318837; + border-color: #1d5020; +} +.btn-success:hover { + color: #ffffff; + background-color: #318837; + border-color: #2f8034; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #ffffff; + background-color: #318837; + border-color: #2f8034; +} +.btn-success:active:hover, +.btn-success.active:hover, +.open > .dropdown-toggle.btn-success:hover, +.btn-success:active:focus, +.btn-success.active:focus, +.open > .dropdown-toggle.btn-success:focus, +.btn-success:active.focus, +.btn-success.active.focus, +.open > .dropdown-toggle.btn-success.focus { + color: #ffffff; + background-color: #286d2c; + border-color: #1d5020; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled.focus, +.btn-success[disabled].focus, +fieldset[disabled] .btn-success.focus { + background-color: #3fad46; + border-color: #3fad46; +} +.btn-success .badge { + color: #3fad46; + background-color: #ffffff; +} +.btn-info { + color: #ffffff; + background-color: #5bc0de; + border-color: #5bc0de; +} +.btn-info:focus, +.btn-info.focus { + color: #ffffff; + background-color: #31b0d5; + border-color: #1f7e9a; +} +.btn-info:hover { + color: #ffffff; + background-color: #31b0d5; + border-color: #2aabd2; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #ffffff; + background-color: #31b0d5; + border-color: #2aabd2; +} +.btn-info:active:hover, +.btn-info.active:hover, +.open > .dropdown-toggle.btn-info:hover, +.btn-info:active:focus, +.btn-info.active:focus, +.open > .dropdown-toggle.btn-info:focus, +.btn-info:active.focus, +.btn-info.active.focus, +.open > .dropdown-toggle.btn-info.focus { + color: #ffffff; + background-color: #269abc; + border-color: #1f7e9a; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled.focus, +.btn-info[disabled].focus, +fieldset[disabled] .btn-info.focus { + background-color: #5bc0de; + border-color: #5bc0de; +} +.btn-info .badge { + color: #5bc0de; + background-color: #ffffff; +} +.btn-warning { + color: #ffffff; + background-color: #f0ad4e; + border-color: #f0ad4e; +} +.btn-warning:focus, +.btn-warning.focus { + color: #ffffff; + background-color: #ec971f; + border-color: #b06d0f; +} +.btn-warning:hover { + color: #ffffff; + background-color: #ec971f; + border-color: #eb9316; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #ffffff; + background-color: #ec971f; + border-color: #eb9316; +} +.btn-warning:active:hover, +.btn-warning.active:hover, +.open > .dropdown-toggle.btn-warning:hover, +.btn-warning:active:focus, +.btn-warning.active:focus, +.open > .dropdown-toggle.btn-warning:focus, +.btn-warning:active.focus, +.btn-warning.active.focus, +.open > .dropdown-toggle.btn-warning.focus { + color: #ffffff; + background-color: #d58512; + border-color: #b06d0f; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled.focus, +.btn-warning[disabled].focus, +fieldset[disabled] .btn-warning.focus { + background-color: #f0ad4e; + border-color: #f0ad4e; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #ffffff; +} +.btn-danger { + color: #ffffff; + background-color: #d9534f; + border-color: #d9534f; +} +.btn-danger:focus, +.btn-danger.focus { + color: #ffffff; + background-color: #c9302c; + border-color: #8b211e; +} +.btn-danger:hover { + color: #ffffff; + background-color: #c9302c; + border-color: #c12e2a; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #ffffff; + background-color: #c9302c; + border-color: #c12e2a; +} +.btn-danger:active:hover, +.btn-danger.active:hover, +.open > .dropdown-toggle.btn-danger:hover, +.btn-danger:active:focus, +.btn-danger.active:focus, +.open > .dropdown-toggle.btn-danger:focus, +.btn-danger:active.focus, +.btn-danger.active.focus, +.open > .dropdown-toggle.btn-danger.focus { + color: #ffffff; + background-color: #ac2925; + border-color: #8b211e; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled.focus, +.btn-danger[disabled].focus, +fieldset[disabled] .btn-danger.focus { + background-color: #d9534f; + border-color: #d9534f; +} +.btn-danger .badge { + color: #d9534f; + background-color: #ffffff; +} +.btn-link { + color: #4582ec; + font-weight: normal; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link.active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #134fb8; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #b3b3b3; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 14px 16px; + font-size: 20px; + line-height: 1.3333333; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 14px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 14px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition-property: height, visibility; + -o-transition-property: height, visibility; + transition-property: height, visibility; + -webkit-transition-duration: 0.35s; + -o-transition-duration: 0.35s; + transition-duration: 0.35s; + -webkit-transition-timing-function: ease; + -o-transition-timing-function: ease; + transition-timing-function: ease; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px dashed; + border-top: 4px solid \9; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropup, +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + font-size: 16px; + text-align: left; + background-color: #ffffff; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); + -webkit-background-clip: padding-box; + background-clip: padding-box; +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 10px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + text-decoration: none; + color: #ffffff; + background-color: #4582ec; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + outline: 0; + background-color: #4582ec; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #b3b3b3; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + cursor: not-allowed; +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + left: auto; + right: 0; +} +.dropdown-menu-left { + left: 0; + right: auto; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 14px; + line-height: 1.42857143; + color: #b3b3b3; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + left: 0; + right: 0; + bottom: 0; + top: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px dashed; + border-bottom: 4px solid \9; + content: ""; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 2px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + left: auto; + right: 0; + } + .navbar-right .dropdown-menu-left { + left: 0; + right: auto; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn, +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-left: 8px; + padding-right: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-left: 12px; + padding-right: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-right-radius: 0; + border-top-left-radius: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + float: none; + display: table-cell; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn input[type="radio"], +[data-toggle="buttons"] > .btn-group > .btn input[type="radio"], +[data-toggle="buttons"] > .btn input[type="checkbox"], +[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-left: 0; + padding-right: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group .form-control:focus { + z-index: 3; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 57px; + padding: 14px 16px; + font-size: 20px; + line-height: 1.3333333; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 57px; + line-height: 57px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 33px; + padding: 5px 10px; + font-size: 14px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 33px; + line-height: 33px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 8px 12px; + font-size: 16px; + font-weight: normal; + line-height: 1; + color: #333333; + text-align: center; + background-color: #eeeeee; + border: 1px solid #dddddd; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 14px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 14px 16px; + font-size: 20px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-bottom-right-radius: 0; + border-top-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-bottom-left-radius: 0; + border-top-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + z-index: 2; + margin-left: -1px; +} +.nav { + margin-bottom: 0; + padding-left: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} +.nav > li.disabled > a { + color: #b3b3b3; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #b3b3b3; + text-decoration: none; + background-color: transparent; + cursor: not-allowed; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eeeeee; + border-color: #4582ec; +} +.nav .nav-divider { + height: 1px; + margin: 10px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #dddddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eeeeee #eeeeee #dddddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555555; + background-color: #ffffff; + border: 1px solid #dddddd; + border-bottom-color: transparent; + cursor: default; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #dddddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #dddddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #ffffff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #ffffff; + background-color: #4582ec; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + text-align: center; + margin-bottom: 5px; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #dddddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #dddddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #ffffff; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar { + position: relative; + min-height: 65px; + margin-bottom: 22px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + overflow-x: visible; + padding-right: 15px; + padding-left: 15px; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); + -webkit-overflow-scrolling: touch; +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-left: 0; + padding-right: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-device-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +.navbar-brand > img { + display: block; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + margin-right: 15px; + padding: 9px 10px; + margin-top: 15.5px; + margin-bottom: 15.5px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 10.75px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 22px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 22px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 21.5px; + padding-bottom: 21.5px; + } +} +.navbar-form { + margin-left: -15px; + margin-right: -15px; + padding: 10px 15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); + margin-top: 12.5px; + margin-bottom: 12.5px; +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .form-control-static { + display: inline-block; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } + .navbar-form .form-group:last-child { + margin-bottom: 0; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + border: 0; + margin-left: 0; + margin-right: 0; + padding-top: 0; + padding-bottom: 0; + -webkit-box-shadow: none; + box-shadow: none; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + margin-bottom: 0; + border-top-right-radius: 4px; + border-top-left-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 12.5px; + margin-bottom: 12.5px; +} +.navbar-btn.btn-sm { + margin-top: 16px; + margin-bottom: 16px; +} +.navbar-btn.btn-xs { + margin-top: 21.5px; + margin-bottom: 21.5px; +} +.navbar-text { + margin-top: 21.5px; + margin-bottom: 21.5px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-left: 15px; + margin-right: 15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + margin-right: -15px; + } + .navbar-right ~ .navbar-right { + margin-right: 0; + } +} +.navbar-default { + background-color: #ffffff; + border-color: #dddddd; +} +.navbar-default .navbar-brand { + color: #4582ec; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #4582ec; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #333333; +} +.navbar-default .navbar-nav > li > a { + color: #4582ec; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #4582ec; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #4582ec; + background-color: transparent; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #333333; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #dddddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #dddddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #cccccc; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #dddddd; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: transparent; + color: #4582ec; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #4582ec; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #4582ec; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #4582ec; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #333333; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #4582ec; +} +.navbar-default .navbar-link:hover { + color: #4582ec; +} +.navbar-default .btn-link { + color: #4582ec; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #4582ec; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #333333; +} +.navbar-inverse { + background-color: #ffffff; + border-color: #dddddd; +} +.navbar-inverse .navbar-brand { + color: #333333; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #333333; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #333333; +} +.navbar-inverse .navbar-nav > li > a { + color: #333333; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #333333; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #333333; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #cccccc; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #dddddd; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #dddddd; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #cccccc; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #ededed; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + background-color: transparent; + color: #333333; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #dddddd; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #dddddd; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #333333; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333333; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #333333; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #cccccc; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #333333; +} +.navbar-inverse .navbar-link:hover { + color: #333333; +} +.navbar-inverse .btn-link { + color: #333333; +} +.navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link:focus { + color: #333333; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #cccccc; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 22px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + content: "/\00a0"; + padding: 0 5px; + color: #cccccc; +} +.breadcrumb > .active { + color: #b3b3b3; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 22px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 8px 12px; + line-height: 1.42857143; + text-decoration: none; + color: #333333; + background-color: #ffffff; + border: 1px solid #dddddd; + margin-left: -1px; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-bottom-left-radius: 4px; + border-top-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-bottom-right-radius: 4px; + border-top-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + z-index: 2; + color: #ffffff; + background-color: #4582ec; + border-color: #4582ec; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 3; + color: #ffffff; + background-color: #4582ec; + border-color: #4582ec; + cursor: default; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #b3b3b3; + background-color: #ffffff; + border-color: #dddddd; + cursor: not-allowed; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 14px 16px; + font-size: 20px; + line-height: 1.3333333; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-bottom-left-radius: 6px; + border-top-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-bottom-right-radius: 6px; + border-top-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 14px; + line-height: 1.5; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-bottom-left-radius: 3px; + border-top-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-bottom-right-radius: 3px; + border-top-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 22px 0; + list-style: none; + text-align: center; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #4582ec; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #b3b3b3; + background-color: #ffffff; + cursor: not-allowed; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #ffffff; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #e6e6e6; +} +.label-primary { + background-color: #4582ec; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #1863e6; +} +.label-success { + background-color: #3fad46; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #318837; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 14px; + font-weight: bold; + color: #ffffff; + line-height: 1; + vertical-align: middle; + white-space: nowrap; + text-align: center; + background-color: #4582ec; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge, +.btn-group-xs > .btn .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} +.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #4582ec; + background-color: #ffffff; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding-top: 30px; + padding-bottom: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #f7f7f7; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 24px; + font-weight: 200; +} +.jumbotron > hr { + border-top-color: #dedede; +} +.container .jumbotron, +.container-fluid .jumbotron { + border-radius: 6px; + padding-left: 15px; + padding-right: 15px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron, + .container-fluid .jumbotron { + padding-left: 60px; + padding-right: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 72px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 22px; + line-height: 1.42857143; + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + -webkit-transition: border 0.2s ease-in-out; + -o-transition: border 0.2s ease-in-out; + transition: border 0.2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-left: auto; + margin-right: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #4582ec; +} +.thumbnail .caption { + padding: 9px; + color: #333333; +} +.alert { + padding: 15px; + margin-bottom: 22px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + background-color: #3fad46; + border-color: #3fad46; + color: #ffffff; +} +.alert-success hr { + border-top-color: #389a3e; +} +.alert-success .alert-link { + color: #e6e6e6; +} +.alert-info { + background-color: #5bc0de; + border-color: #5bc0de; + color: #ffffff; +} +.alert-info hr { + border-top-color: #46b8da; +} +.alert-info .alert-link { + color: #e6e6e6; +} +.alert-warning { + background-color: #f0ad4e; + border-color: #f0ad4e; + color: #ffffff; +} +.alert-warning hr { + border-top-color: #eea236; +} +.alert-warning .alert-link { + color: #e6e6e6; +} +.alert-danger { + background-color: #d9534f; + border-color: #d9534f; + color: #ffffff; +} +.alert-danger hr { + border-top-color: #d43f3a; +} +.alert-danger .alert-link { + color: #e6e6e6; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + overflow: hidden; + height: 22px; + margin-bottom: 22px; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} +.progress-bar { + float: left; + width: 0%; + height: 100%; + font-size: 14px; + line-height: 22px; + color: #ffffff; + text-align: center; + background-color: #4582ec; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar-success { + background-color: #3fad46; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} +.media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media, +.media-body { + zoom: 1; + overflow: hidden; +} +.media-body { + width: 10000px; +} +.media-object { + display: block; +} +.media-object.img-thumbnail { + max-width: none; +} +.media-right, +.media > .pull-right { + padding-left: 10px; +} +.media-left, +.media > .pull-left { + padding-right: 10px; +} +.media-left, +.media-right, +.media-body { + display: table-cell; + vertical-align: top; +} +.media-middle { + vertical-align: middle; +} +.media-bottom { + vertical-align: bottom; +} +.media-heading { + margin-top: 0; + margin-bottom: 5px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + margin-bottom: 20px; + padding-left: 0; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #ffffff; + border: 1px solid #dddddd; +} +.list-group-item:first-child { + border-top-right-radius: 4px; + border-top-left-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +a.list-group-item, +button.list-group-item { + color: #555555; +} +a.list-group-item .list-group-item-heading, +button.list-group-item .list-group-item-heading { + color: #333333; +} +a.list-group-item:hover, +button.list-group-item:hover, +a.list-group-item:focus, +button.list-group-item:focus { + text-decoration: none; + color: #555555; + background-color: #f5f5f5; +} +button.list-group-item { + width: 100%; + text-align: left; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + background-color: #eeeeee; + color: #b3b3b3; + cursor: not-allowed; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #b3b3b3; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #ffffff; + background-color: #4582ec; + border-color: #4582ec; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #fefeff; +} +.list-group-item-success { + color: #3fad46; + background-color: #dff0d8; +} +a.list-group-item-success, +button.list-group-item-success { + color: #3fad46; +} +a.list-group-item-success .list-group-item-heading, +button.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +button.list-group-item-success:hover, +a.list-group-item-success:focus, +button.list-group-item-success:focus { + color: #3fad46; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +button.list-group-item-success.active, +a.list-group-item-success.active:hover, +button.list-group-item-success.active:hover, +a.list-group-item-success.active:focus, +button.list-group-item-success.active:focus { + color: #fff; + background-color: #3fad46; + border-color: #3fad46; +} +.list-group-item-info { + color: #5bc0de; + background-color: #d9edf7; +} +a.list-group-item-info, +button.list-group-item-info { + color: #5bc0de; +} +a.list-group-item-info .list-group-item-heading, +button.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +button.list-group-item-info:hover, +a.list-group-item-info:focus, +button.list-group-item-info:focus { + color: #5bc0de; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +button.list-group-item-info.active, +a.list-group-item-info.active:hover, +button.list-group-item-info.active:hover, +a.list-group-item-info.active:focus, +button.list-group-item-info.active:focus { + color: #fff; + background-color: #5bc0de; + border-color: #5bc0de; +} +.list-group-item-warning { + color: #f0ad4e; + background-color: #fcf8e3; +} +a.list-group-item-warning, +button.list-group-item-warning { + color: #f0ad4e; +} +a.list-group-item-warning .list-group-item-heading, +button.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +button.list-group-item-warning:hover, +a.list-group-item-warning:focus, +button.list-group-item-warning:focus { + color: #f0ad4e; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +button.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +button.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus, +button.list-group-item-warning.active:focus { + color: #fff; + background-color: #f0ad4e; + border-color: #f0ad4e; +} +.list-group-item-danger { + color: #d9534f; + background-color: #f2dede; +} +a.list-group-item-danger, +button.list-group-item-danger { + color: #d9534f; +} +a.list-group-item-danger .list-group-item-heading, +button.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +button.list-group-item-danger:hover, +a.list-group-item-danger:focus, +button.list-group-item-danger:focus { + color: #d9534f; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +button.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +button.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus, +button.list-group-item-danger.active:focus { + color: #fff; + background-color: #d9534f; + border-color: #d9534f; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 22px; + background-color: #ffffff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 18px; + color: inherit; +} +.panel-title > a, +.panel-title > small, +.panel-title > .small, +.panel-title > small > a, +.panel-title > .small > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #ffffff; + border-top: 1px solid #dddddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group, +.panel > .panel-collapse > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item, +.panel > .panel-collapse > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child, +.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child, +.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { + border-top-right-radius: 0; + border-top-left-radius: 0; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table caption, +.panel > .table-responsive > .table caption, +.panel > .panel-collapse > .table caption { + padding-left: 15px; + padding-right: 15px; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-right-radius: 3px; + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { + border-bottom-left-radius: 3px; + border-bottom-right-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive, +.panel > .table + .panel-body, +.panel > .table-responsive + .panel-body { + border-top: 1px solid #dddddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + border: 0; + margin-bottom: 0; +} +.panel-group { + margin-bottom: 22px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body, +.panel-group .panel-heading + .panel-collapse > .list-group { + border-top: 1px solid #dddddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #dddddd; +} +.panel-default { + border-color: #dddddd; +} +.panel-default > .panel-heading { + color: #333333; + background-color: #f5f5f5; + border-color: #dddddd; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #dddddd; +} +.panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333333; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #dddddd; +} +.panel-primary { + border-color: #4582ec; +} +.panel-primary > .panel-heading { + color: #ffffff; + background-color: #4582ec; + border-color: #4582ec; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #4582ec; +} +.panel-primary > .panel-heading .badge { + color: #4582ec; + background-color: #ffffff; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #4582ec; +} +.panel-success { + border-color: #3fad46; +} +.panel-success > .panel-heading { + color: #ffffff; + background-color: #3fad46; + border-color: #3fad46; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #3fad46; +} +.panel-success > .panel-heading .badge { + color: #3fad46; + background-color: #ffffff; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #3fad46; +} +.panel-info { + border-color: #5bc0de; +} +.panel-info > .panel-heading { + color: #ffffff; + background-color: #5bc0de; + border-color: #5bc0de; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #5bc0de; +} +.panel-info > .panel-heading .badge { + color: #5bc0de; + background-color: #ffffff; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #5bc0de; +} +.panel-warning { + border-color: #f0ad4e; +} +.panel-warning > .panel-heading { + color: #ffffff; + background-color: #f0ad4e; + border-color: #f0ad4e; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #f0ad4e; +} +.panel-warning > .panel-heading .badge { + color: #f0ad4e; + background-color: #ffffff; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #f0ad4e; +} +.panel-danger { + border-color: #d9534f; +} +.panel-danger > .panel-heading { + color: #ffffff; + background-color: #d9534f; + border-color: #d9534f; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d9534f; +} +.panel-danger > .panel-heading .badge { + color: #d9534f; + background-color: #ffffff; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d9534f; +} +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + left: 0; + bottom: 0; + height: 100%; + width: 100%; + border: 0; +} +.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.embed-responsive-4by3 { + padding-bottom: 75%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f7f7f7; + border: 1px solid #e5e5e5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 24px; + font-weight: bold; + line-height: 1; + color: #ffffff; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} +.close:hover, +.close:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; + opacity: 0.5; + filter: alpha(opacity=50); +} +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} +.modal-open { + overflow: hidden; +} +.modal { + display: none; + overflow: hidden; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transform: translate(0, -25%); + -ms-transform: translate(0, -25%); + -o-transform: translate(0, -25%); + transform: translate(0, -25%); + -webkit-transition: -webkit-transform 0.3s ease-out; + -o-transition: -o-transform 0.3s ease-out; + transition: transform 0.3s ease-out; +} +.modal.in .modal-dialog { + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #ffffff; + border: 1px solid #999999; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); + -webkit-background-clip: padding-box; + background-clip: padding-box; + outline: 0; +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} +.modal-backdrop.fade { + opacity: 0; + filter: alpha(opacity=0); +} +.modal-backdrop.in { + opacity: 0.5; + filter: alpha(opacity=50); +} +.modal-header { + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 20px; +} +.modal-footer { + padding: 20px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-left: 5px; + margin-bottom: 0; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-family: Georgia, "Times New Roman", Times, serif; + font-style: normal; + font-weight: normal; + letter-spacing: normal; + line-break: auto; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + white-space: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + font-size: 14px; + opacity: 0; + filter: alpha(opacity=0); +} +.tooltip.in { + opacity: 0.9; + filter: alpha(opacity=90); +} +.tooltip.top { + margin-top: -3px; + padding: 5px 0; +} +.tooltip.right { + margin-left: 3px; + padding: 0 5px; +} +.tooltip.bottom { + margin-top: 3px; + padding: 5px 0; +} +.tooltip.left { + margin-left: -3px; + padding: 0 5px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #ffffff; + text-align: center; + background-color: #000000; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.top-left .tooltip-arrow { + bottom: 0; + right: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.top-right .tooltip-arrow { + bottom: 0; + left: 5px; + margin-bottom: -5px; + border-width: 5px 5px 0; + border-top-color: #000000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + right: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + left: 5px; + margin-top: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + font-family: Georgia, "Times New Roman", Times, serif; + font-style: normal; + font-weight: normal; + letter-spacing: normal; + line-break: auto; + line-height: 1.42857143; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + white-space: normal; + word-break: normal; + word-spacing: normal; + word-wrap: normal; + font-size: 16px; + background-color: #ffffff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #cccccc; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + margin: 0; + padding: 8px 14px; + font-size: 16px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + border-width: 10px; + content: ""; +} +.popover.top > .arrow { + left: 50%; + margin-left: -11px; + border-bottom-width: 0; + border-top-color: #999999; + border-top-color: rgba(0, 0, 0, 0.25); + bottom: -11px; +} +.popover.top > .arrow:after { + content: " "; + bottom: 1px; + margin-left: -10px; + border-bottom-width: 0; + border-top-color: #ffffff; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-left-width: 0; + border-right-color: #999999; + border-right-color: rgba(0, 0, 0, 0.25); +} +.popover.right > .arrow:after { + content: " "; + left: 1px; + bottom: -10px; + border-left-width: 0; + border-right-color: #ffffff; +} +.popover.bottom > .arrow { + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999999; + border-bottom-color: rgba(0, 0, 0, 0.25); + top: -11px; +} +.popover.bottom > .arrow:after { + content: " "; + top: 1px; + margin-left: -10px; + border-top-width: 0; + border-bottom-color: #ffffff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999999; + border-left-color: rgba(0, 0, 0, 0.25); +} +.popover.left > .arrow:after { + content: " "; + right: 1px; + border-right-width: 0; + border-left-color: #ffffff; + bottom: -10px; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + overflow: hidden; + width: 100%; +} +.carousel-inner > .item { + display: none; + position: relative; + -webkit-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +@media all and (transform-3d), (-webkit-transform-3d) { + .carousel-inner > .item { + -webkit-transition: -webkit-transform 0.6s ease-in-out; + -o-transition: -o-transform 0.6s ease-in-out; + transition: transform 0.6s ease-in-out; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-perspective: 1000px; + perspective: 1000px; + } + .carousel-inner > .item.next, + .carousel-inner > .item.active.right { + -webkit-transform: translate3d(100%, 0, 0); + transform: translate3d(100%, 0, 0); + left: 0; + } + .carousel-inner > .item.prev, + .carousel-inner > .item.active.left { + -webkit-transform: translate3d(-100%, 0, 0); + transform: translate3d(-100%, 0, 0); + left: 0; + } + .carousel-inner > .item.next.left, + .carousel-inner > .item.prev.right, + .carousel-inner > .item.active { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + left: 0; + } +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 15%; + opacity: 0.5; + filter: alpha(opacity=50); + font-size: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); + background-color: rgba(0, 0, 0, 0); +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001))); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); +} +.carousel-control.right { + left: auto; + right: 0; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5))); + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); +} +.carousel-control:hover, +.carousel-control:focus { + outline: 0; + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + margin-top: -10px; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + line-height: 1; + font-family: serif; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + margin-left: -30%; + padding-left: 0; + list-style: none; + text-align: center; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + border: 1px solid #ffffff; + border-radius: 10px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); +} +.carousel-indicators .active { + margin: 0; + width: 12px; + height: 12px; + background-color: #ffffff; +} +.carousel-caption { + position: absolute; + left: 15%; + right: 15%; + bottom: 20px; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #ffffff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -10px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -10px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -10px; + } + .carousel-caption { + left: 20%; + right: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-header:before, +.modal-header:after, +.modal-footer:before, +.modal-footer:after { + content: " "; + display: table; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-header:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-left: auto; + margin-right: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; +} +.affix { + position: fixed; +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table !important; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table !important; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table !important; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table !important; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table !important; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +.navbar { + font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.navbar-nav, +.navbar-form { + margin-left: 0; + margin-right: 0; +} +.navbar-nav > li > a { + margin: 12.5px 6px; + padding: 8px 12px; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-nav > li > a:hover { + border: 1px solid #ddd; +} +.navbar-nav > .active > a, +.navbar-nav > .active > a:hover { + border: 1px solid #ddd; +} +.navbar-default .navbar-nav > .active > a:hover { + color: #4582ec; +} +.navbar-inverse .navbar-nav > .active > a:hover { + color: #333333; +} +.navbar-brand { + padding-top: 12.5px; + padding-bottom: 12.5px; + line-height: 1.9; +} +@media (min-width: 768px) { + .navbar .navbar-nav > li > a { + padding: 8px 12px; + } +} +@media (max-width: 767px) { + .navbar .navbar-nav > li > a { + margin: 0; + } +} +.btn { + font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif; +} +legend { + font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.input-group-addon { + font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + border: 1px solid #ddd; +} +.pagination { + font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 14px 24px; +} +.pager { + font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.pager a { + color: #333333; +} +.pager a:hover { + border-color: transparent; + color: #fff; +} +.pager .disabled a { + border-color: #dddddd; +} +.close { + color: #fff; + text-decoration: none; + text-shadow: none; + opacity: 0.4; +} +.close:hover, +.close:focus { + color: #fff; + opacity: 1; +} +.alert .alert-link { + color: #ffffff; + text-decoration: underline; +} +.label { + font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: normal; +} +.label-default { + border: 1px solid #ddd; + color: #333333; +} +.badge { + padding: 1px 7px 5px; + vertical-align: 2px; + font-family: "Raleway", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-weight: normal; +} +.panel { + -webkit-box-shadow: none; + box-shadow: none; +} +.panel-default .close { + color: #333333; +} +.modal .close { + color: #333333; +} diff --git a/_sass/_custom.scss b/_sass/_custom.scss new file mode 100644 index 0000000..139597f --- /dev/null +++ b/_sass/_custom.scss @@ -0,0 +1,2 @@ + + diff --git a/_sass/_layout.scss b/_sass/_layout.scss new file mode 100644 index 0000000..a9acbc2 --- /dev/null +++ b/_sass/_layout.scss @@ -0,0 +1,142 @@ +html, body { + height: 100%; +} + +img { + max-width: 100%; +} + +.mt50 { + margin-top: 50px; +} +.mt20 { + margin-top: 20px; +} + +.mt10 { + margin-top: 10px; +} +.navbar-brand { + font-weight: 900; + font-size: 1.85em; + padding: 10px; + @media screen and (max-width: $on-palm) { + font-size: 1.5em; + } +} +.post-meta { + color: $grey-color; +} + +.panel { + border:none; + box-shadow: 0px 0px 1px $grey-color; +} + +.panel:hover { + box-shadow: 0px 0px 6px $grey-color; +} + + +footer { + border-top: 1px solid $grey-color-light; +} + +.social { + list-style: none; + display: inline; + margin-left: 10px; + padding: 5px 8px; + } +.social:hover { + opacity: 0.7; +} +.social img { + width: 20px; +} + +.quora img{ + width: 17px; +} + +.facebook img { + width: 16px; +} + +.recent ul { + list-style: none; + padding: 0; + text-align: justify; +} + +.recent { + padding: 10px; + border: 1px solid $grey-color-light; +} + +.post-img img { + width: 100%; +} + + +.pack { + + + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + flex-wrap: wrap; + -webkit-flex-wrap: wrap; +} + +.panel-container { + display: flex; + flex-direction: row; + overflow: hidden; + height: 82%; + + /* avoid browser level touch actions */ + xtouch-action: none; +} + +.terminal { + font-size: 15px; +} + + +.panel-left { + flex: 0 0 auto; + /* only manually resize */ + padding: 0 15px; + width: 50%; + min-height: 400px; + min-width: 150px; + height: 100%; + overflow-y: auto; +} + +.splitter { + flex: 0 0 auto; + width: 18px; + background: url(https://raw.githubusercontent.com/RickStrahl/jquery-resizable/master/assets/vsizegrip.png) center center no-repeat #2fa8c3; + min-height: 200px; + cursor: col-resize; +} + +.panel-right { + height: 100%; + flex: 1 1 auto; + /* resizable */ + width: 100%; + min-height: 300px; + background: #000; +} + + +.card { + float: none; +} + +code[class*="."] { + cursor: pointer; +} diff --git a/_sass/_syntax-highlighting.scss b/_sass/_syntax-highlighting.scss new file mode 100644 index 0000000..b13b045 --- /dev/null +++ b/_sass/_syntax-highlighting.scss @@ -0,0 +1,72 @@ +/** + * Syntax highlighting styles + */ +.highlight { + background: #fff; + text-shadow: 0px 0px 0.2px; + /* @extend %vertical-rhythm; */ + + .highlighter-rouge & { + background: #eef; + } + + .c { color: #998; font-style: italic } // Comment + .err { color: #a61717; } // Error + .k { font-weight: bold } // Keyword + .o { font-weight: bold } // Operator + .cm { color: #998; font-style: italic } // Comment.Multiline + .cp { color: #999; font-weight: bold } // Comment.Preproc + .c1 { color: #998; font-style: italic } // Comment.Single + .cs { color: #999; font-weight: bold; font-style: italic } // Comment.Special + .gd { color: #000; } // Generic.Deleted + .gd .x { color: #000; } // Generic.Deleted.Specific + .ge { font-style: italic } // Generic.Emph + .gr { color: #a00 } // Generic.Error + .gh { color: #999 } // Generic.Heading + .gi { color: #000;} // Generic.Inserted + .gi .x { color: #000; } // Generic.Inserted.Specific + .go { color: #888 } // Generic.Output + .gp { color: #555 } // Generic.Prompt + .gs { font-weight: bold } // Generic.Strong + .gu { color: #aaa } // Generic.Subheading + .gt { color: #a00 } // Generic.Traceback + .kc { font-weight: bold } // Keyword.Constant + .kd { font-weight: bold } // Keyword.Declaration + .kp { font-weight: bold } // Keyword.Pseudo + .kr { font-weight: bold } // Keyword.Reserved + .kt { color: #458; font-weight: bold } // Keyword.Type + .m { color: #099 } // Literal.Number + .s { color: #d14 } // Literal.String + .na { color: #008080 } // Name.Attribute + .nb { color: #0086B3 } // Name.Builtin + .nc { color: #458; font-weight: bold } // Name.Class + .no { color: #008080 } // Name.Constant + .ni { color: #800080 } // Name.Entity + .ne { color: #900; font-weight: bold } // Name.Exception + .nf { color: #900; font-weight: bold } // Name.Function + .nn { color: #555 } // Name.Namespace + .nt { color: #000080 } // Name.Tag + .nv { color: #008080 } // Name.Variable + .ow { font-weight: bold } // Operator.Word + .w { color: #bbb } // Text.Whitespace + .mf { color: #099 } // Literal.Number.Float + .mh { color: #099 } // Literal.Number.Hex + .mi { color: #099 } // Literal.Number.Integer + .mo { color: #099 } // Literal.Number.Oct + .sb { color: #d14 } // Literal.String.Backtick + .sc { color: #d14 } // Literal.String.Char + .sd { color: #d14 } // Literal.String.Doc + .s2 { color: #d14 } // Literal.String.Double + .se { color: #d14 } // Literal.String.Escape + .sh { color: #d14 } // Literal.String.Heredoc + .si { color: #d14 } // Literal.String.Interpol + .sx { color: #d14 } // Literal.String.Other + .sr { color: #009926 } // Literal.String.Regex + .s1 { color: #d14 } // Literal.String.Single + .ss { color: #990073 } // Literal.String.Symbol + .bp { color: #999 } // Name.Builtin.Pseudo + .vc { color: #008080 } // Name.Variable.Class + .vg { color: #008080 } // Name.Variable.Global + .vi { color: #008080 } // Name.Variable.Instance + .il { color: #099 } // Literal.Number.Integer.Long +} diff --git a/_sass/component/_tag.scss b/_sass/component/_tag.scss new file mode 100644 index 0000000..dcda3c5 --- /dev/null +++ b/_sass/component/_tag.scss @@ -0,0 +1,63 @@ +.post-tag { + display: inline-block; + background: rgba($brand-color, 0.15); + padding: 0 .5rem; + margin-right: .5rem; + border-radius: 4px; + color: $brand-color; + font-family: $base-font-family; + font-size: 90%; + &:before { + content: "\f02b"; + font-family: FontAwesome; + padding-right: .5em; + } + &:hover { + text-decoration: none; + background: $brand-color; + color: #fff; + } +} + +.tags-expo { + :target:before { + content:""; + display:block; + height:72px; /* fixed header height*/ + margin:-72px 0 0; /* negative fixed header height */ + } + .tags-expo-list { + @media (min-width: 38em) { + font-size: 2.9rem; + .post-tag { + margin: .2em .3em; + } + } + } + .tags-expo-section { + ul { + list-style-type: circle; + list-style-position: inside; + padding: 0; + li { + padding: 0 1rem; + &:hover { + list-style-type: disc; + padding: 0 .5rem; + } + } + } + a { + text-decoration: none; + } + .post-date { + display: inline-block; + font-size: 80%; + color: #000; + margin: 0; + padding: 0; + } + font-family: $base-font-family; + } +} + diff --git a/about.md b/about.md new file mode 100644 index 0000000..93a7059 --- /dev/null +++ b/about.md @@ -0,0 +1,10 @@ +--- +layout: page +title: About +permalink: /about/ +--- + +
+ + +This site has been made by Docker captains [Marcos Nils](http://twitter.com/marcosnils) and [Jonathan Leibiusky](http://twitter.com/xetorthio) diff --git a/css/bootstrap.min.scss b/css/bootstrap.min.scss new file mode 100644 index 0000000..865e4df --- /dev/null +++ b/css/bootstrap.min.scss @@ -0,0 +1,51 @@ +--- +# Only the main Sass file needs front matter (the dashes are enough) +--- +@charset "utf-8"; + + + +// Our variables +$base-font-family: Georgia, "Times New Roman", Times, serif; +$base-font-size: 16px; +$base-font-weight: 400; +$small-font-size: $base-font-size * 0.875; +$base-line-height: 1.5; + +$spacing-unit: 30px; + +$text-color: #111; +$background-color: #fdfdfd; +$brand-color: #2a7ae2; + +$grey-color: #828282; +$grey-color-light: lighten($grey-color, 40%); +$grey-color-dark: darken($grey-color, 25%); + +// Width of the content area +$content-width: 800px; + +$on-palm: 600px; +$on-laptop: 800px; + + + +// Use media queries like this: +// @include media-query($on-palm) { +// .wrapper { +// padding-right: $spacing-unit / 2; +// padding-left: $spacing-unit / 2; +// } +// } +@mixin media-query($device) { + @media screen and (max-width: $device) { + @content; + } +} + + + +// Import partials from `sass_dir` (defaults to `_sass`) +@import + "bootstrap-readable" +; diff --git a/css/syntax-highlighting.scss b/css/syntax-highlighting.scss new file mode 100644 index 0000000..3f8b057 --- /dev/null +++ b/css/syntax-highlighting.scss @@ -0,0 +1,51 @@ +--- +# Only the main Sass file needs front matter (the dashes are enough) +--- +@charset "utf-8"; + + + +// Our variables +$base-font-family: Georgia, "Times New Roman", Times, serif; +$base-font-size: 16px; +$base-font-weight: 400; +$small-font-size: $base-font-size * 0.875; +$base-line-height: 1.5; + +$spacing-unit: 30px; + +$text-color: #111; +$background-color: #fdfdfd; +$brand-color: #2a7ae2; + +$grey-color: #828282; +$grey-color-light: lighten($grey-color, 40%); +$grey-color-dark: darken($grey-color, 25%); + +// Width of the content area +$content-width: 800px; + +$on-palm: 600px; +$on-laptop: 800px; + + + +// Use media queries like this: +// @include media-query($on-palm) { +// .wrapper { +// padding-right: $spacing-unit / 2; +// padding-left: $spacing-unit / 2; +// } +// } +@mixin media-query($device) { + @media screen and (max-width: $device) { + @content; + } +} + + + +// Import partials from `sass_dir` (defaults to `_sass`) +@import + "syntax-highlighting" +; diff --git a/css/xterm.css b/css/xterm.css new file mode 100644 index 0000000..4877f86 --- /dev/null +++ b/css/xterm.css @@ -0,0 +1,2206 @@ +/** + * xterm.js: xterm, in the browser + * Copyright (c) 2014-2016, SourceLair Private Company (www.sourcelair.com (MIT License) + * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) + * https://github.com/chjj/term.js + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Originally forked from (with the author's permission): + * Fabrice Bellard's javascript vt100 for jslinux: + * http://bellard.org/jslinux/ + * Copyright (c) 2011 Fabrice Bellard + * The original design remains. The terminal itself + * has been extended to include xterm CSI codes, among + * other features. + */ + +/* + * Default style for xterm.js + */ + +.terminal { + background-color: #000; + color: #fff; + font-family: courier-new, courier, monospace; + font-feature-settings: "liga" 0; + position: relative; +} + +.terminal.focus, +.terminal:focus { + outline: none; +} + +.terminal .xterm-helpers { + position: absolute; + top: 0; +} + +.terminal .xterm-helper-textarea { + /* + * HACK: to fix IE's blinking cursor + * Move textarea out of the screen to the far left, so that the cursor is not visible. + */ + position: absolute; + opacity: 0; + left: -9999em; + top: 0; + width: 0; + height: 0; + z-index: -10; + /** Prevent wrapping so the IME appears against the textarea at the correct position */ + white-space: nowrap; + overflow: hidden; + resize: none; +} + +.terminal .terminal-cursor { + background-color: #fff; + color: #000; +} + +.terminal:not(.focus) .terminal-cursor { + outline: 1px solid #fff; + outline-offset: -1px; + background-color: transparent; +} + +.terminal.focus .terminal-cursor.blinking { + animation: blink-cursor 1.2s infinite step-end; +} + +@keyframes blink-cursor { + 0% { + background-color: #fff; + color: #000; + } + 50% { + background-color: transparent; + color: #FFF; + } +} + +.terminal .composition-view { + background: #000; + color: #FFF; + display: none; + position: absolute; + white-space: nowrap; + z-index: 1; +} + +.terminal .composition-view.active { + display: block; +} + +.terminal .xterm-viewport { + /* On OS X this is required in order for the scroll bar to appear fully opaque */ + background-color: #000; + overflow-y: scroll; +} + +.terminal .xterm-rows { + position: absolute; + left: 0; + top: 0; +} + +.terminal .xterm-rows > div { + /* Lines containing spans and text nodes ocassionally wrap despite being the same width (#327) */ + white-space: nowrap; +} + +.terminal .xterm-scroll-area { + visibility: hidden; +} + +.terminal .xterm-char-measure-element { + display: inline-block; + visibility: hidden; + position: absolute; + left: -9999em; +} + +/* + * Determine default colors for xterm.js + */ +.terminal .xterm-bold { + font-weight: bold; +} + +.terminal .xterm-underline { + text-decoration: underline; +} + +.terminal .xterm-blink { + text-decoration: blink; +} + +.terminal .xterm-hidden { + visibility: hidden; +} + +.terminal .xterm-color-0 { + color: #2e3436; +} + +.terminal .xterm-bg-color-0 { + background-color: #2e3436; +} + +.terminal .xterm-color-1 { + color: #cc0000; +} + +.terminal .xterm-bg-color-1 { + background-color: #cc0000; +} + +.terminal .xterm-color-2 { + color: #4e9a06; +} + +.terminal .xterm-bg-color-2 { + background-color: #4e9a06; +} + +.terminal .xterm-color-3 { + color: #c4a000; +} + +.terminal .xterm-bg-color-3 { + background-color: #c4a000; +} + +.terminal .xterm-color-4 { + color: #3465a4; +} + +.terminal .xterm-bg-color-4 { + background-color: #3465a4; +} + +.terminal .xterm-color-5 { + color: #75507b; +} + +.terminal .xterm-bg-color-5 { + background-color: #75507b; +} + +.terminal .xterm-color-6 { + color: #06989a; +} + +.terminal .xterm-bg-color-6 { + background-color: #06989a; +} + +.terminal .xterm-color-7 { + color: #d3d7cf; +} + +.terminal .xterm-bg-color-7 { + background-color: #d3d7cf; +} + +.terminal .xterm-color-8 { + color: #555753; +} + +.terminal .xterm-bg-color-8 { + background-color: #555753; +} + +.terminal .xterm-color-9 { + color: #ef2929; +} + +.terminal .xterm-bg-color-9 { + background-color: #ef2929; +} + +.terminal .xterm-color-10 { + color: #8ae234; +} + +.terminal .xterm-bg-color-10 { + background-color: #8ae234; +} + +.terminal .xterm-color-11 { + color: #fce94f; +} + +.terminal .xterm-bg-color-11 { + background-color: #fce94f; +} + +.terminal .xterm-color-12 { + color: #729fcf; +} + +.terminal .xterm-bg-color-12 { + background-color: #729fcf; +} + +.terminal .xterm-color-13 { + color: #ad7fa8; +} + +.terminal .xterm-bg-color-13 { + background-color: #ad7fa8; +} + +.terminal .xterm-color-14 { + color: #34e2e2; +} + +.terminal .xterm-bg-color-14 { + background-color: #34e2e2; +} + +.terminal .xterm-color-15 { + color: #eeeeec; +} + +.terminal .xterm-bg-color-15 { + background-color: #eeeeec; +} + +.terminal .xterm-color-16 { + color: #000000; +} + +.terminal .xterm-bg-color-16 { + background-color: #000000; +} + +.terminal .xterm-color-17 { + color: #00005f; +} + +.terminal .xterm-bg-color-17 { + background-color: #00005f; +} + +.terminal .xterm-color-18 { + color: #000087; +} + +.terminal .xterm-bg-color-18 { + background-color: #000087; +} + +.terminal .xterm-color-19 { + color: #0000af; +} + +.terminal .xterm-bg-color-19 { + background-color: #0000af; +} + +.terminal .xterm-color-20 { + color: #0000d7; +} + +.terminal .xterm-bg-color-20 { + background-color: #0000d7; +} + +.terminal .xterm-color-21 { + color: #0000ff; +} + +.terminal .xterm-bg-color-21 { + background-color: #0000ff; +} + +.terminal .xterm-color-22 { + color: #005f00; +} + +.terminal .xterm-bg-color-22 { + background-color: #005f00; +} + +.terminal .xterm-color-23 { + color: #005f5f; +} + +.terminal .xterm-bg-color-23 { + background-color: #005f5f; +} + +.terminal .xterm-color-24 { + color: #005f87; +} + +.terminal .xterm-bg-color-24 { + background-color: #005f87; +} + +.terminal .xterm-color-25 { + color: #005faf; +} + +.terminal .xterm-bg-color-25 { + background-color: #005faf; +} + +.terminal .xterm-color-26 { + color: #005fd7; +} + +.terminal .xterm-bg-color-26 { + background-color: #005fd7; +} + +.terminal .xterm-color-27 { + color: #005fff; +} + +.terminal .xterm-bg-color-27 { + background-color: #005fff; +} + +.terminal .xterm-color-28 { + color: #008700; +} + +.terminal .xterm-bg-color-28 { + background-color: #008700; +} + +.terminal .xterm-color-29 { + color: #00875f; +} + +.terminal .xterm-bg-color-29 { + background-color: #00875f; +} + +.terminal .xterm-color-30 { + color: #008787; +} + +.terminal .xterm-bg-color-30 { + background-color: #008787; +} + +.terminal .xterm-color-31 { + color: #0087af; +} + +.terminal .xterm-bg-color-31 { + background-color: #0087af; +} + +.terminal .xterm-color-32 { + color: #0087d7; +} + +.terminal .xterm-bg-color-32 { + background-color: #0087d7; +} + +.terminal .xterm-color-33 { + color: #0087ff; +} + +.terminal .xterm-bg-color-33 { + background-color: #0087ff; +} + +.terminal .xterm-color-34 { + color: #00af00; +} + +.terminal .xterm-bg-color-34 { + background-color: #00af00; +} + +.terminal .xterm-color-35 { + color: #00af5f; +} + +.terminal .xterm-bg-color-35 { + background-color: #00af5f; +} + +.terminal .xterm-color-36 { + color: #00af87; +} + +.terminal .xterm-bg-color-36 { + background-color: #00af87; +} + +.terminal .xterm-color-37 { + color: #00afaf; +} + +.terminal .xterm-bg-color-37 { + background-color: #00afaf; +} + +.terminal .xterm-color-38 { + color: #00afd7; +} + +.terminal .xterm-bg-color-38 { + background-color: #00afd7; +} + +.terminal .xterm-color-39 { + color: #00afff; +} + +.terminal .xterm-bg-color-39 { + background-color: #00afff; +} + +.terminal .xterm-color-40 { + color: #00d700; +} + +.terminal .xterm-bg-color-40 { + background-color: #00d700; +} + +.terminal .xterm-color-41 { + color: #00d75f; +} + +.terminal .xterm-bg-color-41 { + background-color: #00d75f; +} + +.terminal .xterm-color-42 { + color: #00d787; +} + +.terminal .xterm-bg-color-42 { + background-color: #00d787; +} + +.terminal .xterm-color-43 { + color: #00d7af; +} + +.terminal .xterm-bg-color-43 { + background-color: #00d7af; +} + +.terminal .xterm-color-44 { + color: #00d7d7; +} + +.terminal .xterm-bg-color-44 { + background-color: #00d7d7; +} + +.terminal .xterm-color-45 { + color: #00d7ff; +} + +.terminal .xterm-bg-color-45 { + background-color: #00d7ff; +} + +.terminal .xterm-color-46 { + color: #00ff00; +} + +.terminal .xterm-bg-color-46 { + background-color: #00ff00; +} + +.terminal .xterm-color-47 { + color: #00ff5f; +} + +.terminal .xterm-bg-color-47 { + background-color: #00ff5f; +} + +.terminal .xterm-color-48 { + color: #00ff87; +} + +.terminal .xterm-bg-color-48 { + background-color: #00ff87; +} + +.terminal .xterm-color-49 { + color: #00ffaf; +} + +.terminal .xterm-bg-color-49 { + background-color: #00ffaf; +} + +.terminal .xterm-color-50 { + color: #00ffd7; +} + +.terminal .xterm-bg-color-50 { + background-color: #00ffd7; +} + +.terminal .xterm-color-51 { + color: #00ffff; +} + +.terminal .xterm-bg-color-51 { + background-color: #00ffff; +} + +.terminal .xterm-color-52 { + color: #5f0000; +} + +.terminal .xterm-bg-color-52 { + background-color: #5f0000; +} + +.terminal .xterm-color-53 { + color: #5f005f; +} + +.terminal .xterm-bg-color-53 { + background-color: #5f005f; +} + +.terminal .xterm-color-54 { + color: #5f0087; +} + +.terminal .xterm-bg-color-54 { + background-color: #5f0087; +} + +.terminal .xterm-color-55 { + color: #5f00af; +} + +.terminal .xterm-bg-color-55 { + background-color: #5f00af; +} + +.terminal .xterm-color-56 { + color: #5f00d7; +} + +.terminal .xterm-bg-color-56 { + background-color: #5f00d7; +} + +.terminal .xterm-color-57 { + color: #5f00ff; +} + +.terminal .xterm-bg-color-57 { + background-color: #5f00ff; +} + +.terminal .xterm-color-58 { + color: #5f5f00; +} + +.terminal .xterm-bg-color-58 { + background-color: #5f5f00; +} + +.terminal .xterm-color-59 { + color: #5f5f5f; +} + +.terminal .xterm-bg-color-59 { + background-color: #5f5f5f; +} + +.terminal .xterm-color-60 { + color: #5f5f87; +} + +.terminal .xterm-bg-color-60 { + background-color: #5f5f87; +} + +.terminal .xterm-color-61 { + color: #5f5faf; +} + +.terminal .xterm-bg-color-61 { + background-color: #5f5faf; +} + +.terminal .xterm-color-62 { + color: #5f5fd7; +} + +.terminal .xterm-bg-color-62 { + background-color: #5f5fd7; +} + +.terminal .xterm-color-63 { + color: #5f5fff; +} + +.terminal .xterm-bg-color-63 { + background-color: #5f5fff; +} + +.terminal .xterm-color-64 { + color: #5f8700; +} + +.terminal .xterm-bg-color-64 { + background-color: #5f8700; +} + +.terminal .xterm-color-65 { + color: #5f875f; +} + +.terminal .xterm-bg-color-65 { + background-color: #5f875f; +} + +.terminal .xterm-color-66 { + color: #5f8787; +} + +.terminal .xterm-bg-color-66 { + background-color: #5f8787; +} + +.terminal .xterm-color-67 { + color: #5f87af; +} + +.terminal .xterm-bg-color-67 { + background-color: #5f87af; +} + +.terminal .xterm-color-68 { + color: #5f87d7; +} + +.terminal .xterm-bg-color-68 { + background-color: #5f87d7; +} + +.terminal .xterm-color-69 { + color: #5f87ff; +} + +.terminal .xterm-bg-color-69 { + background-color: #5f87ff; +} + +.terminal .xterm-color-70 { + color: #5faf00; +} + +.terminal .xterm-bg-color-70 { + background-color: #5faf00; +} + +.terminal .xterm-color-71 { + color: #5faf5f; +} + +.terminal .xterm-bg-color-71 { + background-color: #5faf5f; +} + +.terminal .xterm-color-72 { + color: #5faf87; +} + +.terminal .xterm-bg-color-72 { + background-color: #5faf87; +} + +.terminal .xterm-color-73 { + color: #5fafaf; +} + +.terminal .xterm-bg-color-73 { + background-color: #5fafaf; +} + +.terminal .xterm-color-74 { + color: #5fafd7; +} + +.terminal .xterm-bg-color-74 { + background-color: #5fafd7; +} + +.terminal .xterm-color-75 { + color: #5fafff; +} + +.terminal .xterm-bg-color-75 { + background-color: #5fafff; +} + +.terminal .xterm-color-76 { + color: #5fd700; +} + +.terminal .xterm-bg-color-76 { + background-color: #5fd700; +} + +.terminal .xterm-color-77 { + color: #5fd75f; +} + +.terminal .xterm-bg-color-77 { + background-color: #5fd75f; +} + +.terminal .xterm-color-78 { + color: #5fd787; +} + +.terminal .xterm-bg-color-78 { + background-color: #5fd787; +} + +.terminal .xterm-color-79 { + color: #5fd7af; +} + +.terminal .xterm-bg-color-79 { + background-color: #5fd7af; +} + +.terminal .xterm-color-80 { + color: #5fd7d7; +} + +.terminal .xterm-bg-color-80 { + background-color: #5fd7d7; +} + +.terminal .xterm-color-81 { + color: #5fd7ff; +} + +.terminal .xterm-bg-color-81 { + background-color: #5fd7ff; +} + +.terminal .xterm-color-82 { + color: #5fff00; +} + +.terminal .xterm-bg-color-82 { + background-color: #5fff00; +} + +.terminal .xterm-color-83 { + color: #5fff5f; +} + +.terminal .xterm-bg-color-83 { + background-color: #5fff5f; +} + +.terminal .xterm-color-84 { + color: #5fff87; +} + +.terminal .xterm-bg-color-84 { + background-color: #5fff87; +} + +.terminal .xterm-color-85 { + color: #5fffaf; +} + +.terminal .xterm-bg-color-85 { + background-color: #5fffaf; +} + +.terminal .xterm-color-86 { + color: #5fffd7; +} + +.terminal .xterm-bg-color-86 { + background-color: #5fffd7; +} + +.terminal .xterm-color-87 { + color: #5fffff; +} + +.terminal .xterm-bg-color-87 { + background-color: #5fffff; +} + +.terminal .xterm-color-88 { + color: #870000; +} + +.terminal .xterm-bg-color-88 { + background-color: #870000; +} + +.terminal .xterm-color-89 { + color: #87005f; +} + +.terminal .xterm-bg-color-89 { + background-color: #87005f; +} + +.terminal .xterm-color-90 { + color: #870087; +} + +.terminal .xterm-bg-color-90 { + background-color: #870087; +} + +.terminal .xterm-color-91 { + color: #8700af; +} + +.terminal .xterm-bg-color-91 { + background-color: #8700af; +} + +.terminal .xterm-color-92 { + color: #8700d7; +} + +.terminal .xterm-bg-color-92 { + background-color: #8700d7; +} + +.terminal .xterm-color-93 { + color: #8700ff; +} + +.terminal .xterm-bg-color-93 { + background-color: #8700ff; +} + +.terminal .xterm-color-94 { + color: #875f00; +} + +.terminal .xterm-bg-color-94 { + background-color: #875f00; +} + +.terminal .xterm-color-95 { + color: #875f5f; +} + +.terminal .xterm-bg-color-95 { + background-color: #875f5f; +} + +.terminal .xterm-color-96 { + color: #875f87; +} + +.terminal .xterm-bg-color-96 { + background-color: #875f87; +} + +.terminal .xterm-color-97 { + color: #875faf; +} + +.terminal .xterm-bg-color-97 { + background-color: #875faf; +} + +.terminal .xterm-color-98 { + color: #875fd7; +} + +.terminal .xterm-bg-color-98 { + background-color: #875fd7; +} + +.terminal .xterm-color-99 { + color: #875fff; +} + +.terminal .xterm-bg-color-99 { + background-color: #875fff; +} + +.terminal .xterm-color-100 { + color: #878700; +} + +.terminal .xterm-bg-color-100 { + background-color: #878700; +} + +.terminal .xterm-color-101 { + color: #87875f; +} + +.terminal .xterm-bg-color-101 { + background-color: #87875f; +} + +.terminal .xterm-color-102 { + color: #878787; +} + +.terminal .xterm-bg-color-102 { + background-color: #878787; +} + +.terminal .xterm-color-103 { + color: #8787af; +} + +.terminal .xterm-bg-color-103 { + background-color: #8787af; +} + +.terminal .xterm-color-104 { + color: #8787d7; +} + +.terminal .xterm-bg-color-104 { + background-color: #8787d7; +} + +.terminal .xterm-color-105 { + color: #8787ff; +} + +.terminal .xterm-bg-color-105 { + background-color: #8787ff; +} + +.terminal .xterm-color-106 { + color: #87af00; +} + +.terminal .xterm-bg-color-106 { + background-color: #87af00; +} + +.terminal .xterm-color-107 { + color: #87af5f; +} + +.terminal .xterm-bg-color-107 { + background-color: #87af5f; +} + +.terminal .xterm-color-108 { + color: #87af87; +} + +.terminal .xterm-bg-color-108 { + background-color: #87af87; +} + +.terminal .xterm-color-109 { + color: #87afaf; +} + +.terminal .xterm-bg-color-109 { + background-color: #87afaf; +} + +.terminal .xterm-color-110 { + color: #87afd7; +} + +.terminal .xterm-bg-color-110 { + background-color: #87afd7; +} + +.terminal .xterm-color-111 { + color: #87afff; +} + +.terminal .xterm-bg-color-111 { + background-color: #87afff; +} + +.terminal .xterm-color-112 { + color: #87d700; +} + +.terminal .xterm-bg-color-112 { + background-color: #87d700; +} + +.terminal .xterm-color-113 { + color: #87d75f; +} + +.terminal .xterm-bg-color-113 { + background-color: #87d75f; +} + +.terminal .xterm-color-114 { + color: #87d787; +} + +.terminal .xterm-bg-color-114 { + background-color: #87d787; +} + +.terminal .xterm-color-115 { + color: #87d7af; +} + +.terminal .xterm-bg-color-115 { + background-color: #87d7af; +} + +.terminal .xterm-color-116 { + color: #87d7d7; +} + +.terminal .xterm-bg-color-116 { + background-color: #87d7d7; +} + +.terminal .xterm-color-117 { + color: #87d7ff; +} + +.terminal .xterm-bg-color-117 { + background-color: #87d7ff; +} + +.terminal .xterm-color-118 { + color: #87ff00; +} + +.terminal .xterm-bg-color-118 { + background-color: #87ff00; +} + +.terminal .xterm-color-119 { + color: #87ff5f; +} + +.terminal .xterm-bg-color-119 { + background-color: #87ff5f; +} + +.terminal .xterm-color-120 { + color: #87ff87; +} + +.terminal .xterm-bg-color-120 { + background-color: #87ff87; +} + +.terminal .xterm-color-121 { + color: #87ffaf; +} + +.terminal .xterm-bg-color-121 { + background-color: #87ffaf; +} + +.terminal .xterm-color-122 { + color: #87ffd7; +} + +.terminal .xterm-bg-color-122 { + background-color: #87ffd7; +} + +.terminal .xterm-color-123 { + color: #87ffff; +} + +.terminal .xterm-bg-color-123 { + background-color: #87ffff; +} + +.terminal .xterm-color-124 { + color: #af0000; +} + +.terminal .xterm-bg-color-124 { + background-color: #af0000; +} + +.terminal .xterm-color-125 { + color: #af005f; +} + +.terminal .xterm-bg-color-125 { + background-color: #af005f; +} + +.terminal .xterm-color-126 { + color: #af0087; +} + +.terminal .xterm-bg-color-126 { + background-color: #af0087; +} + +.terminal .xterm-color-127 { + color: #af00af; +} + +.terminal .xterm-bg-color-127 { + background-color: #af00af; +} + +.terminal .xterm-color-128 { + color: #af00d7; +} + +.terminal .xterm-bg-color-128 { + background-color: #af00d7; +} + +.terminal .xterm-color-129 { + color: #af00ff; +} + +.terminal .xterm-bg-color-129 { + background-color: #af00ff; +} + +.terminal .xterm-color-130 { + color: #af5f00; +} + +.terminal .xterm-bg-color-130 { + background-color: #af5f00; +} + +.terminal .xterm-color-131 { + color: #af5f5f; +} + +.terminal .xterm-bg-color-131 { + background-color: #af5f5f; +} + +.terminal .xterm-color-132 { + color: #af5f87; +} + +.terminal .xterm-bg-color-132 { + background-color: #af5f87; +} + +.terminal .xterm-color-133 { + color: #af5faf; +} + +.terminal .xterm-bg-color-133 { + background-color: #af5faf; +} + +.terminal .xterm-color-134 { + color: #af5fd7; +} + +.terminal .xterm-bg-color-134 { + background-color: #af5fd7; +} + +.terminal .xterm-color-135 { + color: #af5fff; +} + +.terminal .xterm-bg-color-135 { + background-color: #af5fff; +} + +.terminal .xterm-color-136 { + color: #af8700; +} + +.terminal .xterm-bg-color-136 { + background-color: #af8700; +} + +.terminal .xterm-color-137 { + color: #af875f; +} + +.terminal .xterm-bg-color-137 { + background-color: #af875f; +} + +.terminal .xterm-color-138 { + color: #af8787; +} + +.terminal .xterm-bg-color-138 { + background-color: #af8787; +} + +.terminal .xterm-color-139 { + color: #af87af; +} + +.terminal .xterm-bg-color-139 { + background-color: #af87af; +} + +.terminal .xterm-color-140 { + color: #af87d7; +} + +.terminal .xterm-bg-color-140 { + background-color: #af87d7; +} + +.terminal .xterm-color-141 { + color: #af87ff; +} + +.terminal .xterm-bg-color-141 { + background-color: #af87ff; +} + +.terminal .xterm-color-142 { + color: #afaf00; +} + +.terminal .xterm-bg-color-142 { + background-color: #afaf00; +} + +.terminal .xterm-color-143 { + color: #afaf5f; +} + +.terminal .xterm-bg-color-143 { + background-color: #afaf5f; +} + +.terminal .xterm-color-144 { + color: #afaf87; +} + +.terminal .xterm-bg-color-144 { + background-color: #afaf87; +} + +.terminal .xterm-color-145 { + color: #afafaf; +} + +.terminal .xterm-bg-color-145 { + background-color: #afafaf; +} + +.terminal .xterm-color-146 { + color: #afafd7; +} + +.terminal .xterm-bg-color-146 { + background-color: #afafd7; +} + +.terminal .xterm-color-147 { + color: #afafff; +} + +.terminal .xterm-bg-color-147 { + background-color: #afafff; +} + +.terminal .xterm-color-148 { + color: #afd700; +} + +.terminal .xterm-bg-color-148 { + background-color: #afd700; +} + +.terminal .xterm-color-149 { + color: #afd75f; +} + +.terminal .xterm-bg-color-149 { + background-color: #afd75f; +} + +.terminal .xterm-color-150 { + color: #afd787; +} + +.terminal .xterm-bg-color-150 { + background-color: #afd787; +} + +.terminal .xterm-color-151 { + color: #afd7af; +} + +.terminal .xterm-bg-color-151 { + background-color: #afd7af; +} + +.terminal .xterm-color-152 { + color: #afd7d7; +} + +.terminal .xterm-bg-color-152 { + background-color: #afd7d7; +} + +.terminal .xterm-color-153 { + color: #afd7ff; +} + +.terminal .xterm-bg-color-153 { + background-color: #afd7ff; +} + +.terminal .xterm-color-154 { + color: #afff00; +} + +.terminal .xterm-bg-color-154 { + background-color: #afff00; +} + +.terminal .xterm-color-155 { + color: #afff5f; +} + +.terminal .xterm-bg-color-155 { + background-color: #afff5f; +} + +.terminal .xterm-color-156 { + color: #afff87; +} + +.terminal .xterm-bg-color-156 { + background-color: #afff87; +} + +.terminal .xterm-color-157 { + color: #afffaf; +} + +.terminal .xterm-bg-color-157 { + background-color: #afffaf; +} + +.terminal .xterm-color-158 { + color: #afffd7; +} + +.terminal .xterm-bg-color-158 { + background-color: #afffd7; +} + +.terminal .xterm-color-159 { + color: #afffff; +} + +.terminal .xterm-bg-color-159 { + background-color: #afffff; +} + +.terminal .xterm-color-160 { + color: #d70000; +} + +.terminal .xterm-bg-color-160 { + background-color: #d70000; +} + +.terminal .xterm-color-161 { + color: #d7005f; +} + +.terminal .xterm-bg-color-161 { + background-color: #d7005f; +} + +.terminal .xterm-color-162 { + color: #d70087; +} + +.terminal .xterm-bg-color-162 { + background-color: #d70087; +} + +.terminal .xterm-color-163 { + color: #d700af; +} + +.terminal .xterm-bg-color-163 { + background-color: #d700af; +} + +.terminal .xterm-color-164 { + color: #d700d7; +} + +.terminal .xterm-bg-color-164 { + background-color: #d700d7; +} + +.terminal .xterm-color-165 { + color: #d700ff; +} + +.terminal .xterm-bg-color-165 { + background-color: #d700ff; +} + +.terminal .xterm-color-166 { + color: #d75f00; +} + +.terminal .xterm-bg-color-166 { + background-color: #d75f00; +} + +.terminal .xterm-color-167 { + color: #d75f5f; +} + +.terminal .xterm-bg-color-167 { + background-color: #d75f5f; +} + +.terminal .xterm-color-168 { + color: #d75f87; +} + +.terminal .xterm-bg-color-168 { + background-color: #d75f87; +} + +.terminal .xterm-color-169 { + color: #d75faf; +} + +.terminal .xterm-bg-color-169 { + background-color: #d75faf; +} + +.terminal .xterm-color-170 { + color: #d75fd7; +} + +.terminal .xterm-bg-color-170 { + background-color: #d75fd7; +} + +.terminal .xterm-color-171 { + color: #d75fff; +} + +.terminal .xterm-bg-color-171 { + background-color: #d75fff; +} + +.terminal .xterm-color-172 { + color: #d78700; +} + +.terminal .xterm-bg-color-172 { + background-color: #d78700; +} + +.terminal .xterm-color-173 { + color: #d7875f; +} + +.terminal .xterm-bg-color-173 { + background-color: #d7875f; +} + +.terminal .xterm-color-174 { + color: #d78787; +} + +.terminal .xterm-bg-color-174 { + background-color: #d78787; +} + +.terminal .xterm-color-175 { + color: #d787af; +} + +.terminal .xterm-bg-color-175 { + background-color: #d787af; +} + +.terminal .xterm-color-176 { + color: #d787d7; +} + +.terminal .xterm-bg-color-176 { + background-color: #d787d7; +} + +.terminal .xterm-color-177 { + color: #d787ff; +} + +.terminal .xterm-bg-color-177 { + background-color: #d787ff; +} + +.terminal .xterm-color-178 { + color: #d7af00; +} + +.terminal .xterm-bg-color-178 { + background-color: #d7af00; +} + +.terminal .xterm-color-179 { + color: #d7af5f; +} + +.terminal .xterm-bg-color-179 { + background-color: #d7af5f; +} + +.terminal .xterm-color-180 { + color: #d7af87; +} + +.terminal .xterm-bg-color-180 { + background-color: #d7af87; +} + +.terminal .xterm-color-181 { + color: #d7afaf; +} + +.terminal .xterm-bg-color-181 { + background-color: #d7afaf; +} + +.terminal .xterm-color-182 { + color: #d7afd7; +} + +.terminal .xterm-bg-color-182 { + background-color: #d7afd7; +} + +.terminal .xterm-color-183 { + color: #d7afff; +} + +.terminal .xterm-bg-color-183 { + background-color: #d7afff; +} + +.terminal .xterm-color-184 { + color: #d7d700; +} + +.terminal .xterm-bg-color-184 { + background-color: #d7d700; +} + +.terminal .xterm-color-185 { + color: #d7d75f; +} + +.terminal .xterm-bg-color-185 { + background-color: #d7d75f; +} + +.terminal .xterm-color-186 { + color: #d7d787; +} + +.terminal .xterm-bg-color-186 { + background-color: #d7d787; +} + +.terminal .xterm-color-187 { + color: #d7d7af; +} + +.terminal .xterm-bg-color-187 { + background-color: #d7d7af; +} + +.terminal .xterm-color-188 { + color: #d7d7d7; +} + +.terminal .xterm-bg-color-188 { + background-color: #d7d7d7; +} + +.terminal .xterm-color-189 { + color: #d7d7ff; +} + +.terminal .xterm-bg-color-189 { + background-color: #d7d7ff; +} + +.terminal .xterm-color-190 { + color: #d7ff00; +} + +.terminal .xterm-bg-color-190 { + background-color: #d7ff00; +} + +.terminal .xterm-color-191 { + color: #d7ff5f; +} + +.terminal .xterm-bg-color-191 { + background-color: #d7ff5f; +} + +.terminal .xterm-color-192 { + color: #d7ff87; +} + +.terminal .xterm-bg-color-192 { + background-color: #d7ff87; +} + +.terminal .xterm-color-193 { + color: #d7ffaf; +} + +.terminal .xterm-bg-color-193 { + background-color: #d7ffaf; +} + +.terminal .xterm-color-194 { + color: #d7ffd7; +} + +.terminal .xterm-bg-color-194 { + background-color: #d7ffd7; +} + +.terminal .xterm-color-195 { + color: #d7ffff; +} + +.terminal .xterm-bg-color-195 { + background-color: #d7ffff; +} + +.terminal .xterm-color-196 { + color: #ff0000; +} + +.terminal .xterm-bg-color-196 { + background-color: #ff0000; +} + +.terminal .xterm-color-197 { + color: #ff005f; +} + +.terminal .xterm-bg-color-197 { + background-color: #ff005f; +} + +.terminal .xterm-color-198 { + color: #ff0087; +} + +.terminal .xterm-bg-color-198 { + background-color: #ff0087; +} + +.terminal .xterm-color-199 { + color: #ff00af; +} + +.terminal .xterm-bg-color-199 { + background-color: #ff00af; +} + +.terminal .xterm-color-200 { + color: #ff00d7; +} + +.terminal .xterm-bg-color-200 { + background-color: #ff00d7; +} + +.terminal .xterm-color-201 { + color: #ff00ff; +} + +.terminal .xterm-bg-color-201 { + background-color: #ff00ff; +} + +.terminal .xterm-color-202 { + color: #ff5f00; +} + +.terminal .xterm-bg-color-202 { + background-color: #ff5f00; +} + +.terminal .xterm-color-203 { + color: #ff5f5f; +} + +.terminal .xterm-bg-color-203 { + background-color: #ff5f5f; +} + +.terminal .xterm-color-204 { + color: #ff5f87; +} + +.terminal .xterm-bg-color-204 { + background-color: #ff5f87; +} + +.terminal .xterm-color-205 { + color: #ff5faf; +} + +.terminal .xterm-bg-color-205 { + background-color: #ff5faf; +} + +.terminal .xterm-color-206 { + color: #ff5fd7; +} + +.terminal .xterm-bg-color-206 { + background-color: #ff5fd7; +} + +.terminal .xterm-color-207 { + color: #ff5fff; +} + +.terminal .xterm-bg-color-207 { + background-color: #ff5fff; +} + +.terminal .xterm-color-208 { + color: #ff8700; +} + +.terminal .xterm-bg-color-208 { + background-color: #ff8700; +} + +.terminal .xterm-color-209 { + color: #ff875f; +} + +.terminal .xterm-bg-color-209 { + background-color: #ff875f; +} + +.terminal .xterm-color-210 { + color: #ff8787; +} + +.terminal .xterm-bg-color-210 { + background-color: #ff8787; +} + +.terminal .xterm-color-211 { + color: #ff87af; +} + +.terminal .xterm-bg-color-211 { + background-color: #ff87af; +} + +.terminal .xterm-color-212 { + color: #ff87d7; +} + +.terminal .xterm-bg-color-212 { + background-color: #ff87d7; +} + +.terminal .xterm-color-213 { + color: #ff87ff; +} + +.terminal .xterm-bg-color-213 { + background-color: #ff87ff; +} + +.terminal .xterm-color-214 { + color: #ffaf00; +} + +.terminal .xterm-bg-color-214 { + background-color: #ffaf00; +} + +.terminal .xterm-color-215 { + color: #ffaf5f; +} + +.terminal .xterm-bg-color-215 { + background-color: #ffaf5f; +} + +.terminal .xterm-color-216 { + color: #ffaf87; +} + +.terminal .xterm-bg-color-216 { + background-color: #ffaf87; +} + +.terminal .xterm-color-217 { + color: #ffafaf; +} + +.terminal .xterm-bg-color-217 { + background-color: #ffafaf; +} + +.terminal .xterm-color-218 { + color: #ffafd7; +} + +.terminal .xterm-bg-color-218 { + background-color: #ffafd7; +} + +.terminal .xterm-color-219 { + color: #ffafff; +} + +.terminal .xterm-bg-color-219 { + background-color: #ffafff; +} + +.terminal .xterm-color-220 { + color: #ffd700; +} + +.terminal .xterm-bg-color-220 { + background-color: #ffd700; +} + +.terminal .xterm-color-221 { + color: #ffd75f; +} + +.terminal .xterm-bg-color-221 { + background-color: #ffd75f; +} + +.terminal .xterm-color-222 { + color: #ffd787; +} + +.terminal .xterm-bg-color-222 { + background-color: #ffd787; +} + +.terminal .xterm-color-223 { + color: #ffd7af; +} + +.terminal .xterm-bg-color-223 { + background-color: #ffd7af; +} + +.terminal .xterm-color-224 { + color: #ffd7d7; +} + +.terminal .xterm-bg-color-224 { + background-color: #ffd7d7; +} + +.terminal .xterm-color-225 { + color: #ffd7ff; +} + +.terminal .xterm-bg-color-225 { + background-color: #ffd7ff; +} + +.terminal .xterm-color-226 { + color: #ffff00; +} + +.terminal .xterm-bg-color-226 { + background-color: #ffff00; +} + +.terminal .xterm-color-227 { + color: #ffff5f; +} + +.terminal .xterm-bg-color-227 { + background-color: #ffff5f; +} + +.terminal .xterm-color-228 { + color: #ffff87; +} + +.terminal .xterm-bg-color-228 { + background-color: #ffff87; +} + +.terminal .xterm-color-229 { + color: #ffffaf; +} + +.terminal .xterm-bg-color-229 { + background-color: #ffffaf; +} + +.terminal .xterm-color-230 { + color: #ffffd7; +} + +.terminal .xterm-bg-color-230 { + background-color: #ffffd7; +} + +.terminal .xterm-color-231 { + color: #ffffff; +} + +.terminal .xterm-bg-color-231 { + background-color: #ffffff; +} + +.terminal .xterm-color-232 { + color: #080808; +} + +.terminal .xterm-bg-color-232 { + background-color: #080808; +} + +.terminal .xterm-color-233 { + color: #121212; +} + +.terminal .xterm-bg-color-233 { + background-color: #121212; +} + +.terminal .xterm-color-234 { + color: #1c1c1c; +} + +.terminal .xterm-bg-color-234 { + background-color: #1c1c1c; +} + +.terminal .xterm-color-235 { + color: #262626; +} + +.terminal .xterm-bg-color-235 { + background-color: #262626; +} + +.terminal .xterm-color-236 { + color: #303030; +} + +.terminal .xterm-bg-color-236 { + background-color: #303030; +} + +.terminal .xterm-color-237 { + color: #3a3a3a; +} + +.terminal .xterm-bg-color-237 { + background-color: #3a3a3a; +} + +.terminal .xterm-color-238 { + color: #444444; +} + +.terminal .xterm-bg-color-238 { + background-color: #444444; +} + +.terminal .xterm-color-239 { + color: #4e4e4e; +} + +.terminal .xterm-bg-color-239 { + background-color: #4e4e4e; +} + +.terminal .xterm-color-240 { + color: #585858; +} + +.terminal .xterm-bg-color-240 { + background-color: #585858; +} + +.terminal .xterm-color-241 { + color: #626262; +} + +.terminal .xterm-bg-color-241 { + background-color: #626262; +} + +.terminal .xterm-color-242 { + color: #6c6c6c; +} + +.terminal .xterm-bg-color-242 { + background-color: #6c6c6c; +} + +.terminal .xterm-color-243 { + color: #767676; +} + +.terminal .xterm-bg-color-243 { + background-color: #767676; +} + +.terminal .xterm-color-244 { + color: #808080; +} + +.terminal .xterm-bg-color-244 { + background-color: #808080; +} + +.terminal .xterm-color-245 { + color: #8a8a8a; +} + +.terminal .xterm-bg-color-245 { + background-color: #8a8a8a; +} + +.terminal .xterm-color-246 { + color: #949494; +} + +.terminal .xterm-bg-color-246 { + background-color: #949494; +} + +.terminal .xterm-color-247 { + color: #9e9e9e; +} + +.terminal .xterm-bg-color-247 { + background-color: #9e9e9e; +} + +.terminal .xterm-color-248 { + color: #a8a8a8; +} + +.terminal .xterm-bg-color-248 { + background-color: #a8a8a8; +} + +.terminal .xterm-color-249 { + color: #b2b2b2; +} + +.terminal .xterm-bg-color-249 { + background-color: #b2b2b2; +} + +.terminal .xterm-color-250 { + color: #bcbcbc; +} + +.terminal .xterm-bg-color-250 { + background-color: #bcbcbc; +} + +.terminal .xterm-color-251 { + color: #c6c6c6; +} + +.terminal .xterm-bg-color-251 { + background-color: #c6c6c6; +} + +.terminal .xterm-color-252 { + color: #d0d0d0; +} + +.terminal .xterm-bg-color-252 { + background-color: #d0d0d0; +} + +.terminal .xterm-color-253 { + color: #dadada; +} + +.terminal .xterm-bg-color-253 { + background-color: #dadada; +} + +.terminal .xterm-color-254 { + color: #e4e4e4; +} + +.terminal .xterm-bg-color-254 { + background-color: #e4e4e4; +} + +.terminal .xterm-color-255 { + color: #eeeeee; +} + +.terminal .xterm-bg-color-255 { + background-color: #eeeeee; +} diff --git a/feed.xml b/feed.xml new file mode 100644 index 0000000..a6628bd --- /dev/null +++ b/feed.xml @@ -0,0 +1,30 @@ +--- +layout: null +--- + + + + {{ site.title | xml_escape }} + {{ site.description | xml_escape }} + {{ site.url }}{{ site.baseurl }}/ + + {{ site.time | date_to_rfc822 }} + {{ site.time | date_to_rfc822 }} + Jekyll v{{ jekyll.version }} + {% for post in site.posts limit:10 %} + + {{ post.title | xml_escape }} + {{ post.content | xml_escape }} + {{ post.date | date_to_rfc822 }} + {{ post.url | prepend: site.baseurl | prepend: site.url }} + {{ post.url | prepend: site.baseurl | prepend: site.url }} + {% for tag in post.tags %} + {{ tag | xml_escape }} + {% endfor %} + {% for cat in post.categories %} + {{ cat | xml_escape }} + {% endfor %} + + {% endfor %} + + diff --git a/images/create-gh-pages-branch.JPG b/images/create-gh-pages-branch.JPG new file mode 100644 index 0000000000000000000000000000000000000000..a6fa429b8c586fe4c000c2f7905297baa74cdbaf GIT binary patch literal 9503 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 CP2=?d literal 0 HcmV?d00001 diff --git a/images/delete-github-branch-2.png b/images/delete-github-branch-2.png new file mode 100644 index 0000000000000000000000000000000000000000..94a8248dab29dc8cf0a18cffee160b57f9abe0e6 GIT binary patch literal 6202 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 literal 0 HcmV?d00001 diff --git a/images/docker-logo.png b/images/docker-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..580f2a1da0c12ad0b492215a510e0534cb4339e8 GIT binary patch literal 47520 zcmeFZXHb)2*De}VM5&4hNJkN=f=X{ekls5|1w?x9HCO-zA)tU%0qMPWLKLJ3(n9aj z2^|6i2!Z`1yx;7-f1O`v=FFV;hZ85y{oG}>`&!pp;ghDi0vRzKF$e@AQ&N1P4FVA= zgFx5nZ(Iky`SoT0De!UARq>?<2t-4P`$u4tjsQl1?s>`?dg{2m@$|89w+20b?P6)o zqU2;@W36p%@!HSrkF^8{)WECs;<>Kx-(PZo`^Qr7!IGf6k;1Wm9C%mVf9iO%g zBdW+}5ymQZ-ivahneXpAru`_X-s)k-M6hs`2Sci*i-V-+n4Jb}=dPNO)Q2p$FG%iK z4RB3o+rIOa%@M>-Ix=v&E{O0|E_0YEC6uIR9~*BnxYG{Z=Zy8(Azke|2@Hw6t>Do= z9kAm1X8YT!!qD)rF0gwLNO6Ko5C5NRbxqvqL2MfT{rs;S{%Z&S^@IP$f&Wj&fik(f zAW(Ts>GpTooRk^+AGgR!4-T1h$Uva@J8@S)<%zUkwzbGY%awp(udUW3afgVJc+UC% z>Sr@GaEnOKs)G+dD;wsP^g{%z)BM%sK%nAVlF9_Y(jiMX{~tbI9x{PKlI`di$xB?) zlYK6hI!Y`mgEpEmi&l$LWAyNv2dX7zP1%)M710#EO=TzhO_?W%CPB%B(!!b)bsMh}W?r316f15F*El+O= zHIEw%S>4;HuRAyfkKO_%ipfOdWF@_SE$6?V|9_B!kuG4NHBW2&ooF}eeP*#=w~T25 z&yGtNBNM8ID{1beSB-X78r}npxjDC>fU^b!`YB;LBZh+)|*eoU69T-MCDKMJ`*ikk)!qlJ=`o)AsdWd5xbJ20-%qs1 zcpBX8o_RTW+G|X#8FaaLhD7?>cP=Tp%^bQ_UdfDFg2Fr?I7$ck+06}cStL1wg9SVp zHq7@IHE?msIQQ@> zC=iG%W{4QwbCtI+d$~CgZD*l5AW>Y<1^wJ-BprF#Y*(=0 z!OV@eCuAYQ@6a#|P*s1tbBhU4c;&Od2RwHZt}IF8PoyGX(-j2!D0_jMqkLTwMD+qS zZfoc>55y&fF(=}zja3b3?e^KkfP~c3o%77zskYZs>wf6E^dOI4tFXYSK0kB`Q!|x5 zg=wnK#p{h^{_5r0LWUko>(v4~Pm$`DAp3I^9mp^2o#g|D zOF?w%PZ975#PtBM+IJr_d$1RN=QaHWGXZU7-djmNkX4Fv4_mN@`z#iGg2j@A$&PZ1#J2b1EdZN*fyHb*6j@Q1so>rL`c36<85F{w!)h+DJ^4jF5oiE08e)1~x z@iBzgXIgk>$kTfp!Eh58^&CGck^{{y8B>!=l8!~FQXu4hf6rb0kOSgYzI@sg0dp1i?)R|a-)44kWi&cY5}PWA8l4!jU|>CN&%XR~RT$L|=8m6mN< z!Wa@-FuRL>-}Om@0DFyup$h?{2PLk0ux==$;iwZwnoTve`N>D;EI0v4^mBh7igmw5 z`g0m>3IGET2*vQX(t}jkIN5k#^b2(Rk2ufFy*K^|#3}?U_^|Vn0SKr8ZK{ce6`wFn zf6y8G6e>RPwQXijA?O=8;P4Oov{x+!6>gb&v8>+2AT$`Z`P}YhwN$G7v%>N`<_=pN|!zx@RY2n%>HspXk5V1 z6*d*ToGtvvvD+~gxAP(?HVcA*=TeQ2nsLXEuYL0OLrzNdH5NU*@)Ik-J$R2Xj!Jm1Bh*nk;h`Q5_KWEvTg z3(8i+tth=;N!|oM`}fFTyS0TOA-ZfX)gacKdyGh0`!b%ojbm$?^o0yQTOb?w0w4C5 z4+rK*yI(%D7!P7NG8>Xhr5>EDWlzO4T}YHISnf==B@@O_;x(?+Ber?oy**cy;$dgn zB-MNvTDGJ&eP@N6Q2RbkfGl1CRh!d+#x|yDs#6J!^V3-xD|*wkAr*52KYKxuh*oi)1$vA==wK&we#>WBYq%89$ou4*18ev# zvK19I*|;QNQ)<12cL*UmI`z8~e4%@XDJYI@JK5d0@{jPlunyp!sW8)Tg2#^53eIo! z2XmG!kUKnEA+i_vYSRhz5ih`FlR^V%$G@yadUlpBKsym)C;`&3c1LY z^J-_b#=m~|J$_~(f;lUsSD9i}yJ5?QU*U_+Hd#Xz0-G{c%BFvZ!a{%aCXR#OX2>IjNhhhYnOkDGvnja-j|W0nr18{8UGPqPEk`{6(YzZaj0q= zm|~R)V>xOmlu&!sh(>b_EsJw;X-hHg8MgyrF}g|_qq@0!rPJ7o;`TK?Vya~P?uR!^ zJv-;cnH|TK8!A_KYf>j(%oY z1Y%cssH+Q%1(Z%yoOHw#d1o}J=$AbM^k%weG zNb)cp*^4cPDf@ThEI2jMm;UlQFzK#sOUW~b+wZh9w(%hC z)y;)l2f8Kp_T7#7Uo)ukFVJH6;644fOCeaiXFF`}s@EkuIIRnWv;Rm|FH%|(Z$uy! z_r1){%FR**PR%hKrlx8GV2P_=z$y;W@HPAH3?ys;kUA!`+e|gEFO&&B?y=&=6B!?y zS1{txX4nZsL92o`-a(n+HCBV}2}Vah%6yQbMP59EGS+-L7mezcAj0Pw}`@v{} zLc3yA7Hix4WnPeUpE3=>B}B&{TJrS%J)H?Yvt1Jz zg)eoc2e03YuT|Y3I)CcuTcIId`U3;UngFn+5-|e?=9wy^&TLE{Ts=p^_1->A`Hor5 z^xBolX}YLFU`AMLZVW%bBm0ntJtAkpWpvlpFJrx7Wd%hrN6&V^2#aRfUoGO83?A7& zP`=6>H>|EGbp0ueV19B~*KlMwE>N=Cu}@%bzXO*MBXWqMU&o zgv%)@nGc@DXfVOM+Mjq4!!u2nJH?FHL7!bN+wn}%65p`-Ws3FAM`#4wZeNZ95nTui`Pns(>=g4(u*9eV$u=eOG_y^;7@ea1z2xzkArJ z`&^1$$hoI7z~+0WHo1&&XcDNls<}PANc1nHUoDz*w)y3xdRP+Z(C}pL5dbzZH7xny z%P_6&#s}BSG8ma<(3#rqstk}L5yScA;~jCIDZ|c@>Z)crjlZH$Uk}c|AM&sk?9x#% zO~RA%cX)d*zgBdyLSu0z3{jDb6D)iA%^Ka8A_?STkEGtX`10MF8G5BxUlFJtu#)Q0 zEK2vLbqIND*7cr_+PMNseSODH^XRG6fr9~Q^BpC+do<=FotjBjP z=e{ss;2bI0+r+0<>S6?-R0Ox`BepM&JTkF=mF_;L3g-Z8{fSmv4ZhdPh%We5S>WW8 z|KYT{s9KV~4gdtJt*U%FvZ#4>eS8q51iX#W_;H#}099`b;wTFkVU^Ew&+P|M_P>&cNB5B|TTJzz&espfR19AF4=L$G$Gn28o1t=O72nLVV^NLAQy z$k}>Ls-`lZ3ybmiUvts{} zsiKR>wckW*gWN0pceTg8Ezb`-)=t&tr)Qd0X5d@D_YhL3ycc3V=xu}){pt*}!L(Ty zkoFWzR+!Ar-g`V(>!Ab?1rvVuEoaV#nC_p=m`*W3#mvb*kU+=jRsS{$&(J?dC8%vE zcPHQL@{KCgwuAT~iqK#+dbwl22p0=YBZ2(O*ic>Eta!71(hV~qOk7#2KJ6(F84o$qtz0Z5v5^@smm{P8{bDNF)eA+Gdm&kE-FeVIIMTZ} z=djugaU{>$NEj_}p9vkx^mAN-xmr7lOlvpt89np0IDOXO7bsFJ4rx@>yE|uVv&ugM z#s$N}7#tEhF-fE_C1vb9rD>)$TYGmnYR+JMu;7=eX_Hx*Mfe_(8ofNc4I?q@;>+8V z5H$A}212XLEY^StX~sX?upIwZPBtU7^-pMbG&Ommnepyk#b&5XhD5Y=MWw@FG>rpE zk6mYEJj_r$dRc$NkgkT2Pyfh$%1scO!!)&Lx#cbjWO=n!)7~b%R&NP)r?Wh_=)vTR zKGS*EH@Z~28vMj=L|rgVHa}3UElFxA2@CC(oU3q6v1MXTB3Cu&1bMB=jQg%cA*YT# z(jr_2<~G*1KS5v-Z;?v8pLOvmhN4#cb7bRJFgXocqTsrLBB`vE%RnYCb0Rs|S*lCS>+`po?^4lwQ+2LT?2McJ|Vt6EWy!N_D#B8Rn4vH`0uXh`UG1GBvK zEYr3otZ%GHL}9(5i8*=p2W_ge=;07@S75d@W8y@GBF>p25gsT15O4Z=clp+;Prrf5 z#;)ZweDsJ=56`NbX;_m;|1;X#s5S&sTclnUo6)xSdBSh{Yd}E#3gaptRzC5js)m33 ze}Jv_i1}oT$)D)0vKHFM!3z|_uR<3zPiZ5}IGhR&=}L4{H#}?W>=-}fYQ)vTfDAAE z-HD1F%Vjv%+k2Q~P2gEqk|!gPA`%w{ z6v6iXkuVjXX0cn7{ViravLE5#lxE8RLChO`P8hCSH`Y8a*Hz-;fisR?#)f}dhkp)Dv zjs6dj{u~h#KMx+IpIb7uGcvAiY#9^@T;_`f;;GiFpZ0fAy0B;Nf}hpZ?d1q7{dZ-U z+8K1e{wFI^q6Y+_-`JpwJm;ih8C;u{_bY@DUsy*1+s1W z9<~EXgqm{OC9rP>s7~5AeTlQ+A&QoG-JmokCep>RQacesk5!76dqy4dmDC=ZYKVM% z+~?0)Fw1f1Z)WN!P1X4EWnn?B?amz|m0!h8u40bjv3^pfFeST7CrxzY=;?DX3o4lB z?pjc5_d@?1LvgHRB>%_VSX3$CVEslvAcvz5(s~pre0MB5o$Q0xs)h}(JfNiSII{%J zel0Mt>(MZG>{71q)p09fYNT}rpU+4{OqL1R;jUQ_$hSY1N8AN-jv|{V8pbWuA8Foi zMUb}&z$A@AH9EX~gSxvd285s9-5>3zFI4B5)irVJ3c^f`RZ)9zCZ@!__#Z-q41N){ zgY|18)v5!QYuDTMpmT>Px@c=((jubWB%`{``8pf_Ld)0VcW7Fe014QHhYNhXVh=<` zvt_ApRCjjNDGTKR5s&&*CQruZ{$}MLD_nsoDMjPuM@{`6p$bzLX28NpyjoWk6k3<}o|FX= zwEHRTY+axvRvt!?8~yx5b(yRX_#JS~xGpGIoc*N_6`8AV#hwgW@C81fxk$5VUH?Vm zN99#Ld_+;8rOk#5cOmW8+j@;#Q~kr(R&}?0Y(s33+19&8n|~XAyt7nOr@?~Cg_lV2 zqlABaExFkZhl`D|jUxu$SzX5`Y`u1SxoaV;=0GVqLJ-U1=kkzhYxxO`s z%Af&Utgn=WKZRuakal)U_PrQ8hlk8SMIfdVIl6+veM~-)pVs9%c9?tU2oX5CX zfD;HaIv@aa{K zubLEF!Uw+w!cLoO8N^LDL%8mWmCwM&>|_p#>SgCB1_YTo%3U_P7jjY`9WdW ze3KfF)IzMe&>cP2!JYQuIXj z;L;>dZHZNQIYO*b_8A%)X_aMGe5C=~$)}2DbNT~0p9J6j(i(*~rVMwC%2bLURh*BZ zn1txF-tK3k|YK4|`=#PQ)2&tQte`j`fF z$dO9sax^9ZX1=LJ7e1o{w;zZUp!_03h&O)MtIHt=uk5B?ZmrUp!$q6108v-VE1m$` znQD`jL5S6D{qD&`mBC*|-Q8L}l`Wc*wZ3$k5Tonag8=_YU3#_!p_=4M{3Z~Vjn|Qv zJq~N4h~|j5Y|P7!bZ#oKUd78Wt~cquCnR4>nhpk#s}>9M{U1hibFFs*tOHdQjq-rP z27or<;xk{XyC28b_LChP9u;}zr{Z)QvIJy)o?%I@)rFA)rY_r>7`?ljfUv9DWX*nx z-C1Rg@`&ju>2BN15^hsf^jGbb6~c?~%Lq^u6aITG8)J{127J8mfPu*D$N0RuSrVs{*Th~ zdPN;l1qXg2q=}mp0(&(GrqFyPh7T_rvZCn#Pl(@Cjdthl)%%j@aT?i;BXL=WFn3E4 z|2MvxijA$7{QeGhMZdU?#>AQ4giWR&aQ&x5C6Ed%KJMTNu?w)wfj%s?1t0Bo$~bt` zs_fE6cYMzVE=<3-2GR^>;Guwn@EYLrTjr6bHC{k;GNKG=GeV^Yd!#OKZj;1~J&r?c9C4jyE+;!$az5c|WqMbna4T zKDLr5+GyvKWsSB3oo7?Tm?4DsK;e-lJ$@l#tGmSuxcHf9uCHgk#OiUt&B`FU-auLy5NKJ9!-ymY;AeCD&i*RtG- zQdkd3lIUYrg5CxNd%jRi{@U=%cJoQ&J5?;SN`G!NG&G|TyBFeG#hmy^8a@=>u?;%i@xFVqMEej z+C_UNlEbaWR|3xB8`#96dok(|>S$;vDyxl7fzXnJ?)`ulje7Xevoejj(U;J{jdqJ8 zA|Pl%eGgw*3#zH96%d9TJeEII5f0#*KwswjPI<~EVN+0MG9az{c6JQZ*s>4_cG#ch zVL*|M_hgT6E5InnuG7nA17%L;lxH>+U9@)Y0;ZYlPc8ODYb0~?kL}zC$~G)w;@QDg zTG22g+0E4mRy&jCPbra-FRX4f`u|VbB}O5)+DP?=+Fooa{=;d80(HQxx)t$qVnHdnyQ@FgKBMTsRBZUpkx{s(@%vc zof~$Ahw2D{Ta`9CIh<mQxXs-gMMAmPgVl?Vk!2p|645|!w<6=AbqSZfgwG5kItHB9gk0DpTK7G;p|tm z^F8p!=UmvlAGpan={G~YGdHfd>c96^(qb)BBfOT(SjHjhyN9Ry)6^C*LzD;X@HYhw z7QR6vVgCJ~kl%lAO0G_dug-Z~Ks1QGD8t9h1J^3d`@xg?ZL86&NMnPt z4-SH6vTWo|(6;S@WL%I?q##kuq`j6SofSB-qp_?a0V==WVsP4$NliE4xibjezR8gdW2MwdOL5!G#gz-sfp|PrEiltO)#-fjpl!} zHk9;r^EWQ6hz`)3d@5)j{7Asu-{%h$-VD>hsXcFbOUGhlO%I@XoJAqIU6JsZED`kD zG7+P_2MLDl;u8w)+>3hzpMr;RRstw?7OOY>#LvJq`-CvNF0 zNtKS*YS`g+8#FvNfQi`2*jx2tTA!%18o_E;y*NT67~S35C+YuUN6VH6V6t}s>RoIE zppUdRMg316Kvl!Ds!-9jBZGUrxCn+-{uC+VBxN0pu#T9wWiVo1Ws=Ml%Xo5A`K|mw z0l;n|ys+h``6cAgDkd2O$K!?9Ewc|rnP%zrA=+Nji+JRsDPpjFZb;j_UIZU-{uqreBFdj zlA+mdxATsw${aMGS@P3`528DJWBl>OT14^}N*r{U$B7cQ+;0IoYBp&3|*2 zYC?*e59!q@OaLZc;GJ3_2$V4nkf6ZbGe=W9;zh*0Xp!vt!BY=B8*lcWperWQLo=lXajW5l zsow{bk}UF3ztDs~)SMiGB?F~$BK!Txl&1PyZjYvc({etJ2cUj>p|?uPi_ZzS?*w1r z2HKDX-lgG=<-c&2`PE@cWhyLbe&5MKcD$bV!%6}`o^;5)c?ko|uH;d0V$DZclE0{l zow}f@RG?&rAJuk+ zH9xYeeZ)hNj>c`$dtsSJ?sw*{LUXrt7U~`mm63suMmvdUdkii`PB%DXs4X@#o*eak zLJ*Q{tT)@0`&|}c+gX&f$}Z_>C=t`WdS5!$snE0Ylh8aH2sAMqph!29Tq11e*~Lwk z4Jeh(!M2Ay9;lPGN8I|-!HO;-;(N`xu!du3%Y)s_4nCs3)0F! zuo%R54yjRbvYASHy7>nqK9dKGyp032^WzyV{OTEG1EIouA^c^eZ{K}&X?x(EO8GGt zePFI>-9Z^dS9w6lGGOw5=uB;fr9dEI{ogSHKT{-ote{l}W`U<2wI<0)M;f z!B%XhOlY=NC)B*l=r=3y>^^S$D?s+e;`4+dN>a%Rinu@FzMf}s_%D=4t{GRcF(d(L zzh0Bn^rXif-jB;(k#5V^i^bt~cnt_wWoJ>6HTKTG1_G^cx+_isXdiLp50vVfh`sKe4ihG3hmRhgSnYbo6%+2y;@KrV5UoE2oBa=`C}p5O zU-Lm|w&)?dWWFBg??4unB4Qwck&6Jt!aA0l+lrk3#V;`^GQ_kzkaD1HC;r0=^cP?E z8yK)uJRKe3w(xYX%hl2j{xN#hL)@kiue-m)X_X)3912Yfa9 zee)Ihb54Pe0D@Gr}B>;7qlPYMCo7s1PRejEmLyP6s)Yg+p>w%P=PQeEG{v^X5 z5OY$Dz!96%Z?N*}K#G7^ar{zVAn#}ad&c;+oBh_!`9OmyOOA|LUV*G_Wsgy5#$@9;(gjqFD8rb=Q~tHb<`4bHi!t( z0STSpf#|xL5qRZ8wntfe$dx;BGFC~Lc^)3Z{4auKEmWgS7e(bOHhcx7>s3+b#nbZU zBl1d}K+-dx7F$FX6z%_Y6uKdU*Z|&rM+v-pCxQC+?uSgYCRIiFEHC(Y^Z+j04AjoG z*VP@rRyfI5l&tG1XGO|xS}FSb1s2cu>$xCK%cT{G1%R#zffm{XCi?-8rnO~4`w}b| z+l0pQ@Z@~|OQuBQP&J@v34|mkWmdM4lxnHCvXT$k0~yzHV#4^oNexg4Pbvu_3crly zmfGcLg6PeBA6GY{iU_x95-RtpiIuX(-&jqB%0B~=Nl!&FG0} zE_0ormrl})xD!kSy}y_;IDG}C2LIF3!QO)j6;NjMwTHTmo^4(jA6!^T*KETfI&u~F zEvJk**wXG!l^!X{2KgkXlEN7pQ(xd5^-vC`WT1IMR|q!K(evfKPW1t>3YAs0bBKYR z_{-CbxuU`@t|QF|l2B=4OPA)HYP1M*_V<9|7nsyEVFL^sq3oT-AxWjha!k7?1B4Y< zdSLAnK4Oo0ZYS^mRX;y)%d;|&H-6cOlmi5at&iw9_hF!~0?=H6R)&J}N7oew{bj3L z4pHSu@OcW7$$M{ZAU|0?JnwxD{UIC7EO2uLe*A3+BU3YFvR2N3Y*d`*r2EezbjQvq9n`0^CMb1O9WudthNs*gT7sxqY5t|28rjBDN(Pt^v zp_(4(nNypKR%Xil{Jf zPFpaYZ??z8Kgm;Gu-pn*x4!u$7a|-T*xMYl^tiU50a9N0!f~o1Dn%yrhc7M&G0?-1 z=%(>Vfv`vqFMtHf-RaLXc+-niGYVLC$g)~?$T2ecN^s~oBd(WWruy>-^GaGyittlv zkLv0zzDe_x#VdLib~@yLQ3&uEP*^dMs&|$(oSN4DcF16$ZFXVq@8YW^wMSnU&YeCf z97G~_HvriVzP>awP+!z*OK-YJocW6Qpk+fv&^X3O_F~@LnwR~EeWvUo?@98yYd#N4 z+J?HMZ)W`gM`(vDfB4fk0pFN-#v9BX<7nI#CTkj-IiN7PMdfbcjRpZp)e|sXx6%_e zB27LC;Te@OIwz6q#wqDz0nlzWwEN?l%w}1{1bSz@N#LCP_Z(q9%@YPw;HnDvJPUY6 za2Yf6Om|4o9;*d)8}moYaB>MLv^PmgWd<)>~t{gE^LH z>Do!Qe$65GRFq94U@Mm5=BRZQK@vrpQ^tG#$8Hu>kuA&yr$j{(f3N30U_Nouk=OKa zv&N+GPEvU#1S@!-IkF6Sw9g;sf%m%(^flhvnS3b3;ho4Q*8=w(KEf<=S69DtNw)84 z&+Oe4p|I6Ll`@L80iBwU>~}rQu5z$E=cGc* z21Af56LerFQdNpE9g3m-Kp72#N*5Sm&Y;mJt&#ZP{9 zeO;3no+GA`k=xy#{?_%X{s14=gEkw&LtR%5KixYoL1! zh4P*z)}LawI^ih|G)S^JsPWhbl+QGcy5w;Ie`7EzVpxtGrosb^ zIPxSKV}F#oC$acW=N?uG8F2cXw}@SK^P7wzG2wlV(1oD!9SUyxFMWq^P9i&F<4+^K z5;6{SkymzrqFrIB*&Idb)U8pWI^CSj3DJ8~X5iW%G>h+83OQ?0;~t)e{bpRMYfET0 zQ#ruA9E!4XyzL+Ba2c>T82H_F%AGBBIuJZA3a~sj_cmUi*1;E5iP2YXTp$RQRSVc~jwD zO|iLuyORcE_jA>Twj9&LLOdr|17}Y6KWEdX3W*88kmBYl!K-B>0ZDTjlZ#CxlLiqf zkJ<&FTPZd^4b{*xB)-SO5xS{+R-qlle^o;;`e{^D6|7|Ztl)cwfROv*0Y(6Tw4^E< zTOaZS8Pe3f1ilEWCPj**1)oQ1)CGO;Y!>Zh6adK4D92L>0pXeXb)x%_L>GR>?miD!yMy_2NM)+}c=l2^v0_ zdv?5;)Fb3%ggrxdD=^3<>pc+&I$UY$&O|1SY^D-4m$?OItu_qHEw z*|uj;zS;%=+_t=Qs#qm=w#RyxNqcPWliiuAHMNW{?uE$rJOJXE?&5S_6G-XvA^p72 zHAwhJ)MZGx=t1nlnkeJCWnoKak;0&CZj!DKD;Uz_{h)FPQ7;7%;*kiM)QU^1X2uX|X7zve%gGd z!%_z$2TifYS6atM;peNvchyOitzL=gc?rxk8+_+8vDGD0E6R%P%KL*xFJUC0^AK*` zomi4O=Q|QLhF*W}JoxT#XKVq+Z(Uu`f0`OB9~Bk)EF6AEpW$T6BrMASJM*oSIB(X~ z!Ee~^?8kZc?L3#$Zszd2;M3>rM1!6;d=*f+z z#GFl*EOc{o%c!3I0I2X=H7_HSRNn@>rQIzB6=-Qw!`V5bX+Ra)O_=Xh4XsUeUNk|p&J*B_)Zc>zc_dKw ze(NvKJW{=D78Jr^`yQ`O-<;|xM0E63YF10;MvqoWz23?#{pv965un>Pbo|m~$xiI0 zP>z%HALXC=_h>1h+x+(;I>5%M!P*QGls0#_)y?|vL|mN&ep9pM!m&yG)nThx_kI;6 z+?}~`;ka$-_>QOpsnXiW{{bY8iq#INO=#kkeud8;hLn2Or&pNNSom4F&_jA@8C?nQs zSKF2jR#bFSBdG=SWWPtM$RsMKr}Up6H-ODfrkTy_$5$bY=@&Y1Qq)Acm>avk*R_S8 zad75B1|72Ahk+@S{_28+ITlj=Kt0?VKlAKO+dWw)xIY^ z14_l0j~eNIPtS?7bOcYEwXQxiDFU@P3#pCjmZ3d z*xxcrraL9U6g)rddB?r+wt{nK4RkadxDtXf9$~87wCN zlQ-6pQA6sdT;a$^nm^SKts&+&zpe`ko~0`PQ%crT*j5u1^lW@%<)xhOF@b$$#s5^F zCT=JE`iH_CPV?Xbl8k``qg1w)YBP(3<#v6UpMFFNKB8=K> zOGz1V)5(;d^`UCYzoduG^+o}O#-S0+JJm%!9G$a@81g67>PWgtd%&4_viCq7Y%+Ws?M#YJ-HfY z^5h3qS5)cu*|(aDMpbj`=eCNcSCKkgp?!CIn(IN*J*uhjTOIx1b#8gp&d=_b^oNDE z<*maII~3bfRmN|xRIe=>-v)_3)!m?Y+{mBWH)k6dxDNu^)_(fLANg_OAZd>&dMhi7&6;PEjAZkIu(a> zB)H=)LCga|qMQv1aKda~WGo{{T8Hjl?xgVKx{gBI{vzLSK+@Mg6)M2=K+jB96!42uZz{e@OH#)lU${ zNS7rE3TdRLx?>S|?0E7KlIun%vfQEpYzFx8F!0MQg}73n;ppI8e{oSh2m}&rsxQKZ z-VPmnMV9Ig4{)9P&iaseKnfrwUECWobsFAhSzQGUBf`pyg6;$ilcl&rT!AsB#8er* z%o`D)uCLv7yMiuj!$~U|?OG3%2|`4Hkwb#E-9f{70tAx)fxo2Ho25)+N~`W-{zx4r zOnD8IsMcgr{d8njY*lUOCnq|cVY+TLgp$w}{G2mJ;cCtKze212oTj0ys;eNABADxT zAT8LbFvueSfm@zU)SFu~BrdR-`wC0A{ki;k<2Q=DQyO|Oc6i?DTaWz&cKMwnC0Xy%5A08o;(_wp>4HFRNcL#Dxk$n`83p^}&%Ut) zAB)AnJ!CN)IhHh=0*NLi+<3xivfli)%`;1ZM=JU{<9E@<}&<^lxG)>zl42;mG zNoW-3XX=*{!BUQR8@BG2lm?0yZ<`An_FkIi35=v=-5%N@$cS0c#nf92O?Y(w2o+oL z3KNz(cYW{}H#!0sZ9+F)XTu?yR(!as16Q|W(6VQI3gU<}ynv>OF|y0|^4QhzYLF$m zQ)q$!JLtb|kNs6$rb8#IjhmWffdesLCFE%TRc|#qw1$t#{&$XQ1CgRApgbEv;TO0W zZwNVqLauyth>32mQRFl9&SMn&%7mhaAGXVztiR%4W@0%6c=+#R!>8}v(h%A<-D8|; zV(LP!ppdg<5ucW33!Uk%Snq=b6^p4lsj>W`BzKCKP-rlqJUs-hRGlX!Bbr_jw>wvTv0>sYtGLK7yI)rzA-STr@o^A zz3%z_f)@OYp(DJXPA-`efZO#2HdiH5t7Uz-wL%<$<_kG~;7qdzn^_ZUHuv<1K}nSG zB?fV?$!}?#h@W0ci*XpKhr}_GK&kM?(I_C}yrFt^y>)TptSq4*PzXXX3^0B!uuZ}&G6al>EF|Z9&U>h7b8ya`* zYdyf&o=y9e34pRcYGos99S=Moj6Iymd_hnNG=fpJ&-w?8JR90s%-4RP2VxN!J24ER)ZZf8kmJPLD^TmxGgPlnF9mUKLu|1!G!Vp-ywB zCRvZsnuyWqB3*(?AP7~VAfKD@UD=NF|CXh{6L(D>^ya`vS%A`S3!!>Dg zz-C(Wi|M_}N7MTe2bleQ#GV_U7)StyV7v@P6CU!hZ+`yxL^5Cd2tJwLv!y!ujR-hL zFs@96EITBs62P`Jzx~~SGIIjizVS*Ku36T~&H`Tgfl8@f+{SKzoraee8ndy=cUf$_ zLhpl!b4!tE2XoQXw7#j(+gZTj?|E&G8`46y{w{s{0=y_|V>5nk+vZ&l2GpRDE<@PG z3>0-Z4%OjsPhl>o-KOzfXwz?!2_3h70&MW!i*YWzjbs)gIxF%bh#C#8Pt-D%#0pQIS{eW2<8 z{6Y3nf2a#QFgNhJZQLgmO|fjUg&XyNG5SI&>v0_fxT&0Th+|y*d!@BT?#4Zaxr(JG z)v-N;Zyry0WO|%GEfXuK3k9%6|V@_#SS}kHKZ3B&+!X<$?25yIw zlQDgl8;}5WK-GwaVKu)e8&S5FAPY84xYS`>@M3OnqYdne~G47sAq8UfEgML%K$I~2vr zgS{5_cXQ0^VVSIU2M)%gab@&n6t28?9%KnQbjwlHQ8`2WAz3mA+q@X64C#@NfcX@| zzcZV8Y$|s6hum4_JdUAuqe8+1H^O!cd>jL3CbOa_fjO9&ZT!A6UG1vh+xyd-{H2X1 zVq)wc<2D$$4mIG~gdF5LJ8xwGIL)Z6o??$ZDRx??icjDrV?v6G|4^Q)+vAN^$vg7PEO=%&ID-oq&Q7NqriZYP^ ziBzL{E*<#p@$SSxLu-e6b-#%W!m6y9^1JWZC)c$C+4=FFvJb22kn;ujOdzV)qPMZe zVk6DCr?Zz{*zC|~Z*O6dSmo`f!3y^v+iP~gJjwL~T`|KeY9K=E7o3{5rjoFfuS4@j z5UI!%F*zacAEs~UzjU}B@WJ;-b`Nx_Ql$Jk(~R3X&yhQ!4^DsVt) zGZW{@?Xf5b<|ni8y1S6e6%KyDwS0jo-E{JZ06{#O#m>8yT0LJ0-a+i=WM&Of1sZXe z-kq$nThSVKyM|0Z+e`l|#=<+-wzE#me6r@!i}c$RcfWu3%ZktUd4{xVRezqg4W}dI zpvq!?w?N)>|H0@(LJn8hj~k%%sbM4;_{>>I{Ikv0x{5>l%xW3+7jminsNFx{alyP8 z&)#Igd0F@=#mbq<0_tNwQ5RgKH+XXx`DbP`H2VZGF|ihN@Kr`T#1gn0L%#`pT>OYg zt}8c(99QhyhHZK=D73v`czKmqb7nrc1G5|J@}VEt?uROy{yti*_9oF++U+hQ!x5B zR#$wp=gp0Wi~iY9*h=K4e;4TQo%~)UT>AU_gVm4U!Uy z0@5Mf(%lUMN-5nST?5i6oueQv-7Nx=LwCMwyzlqf&kxvN_ObcGA;_Awu61>st4u4q zP}dOeiI(z}qqE}Z(Dl+?+h1EF+oCJmPec7*)OupbBD(^|`LFz%Z>N`~LklJb(v_HX zAfWRx_xTN!Sy=4t(6i)hv8(~5wP|hdRa|~~eH^#Kk%9oV4!5h~cf-0d=Pfi1eNDxZ z9$ViI#yZxDPc7tD=T0hVSOQ)w(7jZHaDu_Vh5{f`i-)UPed<5HF-Nz2%2colHA*+} zxymiV8?as}{9K`0Ndr=KS{dX#egcu*)~ES}GwTcAM#iEZyvawJHaxH^WP3L88!2x( zg$h-Tgoe-G!y}_vqx#hM71axVIOy|A*cmih%?4ccSB@{uESz7yl)v6Q`W*hls zN!BG!(Tll@DCm=^lA%{w{dwtyG@RbOF>eKq?*&GHwNvH{hVWBlk}Ndlsn2(W_aGEo zgBoLD16xZ{Ev7m3*`Z|YI?qH-x+ zI-V!3XO(v~aVe3a^Ji>2kP6_nrsj=WiK}f7b*sX@@?_5pu7?mXxLSPy8eIA6EGm^Z z;GoUltcofb4SjjGC z{>VzIXs-KdvInaU!~!4&c(pDhNgwy=LcJ~yNc-~ThTPeE{yIwV5HN-g0aOn8mm3@V z4mm7Y0lOEWMn^j{)yuX<7yYHTf|V^U3d>T-Tlq(%?Oraa?~I=FJXyHiu25|e;Gd(8 ze%MN#nu(0%kA5PSQfk` z26W-|Q$EWSH_b16d8Q<9vVGPz+Y`&bMHr9Dyck0MVJl27Olo!j*5riNGfV1fD0^al1`Eqq`5KV#D47I5CwV1 z*(TN@I{@rOaD}IP?Q!GJ?uZ!Cl=b`LT$7ZjYKBXM#PO)H?OSgMAo>R8Z>ePBL@ijXN)SsqdztsWJ_HxX#N{Znjx2OXHLT`mgPwbVVN`m^%0 zJH7u1&4!PMmz8dfRcshEiS&+?JE44OP6Nc85&(Cj;^Olq%eGA7T3dTKE&gewrn^7`*pd(&H+ zV?2b6YiY2c2I|ad?4j>^9rg=v5hw?LT6UdGH`TmdSi13=g~!;2LU&f+q$FI1^NHP2 zQ&Cgd*7l>Hvq-tawsI(9v&0jwz2Cm)mKsu*#g@b4cZm?ty`cI%gsw1rW1> zK5$;wZ>5Vkc4GUMYj{!)B7N;@7Mu9De?!Rc$|;f;fkT1oT_&_}YeTT{3Zh$5KIV#{{5;xa!tORJHZbNSvRjT;GG~qJPPg5-x85RM1dV87kR5qath|*JP zVS?M=Jo#@->h2YczXU{Pys81cTaCb_TS&?fR~>p5y?8ju?RM09QK}sb`_*pOK3XEB zOf45()VI9JR!P--e&+mhV}Q~T4~QL~aNXdR?n|{)F%*{CM}X01Zp(6ras+^1B-LxJ zE;i-$XMq-PU4&${(uE+I7svI!Jmm{n>}m!&7|oF!{rpk+(ET?kJx|hwQN}AO7jfoK zrWf_?cig@v*atCL(1#}9{T1b^UH$rJ1?$Z+MfL)zbo+Gin1FSjMFb;f@D;|bHaLL= zxhl3w7`Twu-p%(u6$kT^o*|?T4Sd;2k#XPvlSvWn@afag{kmFtN+<#Z4@sW&F_y+Y zJap6`jTwC49P(n|ovhEE(VcZZ7uyr`oLYbF7c7zpirTMZ^-U5KT`sc{9APkd(sh?r z_NbHZg&NDW@Po@LXzz7XrMsI~K}+dPhl~=lcB;}SW-1vuaqQ^Bere?}L40W4ND2`D z;mg}nKoxO7714yTqOHa*+fu<`c)lgj;=WaZzzr%O3k~uqNAp6Gm?{Sazc`2z8j*)~`BEz;crNSO=067#GtdGDx&fJCQz@w4|KeHaCQ4akmYx z4zW^(gSc~;46NOpFxI`@D7{v8kJq#Q^d~a4_EuBsYKa@ znzPxaXS0v}EV^}5r%ZSIs|T_OL*;yTkI*@MTr9wYFz;}Xb@h1K9lbjJb{jpJ7IbZi zyYnxp?-QE^-^xfMc_<(`YGOPJ-~=QhVS?|LYTwqkTOQD!-#siJIS zm7ZjO9p3jTs3xkDxTFP=tRB@?6H65MmOGCq=RLRsu;;1mRwd+~*>b&)URrOyV<1SU zFJ6*=LoDIw$6xmR_D^S2YTDZ7RRBYVcB4|GRQm22S!}YP)wduqMczuHcCn?)46vl% znJPLA5;ZX~HkX}2Q?^dAo>GPt1HaJN6=;%-Sj&?q+&98pfdvGrBlbk&=lV z>{|A`e&=;@sc490^^}r-gu>2 ziL2UKjZvcv7r!`yQx08F@$@h}i0U4mTnvpctUd*5|9D2)3{{+t5!E zbk?o^s?89X`ziaW^TG(ocLKK6`>B||>tk05SfCxuC-Lh5)3CdGeBe_F+~KkQsgSSH zqn&Wdh^vhC7QThL;&b)(A?-hzNf5UmA+9C|n=5M)>tgp>)A(#1u!pXHVs?ahA1$n^ za5YaQpt22SV>$X99}P4d_pWYG{!7|m(4E{U0}bNpesWwPr-at~wR|Rqc#2;P3c9Xt z7J5E(F4t-}dMyO_I*f$(znm)hw7S>Ttwz%3;TAj^-7M&_Zo#yk&{ zwYl5K;DJoc{M90Ni~7AyejQK<|= z%-#cyf(~d`&s4;8czD%P=OZQ5dWg#rFpsnCfOj;QeV-B!I+0%TIyisWSithJV&)IE z;uaF01Oa;yGDewrY#`@K3(SBQk+rGJ-c5D64>i7Pb@ie7deFxi>F{Aj#bG*U#K_@a z1qSJuc)U#5!#e+M*8$xa;I2A9*}VT0S27t)DeHa#JVz(IQ29hQ;dOm0OAF#gv|Z29 zkkpWp93Or(K+8&Gb|ZdfLYiB`T2QBJp=Q2(yiiB_Lit-Ow1on zy4$>xT;+Ze@3fGIo^mr+w{3VI(@3l+Hb;7r=4q|m|1f=B@PHJOlUS@E-}*kP1(E=( zjZjiD(t1=gdWtDQvRHRA>D0~tVFQAqcszl`zjnDiaeO#e%Q)uWE8Nm+c7Fb+)`}upTo6WSRt`ISWKna2K^% z@r_E%wq_+>`r=vta+|0lPQ5`ryMDbFl-Ye8jxwf|EkSTQQ*Wg5og0^uFYamSAT^HT z^(1M!`vpVq*N(wc$ZE(luo_c^7KJFuB%8VBuK%1~M_+x5=zQBjms5Aznn`C~S8(3g zMKNygoSF(YX;RUomUK*-t}xxJE2&n6;IZ+A7hp7v}) z{F^l)q!GlwR@H!$40<;SVtfyZ*gi8Qt+yM}d1`tjy2N2F7a6d4ZGBD5vnkv*TQ7f5vFmEW;CH&8!L) zT1{`P3-q2rq89y@<~n*lJT0$}^;?ct5s{#BfUlfZ z?KeF$aa(NX9#O^CbI{Hlk9W>5h%R(UOGKAWif3w9JuK{Po|U=kFq5?zV}!VXynO6q zV7dK!H~CKV88Be*V|;P`(!10BPs>iH?IHcQ75pNP*uwV5aT0z^w~QS1-UZw+GU6!1 zDF!peD5KlX-^uq`jQr^|xrq`qyuLF%A_=YTpVB{FDl=%SdEVsOGEUCOO26)9Y1!aD zFK_vRt$bo`=%r$$0_OpQ=2~gPsVA$FI5>?d{(zcQ%Swl z0Gs3ln{*Bej+t_eY7B;jRNO-^tUjGsR}Kz1MUWER`%F*ubcn%k|dy8vM#peoeK3X+`? z=h>3lFH_*O0s&{0X&20x9jk?klMLuNUK-_(A+oSGIT@HmOu*ILG6-_+)Z?ok!ukCW zzdrBxl`^&O&$#|b`B*unvxRl{*M6J$o^`W#fAd5PNWYshDFIxhJDfMY>+4Qf0KgQ^ zFZ#q^NVo~aLqtggfK!0q&@3$687;SvE=sN=(%me(f9d=baMoe}7vQWuz%n3t=7sjGfV0SLd}oA|W$%;7jppvb zV50?z0y?YWPhY?G#^r&gYY8dUL=pMrIw{4aDwYZv3eQ?vl|K+90t($4Q0`apW0qU3 zgXMY-IPlYSxDL(J-uZ!S2`+ZS24;4BZuq|WL37N55XbBDNI~=g!lLnRm2sbZqUq6* zWv8j7>mu&G_C^bF1^vHFO0^QXKT$xpZ|r?=m;YSv*1=0$!O$4!j%oX-$j>-f1Stn= z3_r(K&9&B`A(q4q>5v!Su*zCo-kQ^Rq7U}s3;C_jiZV1fpzJ@n6LxtFJQ~p?A&5e8 z7;wC1fT;a*yv{`0N4q|mY<{@F!4~d29#f{l4LJPe?1*Y3=ss@c5^Wpva->tWKo9>~ z2U&Icj89lJ+iie2V|9i!fU$2nDR6AlqQCEbD%J7i1NKZ!4qlpAGyGI7#3A{`1-93x zTgYI#vMd&G>*i(u(MaGm?hL)DvHBKhNLIb{5mjn4s9eaL9VTNuNZq6e9 zPpQxiD_`f!GBnSkeFp!>G3`t9dJ`-WT=`^~U*q^L#d;O#C+vD90W@W%&j!@y}1AnZ>fPC(s!LJp( zHg`Uf@+-48k1Av2CoD6ovt*OJp)` zE0tRwiu-CWJ;&*@jfjpi5~1Y4j!N+}bOg2Vs)J#MaxZ>L0Tf9zaD^^;BPN@L<({ES z=L0dpPme^29m0R+@M9DmiL7f3ZhHGmcXf4K!4Lh__tmADvCHe-+=P&6lJe;?79Sx6 zrP?!q)H4oXZ(WjG9!I3$>qdM=e`Zxz7&nANOi0g&Eyd%Cs;e z9!?QaQ{vM*)DRU7XmzOOn2U(Yn;cc&ap>R8d+HuIITKkwkUeAdhFAgQ4#`1&5q5(b zFK4fP_}#k6SQ;_5pi~K^lp?OOUhQHr%ekT^?yD8uJasfxdl9Sb)gzCS;(U|smAgib zm<9=j&;luJS_lOI>xh*az>*Kx5`?m~Y!41#3-%{LWx6|uYpTa*Y9Q{YbJ zL7UqLa)nT9iGs!lSM^zwiee@S^V-}l_0KOVpO+d}=C(BZ5p@htGe+b~_2+(}UZ+R= zaX3v6*e^$}9QhbMkP(z$R<-%sN1K}h82$EJB}kJ8xmbRGV8$$jMISbft2P0HFa-O& zgqeMH+rMn&zuw)+(QrWKqofcGDK8_|1-)Zm?vW?^kr>|f;kVl>Lu)l+tcX}3H6H;3 zuBQ<4%#Acbrf|HnF8s|wSBikf1bq=0`Y63m|#ogbt`PByZ>-sHWx-t zQt`o>1kMZkdZcPcHgf&nt&)Jaf=KcydlZAJrodL3^TO!Tx#gWy!&(yzJC$6__t0

hx_U_2he?{J&tjKhvWQi8j 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 Z=uWooiJtnDoxdX6$k6P1ng0E#{{wPof5HF& literal 0 HcmV?d00001 diff --git a/images/facebook.svg b/images/facebook.svg new file mode 100644 index 0000000..9e83cfc --- /dev/null +++ b/images/facebook.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/github.svg b/images/github.svg new file mode 100644 index 0000000..423790c --- /dev/null +++ b/images/github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/images/gopher.png b/images/gopher.png new file mode 100644 index 0000000000000000000000000000000000000000..110312a5c39859f04a690c565149bddca4f440df GIT binary patch literal 34156 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 literal 0 HcmV?d00001 diff --git a/images/simple-logo.png b/images/simple-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a11a1b4f9eb42c4bd53ab5730c416ec4e0b86887 GIT binary patch literal 17608 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 \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..add2392 --- /dev/null +++ b/index.html @@ -0,0 +1,73 @@ +--- +layout: default +--- + +

+ +
+
+
+ + {% for post in paginator.posts %} +
+ +
+
+

{{ post.title | truncate: 25 }}

+
+ {% if post.img %} + {{post.title}} + {% else %} + {{site.title}} + {% endif %} +
+ {{ post.excerpt | strip_html | strip_newlines | truncate: 160 }} + Read +
+
+
+ + {% endfor %} + +
+
+ + {% include sidebar.html %} +
+ + + + +
+
+
+ {% if paginator.total_pages > 1 %} +
    + {% if paginator.previous_page %} +
  • « Prev
  • + {% else %} +
  • « Prev
  • + {% endif %} + + {% for page in (1..paginator.total_pages) %} + {% if page == paginator.page %} +
  • {{ page }}
  • + {% elsif page == 1 %} +
  • {{ page }}
  • + {% else %} +
  • {{ page }}
  • + {% endif %} + {% endfor %} + + {% if paginator.next_page %} +
  • Next »
  • + {% else %} +
  • Next »
  • + {% endif %} +
+ {% endif %} + +
+
+
+
diff --git a/js/bootstrap.min.js b/js/bootstrap.min.js new file mode 100644 index 0000000..e79c065 --- /dev/null +++ b/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.6",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.6",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/js/fit.js b/js/fit.js new file mode 100644 index 0000000..3a3206d --- /dev/null +++ b/js/fit.js @@ -0,0 +1,59 @@ +/** + * Fit terminal columns and rows to the dimensions of its DOM element. + * + * ## Approach + * - Rows: Truncate the division of the terminal parent element height by the terminal row height. + * + * - Columns: Truncate the division of the terminal parent element width by the terminal character + * width (apply display: inline at the terminal row and truncate its width with the current + * number of columns). + * @module xterm/addons/fit/fit + * @license MIT + */ +(function (fit) { + if (typeof exports === 'object' && typeof module === 'object') { + /* + * CommonJS environment + */ + module.exports = fit(require('../../xterm')); + } + else if (typeof define == 'function') { + /* + * Require.js is available + */ + define(['../../xterm'], fit); + } + else { + /* + * Plain browser environment + */ + fit(window.Terminal); + } +})(function (Xterm) { + var exports = {}; + exports.proposeGeometry = function (term) { + var parentElementStyle = window.getComputedStyle(term.element.parentElement), parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')), parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17), elementStyle = window.getComputedStyle(term.element), elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')), elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')), availableHeight = parentElementHeight - elementPaddingVer, availableWidth = parentElementWidth - elementPaddingHor, container = term.rowContainer, subjectRow = term.rowContainer.firstElementChild, contentBuffer = subjectRow.innerHTML, characterHeight, rows, characterWidth, cols, geometry; + subjectRow.style.display = 'inline'; + subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace + characterWidth = subjectRow.getBoundingClientRect().width; + subjectRow.style.display = ''; // Revert style before calculating height, since they differ. + characterHeight = parseInt(subjectRow.offsetHeight); + subjectRow.innerHTML = contentBuffer; + rows = parseInt(availableHeight / characterHeight); + cols = parseInt(availableWidth / characterWidth); + geometry = { cols: cols, rows: rows }; + return geometry; + }; + exports.fit = function (term) { + var geometry = exports.proposeGeometry(term); + term.resize(geometry.cols, geometry.rows); + }; + Xterm.prototype.proposeGeometry = function () { + return exports.proposeGeometry(this); + }; + Xterm.prototype.fit = function () { + return exports.fit(this); + }; + return exports; +}); +//# sourceMappingURL=fit.js.map diff --git a/js/sdk.js b/js/sdk.js new file mode 100644 index 0000000..7252534 --- /dev/null +++ b/js/sdk.js @@ -0,0 +1,220 @@ +(function (window, document) { + + 'use strict'; + + function injectScript(src, cb) { + var sj = document.createElement('script'); + sj.type = 'text/javascript'; + sj.async = true; + sj.src = src; + sj.addEventListener ? sj.addEventListener('load', cb, false) : sj.attachEvent('onload', cb); + var s = document.getElementsByTagName('script')[0]; + s.parentNode.insertBefore(sj, s); + } + + + // declare + var pwd = function () { + this.instances = {}; + this.instanceBuffer = {}; + return; + }; + + var verifyCallback = function(response) { + var self = this; + var data = encodeURIComponent('g-recaptcha-response') + '=' + encodeURIComponent(response); + postRequest(this.baseUrl + '/', {headers:{'Content-type':'application/x-www-form-urlencoded'}}, data, function(resp) { + + //TODO handle errors + if (resp.status == 200) { + self.init(resp.responseText, self.opts); + self.selectors.forEach(function(sel){ + self.terminal(sel, function(){ + //Remove captchas after initializing terminals; + var captcha = document.querySelectorAll(sel + ' .captcha'); + captcha.forEach(function(el){ + el.parentNode.removeChild(el); + }); + + }); + }); + }; + }); + }; + + // register recaptcha onload callback + window.onloadCallback = function() { + window.pwd.selectors.forEach(function(sel) { + var els = document.querySelectorAll(sel); + els.forEach(function(el) { + var captcha = document.createElement('div'); + captcha.className = 'captcha'; + el.appendChild(captcha); + window.grecaptcha.render(captcha, {'sitekey': '6Ld8pREUAAAAAOkrGItiEeczO9Tfi99sIHoMvFA_', 'callback': verifyCallback.bind(window.pwd)}); + }); + }); + + }; + + pwd.prototype.newSession = function(selectors, opts) { + this.opts = opts || {}; + this.baseUrl = this.opts.baseUrl || 'http://play-with-docker.com'; + selectors = selectors || []; + if (selectors.length > 0) { + this.selectors = selectors; + injectScript('https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit'); + } else { + console.warn('No DOM elements found for selectors', selectors); + } + }; + + // your sdk init function + pwd.prototype.init = function (sessionId, opts) { + var self = this; + opts = opts || {}; + this.baseUrl = opts.baseUrl || 'http://play-with-docker.com'; + this.sessionId = sessionId; + this.socket = io(this.baseUrl, {path: '/sessions/' + sessionId + '/ws' }); + this.socket.on('terminal out', function(name ,data) { + var instance = self.instances[name]; + if (instance && instance.terms) { + instance.terms.forEach(function(term) {term.write(data)}); + } else { + //Buffer the data if term is not ready + if (self.instanceBuffer[name] == undefined) self.instanceBuffer[name] = '';;;; + self.instanceBuffer[name] += data; + } + }); + + // Resize all terminals + this.socket.on('viewport resize', function(cols, rows) { + // Resize all terminals + for (var name in self.instances) { + self.instances[name].terms.forEach(function(term){ + term.resize(cols,rows); + }); + }; + }); + + // Handle window resizing + window.onresize = function() { + self.resize(); + }; + }; + + + pwd.prototype.resize = function() { + var name = Object.keys(this.instances)[0] + if (name) { + var size = this.instances[name].terms[0].proposeGeometry(); + this.socket.emit('viewport resize', size.cols, size.rows); + } + }; + + // I know, opts and data can be ommited. I'm not a JS developer =( + // Data needs to be sent encoded appropriately + function postRequest(url,opts, data, callback) { + var request = new XMLHttpRequest(); + request.open('POST', url, true); + + if (opts && opts.headers) { + for (var key in opts.headers) { + request.setRequestHeader(key, opts.headers[key]); + } + } + request.setRequestHeader('X-Requested-With', 'XMLHttpRequest') + request.onload = function() { + callback(request); + }; + request.send(data); + }; + + pwd.prototype.createInstance = function(callback) { + var self = this; + //TODO handle http connection errors + postRequest(self.baseUrl + '/sessions/' + this.sessionId + '/instances', undefined, undefined, function(response) { + if (response.status == 200) { + var i = JSON.parse(response.responseText); + i.terms = []; + self.instances[i.name] = i; + callback(undefined, i); + } else if (response.status == 409) { + var err = new Error(); + err.max = true; + callback(err); + } else { + callback(new Error()); + } + }); + } + + pwd.prototype.createTerminal = function(selector, name) { + var self = this; + var i = this.instances[name]; + // Create terminal might be called independently + // That's why we need to lazy-load the term in memory if it doesn't exist + if (!i) { + i = {name: name, terms: []}; + this.instances[name] = i; + } + + + var elements = document.querySelectorAll(selector); + elements.forEach(function(el) { + var term = new Terminal({cursorBlink: false}); + term.open(el); + term.on('data', function(d) { + self.socket.emit('terminal in', i.name, d); + }); + var size = term.proposeGeometry(); + self.socket.emit('viewport resize', size.cols, size.rows); + i.terms.push(term); + }); + + + + // Attach block actions + var actions = document.querySelectorAll('code[class*="'+selector+'"]'); + actions.forEach(function(actionEl) { + actionEl.onclick = function() { + self.socket.emit('terminal in', i.name, this.innerText); + }; + }); + + + if (self.instanceBuffer[name]) { + //Flush buffer and clear it + i.terms.forEach(function(term){ + term.write(self.instanceBuffer[name]); + }); + self.instanceBuffer[name] = ''; + } + + return i.terms; + } + + pwd.prototype.terminal = function(selector, callback) { + var self = this; + this.createInstance(function(err, instance) { + if (err && err.max) { + !callback || callback(new Error("Max instances reached")) + return + } else if (err) { + !callback || callback(new Error("Error creating instance")) + return + } + + self.createTerminal(selector, instance.name); + + + !callback || callback(undefined, instance); + + }); + } + + + + // define your namespace myApp + window.pwd = new pwd(); + +})(window, document); diff --git a/js/xterm.js b/js/xterm.js new file mode 100644 index 0000000..f44b6e1 --- /dev/null +++ b/js/xterm.js @@ -0,0 +1,5160 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Terminal = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { + self.terminal.handler(diff); + } + } + }, 0); + }; + /** + * Positions the composition view on top of the cursor and the textarea just below it (so the + * IME helper dialog is positioned correctly). + * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is + * necessary as the IME events across browsers are not consistently triggered. + */ + CompositionHelper.prototype.updateCompositionElements = function (dontRecurse) { + if (!this.isComposing) { + return; + } + var cursor = this.terminal.element.querySelector('.terminal-cursor'); + if (cursor) { + // Take .xterm-rows offsetTop into account as well in case it's positioned absolutely within + // the .xterm element. + var xtermRows = this.terminal.element.querySelector('.xterm-rows'); + var cursorTop = xtermRows.offsetTop + cursor.offsetTop; + this.compositionView.style.left = cursor.offsetLeft + 'px'; + this.compositionView.style.top = cursorTop + 'px'; + this.compositionView.style.height = cursor.offsetHeight + 'px'; + this.compositionView.style.lineHeight = cursor.offsetHeight + 'px'; + // Sync the textarea to the exact position of the composition view so the IME knows where the + // text is. + var compositionViewBounds = this.compositionView.getBoundingClientRect(); + this.textarea.style.left = cursor.offsetLeft + 'px'; + this.textarea.style.top = cursorTop + 'px'; + this.textarea.style.width = compositionViewBounds.width + 'px'; + this.textarea.style.height = compositionViewBounds.height + 'px'; + this.textarea.style.lineHeight = compositionViewBounds.height + 'px'; + } + if (!dontRecurse) { + setTimeout(this.updateCompositionElements.bind(this, true), 0); + } + }; + ; + /** + * Clears the textarea's position so that the cursor does not blink on IE. + * @private + */ + CompositionHelper.prototype.clearTextareaPosition = function () { + this.textarea.style.left = ''; + this.textarea.style.top = ''; + }; + ; + return CompositionHelper; +}()); +exports.CompositionHelper = CompositionHelper; + +},{}],2:[function(require,module,exports){ +/** + * @license MIT + */ +"use strict"; +function EventEmitter() { + this._events = this._events || {}; +} +exports.EventEmitter = EventEmitter; +EventEmitter.prototype.addListener = function (type, listener) { + this._events[type] = this._events[type] || []; + this._events[type].push(listener); +}; +EventEmitter.prototype.on = EventEmitter.prototype.addListener; +EventEmitter.prototype.removeListener = function (type, listener) { + if (!this._events[type]) + return; + var obj = this._events[type], i = obj.length; + while (i--) { + if (obj[i] === listener || obj[i].listener === listener) { + obj.splice(i, 1); + return; + } + } +}; +EventEmitter.prototype.off = EventEmitter.prototype.removeListener; +EventEmitter.prototype.removeAllListeners = function (type) { + if (this._events[type]) + delete this._events[type]; +}; +EventEmitter.prototype.once = function (type, listener) { + var self = this; + function on() { + var args = Array.prototype.slice.call(arguments); + this.removeListener(type, on); + return listener.apply(this, args); + } + on.listener = listener; + return this.on(type, on); +}; +EventEmitter.prototype.emit = function (type) { + if (!this._events[type]) + return; + var args = Array.prototype.slice.call(arguments, 1), obj = this._events[type], l = obj.length, i = 0; + for (; i < l; i++) { + obj[i].apply(this, args); + } +}; +EventEmitter.prototype.listeners = function (type) { + return this._events[type] = this._events[type] || []; +}; + +},{}],3:[function(require,module,exports){ +/** + * @license MIT + */ +"use strict"; +/** + * Represents the viewport of a terminal, the visible area within the larger buffer of output. + * Logic for the virtual scroll bar is included in this object. + */ +var Viewport = (function () { + /** + * Creates a new Viewport. + * @param terminal The terminal this viewport belongs to. + * @param viewportElement The DOM element acting as the viewport. + * @param scrollArea The DOM element acting as the scroll area. + * @param charMeasureElement A DOM element used to measure the character size of. the terminal. + */ + function Viewport(terminal, viewportElement, scrollArea, charMeasureElement) { + this.terminal = terminal; + this.viewportElement = viewportElement; + this.scrollArea = scrollArea; + this.charMeasureElement = charMeasureElement; + this.currentRowHeight = 0; + this.lastRecordedBufferLength = 0; + this.lastRecordedViewportHeight = 0; + this.terminal.on('scroll', this.syncScrollArea.bind(this)); + this.terminal.on('resize', this.syncScrollArea.bind(this)); + this.viewportElement.addEventListener('scroll', this.onScroll.bind(this)); + this.syncScrollArea(); + } + /** + * Refreshes row height, setting line-height, viewport height and scroll area height if + * necessary. + * @param charSize A character size measurement bounding rect object, if it doesn't exist it will + * be created. + */ + Viewport.prototype.refresh = function (charSize) { + var size = charSize || this.charMeasureElement.getBoundingClientRect(); + if (size.height > 0) { + var rowHeightChanged = size.height !== this.currentRowHeight; + if (rowHeightChanged) { + this.currentRowHeight = size.height; + this.viewportElement.style.lineHeight = size.height + 'px'; + this.terminal.rowContainer.style.lineHeight = size.height + 'px'; + } + var viewportHeightChanged = this.lastRecordedViewportHeight !== this.terminal.rows; + if (rowHeightChanged || viewportHeightChanged) { + this.lastRecordedViewportHeight = this.terminal.rows; + this.viewportElement.style.height = size.height * this.terminal.rows + 'px'; + } + this.scrollArea.style.height = (size.height * this.lastRecordedBufferLength) + 'px'; + } + }; + /** + * Updates dimensions and synchronizes the scroll area if necessary. + */ + Viewport.prototype.syncScrollArea = function () { + if (this.lastRecordedBufferLength !== this.terminal.lines.length) { + // If buffer height changed + this.lastRecordedBufferLength = this.terminal.lines.length; + this.refresh(); + } + else if (this.lastRecordedViewportHeight !== this.terminal.rows) { + // If viewport height changed + this.refresh(); + } + else { + // If size has changed, refresh viewport + var size = this.charMeasureElement.getBoundingClientRect(); + if (size.height !== this.currentRowHeight) { + this.refresh(size); + } + } + // Sync scrollTop + var scrollTop = this.terminal.ydisp * this.currentRowHeight; + if (this.viewportElement.scrollTop !== scrollTop) { + this.viewportElement.scrollTop = scrollTop; + } + }; + /** + * Handles scroll events on the viewport, calculating the new viewport and requesting the + * terminal to scroll to it. + * @param ev The scroll event. + */ + Viewport.prototype.onScroll = function (ev) { + var newRow = Math.round(this.viewportElement.scrollTop / this.currentRowHeight); + var diff = newRow - this.terminal.ydisp; + this.terminal.scrollDisp(diff, true); + }; + /** + * Handles mouse wheel events by adjusting the viewport's scrollTop and delegating the actual + * scrolling to `onScroll`, this event needs to be attached manually by the consumer of + * `Viewport`. + * @param ev The mouse wheel event. + */ + Viewport.prototype.onWheel = function (ev) { + if (ev.deltaY === 0) { + // Do nothing if it's not a vertical scroll event + return; + } + // Fallback to WheelEvent.DOM_DELTA_PIXEL + var multiplier = 1; + if (ev.deltaMode === WheelEvent.DOM_DELTA_LINE) { + multiplier = this.currentRowHeight; + } + else if (ev.deltaMode === WheelEvent.DOM_DELTA_PAGE) { + multiplier = this.currentRowHeight * this.terminal.rows; + } + this.viewportElement.scrollTop += ev.deltaY * multiplier; + // Prevent the page from scrolling when the terminal scrolls + ev.preventDefault(); + }; + ; + return Viewport; +}()); +exports.Viewport = Viewport; + +},{}],4:[function(require,module,exports){ +/** + * Clipboard handler module: exports methods for handling all clipboard-related events in the + * terminal. + * @module xterm/handlers/Clipboard + * @license MIT + */ +"use strict"; +/** + * Prepares text copied from terminal selection, to be saved in the clipboard by: + * 1. stripping all trailing white spaces + * 2. converting all non-breaking spaces to regular spaces + * @param {string} text The copied text that needs processing for storing in clipboard + * @returns {string} + */ +function prepareTextForClipboard(text) { + var space = String.fromCharCode(32), nonBreakingSpace = String.fromCharCode(160), allNonBreakingSpaces = new RegExp(nonBreakingSpace, 'g'), processedText = text.split('\n').map(function (line) { + // Strip all trailing white spaces and convert all non-breaking spaces + // to regular spaces. + var processedLine = line.replace(/\s+$/g, '').replace(allNonBreakingSpaces, space); + return processedLine; + }).join('\n'); + return processedText; +} +exports.prepareTextForClipboard = prepareTextForClipboard; +/** + * Binds copy functionality to the given terminal. + * @param {ClipboardEvent} ev The original copy event to be handled + */ +function copyHandler(ev, term) { + // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData` + // property that we use below for Internet Explorer. + var copiedText = window.getSelection().toString(), text = prepareTextForClipboard(copiedText); + if (term.browser.isMSIE) { + window.clipboardData.setData('Text', text); + } + else { + ev.clipboardData.setData('text/plain', text); + } + ev.preventDefault(); // Prevent or the original text will be copied. +} +exports.copyHandler = copyHandler; +/** + * Redirect the clipboard's data to the terminal's input handler. + * @param {ClipboardEvent} ev The original paste event to be handled + * @param {Terminal} term The terminal on which to apply the handled paste event + */ +function pasteHandler(ev, term) { + ev.stopPropagation(); + var text; + var dispatchPaste = function (text) { + term.handler(text); + term.textarea.value = ''; + return term.cancel(ev); + }; + if (term.browser.isMSIE) { + if (window.clipboardData) { + text = window.clipboardData.getData('Text'); + dispatchPaste(text); + } + } + else { + if (ev.clipboardData) { + text = ev.clipboardData.getData('text/plain'); + dispatchPaste(text); + } + } +} +exports.pasteHandler = pasteHandler; +/** + * Bind to right-click event and allow right-click copy and paste. + * + * **Logic** + * If text is selected and right-click happens on selected text, then + * do nothing to allow seamless copying. + * If no text is selected or right-click is outside of the selection + * area, then bring the terminal's input below the cursor, in order to + * trigger the event on the textarea and allow-right click paste, without + * caring about disappearing selection. + * @param {MouseEvent} ev The original right click event to be handled + * @param {Terminal} term The terminal on which to apply the handled paste event + */ +function rightClickHandler(ev, term) { + var s = document.getSelection(), selectedText = prepareTextForClipboard(s.toString()), clickIsOnSelection = false, x = ev.clientX, y = ev.clientY; + if (s.rangeCount) { + var r = s.getRangeAt(0), cr = r.getClientRects(); + for (var i = 0; i < cr.length; i++) { + var rect = cr[i]; + clickIsOnSelection = ((x > rect.left) && (x < rect.right) && + (y > rect.top) && (y < rect.bottom)); + if (clickIsOnSelection) { + break; + } + } + // If we clicked on selection and selection is not a single space, + // then mark the right click as copy-only. We check for the single + // space selection, as this can happen when clicking on an   + // and there is not much pointing in copying a single space. + if (selectedText.match(/^\s$/) || !selectedText.length) { + clickIsOnSelection = false; + } + } + // Bring textarea at the cursor position + if (!clickIsOnSelection) { + term.textarea.style.position = 'fixed'; + term.textarea.style.width = '20px'; + term.textarea.style.height = '20px'; + term.textarea.style.left = (x - 10) + 'px'; + term.textarea.style.top = (y - 10) + 'px'; + term.textarea.style.zIndex = '1000'; + term.textarea.focus(); + // Reset the terminal textarea's styling + setTimeout(function () { + term.textarea.style.position = null; + term.textarea.style.width = null; + term.textarea.style.height = null; + term.textarea.style.left = null; + term.textarea.style.top = null; + term.textarea.style.zIndex = null; + }, 4); + } +} +exports.rightClickHandler = rightClickHandler; + +},{}],5:[function(require,module,exports){ +/** + * Attributes and methods to help with identifying the current browser and platform. + * @module xterm/utils/Browser + * @license MIT + */ +"use strict"; +var Generic_js_1 = require('./Generic.js'); +var isNode = (typeof navigator == 'undefined') ? true : false; +var userAgent = (isNode) ? 'node' : navigator.userAgent; +var platform = (isNode) ? 'node' : navigator.platform; +exports.isFirefox = !!~userAgent.indexOf('Firefox'); +exports.isMSIE = !!~userAgent.indexOf('MSIE') || !!~userAgent.indexOf('Trident'); +// Find the users platform. We use this to interpret the meta key +// and ISO third level shifts. +// http://stackoverflow.com/q/19877924/577598 +exports.isMac = Generic_js_1.contains(['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'], platform); +exports.isIpad = platform === 'iPad'; +exports.isIphone = platform === 'iPhone'; +exports.isMSWindows = Generic_js_1.contains(['Windows', 'Win16', 'Win32', 'WinCE'], platform); + +},{"./Generic.js":6}],6:[function(require,module,exports){ +/** + * Generic utilities module with methods that can be helpful at different parts of the code base. + * @module xterm/utils/Generic + * @license MIT + */ +"use strict"; +/** + * Return if the given array contains the given element + * @param {Array} array The array to search for the given element. + * @param {Object} el The element to look for into the array + */ +exports.contains = function (arr, el) { + return arr.indexOf(el) >= 0; +}; + +},{}],7:[function(require,module,exports){ +/** + * xterm.js: xterm, in the browser + * Originally forked from (with the author's permission): + * Fabrice Bellard's javascript vt100 for jslinux: + * http://bellard.org/jslinux/ + * Copyright (c) 2011 Fabrice Bellard + * The original design remains. The terminal itself + * has been extended to include xterm CSI codes, among + * other features. + * @license MIT + */ +"use strict"; +var CompositionHelper_js_1 = require('./CompositionHelper.js'); +var EventEmitter_js_1 = require('./EventEmitter.js'); +var Viewport_js_1 = require('./Viewport.js'); +var Clipboard_js_1 = require('./handlers/Clipboard.js'); +var Browser = require('./utils/Browser'); +/** + * Terminal Emulation References: + * http://vt100.net/ + * http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt + * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html + * http://invisible-island.net/vttest/ + * http://www.inwap.com/pdp10/ansicode.txt + * http://linux.die.net/man/4/console_codes + * http://linux.die.net/man/7/urxvt + */ +// Let it work inside Node.js for automated testing purposes. +var document = (typeof window != 'undefined') ? window.document : null; +/** + * States + */ +var normal = 0, escaped = 1, csi = 2, osc = 3, charset = 4, dcs = 5, ignore = 6; +/** + * Terminal + */ +/** + * Creates a new `Terminal` object. + * + * @param {object} options An object containing a set of options, the available options are: + * - `cursorBlink` (boolean): Whether the terminal cursor blinks + * - `cols` (number): The number of columns of the terminal (horizontal size) + * - `rows` (number): The number of rows of the terminal (vertical size) + * + * @public + * @class Xterm Xterm + * @alias module:xterm/src/xterm + */ +function Terminal(options) { + var self = this; + if (!(this instanceof Terminal)) { + return new Terminal(arguments[0], arguments[1], arguments[2]); + } + self.browser = Browser; + self.cancel = Terminal.cancel; + EventEmitter_js_1.EventEmitter.call(this); + if (typeof options === 'number') { + options = { + cols: arguments[0], + rows: arguments[1], + handler: arguments[2] + }; + } + options = options || {}; + Object.keys(Terminal.defaults).forEach(function (key) { + if (options[key] == null) { + options[key] = Terminal.options[key]; + if (Terminal[key] !== Terminal.defaults[key]) { + options[key] = Terminal[key]; + } + } + self[key] = options[key]; + }); + if (options.colors.length === 8) { + options.colors = options.colors.concat(Terminal._colors.slice(8)); + } + else if (options.colors.length === 16) { + options.colors = options.colors.concat(Terminal._colors.slice(16)); + } + else if (options.colors.length === 10) { + options.colors = options.colors.slice(0, -2).concat(Terminal._colors.slice(8, -2), options.colors.slice(-2)); + } + else if (options.colors.length === 18) { + options.colors = options.colors.concat(Terminal._colors.slice(16, -2), options.colors.slice(-2)); + } + this.colors = options.colors; + this.options = options; + // this.context = options.context || window; + // this.document = options.document || document; + this.parent = options.body || options.parent || (document ? document.getElementsByTagName('body')[0] : null); + this.cols = options.cols || options.geometry[0]; + this.rows = options.rows || options.geometry[1]; + this.geometry = [this.cols, this.rows]; + if (options.handler) { + this.on('data', options.handler); + } + /** + * The scroll position of the y cursor, ie. ybase + y = the y position within the entire + * buffer + */ + this.ybase = 0; + /** + * The scroll position of the viewport + */ + this.ydisp = 0; + /** + * The cursor's x position after ybase + */ + this.x = 0; + /** + * The cursor's y position after ybase + */ + this.y = 0; + /** + * Used to debounce the refresh function + */ + this.isRefreshing = false; + /** + * Whether there is a full terminal refresh queued + */ + this.cursorState = 0; + this.cursorHidden = false; + this.convertEol; + this.state = 0; + this.queue = ''; + this.scrollTop = 0; + this.scrollBottom = this.rows - 1; + this.customKeydownHandler = null; + // modes + this.applicationKeypad = false; + this.applicationCursor = false; + this.originMode = false; + this.insertMode = false; + this.wraparoundMode = true; // defaults: xterm - true, vt100 - false + this.normal = null; + // charset + this.charset = null; + this.gcharset = null; + this.glevel = 0; + this.charsets = [null]; + // mouse properties + this.decLocator; + this.x10Mouse; + this.vt200Mouse; + this.vt300Mouse; + this.normalMouse; + this.mouseEvents; + this.sendFocus; + this.utfMouse; + this.sgrMouse; + this.urxvtMouse; + // misc + this.element; + this.children; + this.refreshStart; + this.refreshEnd; + this.savedX; + this.savedY; + this.savedCols; + // stream + this.readable = true; + this.writable = true; + this.defAttr = (0 << 18) | (257 << 9) | (256 << 0); + this.curAttr = this.defAttr; + this.params = []; + this.currentParam = 0; + this.prefix = ''; + this.postfix = ''; + // leftover surrogate high from previous write invocation + this.surrogate_high = ''; + /** + * An array of all lines in the entire buffer, including the prompt. The lines are array of + * characters which are 2-length arrays where [0] is an attribute and [1] is the character. + */ + this.lines = []; + var i = this.rows; + while (i--) { + this.lines.push(this.blankLine()); + } + this.tabs; + this.setupStops(); + // Store if user went browsing history in scrollback + this.userScrolling = false; +} +inherits(Terminal, EventEmitter_js_1.EventEmitter); +/** + * back_color_erase feature for xterm. + */ +Terminal.prototype.eraseAttr = function () { + // if (this.is('screen')) return this.defAttr; + return (this.defAttr & ~0x1ff) | (this.curAttr & 0x1ff); +}; +/** + * Colors + */ +// Colors 0-15 +Terminal.tangoColors = [ + // dark: + '#2e3436', + '#cc0000', + '#4e9a06', + '#c4a000', + '#3465a4', + '#75507b', + '#06989a', + '#d3d7cf', + // bright: + '#555753', + '#ef2929', + '#8ae234', + '#fce94f', + '#729fcf', + '#ad7fa8', + '#34e2e2', + '#eeeeec' +]; +// Colors 0-15 + 16-255 +// Much thanks to TooTallNate for writing this. +Terminal.colors = (function () { + var colors = Terminal.tangoColors.slice(), r = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff], i; + // 16-231 + i = 0; + for (; i < 216; i++) { + out(r[(i / 36) % 6 | 0], r[(i / 6) % 6 | 0], r[i % 6]); + } + // 232-255 (grey) + i = 0; + for (; i < 24; i++) { + r = 8 + i * 10; + out(r, r, r); + } + function out(r, g, b) { + colors.push('#' + hex(r) + hex(g) + hex(b)); + } + function hex(c) { + c = c.toString(16); + return c.length < 2 ? '0' + c : c; + } + return colors; +})(); +Terminal._colors = Terminal.colors.slice(); +Terminal.vcolors = (function () { + var out = [], colors = Terminal.colors, i = 0, color; + for (; i < 256; i++) { + color = parseInt(colors[i].substring(1), 16); + out.push([ + (color >> 16) & 0xff, + (color >> 8) & 0xff, + color & 0xff + ]); + } + return out; +})(); +/** + * Options + */ +Terminal.defaults = { + colors: Terminal.colors, + theme: 'default', + convertEol: false, + termName: 'xterm', + geometry: [80, 24], + cursorBlink: false, + visualBell: false, + popOnBell: false, + scrollback: 1000, + screenKeys: false, + debug: false, + cancelEvents: false +}; +Terminal.options = {}; +Terminal.focus = null; +each(keys(Terminal.defaults), function (key) { + Terminal[key] = Terminal.defaults[key]; + Terminal.options[key] = Terminal.defaults[key]; +}); +/** + * Focus the terminal. Delegates focus handling to the terminal's DOM element. + */ +Terminal.prototype.focus = function () { + return this.textarea.focus(); +}; +/** + * Retrieves an option's value from the terminal. + * @param {string} key The option key. + */ +Terminal.prototype.getOption = function (key, value) { + if (!(key in Terminal.defaults)) { + throw new Error('No option with key "' + key + '"'); + } + if (typeof this.options[key] !== 'undefined') { + return this.options[key]; + } + return this[key]; +}; +/** + * Sets an option on the terminal. + * @param {string} key The option key. + * @param {string} value The option value. + */ +Terminal.prototype.setOption = function (key, value) { + if (!(key in Terminal.defaults)) { + throw new Error('No option with key "' + key + '"'); + } + this[key] = value; + this.options[key] = value; +}; +/** + * Binds the desired focus behavior on a given terminal object. + * + * @static + */ +Terminal.bindFocus = function (term) { + on(term.textarea, 'focus', function (ev) { + if (term.sendFocus) { + term.send('\x1b[I'); + } + term.element.classList.add('focus'); + term.showCursor(); + Terminal.focus = term; + term.emit('focus', { terminal: term }); + }); +}; +/** + * Blur the terminal. Delegates blur handling to the terminal's DOM element. + */ +Terminal.prototype.blur = function () { + return this.textarea.blur(); +}; +/** + * Binds the desired blur behavior on a given terminal object. + * + * @static + */ +Terminal.bindBlur = function (term) { + on(term.textarea, 'blur', function (ev) { + term.refresh(term.y, term.y); + if (term.sendFocus) { + term.send('\x1b[O'); + } + term.element.classList.remove('focus'); + Terminal.focus = null; + term.emit('blur', { terminal: term }); + }); +}; +/** + * Initialize default behavior + */ +Terminal.prototype.initGlobal = function () { + var term = this; + Terminal.bindKeys(this); + Terminal.bindFocus(this); + Terminal.bindBlur(this); + // Bind clipboard functionality + on(this.element, 'copy', function (ev) { + Clipboard_js_1.copyHandler.call(this, ev, term); + }); + on(this.textarea, 'paste', function (ev) { + Clipboard_js_1.pasteHandler.call(this, ev, term); + }); + on(this.element, 'paste', function (ev) { + Clipboard_js_1.pasteHandler.call(this, ev, term); + }); + function rightClickHandlerWrapper(ev) { + Clipboard_js_1.rightClickHandler.call(this, ev, term); + } + if (term.browser.isFirefox) { + on(this.element, 'mousedown', function (ev) { + if (ev.button == 2) { + rightClickHandlerWrapper(ev); + } + }); + } + else { + on(this.element, 'contextmenu', rightClickHandlerWrapper); + } +}; +/** + * Apply key handling to the terminal + */ +Terminal.bindKeys = function (term) { + on(term.element, 'keydown', function (ev) { + if (document.activeElement != this) { + return; + } + term.keyDown(ev); + }, true); + on(term.element, 'keypress', function (ev) { + if (document.activeElement != this) { + return; + } + term.keyPress(ev); + }, true); + on(term.element, 'keyup', term.focus.bind(term)); + on(term.textarea, 'keydown', function (ev) { + term.keyDown(ev); + }, true); + on(term.textarea, 'keypress', function (ev) { + term.keyPress(ev); + // Truncate the textarea's value, since it is not needed + this.value = ''; + }, true); + on(term.textarea, 'compositionstart', term.compositionHelper.compositionstart.bind(term.compositionHelper)); + on(term.textarea, 'compositionupdate', term.compositionHelper.compositionupdate.bind(term.compositionHelper)); + on(term.textarea, 'compositionend', term.compositionHelper.compositionend.bind(term.compositionHelper)); + term.on('refresh', term.compositionHelper.updateCompositionElements.bind(term.compositionHelper)); +}; +/** + * Insert the given row to the terminal or produce a new one + * if no row argument is passed. Return the inserted row. + * @param {HTMLElement} row (optional) The row to append to the terminal. + */ +Terminal.prototype.insertRow = function (row) { + if (typeof row != 'object') { + row = document.createElement('div'); + } + this.rowContainer.appendChild(row); + this.children.push(row); + return row; +}; +/** + * Opens the terminal within an element. + * + * @param {HTMLElement} parent The element to create the terminal within. + */ +Terminal.prototype.open = function (parent) { + var self = this, i = 0, div; + this.parent = parent || this.parent; + if (!this.parent) { + throw new Error('Terminal requires a parent element.'); + } + // Grab global elements + this.context = this.parent.ownerDocument.defaultView; + this.document = this.parent.ownerDocument; + this.body = this.document.getElementsByTagName('body')[0]; + //Create main element container + this.element = this.document.createElement('div'); + this.element.classList.add('terminal'); + this.element.classList.add('xterm'); + this.element.classList.add('xterm-theme-' + this.theme); + this.element.style.height; + this.element.setAttribute('tabindex', 0); + this.viewportElement = document.createElement('div'); + this.viewportElement.classList.add('xterm-viewport'); + this.element.appendChild(this.viewportElement); + this.viewportScrollArea = document.createElement('div'); + this.viewportScrollArea.classList.add('xterm-scroll-area'); + this.viewportElement.appendChild(this.viewportScrollArea); + // Create the container that will hold the lines of the terminal and then + // produce the lines the lines. + this.rowContainer = document.createElement('div'); + this.rowContainer.classList.add('xterm-rows'); + this.element.appendChild(this.rowContainer); + this.children = []; + // Create the container that will hold helpers like the textarea for + // capturing DOM Events. Then produce the helpers. + this.helperContainer = document.createElement('div'); + this.helperContainer.classList.add('xterm-helpers'); + // TODO: This should probably be inserted once it's filled to prevent an additional layout + this.element.appendChild(this.helperContainer); + this.textarea = document.createElement('textarea'); + this.textarea.classList.add('xterm-helper-textarea'); + this.textarea.setAttribute('autocorrect', 'off'); + this.textarea.setAttribute('autocapitalize', 'off'); + this.textarea.setAttribute('spellcheck', 'false'); + this.textarea.tabIndex = 0; + this.textarea.addEventListener('focus', function () { + self.emit('focus', { terminal: self }); + }); + this.textarea.addEventListener('blur', function () { + self.emit('blur', { terminal: self }); + }); + this.helperContainer.appendChild(this.textarea); + this.compositionView = document.createElement('div'); + this.compositionView.classList.add('composition-view'); + this.compositionHelper = new CompositionHelper_js_1.CompositionHelper(this.textarea, this.compositionView, this); + this.helperContainer.appendChild(this.compositionView); + this.charMeasureElement = document.createElement('div'); + this.charMeasureElement.classList.add('xterm-char-measure-element'); + this.charMeasureElement.innerHTML = 'W'; + this.helperContainer.appendChild(this.charMeasureElement); + for (; i < this.rows; i++) { + this.insertRow(); + } + this.parent.appendChild(this.element); + this.viewport = new Viewport_js_1.Viewport(this, this.viewportElement, this.viewportScrollArea, this.charMeasureElement); + // Draw the screen. + this.refresh(0, this.rows - 1); + // Initialize global actions that + // need to be taken on the document. + this.initGlobal(); + // Ensure there is a Terminal.focus. + this.focus(); + on(this.element, 'click', function () { + var selection = document.getSelection(), collapsed = selection.isCollapsed, isRange = typeof collapsed == 'boolean' ? !collapsed : selection.type == 'Range'; + if (!isRange) { + self.focus(); + } + }); + // Listen for mouse events and translate + // them into terminal mouse protocols. + this.bindMouse(); + // Figure out whether boldness affects + // the character width of monospace fonts. + if (Terminal.brokenBold == null) { + Terminal.brokenBold = isBoldBroken(this.document); + } + /** + * This event is emitted when terminal has completed opening. + * + * @event open + */ + this.emit('open'); +}; +/** + * Attempts to load an add-on using CommonJS or RequireJS (whichever is available). + * @param {string} addon The name of the addon to load + * @static + */ +Terminal.loadAddon = function (addon, callback) { + if (typeof exports === 'object' && typeof module === 'object') { + // CommonJS + return require('./addons/' + addon + '/' + addon); + } + else if (typeof define == 'function') { + // RequireJS + return require(['./addons/' + addon + '/' + addon], callback); + } + else { + console.error('Cannot load a module without a CommonJS or RequireJS environment.'); + return false; + } +}; +/** + * XTerm mouse events + * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Mouse%20Tracking + * To better understand these + * the xterm code is very helpful: + * Relevant files: + * button.c, charproc.c, misc.c + * Relevant functions in xterm/button.c: + * BtnCode, EmitButtonCode, EditorButton, SendMousePosition + */ +Terminal.prototype.bindMouse = function () { + var el = this.element, self = this, pressed = 32; + // mouseup, mousedown, wheel + // left click: ^[[M 3<^[[M#3< + // wheel up: ^[[M`3> + function sendButton(ev) { + var button, pos; + // get the xterm-style button + button = getButton(ev); + // get mouse coordinates + pos = getCoords(ev); + if (!pos) + return; + sendEvent(button, pos); + switch (ev.overrideType || ev.type) { + case 'mousedown': + pressed = button; + break; + case 'mouseup': + // keep it at the left + // button, just in case. + pressed = 32; + break; + case 'wheel': + // nothing. don't + // interfere with + // `pressed`. + break; + } + } + // motion example of a left click: + // ^[[M 3<^[[M@4<^[[M@5<^[[M@6<^[[M@7<^[[M#7< + function sendMove(ev) { + var button = pressed, pos; + pos = getCoords(ev); + if (!pos) + return; + // buttons marked as motions + // are incremented by 32 + button += 32; + sendEvent(button, pos); + } + // encode button and + // position to characters + function encode(data, ch) { + if (!self.utfMouse) { + if (ch === 255) + return data.push(0); + if (ch > 127) + ch = 127; + data.push(ch); + } + else { + if (ch === 2047) + return data.push(0); + if (ch < 127) { + data.push(ch); + } + else { + if (ch > 2047) + ch = 2047; + data.push(0xC0 | (ch >> 6)); + data.push(0x80 | (ch & 0x3F)); + } + } + } + // send a mouse event: + // regular/utf8: ^[[M Cb Cx Cy + // urxvt: ^[[ Cb ; Cx ; Cy M + // sgr: ^[[ Cb ; Cx ; Cy M/m + // vt300: ^[[ 24(1/3/5)~ [ Cx , Cy ] \r + // locator: CSI P e ; P b ; P r ; P c ; P p & w + function sendEvent(button, pos) { + // self.emit('mouse', { + // x: pos.x - 32, + // y: pos.x - 32, + // button: button + // }); + if (self.vt300Mouse) { + // NOTE: Unstable. + // http://www.vt100.net/docs/vt3xx-gp/chapter15.html + button &= 3; + pos.x -= 32; + pos.y -= 32; + var data = '\x1b[24'; + if (button === 0) + data += '1'; + else if (button === 1) + data += '3'; + else if (button === 2) + data += '5'; + else if (button === 3) + return; + else + data += '0'; + data += '~[' + pos.x + ',' + pos.y + ']\r'; + self.send(data); + return; + } + if (self.decLocator) { + // NOTE: Unstable. + button &= 3; + pos.x -= 32; + pos.y -= 32; + if (button === 0) + button = 2; + else if (button === 1) + button = 4; + else if (button === 2) + button = 6; + else if (button === 3) + button = 3; + self.send('\x1b[' + + button + + ';' + + (button === 3 ? 4 : 0) + + ';' + + pos.y + + ';' + + pos.x + + ';' + + (pos.page || 0) + + '&w'); + return; + } + if (self.urxvtMouse) { + pos.x -= 32; + pos.y -= 32; + pos.x++; + pos.y++; + self.send('\x1b[' + button + ';' + pos.x + ';' + pos.y + 'M'); + return; + } + if (self.sgrMouse) { + pos.x -= 32; + pos.y -= 32; + self.send('\x1b[<' + + (((button & 3) === 3 ? button & ~3 : button) - 32) + + ';' + + pos.x + + ';' + + pos.y + + ((button & 3) === 3 ? 'm' : 'M')); + return; + } + var data = []; + encode(data, button); + encode(data, pos.x); + encode(data, pos.y); + self.send('\x1b[M' + String.fromCharCode.apply(String, data)); + } + function getButton(ev) { + var button, shift, meta, ctrl, mod; + // two low bits: + // 0 = left + // 1 = middle + // 2 = right + // 3 = release + // wheel up/down: + // 1, and 2 - with 64 added + switch (ev.overrideType || ev.type) { + case 'mousedown': + button = ev.button != null + ? +ev.button + : ev.which != null + ? ev.which - 1 + : null; + if (self.browser.isMSIE) { + button = button === 1 ? 0 : button === 4 ? 1 : button; + } + break; + case 'mouseup': + button = 3; + break; + case 'DOMMouseScroll': + button = ev.detail < 0 + ? 64 + : 65; + break; + case 'wheel': + button = ev.wheelDeltaY > 0 + ? 64 + : 65; + break; + } + // next three bits are the modifiers: + // 4 = shift, 8 = meta, 16 = control + shift = ev.shiftKey ? 4 : 0; + meta = ev.metaKey ? 8 : 0; + ctrl = ev.ctrlKey ? 16 : 0; + mod = shift | meta | ctrl; + // no mods + if (self.vt200Mouse) { + // ctrl only + mod &= ctrl; + } + else if (!self.normalMouse) { + mod = 0; + } + // increment to SP + button = (32 + (mod << 2)) + button; + return button; + } + // mouse coordinates measured in cols/rows + function getCoords(ev) { + var x, y, w, h, el; + // ignore browsers without pageX for now + if (ev.pageX == null) + return; + x = ev.pageX; + y = ev.pageY; + el = self.element; + // should probably check offsetParent + // but this is more portable + while (el && el !== self.document.documentElement) { + x -= el.offsetLeft; + y -= el.offsetTop; + el = 'offsetParent' in el + ? el.offsetParent + : el.parentNode; + } + // convert to cols/rows + w = self.element.clientWidth; + h = self.element.clientHeight; + x = Math.ceil((x / w) * self.cols); + y = Math.ceil((y / h) * self.rows); + // be sure to avoid sending + // bad positions to the program + if (x < 0) + x = 0; + if (x > self.cols) + x = self.cols; + if (y < 0) + y = 0; + if (y > self.rows) + y = self.rows; + // xterm sends raw bytes and + // starts at 32 (SP) for each. + x += 32; + y += 32; + return { + x: x, + y: y, + type: 'wheel' + }; + } + on(el, 'mousedown', function (ev) { + if (!self.mouseEvents) + return; + // send the button + sendButton(ev); + // ensure focus + self.focus(); + // fix for odd bug + //if (self.vt200Mouse && !self.normalMouse) { + if (self.vt200Mouse) { + ev.overrideType = 'mouseup'; + sendButton(ev); + return self.cancel(ev); + } + // bind events + if (self.normalMouse) + on(self.document, 'mousemove', sendMove); + // x10 compatibility mode can't send button releases + if (!self.x10Mouse) { + on(self.document, 'mouseup', function up(ev) { + sendButton(ev); + if (self.normalMouse) + off(self.document, 'mousemove', sendMove); + off(self.document, 'mouseup', up); + return self.cancel(ev); + }); + } + return self.cancel(ev); + }); + //if (self.normalMouse) { + // on(self.document, 'mousemove', sendMove); + //} + on(el, 'wheel', function (ev) { + if (!self.mouseEvents) + return; + if (self.x10Mouse + || self.vt300Mouse + || self.decLocator) + return; + sendButton(ev); + return self.cancel(ev); + }); + // allow wheel scrolling in + // the shell for example + on(el, 'wheel', function (ev) { + if (self.mouseEvents) + return; + self.viewport.onWheel(ev); + return self.cancel(ev); + }); +}; +/** + * Destroys the terminal. + */ +Terminal.prototype.destroy = function () { + this.readable = false; + this.writable = false; + this._events = {}; + this.handler = function () { }; + this.write = function () { }; + if (this.element.parentNode) { + this.element.parentNode.removeChild(this.element); + } + //this.emit('close'); +}; +/** + * Flags used to render terminal text properly + */ +Terminal.flags = { + BOLD: 1, + UNDERLINE: 2, + BLINK: 4, + INVERSE: 8, + INVISIBLE: 16 +}; +/** + * Refreshes (re-renders) terminal content within two rows (inclusive) + * + * Rendering Engine: + * + * In the screen buffer, each character is stored as a an array with a character + * and a 32-bit integer: + * - First value: a utf-16 character. + * - Second value: + * - Next 9 bits: background color (0-511). + * - Next 9 bits: foreground color (0-511). + * - Next 14 bits: a mask for misc. flags: + * - 1=bold + * - 2=underline + * - 4=blink + * - 8=inverse + * - 16=invisible + * + * @param {number} start The row to start from (between 0 and terminal's height terminal - 1) + * @param {number} end The row to end at (between fromRow and terminal's height terminal - 1) + * @param {boolean} queue Whether the refresh should ran right now or be queued + */ +Terminal.prototype.refresh = function (start, end, queue) { + var self = this; + // queue defaults to true + queue = (typeof queue == 'undefined') ? true : queue; + /** + * The refresh queue allows refresh to execute only approximately 30 times a second. For + * commands that pass a significant amount of output to the write function, this prevents the + * terminal from maxing out the CPU and making the UI unresponsive. While commands can still + * run beyond what they do on the terminal, it is far better with a debounce in place as + * every single terminal manipulation does not need to be constructed in the DOM. + * + * A side-effect of this is that it makes ^C to interrupt a process seem more responsive. + */ + if (queue) { + // If refresh should be queued, order the refresh and return. + if (this._refreshIsQueued) { + // If a refresh has already been queued, just order a full refresh next + this._fullRefreshNext = true; + } + else { + setTimeout(function () { + self.refresh(start, end, false); + }, 34); + this._refreshIsQueued = true; + } + return; + } + // If refresh should be run right now (not be queued), release the lock + this._refreshIsQueued = false; + // If multiple refreshes were requested, make a full refresh. + if (this._fullRefreshNext) { + start = 0; + end = this.rows - 1; + this._fullRefreshNext = false; // reset lock + } + var x, y, i, line, out, ch, ch_width, width, data, attr, bg, fg, flags, row, parent, focused = document.activeElement; + // If this is a big refresh, remove the terminal rows from the DOM for faster calculations + if (end - start >= this.rows / 2) { + parent = this.element.parentNode; + if (parent) { + this.element.removeChild(this.rowContainer); + } + } + width = this.cols; + y = start; + if (end >= this.rows.length) { + this.log('`end` is too large. Most likely a bad CSR.'); + end = this.rows.length - 1; + } + for (; y <= end; y++) { + row = y + this.ydisp; + line = this.lines[row]; + out = ''; + if (this.y === y - (this.ybase - this.ydisp) + && this.cursorState + && !this.cursorHidden) { + x = this.x; + } + else { + x = -1; + } + attr = this.defAttr; + i = 0; + for (; i < width; i++) { + data = line[i][0]; + ch = line[i][1]; + ch_width = line[i][2]; + if (!ch_width) + continue; + if (i === x) + data = -1; + if (data !== attr) { + if (attr !== this.defAttr) { + out += ''; + } + if (data !== this.defAttr) { + if (data === -1) { + out += ''; + } + else { + var classNames = []; + bg = data & 0x1ff; + fg = (data >> 9) & 0x1ff; + flags = data >> 18; + if (flags & Terminal.flags.BOLD) { + if (!Terminal.brokenBold) { + classNames.push('xterm-bold'); + } + // See: XTerm*boldColors + if (fg < 8) + fg += 8; + } + if (flags & Terminal.flags.UNDERLINE) { + classNames.push('xterm-underline'); + } + if (flags & Terminal.flags.BLINK) { + classNames.push('xterm-blink'); + } + // If inverse flag is on, then swap the foreground and background variables. + if (flags & Terminal.flags.INVERSE) { + /* One-line variable swap in JavaScript: http://stackoverflow.com/a/16201730 */ + bg = [fg, fg = bg][0]; + // Should inverse just be before the + // above boldColors effect instead? + if ((flags & 1) && fg < 8) + fg += 8; + } + if (flags & Terminal.flags.INVISIBLE) { + classNames.push('xterm-hidden'); + } + /** + * Weird situation: Invert flag used black foreground and white background results + * in invalid background color, positioned at the 256 index of the 256 terminal + * color map. Pin the colors manually in such a case. + * + * Source: https://github.com/sourcelair/xterm.js/issues/57 + */ + if (flags & Terminal.flags.INVERSE) { + if (bg == 257) { + bg = 15; + } + if (fg == 256) { + fg = 0; + } + } + if (bg < 256) { + classNames.push('xterm-bg-color-' + bg); + } + if (fg < 256) { + classNames.push('xterm-color-' + fg); + } + out += '': + out += '>'; + break; + default: + if (ch <= ' ') { + out += ' '; + } + else { + out += ch; + } + break; + } + attr = data; + } + if (attr !== this.defAttr) { + out += ''; + } + this.children[y].innerHTML = out; + } + if (parent) { + this.element.appendChild(this.rowContainer); + } + this.emit('refresh', { element: this.element, start: start, end: end }); +}; +/** + * Display the cursor element + */ +Terminal.prototype.showCursor = function () { + if (!this.cursorState) { + this.cursorState = 1; + this.refresh(this.y, this.y); + } +}; +/** + * Scroll the terminal + */ +Terminal.prototype.scroll = function () { + var row; + if (++this.ybase === this.scrollback) { + this.ybase = this.ybase / 2 | 0; + this.lines = this.lines.slice(-(this.ybase + this.rows) + 1); + } + if (!this.userScrolling) { + this.ydisp = this.ybase; + } + // last line + row = this.ybase + this.rows - 1; + // subtract the bottom scroll region + row -= this.rows - 1 - this.scrollBottom; + if (row === this.lines.length) { + // potential optimization: + // pushing is faster than splicing + // when they amount to the same + // behavior. + this.lines.push(this.blankLine()); + } + else { + // add our new line + this.lines.splice(row, 0, this.blankLine()); + } + if (this.scrollTop !== 0) { + if (this.ybase !== 0) { + this.ybase--; + if (!this.userScrolling) { + this.ydisp = this.ybase; + } + } + this.lines.splice(this.ybase + this.scrollTop, 1); + } + // this.maxRange(); + this.updateRange(this.scrollTop); + this.updateRange(this.scrollBottom); + /** + * This event is emitted whenever the terminal is scrolled. + * The one parameter passed is the new y display position. + * + * @event scroll + */ + this.emit('scroll', this.ydisp); +}; +/** + * Scroll the display of the terminal + * @param {number} disp The number of lines to scroll down (negatives scroll up). + * @param {boolean} suppressScrollEvent Don't emit the scroll event as scrollDisp. This is used + * to avoid unwanted events being handled by the veiwport when the event was triggered from the + * viewport originally. + */ +Terminal.prototype.scrollDisp = function (disp, suppressScrollEvent) { + if (disp < 0) { + this.userScrolling = true; + } + else if (disp + this.ydisp >= this.ybase) { + this.userScrolling = false; + } + this.ydisp += disp; + if (this.ydisp > this.ybase) { + this.ydisp = this.ybase; + } + else if (this.ydisp < 0) { + this.ydisp = 0; + } + if (!suppressScrollEvent) { + this.emit('scroll', this.ydisp); + } + this.refresh(0, this.rows - 1); +}; +/** + * Scroll the display of the terminal by a number of pages. + * @param {number} pageCount The number of pages to scroll (negative scrolls up). + */ +Terminal.prototype.scrollPages = function (pageCount) { + this.scrollDisp(pageCount * (this.rows - 1)); +}; +/** + * Scrolls the display of the terminal to the top. + */ +Terminal.prototype.scrollToTop = function () { + this.scrollDisp(-this.ydisp); +}; +/** + * Scrolls the display of the terminal to the bottom. + */ +Terminal.prototype.scrollToBottom = function () { + this.scrollDisp(this.ybase - this.ydisp); +}; +/** + * Writes text to the terminal. + * @param {string} text The text to write to the terminal. + */ +Terminal.prototype.write = function (data) { + var l = data.length, i = 0, j, cs, ch, code, low, ch_width, row; + this.refreshStart = this.y; + this.refreshEnd = this.y; + // apply leftover surrogate high from last write + if (this.surrogate_high) { + data = this.surrogate_high + data; + this.surrogate_high = ''; + } + for (; i < l; i++) { + ch = data[i]; + // FIXME: higher chars than 0xa0 are not allowed in escape sequences + // --> maybe move to default + code = data.charCodeAt(i); + if (0xD800 <= code && code <= 0xDBFF) { + // we got a surrogate high + // get surrogate low (next 2 bytes) + low = data.charCodeAt(i + 1); + if (isNaN(low)) { + // end of data stream, save surrogate high + this.surrogate_high = ch; + continue; + } + code = ((code - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; + ch += data.charAt(i + 1); + } + // surrogate low - already handled above + if (0xDC00 <= code && code <= 0xDFFF) + continue; + switch (this.state) { + case normal: + switch (ch) { + case '\x07': + this.bell(); + break; + // '\n', '\v', '\f' + case '\n': + case '\x0b': + case '\x0c': + if (this.convertEol) { + this.x = 0; + } + this.y++; + if (this.y > this.scrollBottom) { + this.y--; + this.scroll(); + } + break; + // '\r' + case '\r': + this.x = 0; + break; + // '\b' + case '\x08': + if (this.x > 0) { + this.x--; + } + break; + // '\t' + case '\t': + this.x = this.nextStop(); + break; + // shift out + case '\x0e': + this.setgLevel(1); + break; + // shift in + case '\x0f': + this.setgLevel(0); + break; + // '\e' + case '\x1b': + this.state = escaped; + break; + default: + // ' ' + // calculate print space + // expensive call, therefore we save width in line buffer + ch_width = wcwidth(code); + if (ch >= ' ') { + if (this.charset && this.charset[ch]) { + ch = this.charset[ch]; + } + row = this.y + this.ybase; + // insert combining char in last cell + // FIXME: needs handling after cursor jumps + if (!ch_width && this.x) { + // dont overflow left + if (this.lines[row][this.x - 1]) { + if (!this.lines[row][this.x - 1][2]) { + // found empty cell after fullwidth, need to go 2 cells back + if (this.lines[row][this.x - 2]) + this.lines[row][this.x - 2][1] += ch; + } + else { + this.lines[row][this.x - 1][1] += ch; + } + this.updateRange(this.y); + } + break; + } + // goto next line if ch would overflow + // TODO: needs a global min terminal width of 2 + if (this.x + ch_width - 1 >= this.cols) { + // autowrap - DECAWM + if (this.wraparoundMode) { + this.x = 0; + this.y++; + if (this.y > this.scrollBottom) { + this.y--; + this.scroll(); + } + } + else { + this.x = this.cols - 1; + if (ch_width === 2) + continue; + } + } + row = this.y + this.ybase; + // insert mode: move characters to right + if (this.insertMode) { + // do this twice for a fullwidth char + for (var moves = 0; moves < ch_width; ++moves) { + // remove last cell, if it's width is 0 + // we have to adjust the second last cell as well + var removed = this.lines[this.y + this.ybase].pop(); + if (removed[2] === 0 + && this.lines[row][this.cols - 2] + && this.lines[row][this.cols - 2][2] === 2) + this.lines[row][this.cols - 2] = [this.curAttr, ' ', 1]; + // insert empty cell at cursor + this.lines[row].splice(this.x, 0, [this.curAttr, ' ', 1]); + } + } + this.lines[row][this.x] = [this.curAttr, ch, ch_width]; + this.x++; + this.updateRange(this.y); + // fullwidth char - set next cell width to zero and advance cursor + if (ch_width === 2) { + this.lines[row][this.x] = [this.curAttr, '', 0]; + this.x++; + } + } + break; + } + break; + case escaped: + switch (ch) { + // ESC [ Control Sequence Introducer ( CSI is 0x9b). + case '[': + this.params = []; + this.currentParam = 0; + this.state = csi; + break; + // ESC ] Operating System Command ( OSC is 0x9d). + case ']': + this.params = []; + this.currentParam = 0; + this.state = osc; + break; + // ESC P Device Control String ( DCS is 0x90). + case 'P': + this.params = []; + this.currentParam = 0; + this.state = dcs; + break; + // ESC _ Application Program Command ( APC is 0x9f). + case '_': + this.state = ignore; + break; + // ESC ^ Privacy Message ( PM is 0x9e). + case '^': + this.state = ignore; + break; + // ESC c Full Reset (RIS). + case 'c': + this.reset(); + break; + // ESC E Next Line ( NEL is 0x85). + // ESC D Index ( IND is 0x84). + case 'E': + this.x = 0; + ; + case 'D': + this.index(); + break; + // ESC M Reverse Index ( RI is 0x8d). + case 'M': + this.reverseIndex(); + break; + // ESC % Select default/utf-8 character set. + // @ = default, G = utf-8 + case '%': + //this.charset = null; + this.setgLevel(0); + this.setgCharset(0, Terminal.charsets.US); + this.state = normal; + i++; + break; + // ESC (,),*,+,-,. Designate G0-G2 Character Set. + case '(': // <-- this seems to get all the attention + case ')': + case '*': + case '+': + case '-': + case '.': + switch (ch) { + case '(': + this.gcharset = 0; + break; + case ')': + this.gcharset = 1; + break; + case '*': + this.gcharset = 2; + break; + case '+': + this.gcharset = 3; + break; + case '-': + this.gcharset = 1; + break; + case '.': + this.gcharset = 2; + break; + } + this.state = charset; + break; + // Designate G3 Character Set (VT300). + // A = ISO Latin-1 Supplemental. + // Not implemented. + case '/': + this.gcharset = 3; + this.state = charset; + i--; + break; + // ESC N + // Single Shift Select of G2 Character Set + // ( SS2 is 0x8e). This affects next character only. + case 'N': + break; + // ESC O + // Single Shift Select of G3 Character Set + // ( SS3 is 0x8f). This affects next character only. + case 'O': + break; + // ESC n + // Invoke the G2 Character Set as GL (LS2). + case 'n': + this.setgLevel(2); + break; + // ESC o + // Invoke the G3 Character Set as GL (LS3). + case 'o': + this.setgLevel(3); + break; + // ESC | + // Invoke the G3 Character Set as GR (LS3R). + case '|': + this.setgLevel(3); + break; + // ESC } + // Invoke the G2 Character Set as GR (LS2R). + case '}': + this.setgLevel(2); + break; + // ESC ~ + // Invoke the G1 Character Set as GR (LS1R). + case '~': + this.setgLevel(1); + break; + // ESC 7 Save Cursor (DECSC). + case '7': + this.saveCursor(); + this.state = normal; + break; + // ESC 8 Restore Cursor (DECRC). + case '8': + this.restoreCursor(); + this.state = normal; + break; + // ESC # 3 DEC line height/width + case '#': + this.state = normal; + i++; + break; + // ESC H Tab Set (HTS is 0x88). + case 'H': + this.tabSet(); + break; + // ESC = Application Keypad (DECKPAM). + case '=': + this.log('Serial port requested application keypad.'); + this.applicationKeypad = true; + this.viewport.syncScrollArea(); + this.state = normal; + break; + // ESC > Normal Keypad (DECKPNM). + case '>': + this.log('Switching back to normal keypad.'); + this.applicationKeypad = false; + this.viewport.syncScrollArea(); + this.state = normal; + break; + default: + this.state = normal; + this.error('Unknown ESC control: %s.', ch); + break; + } + break; + case charset: + switch (ch) { + case '0': + cs = Terminal.charsets.SCLD; + break; + case 'A': + cs = Terminal.charsets.UK; + break; + case 'B': + cs = Terminal.charsets.US; + break; + case '4': + cs = Terminal.charsets.Dutch; + break; + case 'C': // Finnish + case '5': + cs = Terminal.charsets.Finnish; + break; + case 'R': + cs = Terminal.charsets.French; + break; + case 'Q': + cs = Terminal.charsets.FrenchCanadian; + break; + case 'K': + cs = Terminal.charsets.German; + break; + case 'Y': + cs = Terminal.charsets.Italian; + break; + case 'E': // NorwegianDanish + case '6': + cs = Terminal.charsets.NorwegianDanish; + break; + case 'Z': + cs = Terminal.charsets.Spanish; + break; + case 'H': // Swedish + case '7': + cs = Terminal.charsets.Swedish; + break; + case '=': + cs = Terminal.charsets.Swiss; + break; + case '/': + cs = Terminal.charsets.ISOLatin; + i++; + break; + default: + cs = Terminal.charsets.US; + break; + } + this.setgCharset(this.gcharset, cs); + this.gcharset = null; + this.state = normal; + break; + case osc: + // OSC Ps ; Pt ST + // OSC Ps ; Pt BEL + // Set Text Parameters. + if (ch === '\x1b' || ch === '\x07') { + if (ch === '\x1b') + i++; + this.params.push(this.currentParam); + switch (this.params[0]) { + case 0: + case 1: + case 2: + if (this.params[1]) { + this.title = this.params[1]; + this.handleTitle(this.title); + } + break; + case 3: + // set X property + break; + case 4: + case 5: + // change dynamic colors + break; + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + // change dynamic ui colors + break; + case 46: + // change log file + break; + case 50: + // dynamic font + break; + case 51: + // emacs shell + break; + case 52: + // manipulate selection data + break; + case 104: + case 105: + case 110: + case 111: + case 112: + case 113: + case 114: + case 115: + case 116: + case 117: + case 118: + // reset colors + break; + } + this.params = []; + this.currentParam = 0; + this.state = normal; + } + else { + if (!this.params.length) { + if (ch >= '0' && ch <= '9') { + this.currentParam = + this.currentParam * 10 + ch.charCodeAt(0) - 48; + } + else if (ch === ';') { + this.params.push(this.currentParam); + this.currentParam = ''; + } + } + else { + this.currentParam += ch; + } + } + break; + case csi: + // '?', '>', '!' + if (ch === '?' || ch === '>' || ch === '!') { + this.prefix = ch; + break; + } + // 0 - 9 + if (ch >= '0' && ch <= '9') { + this.currentParam = this.currentParam * 10 + ch.charCodeAt(0) - 48; + break; + } + // '$', '"', ' ', '\'' + if (ch === '$' || ch === '"' || ch === ' ' || ch === '\'') { + this.postfix = ch; + break; + } + this.params.push(this.currentParam); + this.currentParam = 0; + // ';' + if (ch === ';') + break; + this.state = normal; + switch (ch) { + // CSI Ps A + // Cursor Up Ps Times (default = 1) (CUU). + case 'A': + this.cursorUp(this.params); + break; + // CSI Ps B + // Cursor Down Ps Times (default = 1) (CUD). + case 'B': + this.cursorDown(this.params); + break; + // CSI Ps C + // Cursor Forward Ps Times (default = 1) (CUF). + case 'C': + this.cursorForward(this.params); + break; + // CSI Ps D + // Cursor Backward Ps Times (default = 1) (CUB). + case 'D': + this.cursorBackward(this.params); + break; + // CSI Ps ; Ps H + // Cursor Position [row;column] (default = [1,1]) (CUP). + case 'H': + this.cursorPos(this.params); + break; + // CSI Ps J Erase in Display (ED). + case 'J': + this.eraseInDisplay(this.params); + break; + // CSI Ps K Erase in Line (EL). + case 'K': + this.eraseInLine(this.params); + break; + // CSI Pm m Character Attributes (SGR). + case 'm': + if (!this.prefix) { + this.charAttributes(this.params); + } + break; + // CSI Ps n Device Status Report (DSR). + case 'n': + if (!this.prefix) { + this.deviceStatus(this.params); + } + break; + /** + * Additions + */ + // CSI Ps @ + // Insert Ps (Blank) Character(s) (default = 1) (ICH). + case '@': + this.insertChars(this.params); + break; + // CSI Ps E + // Cursor Next Line Ps Times (default = 1) (CNL). + case 'E': + this.cursorNextLine(this.params); + break; + // CSI Ps F + // Cursor Preceding Line Ps Times (default = 1) (CNL). + case 'F': + this.cursorPrecedingLine(this.params); + break; + // CSI Ps G + // Cursor Character Absolute [column] (default = [row,1]) (CHA). + case 'G': + this.cursorCharAbsolute(this.params); + break; + // CSI Ps L + // Insert Ps Line(s) (default = 1) (IL). + case 'L': + this.insertLines(this.params); + break; + // CSI Ps M + // Delete Ps Line(s) (default = 1) (DL). + case 'M': + this.deleteLines(this.params); + break; + // CSI Ps P + // Delete Ps Character(s) (default = 1) (DCH). + case 'P': + this.deleteChars(this.params); + break; + // CSI Ps X + // Erase Ps Character(s) (default = 1) (ECH). + case 'X': + this.eraseChars(this.params); + break; + // CSI Pm ` Character Position Absolute + // [column] (default = [row,1]) (HPA). + case '`': + this.charPosAbsolute(this.params); + break; + // 141 61 a * HPR - + // Horizontal Position Relative + case 'a': + this.HPositionRelative(this.params); + break; + // CSI P s c + // Send Device Attributes (Primary DA). + // CSI > P s c + // Send Device Attributes (Secondary DA) + case 'c': + this.sendDeviceAttributes(this.params); + break; + // CSI Pm d + // Line Position Absolute [row] (default = [1,column]) (VPA). + case 'd': + this.linePosAbsolute(this.params); + break; + // 145 65 e * VPR - Vertical Position Relative + case 'e': + this.VPositionRelative(this.params); + break; + // CSI Ps ; Ps f + // Horizontal and Vertical Position [row;column] (default = + // [1,1]) (HVP). + case 'f': + this.HVPosition(this.params); + break; + // CSI Pm h Set Mode (SM). + // CSI ? Pm h - mouse escape codes, cursor escape codes + case 'h': + this.setMode(this.params); + break; + // CSI Pm l Reset Mode (RM). + // CSI ? Pm l + case 'l': + this.resetMode(this.params); + break; + // CSI Ps ; Ps r + // Set Scrolling Region [top;bottom] (default = full size of win- + // dow) (DECSTBM). + // CSI ? Pm r + case 'r': + this.setScrollRegion(this.params); + break; + // CSI s + // Save cursor (ANSI.SYS). + case 's': + this.saveCursor(this.params); + break; + // CSI u + // Restore cursor (ANSI.SYS). + case 'u': + this.restoreCursor(this.params); + break; + /** + * Lesser Used + */ + // CSI Ps I + // Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). + case 'I': + this.cursorForwardTab(this.params); + break; + // CSI Ps S Scroll up Ps lines (default = 1) (SU). + case 'S': + this.scrollUp(this.params); + break; + // CSI Ps T Scroll down Ps lines (default = 1) (SD). + // CSI Ps ; Ps ; Ps ; Ps ; Ps T + // CSI > Ps; Ps T + case 'T': + // if (this.prefix === '>') { + // this.resetTitleModes(this.params); + // break; + // } + // if (this.params.length > 2) { + // this.initMouseTracking(this.params); + // break; + // } + if (this.params.length < 2 && !this.prefix) { + this.scrollDown(this.params); + } + break; + // CSI Ps Z + // Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). + case 'Z': + this.cursorBackwardTab(this.params); + break; + // CSI Ps b Repeat the preceding graphic character Ps times (REP). + case 'b': + this.repeatPrecedingCharacter(this.params); + break; + // CSI Ps g Tab Clear (TBC). + case 'g': + this.tabClear(this.params); + break; + // CSI Pm i Media Copy (MC). + // CSI ? Pm i + // case 'i': + // this.mediaCopy(this.params); + // break; + // CSI Pm m Character Attributes (SGR). + // CSI > Ps; Ps m + // case 'm': // duplicate + // if (this.prefix === '>') { + // this.setResources(this.params); + // } else { + // this.charAttributes(this.params); + // } + // break; + // CSI Ps n Device Status Report (DSR). + // CSI > Ps n + // case 'n': // duplicate + // if (this.prefix === '>') { + // this.disableModifiers(this.params); + // } else { + // this.deviceStatus(this.params); + // } + // break; + // CSI > Ps p Set pointer mode. + // CSI ! p Soft terminal reset (DECSTR). + // CSI Ps$ p + // Request ANSI mode (DECRQM). + // CSI ? Ps$ p + // Request DEC private mode (DECRQM). + // CSI Ps ; Ps " p + case 'p': + switch (this.prefix) { + // case '>': + // this.setPointerMode(this.params); + // break; + case '!': + this.softReset(this.params); + break; + } + break; + // CSI Ps q Load LEDs (DECLL). + // CSI Ps SP q + // CSI Ps " q + // case 'q': + // if (this.postfix === ' ') { + // this.setCursorStyle(this.params); + // break; + // } + // if (this.postfix === '"') { + // this.setCharProtectionAttr(this.params); + // break; + // } + // this.loadLEDs(this.params); + // break; + // CSI Ps ; Ps r + // Set Scrolling Region [top;bottom] (default = full size of win- + // dow) (DECSTBM). + // CSI ? Pm r + // CSI Pt; Pl; Pb; Pr; Ps$ r + // case 'r': // duplicate + // if (this.prefix === '?') { + // this.restorePrivateValues(this.params); + // } else if (this.postfix === '$') { + // this.setAttrInRectangle(this.params); + // } else { + // this.setScrollRegion(this.params); + // } + // break; + // CSI s Save cursor (ANSI.SYS). + // CSI ? Pm s + // case 's': // duplicate + // if (this.prefix === '?') { + // this.savePrivateValues(this.params); + // } else { + // this.saveCursor(this.params); + // } + // break; + // CSI Ps ; Ps ; Ps t + // CSI Pt; Pl; Pb; Pr; Ps$ t + // CSI > Ps; Ps t + // CSI Ps SP t + // case 't': + // if (this.postfix === '$') { + // this.reverseAttrInRectangle(this.params); + // } else if (this.postfix === ' ') { + // this.setWarningBellVolume(this.params); + // } else { + // if (this.prefix === '>') { + // this.setTitleModeFeature(this.params); + // } else { + // this.manipulateWindow(this.params); + // } + // } + // break; + // CSI u Restore cursor (ANSI.SYS). + // CSI Ps SP u + // case 'u': // duplicate + // if (this.postfix === ' ') { + // this.setMarginBellVolume(this.params); + // } else { + // this.restoreCursor(this.params); + // } + // break; + // CSI Pt; Pl; Pb; Pr; Pp; Pt; Pl; Pp$ v + // case 'v': + // if (this.postfix === '$') { + // this.copyRectagle(this.params); + // } + // break; + // CSI Pt ; Pl ; Pb ; Pr ' w + // case 'w': + // if (this.postfix === '\'') { + // this.enableFilterRectangle(this.params); + // } + // break; + // CSI Ps x Request Terminal Parameters (DECREQTPARM). + // CSI Ps x Select Attribute Change Extent (DECSACE). + // CSI Pc; Pt; Pl; Pb; Pr$ x + // case 'x': + // if (this.postfix === '$') { + // this.fillRectangle(this.params); + // } else { + // this.requestParameters(this.params); + // //this.__(this.params); + // } + // break; + // CSI Ps ; Pu ' z + // CSI Pt; Pl; Pb; Pr$ z + // case 'z': + // if (this.postfix === '\'') { + // this.enableLocatorReporting(this.params); + // } else if (this.postfix === '$') { + // this.eraseRectangle(this.params); + // } + // break; + // CSI Pm ' { + // CSI Pt; Pl; Pb; Pr$ { + // case '{': + // if (this.postfix === '\'') { + // this.setLocatorEvents(this.params); + // } else if (this.postfix === '$') { + // this.selectiveEraseRectangle(this.params); + // } + // break; + // CSI Ps ' | + // case '|': + // if (this.postfix === '\'') { + // this.requestLocatorPosition(this.params); + // } + // break; + // CSI P m SP } + // Insert P s Column(s) (default = 1) (DECIC), VT420 and up. + // case '}': + // if (this.postfix === ' ') { + // this.insertColumns(this.params); + // } + // break; + // CSI P m SP ~ + // Delete P s Column(s) (default = 1) (DECDC), VT420 and up + // case '~': + // if (this.postfix === ' ') { + // this.deleteColumns(this.params); + // } + // break; + default: + this.error('Unknown CSI code: %s.', ch); + break; + } + this.prefix = ''; + this.postfix = ''; + break; + case dcs: + if (ch === '\x1b' || ch === '\x07') { + if (ch === '\x1b') + i++; + switch (this.prefix) { + // User-Defined Keys (DECUDK). + case '': + break; + // Request Status String (DECRQSS). + // test: echo -e '\eP$q"p\e\\' + case '$q': + var pt = this.currentParam, valid = false; + switch (pt) { + // DECSCA + case '"q': + pt = '0"q'; + break; + // DECSCL + case '"p': + pt = '61"p'; + break; + // DECSTBM + case 'r': + pt = '' + + (this.scrollTop + 1) + + ';' + + (this.scrollBottom + 1) + + 'r'; + break; + // SGR + case 'm': + pt = '0m'; + break; + default: + this.error('Unknown DCS Pt: %s.', pt); + pt = ''; + break; + } + this.send('\x1bP' + +valid + '$r' + pt + '\x1b\\'); + break; + // Set Termcap/Terminfo Data (xterm, experimental). + case '+p': + break; + // Request Termcap/Terminfo String (xterm, experimental) + // Regular xterm does not even respond to this sequence. + // This can cause a small glitch in vim. + // test: echo -ne '\eP+q6b64\e\\' + case '+q': + var pt = this.currentParam, valid = false; + this.send('\x1bP' + +valid + '+r' + pt + '\x1b\\'); + break; + default: + this.error('Unknown DCS prefix: %s.', this.prefix); + break; + } + this.currentParam = 0; + this.prefix = ''; + this.state = normal; + } + else if (!this.currentParam) { + if (!this.prefix && ch !== '$' && ch !== '+') { + this.currentParam = ch; + } + else if (this.prefix.length === 2) { + this.currentParam = ch; + } + else { + this.prefix += ch; + } + } + else { + this.currentParam += ch; + } + break; + case ignore: + // For PM and APC. + if (ch === '\x1b' || ch === '\x07') { + if (ch === '\x1b') + i++; + this.state = normal; + } + break; + } + } + this.updateRange(this.y); + this.refresh(this.refreshStart, this.refreshEnd); +}; +/** + * Writes text to the terminal, followed by a break line character (\n). + * @param {string} text The text to write to the terminal. + */ +Terminal.prototype.writeln = function (data) { + this.write(data + '\r\n'); +}; +/** + * Attaches a custom keydown handler which is run before keys are processed, giving consumers of + * xterm.js ultimate control as to what keys should be processed by the terminal and what keys + * should not. + * @param {function} customKeydownHandler The custom KeyboardEvent handler to attach. This is a + * function that takes a KeyboardEvent, allowing consumers to stop propogation and/or prevent + * the default action. The function returns whether the event should be processed by xterm.js. + */ +Terminal.prototype.attachCustomKeydownHandler = function (customKeydownHandler) { + this.customKeydownHandler = customKeydownHandler; +}; +/** + * Handle a keydown event + * Key Resources: + * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent + * @param {KeyboardEvent} ev The keydown event to be handled. + */ +Terminal.prototype.keyDown = function (ev) { + if (this.customKeydownHandler && this.customKeydownHandler(ev) === false) { + return false; + } + if (!this.compositionHelper.keydown.bind(this.compositionHelper)(ev)) { + if (this.ybase !== this.ydisp) { + this.scrollToBottom(); + } + return false; + } + var self = this; + var result = this.evaluateKeyEscapeSequence(ev); + if (result.scrollDisp) { + this.scrollDisp(result.scrollDisp); + return this.cancel(ev, true); + } + if (isThirdLevelShift(this, ev)) { + return true; + } + if (result.cancel) { + // The event is canceled at the end already, is this necessary? + this.cancel(ev, true); + } + if (!result.key) { + return true; + } + this.emit('keydown', ev); + this.emit('key', result.key, ev); + this.showCursor(); + this.handler(result.key); + return this.cancel(ev, true); +}; +/** + * Returns an object that determines how a KeyboardEvent should be handled. The key of the + * returned value is the new key code to pass to the PTY. + * + * Reference: http://invisible-island.net/xterm/ctlseqs/ctlseqs.html + * @param {KeyboardEvent} ev The keyboard event to be translated to key escape sequence. + */ +Terminal.prototype.evaluateKeyEscapeSequence = function (ev) { + var result = { + // Whether to cancel event propogation (NOTE: this may not be needed since the event is + // canceled at the end of keyDown + cancel: false, + // The new key even to emit + key: undefined, + // The number of characters to scroll, if this is defined it will cancel the event + scrollDisp: undefined + }; + var modifiers = ev.shiftKey << 0 | ev.altKey << 1 | ev.ctrlKey << 2 | ev.metaKey << 3; + switch (ev.keyCode) { + case 8: + // backspace + if (ev.shiftKey) { + result.key = '\x08'; // ^H + break; + } + result.key = '\x7f'; // ^? + break; + case 9: + // tab + if (ev.shiftKey) { + result.key = '\x1b[Z'; + break; + } + result.key = '\t'; + result.cancel = true; + break; + case 13: + // return/enter + result.key = '\r'; + result.cancel = true; + break; + case 27: + // escape + result.key = '\x1b'; + result.cancel = true; + break; + case 37: + // left-arrow + if (modifiers) { + result.key = '\x1b[1;' + (modifiers + 1) + 'D'; + // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards + // http://unix.stackexchange.com/a/108106 + if (result.key == '\x1b[1;3D') { + result.key = '\x1b[1;5D'; + } + } + else if (this.applicationCursor) { + result.key = '\x1bOD'; + } + else { + result.key = '\x1b[D'; + } + break; + case 39: + // right-arrow + if (modifiers) { + result.key = '\x1b[1;' + (modifiers + 1) + 'C'; + // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward + // http://unix.stackexchange.com/a/108106 + if (result.key == '\x1b[1;3C') { + result.key = '\x1b[1;5C'; + } + } + else if (this.applicationCursor) { + result.key = '\x1bOC'; + } + else { + result.key = '\x1b[C'; + } + break; + case 38: + // up-arrow + if (modifiers) { + result.key = '\x1b[1;' + (modifiers + 1) + 'A'; + // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow + // http://unix.stackexchange.com/a/108106 + if (result.key == '\x1b[1;3A') { + result.key = '\x1b[1;5A'; + } + } + else if (this.applicationCursor) { + result.key = '\x1bOA'; + } + else { + result.key = '\x1b[A'; + } + break; + case 40: + // down-arrow + if (modifiers) { + result.key = '\x1b[1;' + (modifiers + 1) + 'B'; + // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow + // http://unix.stackexchange.com/a/108106 + if (result.key == '\x1b[1;3B') { + result.key = '\x1b[1;5B'; + } + } + else if (this.applicationCursor) { + result.key = '\x1bOB'; + } + else { + result.key = '\x1b[B'; + } + break; + case 45: + // insert + if (!ev.shiftKey && !ev.ctrlKey) { + // or + are used to + // copy-paste on some systems. + result.key = '\x1b[2~'; + } + break; + case 46: + // delete + if (modifiers) { + result.key = '\x1b[3;' + (modifiers + 1) + '~'; + } + else { + result.key = '\x1b[3~'; + } + break; + case 36: + // home + if (modifiers) + result.key = '\x1b[1;' + (modifiers + 1) + 'H'; + else if (this.applicationCursor) + result.key = '\x1bOH'; + else + result.key = '\x1b[H'; + break; + case 35: + // end + if (modifiers) + result.key = '\x1b[1;' + (modifiers + 1) + 'F'; + else if (this.applicationCursor) + result.key = '\x1bOF'; + else + result.key = '\x1b[F'; + break; + case 33: + // page up + if (ev.shiftKey) { + result.scrollDisp = -(this.rows - 1); + } + else { + result.key = '\x1b[5~'; + } + break; + case 34: + // page down + if (ev.shiftKey) { + result.scrollDisp = this.rows - 1; + } + else { + result.key = '\x1b[6~'; + } + break; + case 112: + // F1-F12 + if (modifiers) { + result.key = '\x1b[1;' + (modifiers + 1) + 'P'; + } + else { + result.key = '\x1bOP'; + } + break; + case 113: + if (modifiers) { + result.key = '\x1b[1;' + (modifiers + 1) + 'Q'; + } + else { + result.key = '\x1bOQ'; + } + break; + case 114: + if (modifiers) { + result.key = '\x1b[1;' + (modifiers + 1) + 'R'; + } + else { + result.key = '\x1bOR'; + } + break; + case 115: + if (modifiers) { + result.key = '\x1b[1;' + (modifiers + 1) + 'S'; + } + else { + result.key = '\x1bOS'; + } + break; + case 116: + if (modifiers) { + result.key = '\x1b[15;' + (modifiers + 1) + '~'; + } + else { + result.key = '\x1b[15~'; + } + break; + case 117: + if (modifiers) { + result.key = '\x1b[17;' + (modifiers + 1) + '~'; + } + else { + result.key = '\x1b[17~'; + } + break; + case 118: + if (modifiers) { + result.key = '\x1b[18;' + (modifiers + 1) + '~'; + } + else { + result.key = '\x1b[18~'; + } + break; + case 119: + if (modifiers) { + result.key = '\x1b[19;' + (modifiers + 1) + '~'; + } + else { + result.key = '\x1b[19~'; + } + break; + case 120: + if (modifiers) { + result.key = '\x1b[20;' + (modifiers + 1) + '~'; + } + else { + result.key = '\x1b[20~'; + } + break; + case 121: + if (modifiers) { + result.key = '\x1b[21;' + (modifiers + 1) + '~'; + } + else { + result.key = '\x1b[21~'; + } + break; + case 122: + if (modifiers) { + result.key = '\x1b[23;' + (modifiers + 1) + '~'; + } + else { + result.key = '\x1b[23~'; + } + break; + case 123: + if (modifiers) { + result.key = '\x1b[24;' + (modifiers + 1) + '~'; + } + else { + result.key = '\x1b[24~'; + } + break; + default: + // a-z and space + if (ev.ctrlKey && !ev.shiftKey && !ev.altKey && !ev.metaKey) { + if (ev.keyCode >= 65 && ev.keyCode <= 90) { + result.key = String.fromCharCode(ev.keyCode - 64); + } + else if (ev.keyCode === 32) { + // NUL + result.key = String.fromCharCode(0); + } + else if (ev.keyCode >= 51 && ev.keyCode <= 55) { + // escape, file sep, group sep, record sep, unit sep + result.key = String.fromCharCode(ev.keyCode - 51 + 27); + } + else if (ev.keyCode === 56) { + // delete + result.key = String.fromCharCode(127); + } + else if (ev.keyCode === 219) { + // ^[ - Control Sequence Introducer (CSI) + result.key = String.fromCharCode(27); + } + else if (ev.keyCode === 220) { + // ^\ - String Terminator (ST) + result.key = String.fromCharCode(28); + } + else if (ev.keyCode === 221) { + // ^] - Operating System Command (OSC) + result.key = String.fromCharCode(29); + } + } + else if (!this.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) { + // On Mac this is a third level shift. Use instead. + if (ev.keyCode >= 65 && ev.keyCode <= 90) { + result.key = '\x1b' + String.fromCharCode(ev.keyCode + 32); + } + else if (ev.keyCode === 192) { + result.key = '\x1b`'; + } + else if (ev.keyCode >= 48 && ev.keyCode <= 57) { + result.key = '\x1b' + (ev.keyCode - 48); + } + } + break; + } + return result; +}; +/** + * Set the G level of the terminal + * @param g + */ +Terminal.prototype.setgLevel = function (g) { + this.glevel = g; + this.charset = this.charsets[g]; +}; +/** + * Set the charset for the given G level of the terminal + * @param g + * @param charset + */ +Terminal.prototype.setgCharset = function (g, charset) { + this.charsets[g] = charset; + if (this.glevel === g) { + this.charset = charset; + } +}; +/** + * Handle a keypress event. + * Key Resources: + * - https://developer.mozilla.org/en-US/docs/DOM/KeyboardEvent + * @param {KeyboardEvent} ev The keypress event to be handled. + */ +Terminal.prototype.keyPress = function (ev) { + var key; + this.cancel(ev); + if (ev.charCode) { + key = ev.charCode; + } + else if (ev.which == null) { + key = ev.keyCode; + } + else if (ev.which !== 0 && ev.charCode !== 0) { + key = ev.which; + } + else { + return false; + } + if (!key || ((ev.altKey || ev.ctrlKey || ev.metaKey) && !isThirdLevelShift(this, ev))) { + return false; + } + key = String.fromCharCode(key); + this.emit('keypress', key, ev); + this.emit('key', key, ev); + this.showCursor(); + this.handler(key); + return false; +}; +/** + * Send data for handling to the terminal + * @param {string} data + */ +Terminal.prototype.send = function (data) { + var self = this; + if (!this.queue) { + setTimeout(function () { + self.handler(self.queue); + self.queue = ''; + }, 1); + } + this.queue += data; +}; +/** + * Ring the bell. + * Note: We could do sweet things with webaudio here + */ +Terminal.prototype.bell = function () { + if (!this.visualBell) + return; + var self = this; + this.element.style.borderColor = 'white'; + setTimeout(function () { + self.element.style.borderColor = ''; + }, 10); + if (this.popOnBell) + this.focus(); +}; +/** + * Log the current state to the console. + */ +Terminal.prototype.log = function () { + if (!this.debug) + return; + if (!this.context.console || !this.context.console.log) + return; + var args = Array.prototype.slice.call(arguments); + this.context.console.log.apply(this.context.console, args); +}; +/** + * Log the current state as error to the console. + */ +Terminal.prototype.error = function () { + if (!this.debug) + return; + if (!this.context.console || !this.context.console.error) + return; + var args = Array.prototype.slice.call(arguments); + this.context.console.error.apply(this.context.console, args); +}; +/** + * Resizes the terminal. + * + * @param {number} x The number of columns to resize to. + * @param {number} y The number of rows to resize to. + */ +Terminal.prototype.resize = function (x, y) { + var line, el, i, j, ch, addToY; + if (x === this.cols && y === this.rows) { + return; + } + if (x < 1) + x = 1; + if (y < 1) + y = 1; + // resize cols + j = this.cols; + if (j < x) { + ch = [this.defAttr, ' ', 1]; // does xterm use the default attr? + i = this.lines.length; + while (i--) { + while (this.lines[i].length < x) { + this.lines[i].push(ch); + } + } + } + else { + i = this.lines.length; + while (i--) { + while (this.lines[i].length > x) { + this.lines[i].pop(); + } + } + } + this.setupStops(j); + this.cols = x; + // resize rows + j = this.rows; + addToY = 0; + if (j < y) { + el = this.element; + while (j++ < y) { + // y is rows, not this.y + if (this.lines.length < y + this.ybase) { + if (this.ybase > 0 && this.lines.length <= this.ybase + this.y + addToY + 1) { + // There is room above the buffer and there are no empty elements below the line, + // scroll up + this.ybase--; + addToY++; + if (this.ydisp > 0) { + // Viewport is at the top of the buffer, must increase downwards + this.ydisp--; + } + } + else { + // Add a blank line if there is no buffer left at the top to scroll to, or if there + // are blank lines after the cursor + this.lines.push(this.blankLine()); + } + } + if (this.children.length < y) { + this.insertRow(); + } + } + } + else { + while (j-- > y) { + if (this.lines.length > y + this.ybase) { + if (this.lines.length > this.ybase + this.y + 1) { + // The line is a blank line below the cursor, remove it + this.lines.pop(); + } + else { + // The line is the cursor, scroll down + this.ybase++; + this.ydisp++; + } + } + if (this.children.length > y) { + el = this.children.shift(); + if (!el) + continue; + el.parentNode.removeChild(el); + } + } + } + this.rows = y; + // Make sure that the cursor stays on screen + if (this.y >= y) { + this.y = y - 1; + } + if (addToY) { + this.y += addToY; + } + if (this.x >= x) { + this.x = x - 1; + } + this.scrollTop = 0; + this.scrollBottom = y - 1; + this.refresh(0, this.rows - 1); + this.normal = null; + this.geometry = [this.cols, this.rows]; + this.emit('resize', { terminal: this, cols: x, rows: y }); +}; +/** + * Updates the range of rows to refresh + * @param {number} y The number of rows to refresh next. + */ +Terminal.prototype.updateRange = function (y) { + if (y < this.refreshStart) + this.refreshStart = y; + if (y > this.refreshEnd) + this.refreshEnd = y; + // if (y > this.refreshEnd) { + // this.refreshEnd = y; + // if (y > this.rows - 1) { + // this.refreshEnd = this.rows - 1; + // } + // } +}; +/** + * Set the range of refreshing to the maximum value + */ +Terminal.prototype.maxRange = function () { + this.refreshStart = 0; + this.refreshEnd = this.rows - 1; +}; +/** + * Setup the tab stops. + * @param {number} i + */ +Terminal.prototype.setupStops = function (i) { + if (i != null) { + if (!this.tabs[i]) { + i = this.prevStop(i); + } + } + else { + this.tabs = {}; + i = 0; + } + for (; i < this.cols; i += 8) { + this.tabs[i] = true; + } +}; +/** + * Move the cursor to the previous tab stop from the given position (default is current). + * @param {number} x The position to move the cursor to the previous tab stop. + */ +Terminal.prototype.prevStop = function (x) { + if (x == null) + x = this.x; + while (!this.tabs[--x] && x > 0) + ; + return x >= this.cols + ? this.cols - 1 + : x < 0 ? 0 : x; +}; +/** + * Move the cursor one tab stop forward from the given position (default is current). + * @param {number} x The position to move the cursor one tab stop forward. + */ +Terminal.prototype.nextStop = function (x) { + if (x == null) + x = this.x; + while (!this.tabs[++x] && x < this.cols) + ; + return x >= this.cols + ? this.cols - 1 + : x < 0 ? 0 : x; +}; +/** + * Erase in the identified line everything from "x" to the end of the line (right). + * @param {number} x The column from which to start erasing to the end of the line. + * @param {number} y The line in which to operate. + */ +Terminal.prototype.eraseRight = function (x, y) { + var line = this.lines[this.ybase + y], ch = [this.eraseAttr(), ' ', 1]; // xterm + for (; x < this.cols; x++) { + line[x] = ch; + } + this.updateRange(y); +}; +/** + * Erase in the identified line everything from "x" to the start of the line (left). + * @param {number} x The column from which to start erasing to the start of the line. + * @param {number} y The line in which to operate. + */ +Terminal.prototype.eraseLeft = function (x, y) { + var line = this.lines[this.ybase + y], ch = [this.eraseAttr(), ' ', 1]; // xterm + x++; + while (x--) + line[x] = ch; + this.updateRange(y); +}; +/** + * Clears the entire buffer, making the prompt line the new first line. + */ +Terminal.prototype.clear = function () { + if (this.ybase === 0 && this.y === 0) { + // Don't clear if it's already clear + return; + } + this.lines = [this.lines[this.ybase + this.y]]; + this.ydisp = 0; + this.ybase = 0; + this.y = 0; + for (var i = 1; i < this.rows; i++) { + this.lines.push(this.blankLine()); + } + this.refresh(0, this.rows - 1); + this.emit('scroll', this.ydisp); +}; +/** + * Erase all content in the given line + * @param {number} y The line to erase all of its contents. + */ +Terminal.prototype.eraseLine = function (y) { + this.eraseRight(0, y); +}; +/** + * Return the data array of a blank line/ + * @param {number} cur First bunch of data for each "blank" character. + */ +Terminal.prototype.blankLine = function (cur) { + var attr = cur + ? this.eraseAttr() + : this.defAttr; + var ch = [attr, ' ', 1] // width defaults to 1 halfwidth character + , line = [], i = 0; + for (; i < this.cols; i++) { + line[i] = ch; + } + return line; +}; +/** + * If cur return the back color xterm feature attribute. Else return defAttr. + * @param {object} cur + */ +Terminal.prototype.ch = function (cur) { + return cur + ? [this.eraseAttr(), ' ', 1] + : [this.defAttr, ' ', 1]; +}; +/** + * Evaluate if the current erminal is the given argument. + * @param {object} term The terminal to evaluate + */ +Terminal.prototype.is = function (term) { + var name = this.termName; + return (name + '').indexOf(term) === 0; +}; +/** + * Emit the 'data' event and populate the given data. + * @param {string} data The data to populate in the event. + */ +Terminal.prototype.handler = function (data) { + // Input is being sent to the terminal, the terminal should focus the prompt. + if (this.ybase !== this.ydisp) { + this.scrollToBottom(); + } + this.emit('data', data); +}; +/** + * Emit the 'title' event and populate the given title. + * @param {string} title The title to populate in the event. + */ +Terminal.prototype.handleTitle = function (title) { + /** + * This event is emitted when the title of the terminal is changed + * from inside the terminal. The parameter is the new title. + * + * @event title + */ + this.emit('title', title); +}; +/** + * ESC + */ +/** + * ESC D Index (IND is 0x84). + */ +Terminal.prototype.index = function () { + this.y++; + if (this.y > this.scrollBottom) { + this.y--; + this.scroll(); + } + this.state = normal; +}; +/** + * ESC M Reverse Index (RI is 0x8d). + */ +Terminal.prototype.reverseIndex = function () { + var j; + this.y--; + if (this.y < this.scrollTop) { + this.y++; + // possibly move the code below to term.reverseScroll(); + // test: echo -ne '\e[1;1H\e[44m\eM\e[0m' + // blankLine(true) is xterm/linux behavior + this.lines.splice(this.y + this.ybase, 0, this.blankLine(true)); + j = this.rows - 1 - this.scrollBottom; + this.lines.splice(this.rows - 1 + this.ybase - j + 1, 1); + // this.maxRange(); + this.updateRange(this.scrollTop); + this.updateRange(this.scrollBottom); + } + this.state = normal; +}; +/** + * ESC c Full Reset (RIS). + */ +Terminal.prototype.reset = function () { + this.options.rows = this.rows; + this.options.cols = this.cols; + var customKeydownHandler = this.customKeydownHandler; + Terminal.call(this, this.options); + this.customKeydownHandler = customKeydownHandler; + this.refresh(0, this.rows - 1); + this.viewport.syncScrollArea(); +}; +/** + * ESC H Tab Set (HTS is 0x88). + */ +Terminal.prototype.tabSet = function () { + this.tabs[this.x] = true; + this.state = normal; +}; +/** + * CSI + */ +/** + * CSI Ps A + * Cursor Up Ps Times (default = 1) (CUU). + */ +Terminal.prototype.cursorUp = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + this.y -= param; + if (this.y < 0) + this.y = 0; +}; +/** + * CSI Ps B + * Cursor Down Ps Times (default = 1) (CUD). + */ +Terminal.prototype.cursorDown = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + this.y += param; + if (this.y >= this.rows) { + this.y = this.rows - 1; + } +}; +/** + * CSI Ps C + * Cursor Forward Ps Times (default = 1) (CUF). + */ +Terminal.prototype.cursorForward = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + this.x += param; + if (this.x >= this.cols) { + this.x = this.cols - 1; + } +}; +/** + * CSI Ps D + * Cursor Backward Ps Times (default = 1) (CUB). + */ +Terminal.prototype.cursorBackward = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + this.x -= param; + if (this.x < 0) + this.x = 0; +}; +/** + * CSI Ps ; Ps H + * Cursor Position [row;column] (default = [1,1]) (CUP). + */ +Terminal.prototype.cursorPos = function (params) { + var row, col; + row = params[0] - 1; + if (params.length >= 2) { + col = params[1] - 1; + } + else { + col = 0; + } + if (row < 0) { + row = 0; + } + else if (row >= this.rows) { + row = this.rows - 1; + } + if (col < 0) { + col = 0; + } + else if (col >= this.cols) { + col = this.cols - 1; + } + this.x = col; + this.y = row; +}; +/** + * CSI Ps J Erase in Display (ED). + * Ps = 0 -> Erase Below (default). + * Ps = 1 -> Erase Above. + * Ps = 2 -> Erase All. + * Ps = 3 -> Erase Saved Lines (xterm). + * CSI ? Ps J + * Erase in Display (DECSED). + * Ps = 0 -> Selective Erase Below (default). + * Ps = 1 -> Selective Erase Above. + * Ps = 2 -> Selective Erase All. + */ +Terminal.prototype.eraseInDisplay = function (params) { + var j; + switch (params[0]) { + case 0: + this.eraseRight(this.x, this.y); + j = this.y + 1; + for (; j < this.rows; j++) { + this.eraseLine(j); + } + break; + case 1: + this.eraseLeft(this.x, this.y); + j = this.y; + while (j--) { + this.eraseLine(j); + } + break; + case 2: + j = this.rows; + while (j--) + this.eraseLine(j); + break; + case 3: + ; // no saved lines + break; + } +}; +/** + * CSI Ps K Erase in Line (EL). + * Ps = 0 -> Erase to Right (default). + * Ps = 1 -> Erase to Left. + * Ps = 2 -> Erase All. + * CSI ? Ps K + * Erase in Line (DECSEL). + * Ps = 0 -> Selective Erase to Right (default). + * Ps = 1 -> Selective Erase to Left. + * Ps = 2 -> Selective Erase All. + */ +Terminal.prototype.eraseInLine = function (params) { + switch (params[0]) { + case 0: + this.eraseRight(this.x, this.y); + break; + case 1: + this.eraseLeft(this.x, this.y); + break; + case 2: + this.eraseLine(this.y); + break; + } +}; +/** + * CSI Pm m Character Attributes (SGR). + * Ps = 0 -> Normal (default). + * Ps = 1 -> Bold. + * Ps = 4 -> Underlined. + * Ps = 5 -> Blink (appears as Bold). + * Ps = 7 -> Inverse. + * Ps = 8 -> Invisible, i.e., hidden (VT300). + * Ps = 2 2 -> Normal (neither bold nor faint). + * Ps = 2 4 -> Not underlined. + * Ps = 2 5 -> Steady (not blinking). + * Ps = 2 7 -> Positive (not inverse). + * Ps = 2 8 -> Visible, i.e., not hidden (VT300). + * Ps = 3 0 -> Set foreground color to Black. + * Ps = 3 1 -> Set foreground color to Red. + * Ps = 3 2 -> Set foreground color to Green. + * Ps = 3 3 -> Set foreground color to Yellow. + * Ps = 3 4 -> Set foreground color to Blue. + * Ps = 3 5 -> Set foreground color to Magenta. + * Ps = 3 6 -> Set foreground color to Cyan. + * Ps = 3 7 -> Set foreground color to White. + * Ps = 3 9 -> Set foreground color to default (original). + * Ps = 4 0 -> Set background color to Black. + * Ps = 4 1 -> Set background color to Red. + * Ps = 4 2 -> Set background color to Green. + * Ps = 4 3 -> Set background color to Yellow. + * Ps = 4 4 -> Set background color to Blue. + * Ps = 4 5 -> Set background color to Magenta. + * Ps = 4 6 -> Set background color to Cyan. + * Ps = 4 7 -> Set background color to White. + * Ps = 4 9 -> Set background color to default (original). + * + * If 16-color support is compiled, the following apply. Assume + * that xterm's resources are set so that the ISO color codes are + * the first 8 of a set of 16. Then the aixterm colors are the + * bright versions of the ISO colors: + * Ps = 9 0 -> Set foreground color to Black. + * Ps = 9 1 -> Set foreground color to Red. + * Ps = 9 2 -> Set foreground color to Green. + * Ps = 9 3 -> Set foreground color to Yellow. + * Ps = 9 4 -> Set foreground color to Blue. + * Ps = 9 5 -> Set foreground color to Magenta. + * Ps = 9 6 -> Set foreground color to Cyan. + * Ps = 9 7 -> Set foreground color to White. + * Ps = 1 0 0 -> Set background color to Black. + * Ps = 1 0 1 -> Set background color to Red. + * Ps = 1 0 2 -> Set background color to Green. + * Ps = 1 0 3 -> Set background color to Yellow. + * Ps = 1 0 4 -> Set background color to Blue. + * Ps = 1 0 5 -> Set background color to Magenta. + * Ps = 1 0 6 -> Set background color to Cyan. + * Ps = 1 0 7 -> Set background color to White. + * + * If xterm is compiled with the 16-color support disabled, it + * supports the following, from rxvt: + * Ps = 1 0 0 -> Set foreground and background color to + * default. + * + * If 88- or 256-color support is compiled, the following apply. + * Ps = 3 8 ; 5 ; Ps -> Set foreground color to the second + * Ps. + * Ps = 4 8 ; 5 ; Ps -> Set background color to the second + * Ps. + */ +Terminal.prototype.charAttributes = function (params) { + // Optimize a single SGR0. + if (params.length === 1 && params[0] === 0) { + this.curAttr = this.defAttr; + return; + } + var l = params.length, i = 0, flags = this.curAttr >> 18, fg = (this.curAttr >> 9) & 0x1ff, bg = this.curAttr & 0x1ff, p; + for (; i < l; i++) { + p = params[i]; + if (p >= 30 && p <= 37) { + // fg color 8 + fg = p - 30; + } + else if (p >= 40 && p <= 47) { + // bg color 8 + bg = p - 40; + } + else if (p >= 90 && p <= 97) { + // fg color 16 + p += 8; + fg = p - 90; + } + else if (p >= 100 && p <= 107) { + // bg color 16 + p += 8; + bg = p - 100; + } + else if (p === 0) { + // default + flags = this.defAttr >> 18; + fg = (this.defAttr >> 9) & 0x1ff; + bg = this.defAttr & 0x1ff; + } + else if (p === 1) { + // bold text + flags |= 1; + } + else if (p === 4) { + // underlined text + flags |= 2; + } + else if (p === 5) { + // blink + flags |= 4; + } + else if (p === 7) { + // inverse and positive + // test with: echo -e '\e[31m\e[42mhello\e[7mworld\e[27mhi\e[m' + flags |= 8; + } + else if (p === 8) { + // invisible + flags |= 16; + } + else if (p === 22) { + // not bold + flags &= ~1; + } + else if (p === 24) { + // not underlined + flags &= ~2; + } + else if (p === 25) { + // not blink + flags &= ~4; + } + else if (p === 27) { + // not inverse + flags &= ~8; + } + else if (p === 28) { + // not invisible + flags &= ~16; + } + else if (p === 39) { + // reset fg + fg = (this.defAttr >> 9) & 0x1ff; + } + else if (p === 49) { + // reset bg + bg = this.defAttr & 0x1ff; + } + else if (p === 38) { + // fg color 256 + if (params[i + 1] === 2) { + i += 2; + fg = matchColor(params[i] & 0xff, params[i + 1] & 0xff, params[i + 2] & 0xff); + if (fg === -1) + fg = 0x1ff; + i += 2; + } + else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + fg = p; + } + } + else if (p === 48) { + // bg color 256 + if (params[i + 1] === 2) { + i += 2; + bg = matchColor(params[i] & 0xff, params[i + 1] & 0xff, params[i + 2] & 0xff); + if (bg === -1) + bg = 0x1ff; + i += 2; + } + else if (params[i + 1] === 5) { + i += 2; + p = params[i] & 0xff; + bg = p; + } + } + else if (p === 100) { + // reset fg/bg + fg = (this.defAttr >> 9) & 0x1ff; + bg = this.defAttr & 0x1ff; + } + else { + this.error('Unknown SGR attribute: %d.', p); + } + } + this.curAttr = (flags << 18) | (fg << 9) | bg; +}; +/** + * CSI Ps n Device Status Report (DSR). + * Ps = 5 -> Status Report. Result (``OK'') is + * CSI 0 n + * Ps = 6 -> Report Cursor Position (CPR) [row;column]. + * Result is + * CSI r ; c R + * CSI ? Ps n + * Device Status Report (DSR, DEC-specific). + * Ps = 6 -> Report Cursor Position (CPR) [row;column] as CSI + * ? r ; c R (assumes page is zero). + * Ps = 1 5 -> Report Printer status as CSI ? 1 0 n (ready). + * or CSI ? 1 1 n (not ready). + * Ps = 2 5 -> Report UDK status as CSI ? 2 0 n (unlocked) + * or CSI ? 2 1 n (locked). + * Ps = 2 6 -> Report Keyboard status as + * CSI ? 2 7 ; 1 ; 0 ; 0 n (North American). + * The last two parameters apply to VT400 & up, and denote key- + * board ready and LK01 respectively. + * Ps = 5 3 -> Report Locator status as + * CSI ? 5 3 n Locator available, if compiled-in, or + * CSI ? 5 0 n No Locator, if not. + */ +Terminal.prototype.deviceStatus = function (params) { + if (!this.prefix) { + switch (params[0]) { + case 5: + // status report + this.send('\x1b[0n'); + break; + case 6: + // cursor position + this.send('\x1b[' + + (this.y + 1) + + ';' + + (this.x + 1) + + 'R'); + break; + } + } + else if (this.prefix === '?') { + // modern xterm doesnt seem to + // respond to any of these except ?6, 6, and 5 + switch (params[0]) { + case 6: + // cursor position + this.send('\x1b[?' + + (this.y + 1) + + ';' + + (this.x + 1) + + 'R'); + break; + case 15: + // no printer + // this.send('\x1b[?11n'); + break; + case 25: + // dont support user defined keys + // this.send('\x1b[?21n'); + break; + case 26: + // north american keyboard + // this.send('\x1b[?27;1;0;0n'); + break; + case 53: + // no dec locator/mouse + // this.send('\x1b[?50n'); + break; + } + } +}; +/** + * Additions + */ +/** + * CSI Ps @ + * Insert Ps (Blank) Character(s) (default = 1) (ICH). + */ +Terminal.prototype.insertChars = function (params) { + var param, row, j, ch; + param = params[0]; + if (param < 1) + param = 1; + row = this.y + this.ybase; + j = this.x; + ch = [this.eraseAttr(), ' ', 1]; // xterm + while (param-- && j < this.cols) { + this.lines[row].splice(j++, 0, ch); + this.lines[row].pop(); + } +}; +/** + * CSI Ps E + * Cursor Next Line Ps Times (default = 1) (CNL). + * same as CSI Ps B ? + */ +Terminal.prototype.cursorNextLine = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + this.y += param; + if (this.y >= this.rows) { + this.y = this.rows - 1; + } + this.x = 0; +}; +/** + * CSI Ps F + * Cursor Preceding Line Ps Times (default = 1) (CNL). + * reuse CSI Ps A ? + */ +Terminal.prototype.cursorPrecedingLine = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + this.y -= param; + if (this.y < 0) + this.y = 0; + this.x = 0; +}; +/** + * CSI Ps G + * Cursor Character Absolute [column] (default = [row,1]) (CHA). + */ +Terminal.prototype.cursorCharAbsolute = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + this.x = param - 1; +}; +/** + * CSI Ps L + * Insert Ps Line(s) (default = 1) (IL). + */ +Terminal.prototype.insertLines = function (params) { + var param, row, j; + param = params[0]; + if (param < 1) + param = 1; + row = this.y + this.ybase; + j = this.rows - 1 - this.scrollBottom; + j = this.rows - 1 + this.ybase - j + 1; + while (param--) { + // test: echo -e '\e[44m\e[1L\e[0m' + // blankLine(true) - xterm/linux behavior + this.lines.splice(row, 0, this.blankLine(true)); + this.lines.splice(j, 1); + } + // this.maxRange(); + this.updateRange(this.y); + this.updateRange(this.scrollBottom); +}; +/** + * CSI Ps M + * Delete Ps Line(s) (default = 1) (DL). + */ +Terminal.prototype.deleteLines = function (params) { + var param, row, j; + param = params[0]; + if (param < 1) + param = 1; + row = this.y + this.ybase; + j = this.rows - 1 - this.scrollBottom; + j = this.rows - 1 + this.ybase - j; + while (param--) { + // test: echo -e '\e[44m\e[1M\e[0m' + // blankLine(true) - xterm/linux behavior + this.lines.splice(j + 1, 0, this.blankLine(true)); + this.lines.splice(row, 1); + } + // this.maxRange(); + this.updateRange(this.y); + this.updateRange(this.scrollBottom); +}; +/** + * CSI Ps P + * Delete Ps Character(s) (default = 1) (DCH). + */ +Terminal.prototype.deleteChars = function (params) { + var param, row, ch; + param = params[0]; + if (param < 1) + param = 1; + row = this.y + this.ybase; + ch = [this.eraseAttr(), ' ', 1]; // xterm + while (param--) { + this.lines[row].splice(this.x, 1); + this.lines[row].push(ch); + } +}; +/** + * CSI Ps X + * Erase Ps Character(s) (default = 1) (ECH). + */ +Terminal.prototype.eraseChars = function (params) { + var param, row, j, ch; + param = params[0]; + if (param < 1) + param = 1; + row = this.y + this.ybase; + j = this.x; + ch = [this.eraseAttr(), ' ', 1]; // xterm + while (param-- && j < this.cols) { + this.lines[row][j++] = ch; + } +}; +/** + * CSI Pm ` Character Position Absolute + * [column] (default = [row,1]) (HPA). + */ +Terminal.prototype.charPosAbsolute = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + this.x = param - 1; + if (this.x >= this.cols) { + this.x = this.cols - 1; + } +}; +/** + * 141 61 a * HPR - + * Horizontal Position Relative + * reuse CSI Ps C ? + */ +Terminal.prototype.HPositionRelative = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + this.x += param; + if (this.x >= this.cols) { + this.x = this.cols - 1; + } +}; +/** + * CSI Ps c Send Device Attributes (Primary DA). + * Ps = 0 or omitted -> request attributes from terminal. The + * response depends on the decTerminalID resource setting. + * -> CSI ? 1 ; 2 c (``VT100 with Advanced Video Option'') + * -> CSI ? 1 ; 0 c (``VT101 with No Options'') + * -> CSI ? 6 c (``VT102'') + * -> CSI ? 6 0 ; 1 ; 2 ; 6 ; 8 ; 9 ; 1 5 ; c (``VT220'') + * The VT100-style response parameters do not mean anything by + * themselves. VT220 parameters do, telling the host what fea- + * tures the terminal supports: + * Ps = 1 -> 132-columns. + * Ps = 2 -> Printer. + * Ps = 6 -> Selective erase. + * Ps = 8 -> User-defined keys. + * Ps = 9 -> National replacement character sets. + * Ps = 1 5 -> Technical characters. + * Ps = 2 2 -> ANSI color, e.g., VT525. + * Ps = 2 9 -> ANSI text locator (i.e., DEC Locator mode). + * CSI > Ps c + * Send Device Attributes (Secondary DA). + * Ps = 0 or omitted -> request the terminal's identification + * code. The response depends on the decTerminalID resource set- + * ting. It should apply only to VT220 and up, but xterm extends + * this to VT100. + * -> CSI > Pp ; Pv ; Pc c + * where Pp denotes the terminal type + * Pp = 0 -> ``VT100''. + * Pp = 1 -> ``VT220''. + * and Pv is the firmware version (for xterm, this was originally + * the XFree86 patch number, starting with 95). In a DEC termi- + * nal, Pc indicates the ROM cartridge registration number and is + * always zero. + * More information: + * xterm/charproc.c - line 2012, for more information. + * vim responds with ^[[?0c or ^[[?1c after the terminal's response (?) + */ +Terminal.prototype.sendDeviceAttributes = function (params) { + if (params[0] > 0) + return; + if (!this.prefix) { + if (this.is('xterm') + || this.is('rxvt-unicode') + || this.is('screen')) { + this.send('\x1b[?1;2c'); + } + else if (this.is('linux')) { + this.send('\x1b[?6c'); + } + } + else if (this.prefix === '>') { + // xterm and urxvt + // seem to spit this + // out around ~370 times (?). + if (this.is('xterm')) { + this.send('\x1b[>0;276;0c'); + } + else if (this.is('rxvt-unicode')) { + this.send('\x1b[>85;95;0c'); + } + else if (this.is('linux')) { + // not supported by linux console. + // linux console echoes parameters. + this.send(params[0] + 'c'); + } + else if (this.is('screen')) { + this.send('\x1b[>83;40003;0c'); + } + } +}; +/** + * CSI Pm d + * Line Position Absolute [row] (default = [1,column]) (VPA). + */ +Terminal.prototype.linePosAbsolute = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + this.y = param - 1; + if (this.y >= this.rows) { + this.y = this.rows - 1; + } +}; +/** + * 145 65 e * VPR - Vertical Position Relative + * reuse CSI Ps B ? + */ +Terminal.prototype.VPositionRelative = function (params) { + var param = params[0]; + if (param < 1) + param = 1; + this.y += param; + if (this.y >= this.rows) { + this.y = this.rows - 1; + } +}; +/** + * CSI Ps ; Ps f + * Horizontal and Vertical Position [row;column] (default = + * [1,1]) (HVP). + */ +Terminal.prototype.HVPosition = function (params) { + if (params[0] < 1) + params[0] = 1; + if (params[1] < 1) + params[1] = 1; + this.y = params[0] - 1; + if (this.y >= this.rows) { + this.y = this.rows - 1; + } + this.x = params[1] - 1; + if (this.x >= this.cols) { + this.x = this.cols - 1; + } +}; +/** + * CSI Pm h Set Mode (SM). + * Ps = 2 -> Keyboard Action Mode (AM). + * Ps = 4 -> Insert Mode (IRM). + * Ps = 1 2 -> Send/receive (SRM). + * Ps = 2 0 -> Automatic Newline (LNM). + * CSI ? Pm h + * DEC Private Mode Set (DECSET). + * Ps = 1 -> Application Cursor Keys (DECCKM). + * Ps = 2 -> Designate USASCII for character sets G0-G3 + * (DECANM), and set VT100 mode. + * Ps = 3 -> 132 Column Mode (DECCOLM). + * Ps = 4 -> Smooth (Slow) Scroll (DECSCLM). + * Ps = 5 -> Reverse Video (DECSCNM). + * Ps = 6 -> Origin Mode (DECOM). + * Ps = 7 -> Wraparound Mode (DECAWM). + * Ps = 8 -> Auto-repeat Keys (DECARM). + * Ps = 9 -> Send Mouse X & Y on button press. See the sec- + * tion Mouse Tracking. + * Ps = 1 0 -> Show toolbar (rxvt). + * Ps = 1 2 -> Start Blinking Cursor (att610). + * Ps = 1 8 -> Print form feed (DECPFF). + * Ps = 1 9 -> Set print extent to full screen (DECPEX). + * Ps = 2 5 -> Show Cursor (DECTCEM). + * Ps = 3 0 -> Show scrollbar (rxvt). + * Ps = 3 5 -> Enable font-shifting functions (rxvt). + * Ps = 3 8 -> Enter Tektronix Mode (DECTEK). + * Ps = 4 0 -> Allow 80 -> 132 Mode. + * Ps = 4 1 -> more(1) fix (see curses resource). + * Ps = 4 2 -> Enable Nation Replacement Character sets (DECN- + * RCM). + * Ps = 4 4 -> Turn On Margin Bell. + * Ps = 4 5 -> Reverse-wraparound Mode. + * Ps = 4 6 -> Start Logging. This is normally disabled by a + * compile-time option. + * Ps = 4 7 -> Use Alternate Screen Buffer. (This may be dis- + * abled by the titeInhibit resource). + * Ps = 6 6 -> Application keypad (DECNKM). + * Ps = 6 7 -> Backarrow key sends backspace (DECBKM). + * Ps = 1 0 0 0 -> Send Mouse X & Y on button press and + * release. See the section Mouse Tracking. + * Ps = 1 0 0 1 -> Use Hilite Mouse Tracking. + * Ps = 1 0 0 2 -> Use Cell Motion Mouse Tracking. + * Ps = 1 0 0 3 -> Use All Motion Mouse Tracking. + * Ps = 1 0 0 4 -> Send FocusIn/FocusOut events. + * Ps = 1 0 0 5 -> Enable Extended Mouse Mode. + * Ps = 1 0 1 0 -> Scroll to bottom on tty output (rxvt). + * Ps = 1 0 1 1 -> Scroll to bottom on key press (rxvt). + * Ps = 1 0 3 4 -> Interpret "meta" key, sets eighth bit. + * (enables the eightBitInput resource). + * Ps = 1 0 3 5 -> Enable special modifiers for Alt and Num- + * Lock keys. (This enables the numLock resource). + * Ps = 1 0 3 6 -> Send ESC when Meta modifies a key. (This + * enables the metaSendsEscape resource). + * Ps = 1 0 3 7 -> Send DEL from the editing-keypad Delete + * key. + * Ps = 1 0 3 9 -> Send ESC when Alt modifies a key. (This + * enables the altSendsEscape resource). + * Ps = 1 0 4 0 -> Keep selection even if not highlighted. + * (This enables the keepSelection resource). + * Ps = 1 0 4 1 -> Use the CLIPBOARD selection. (This enables + * the selectToClipboard resource). + * Ps = 1 0 4 2 -> Enable Urgency window manager hint when + * Control-G is received. (This enables the bellIsUrgent + * resource). + * Ps = 1 0 4 3 -> Enable raising of the window when Control-G + * is received. (enables the popOnBell resource). + * Ps = 1 0 4 7 -> Use Alternate Screen Buffer. (This may be + * disabled by the titeInhibit resource). + * Ps = 1 0 4 8 -> Save cursor as in DECSC. (This may be dis- + * abled by the titeInhibit resource). + * Ps = 1 0 4 9 -> Save cursor as in DECSC and use Alternate + * Screen Buffer, clearing it first. (This may be disabled by + * the titeInhibit resource). This combines the effects of the 1 + * 0 4 7 and 1 0 4 8 modes. Use this with terminfo-based + * applications rather than the 4 7 mode. + * Ps = 1 0 5 0 -> Set terminfo/termcap function-key mode. + * Ps = 1 0 5 1 -> Set Sun function-key mode. + * Ps = 1 0 5 2 -> Set HP function-key mode. + * Ps = 1 0 5 3 -> Set SCO function-key mode. + * Ps = 1 0 6 0 -> Set legacy keyboard emulation (X11R6). + * Ps = 1 0 6 1 -> Set VT220 keyboard emulation. + * Ps = 2 0 0 4 -> Set bracketed paste mode. + * Modes: + * http: *vt100.net/docs/vt220-rm/chapter4.html + */ +Terminal.prototype.setMode = function (params) { + if (typeof params === 'object') { + var l = params.length, i = 0; + for (; i < l; i++) { + this.setMode(params[i]); + } + return; + } + if (!this.prefix) { + switch (params) { + case 4: + this.insertMode = true; + break; + case 20: + //this.convertEol = true; + break; + } + } + else if (this.prefix === '?') { + switch (params) { + case 1: + this.applicationCursor = true; + break; + case 2: + this.setgCharset(0, Terminal.charsets.US); + this.setgCharset(1, Terminal.charsets.US); + this.setgCharset(2, Terminal.charsets.US); + this.setgCharset(3, Terminal.charsets.US); + // set VT100 mode here + break; + case 3: + this.savedCols = this.cols; + this.resize(132, this.rows); + break; + case 6: + this.originMode = true; + break; + case 7: + this.wraparoundMode = true; + break; + case 12: + // this.cursorBlink = true; + break; + case 66: + this.log('Serial port requested application keypad.'); + this.applicationKeypad = true; + this.viewport.syncScrollArea(); + break; + case 9: // X10 Mouse + // no release, no motion, no wheel, no modifiers. + case 1000: // vt200 mouse + // no motion. + // no modifiers, except control on the wheel. + case 1002: // button event mouse + case 1003: + // any event - sends motion events, + // even if there is no button held down. + this.x10Mouse = params === 9; + this.vt200Mouse = params === 1000; + this.normalMouse = params > 1000; + this.mouseEvents = true; + this.element.style.cursor = 'default'; + this.log('Binding to mouse events.'); + break; + case 1004: + // focusin: ^[[I + // focusout: ^[[O + this.sendFocus = true; + break; + case 1005: + this.utfMouse = true; + // for wide terminals + // simply encodes large values as utf8 characters + break; + case 1006: + this.sgrMouse = true; + // for wide terminals + // does not add 32 to fields + // press: ^[[ Keyboard Action Mode (AM). + * Ps = 4 -> Replace Mode (IRM). + * Ps = 1 2 -> Send/receive (SRM). + * Ps = 2 0 -> Normal Linefeed (LNM). + * CSI ? Pm l + * DEC Private Mode Reset (DECRST). + * Ps = 1 -> Normal Cursor Keys (DECCKM). + * Ps = 2 -> Designate VT52 mode (DECANM). + * Ps = 3 -> 80 Column Mode (DECCOLM). + * Ps = 4 -> Jump (Fast) Scroll (DECSCLM). + * Ps = 5 -> Normal Video (DECSCNM). + * Ps = 6 -> Normal Cursor Mode (DECOM). + * Ps = 7 -> No Wraparound Mode (DECAWM). + * Ps = 8 -> No Auto-repeat Keys (DECARM). + * Ps = 9 -> Don't send Mouse X & Y on button press. + * Ps = 1 0 -> Hide toolbar (rxvt). + * Ps = 1 2 -> Stop Blinking Cursor (att610). + * Ps = 1 8 -> Don't print form feed (DECPFF). + * Ps = 1 9 -> Limit print to scrolling region (DECPEX). + * Ps = 2 5 -> Hide Cursor (DECTCEM). + * Ps = 3 0 -> Don't show scrollbar (rxvt). + * Ps = 3 5 -> Disable font-shifting functions (rxvt). + * Ps = 4 0 -> Disallow 80 -> 132 Mode. + * Ps = 4 1 -> No more(1) fix (see curses resource). + * Ps = 4 2 -> Disable Nation Replacement Character sets (DEC- + * NRCM). + * Ps = 4 4 -> Turn Off Margin Bell. + * Ps = 4 5 -> No Reverse-wraparound Mode. + * Ps = 4 6 -> Stop Logging. (This is normally disabled by a + * compile-time option). + * Ps = 4 7 -> Use Normal Screen Buffer. + * Ps = 6 6 -> Numeric keypad (DECNKM). + * Ps = 6 7 -> Backarrow key sends delete (DECBKM). + * Ps = 1 0 0 0 -> Don't send Mouse X & Y on button press and + * release. See the section Mouse Tracking. + * Ps = 1 0 0 1 -> Don't use Hilite Mouse Tracking. + * Ps = 1 0 0 2 -> Don't use Cell Motion Mouse Tracking. + * Ps = 1 0 0 3 -> Don't use All Motion Mouse Tracking. + * Ps = 1 0 0 4 -> Don't send FocusIn/FocusOut events. + * Ps = 1 0 0 5 -> Disable Extended Mouse Mode. + * Ps = 1 0 1 0 -> Don't scroll to bottom on tty output + * (rxvt). + * Ps = 1 0 1 1 -> Don't scroll to bottom on key press (rxvt). + * Ps = 1 0 3 4 -> Don't interpret "meta" key. (This disables + * the eightBitInput resource). + * Ps = 1 0 3 5 -> Disable special modifiers for Alt and Num- + * Lock keys. (This disables the numLock resource). + * Ps = 1 0 3 6 -> Don't send ESC when Meta modifies a key. + * (This disables the metaSendsEscape resource). + * Ps = 1 0 3 7 -> Send VT220 Remove from the editing-keypad + * Delete key. + * Ps = 1 0 3 9 -> Don't send ESC when Alt modifies a key. + * (This disables the altSendsEscape resource). + * Ps = 1 0 4 0 -> Do not keep selection when not highlighted. + * (This disables the keepSelection resource). + * Ps = 1 0 4 1 -> Use the PRIMARY selection. (This disables + * the selectToClipboard resource). + * Ps = 1 0 4 2 -> Disable Urgency window manager hint when + * Control-G is received. (This disables the bellIsUrgent + * resource). + * Ps = 1 0 4 3 -> Disable raising of the window when Control- + * G is received. (This disables the popOnBell resource). + * Ps = 1 0 4 7 -> Use Normal Screen Buffer, clearing screen + * first if in the Alternate Screen. (This may be disabled by + * the titeInhibit resource). + * Ps = 1 0 4 8 -> Restore cursor as in DECRC. (This may be + * disabled by the titeInhibit resource). + * Ps = 1 0 4 9 -> Use Normal Screen Buffer and restore cursor + * as in DECRC. (This may be disabled by the titeInhibit + * resource). This combines the effects of the 1 0 4 7 and 1 0 + * 4 8 modes. Use this with terminfo-based applications rather + * than the 4 7 mode. + * Ps = 1 0 5 0 -> Reset terminfo/termcap function-key mode. + * Ps = 1 0 5 1 -> Reset Sun function-key mode. + * Ps = 1 0 5 2 -> Reset HP function-key mode. + * Ps = 1 0 5 3 -> Reset SCO function-key mode. + * Ps = 1 0 6 0 -> Reset legacy keyboard emulation (X11R6). + * Ps = 1 0 6 1 -> Reset keyboard emulation to Sun/PC style. + * Ps = 2 0 0 4 -> Reset bracketed paste mode. + */ +Terminal.prototype.resetMode = function (params) { + if (typeof params === 'object') { + var l = params.length, i = 0; + for (; i < l; i++) { + this.resetMode(params[i]); + } + return; + } + if (!this.prefix) { + switch (params) { + case 4: + this.insertMode = false; + break; + case 20: + //this.convertEol = false; + break; + } + } + else if (this.prefix === '?') { + switch (params) { + case 1: + this.applicationCursor = false; + break; + case 3: + if (this.cols === 132 && this.savedCols) { + this.resize(this.savedCols, this.rows); + } + delete this.savedCols; + break; + case 6: + this.originMode = false; + break; + case 7: + this.wraparoundMode = false; + break; + case 12: + // this.cursorBlink = false; + break; + case 66: + this.log('Switching back to normal keypad.'); + this.applicationKeypad = false; + this.viewport.syncScrollArea(); + break; + case 9: // X10 Mouse + case 1000: // vt200 mouse + case 1002: // button event mouse + case 1003: + this.x10Mouse = false; + this.vt200Mouse = false; + this.normalMouse = false; + this.mouseEvents = false; + this.element.style.cursor = ''; + break; + case 1004: + this.sendFocus = false; + break; + case 1005: + this.utfMouse = false; + break; + case 1006: + this.sgrMouse = false; + break; + case 1015: + this.urxvtMouse = false; + break; + case 25: + this.cursorHidden = true; + break; + case 1049: + ; // FALL-THROUGH + case 47: // normal screen buffer + case 1047: + if (this.normal) { + this.lines = this.normal.lines; + this.ybase = this.normal.ybase; + this.ydisp = this.normal.ydisp; + this.x = this.normal.x; + this.y = this.normal.y; + this.scrollTop = this.normal.scrollTop; + this.scrollBottom = this.normal.scrollBottom; + this.tabs = this.normal.tabs; + this.normal = null; + // if (params === 1049) { + // this.x = this.savedX; + // this.y = this.savedY; + // } + this.refresh(0, this.rows - 1); + this.showCursor(); + } + break; + } + } +}; +/** + * CSI Ps ; Ps r + * Set Scrolling Region [top;bottom] (default = full size of win- + * dow) (DECSTBM). + * CSI ? Pm r + */ +Terminal.prototype.setScrollRegion = function (params) { + if (this.prefix) + return; + this.scrollTop = (params[0] || 1) - 1; + this.scrollBottom = (params[1] || this.rows) - 1; + this.x = 0; + this.y = 0; +}; +/** + * CSI s + * Save cursor (ANSI.SYS). + */ +Terminal.prototype.saveCursor = function (params) { + this.savedX = this.x; + this.savedY = this.y; +}; +/** + * CSI u + * Restore cursor (ANSI.SYS). + */ +Terminal.prototype.restoreCursor = function (params) { + this.x = this.savedX || 0; + this.y = this.savedY || 0; +}; +/** + * Lesser Used + */ +/** + * CSI Ps I + * Cursor Forward Tabulation Ps tab stops (default = 1) (CHT). + */ +Terminal.prototype.cursorForwardTab = function (params) { + var param = params[0] || 1; + while (param--) { + this.x = this.nextStop(); + } +}; +/** + * CSI Ps S Scroll up Ps lines (default = 1) (SU). + */ +Terminal.prototype.scrollUp = function (params) { + var param = params[0] || 1; + while (param--) { + this.lines.splice(this.ybase + this.scrollTop, 1); + this.lines.splice(this.ybase + this.scrollBottom, 0, this.blankLine()); + } + // this.maxRange(); + this.updateRange(this.scrollTop); + this.updateRange(this.scrollBottom); +}; +/** + * CSI Ps T Scroll down Ps lines (default = 1) (SD). + */ +Terminal.prototype.scrollDown = function (params) { + var param = params[0] || 1; + while (param--) { + this.lines.splice(this.ybase + this.scrollBottom, 1); + this.lines.splice(this.ybase + this.scrollTop, 0, this.blankLine()); + } + // this.maxRange(); + this.updateRange(this.scrollTop); + this.updateRange(this.scrollBottom); +}; +/** + * CSI Ps ; Ps ; Ps ; Ps ; Ps T + * Initiate highlight mouse tracking. Parameters are + * [func;startx;starty;firstrow;lastrow]. See the section Mouse + * Tracking. + */ +Terminal.prototype.initMouseTracking = function (params) { + // Relevant: DECSET 1001 +}; +/** + * CSI > Ps; Ps T + * Reset one or more features of the title modes to the default + * value. Normally, "reset" disables the feature. It is possi- + * ble to disable the ability to reset features by compiling a + * different default for the title modes into xterm. + * Ps = 0 -> Do not set window/icon labels using hexadecimal. + * Ps = 1 -> Do not query window/icon labels using hexadeci- + * mal. + * Ps = 2 -> Do not set window/icon labels using UTF-8. + * Ps = 3 -> Do not query window/icon labels using UTF-8. + * (See discussion of "Title Modes"). + */ +Terminal.prototype.resetTitleModes = function (params) { + ; +}; +/** + * CSI Ps Z Cursor Backward Tabulation Ps tab stops (default = 1) (CBT). + */ +Terminal.prototype.cursorBackwardTab = function (params) { + var param = params[0] || 1; + while (param--) { + this.x = this.prevStop(); + } +}; +/** + * CSI Ps b Repeat the preceding graphic character Ps times (REP). + */ +Terminal.prototype.repeatPrecedingCharacter = function (params) { + var param = params[0] || 1, line = this.lines[this.ybase + this.y], ch = line[this.x - 1] || [this.defAttr, ' ', 1]; + while (param--) + line[this.x++] = ch; +}; +/** + * CSI Ps g Tab Clear (TBC). + * Ps = 0 -> Clear Current Column (default). + * Ps = 3 -> Clear All. + * Potentially: + * Ps = 2 -> Clear Stops on Line. + * http://vt100.net/annarbor/aaa-ug/section6.html + */ +Terminal.prototype.tabClear = function (params) { + var param = params[0]; + if (param <= 0) { + delete this.tabs[this.x]; + } + else if (param === 3) { + this.tabs = {}; + } +}; +/** + * CSI Pm i Media Copy (MC). + * Ps = 0 -> Print screen (default). + * Ps = 4 -> Turn off printer controller mode. + * Ps = 5 -> Turn on printer controller mode. + * CSI ? Pm i + * Media Copy (MC, DEC-specific). + * Ps = 1 -> Print line containing cursor. + * Ps = 4 -> Turn off autoprint mode. + * Ps = 5 -> Turn on autoprint mode. + * Ps = 1 0 -> Print composed display, ignores DECPEX. + * Ps = 1 1 -> Print all pages. + */ +Terminal.prototype.mediaCopy = function (params) { + ; +}; +/** + * CSI > Ps; Ps m + * Set or reset resource-values used by xterm to decide whether + * to construct escape sequences holding information about the + * modifiers pressed with a given key. The first parameter iden- + * tifies the resource to set/reset. The second parameter is the + * value to assign to the resource. If the second parameter is + * omitted, the resource is reset to its initial value. + * Ps = 1 -> modifyCursorKeys. + * Ps = 2 -> modifyFunctionKeys. + * Ps = 4 -> modifyOtherKeys. + * If no parameters are given, all resources are reset to their + * initial values. + */ +Terminal.prototype.setResources = function (params) { + ; +}; +/** + * CSI > Ps n + * Disable modifiers which may be enabled via the CSI > Ps; Ps m + * sequence. This corresponds to a resource value of "-1", which + * cannot be set with the other sequence. The parameter identi- + * fies the resource to be disabled: + * Ps = 1 -> modifyCursorKeys. + * Ps = 2 -> modifyFunctionKeys. + * Ps = 4 -> modifyOtherKeys. + * If the parameter is omitted, modifyFunctionKeys is disabled. + * When modifyFunctionKeys is disabled, xterm uses the modifier + * keys to make an extended sequence of functions rather than + * adding a parameter to each function key to denote the modi- + * fiers. + */ +Terminal.prototype.disableModifiers = function (params) { + ; +}; +/** + * CSI > Ps p + * Set resource value pointerMode. This is used by xterm to + * decide whether to hide the pointer cursor as the user types. + * Valid values for the parameter: + * Ps = 0 -> never hide the pointer. + * Ps = 1 -> hide if the mouse tracking mode is not enabled. + * Ps = 2 -> always hide the pointer. If no parameter is + * given, xterm uses the default, which is 1 . + */ +Terminal.prototype.setPointerMode = function (params) { + ; +}; +/** + * CSI ! p Soft terminal reset (DECSTR). + * http://vt100.net/docs/vt220-rm/table4-10.html + */ +Terminal.prototype.softReset = function (params) { + this.cursorHidden = false; + this.insertMode = false; + this.originMode = false; + this.wraparoundMode = false; // autowrap + this.applicationKeypad = false; // ? + this.viewport.syncScrollArea(); + this.applicationCursor = false; + this.scrollTop = 0; + this.scrollBottom = this.rows - 1; + this.curAttr = this.defAttr; + this.x = this.y = 0; // ? + this.charset = null; + this.glevel = 0; // ?? + this.charsets = [null]; // ?? +}; +/** + * CSI Ps$ p + * Request ANSI mode (DECRQM). For VT300 and up, reply is + * CSI Ps; Pm$ y + * where Ps is the mode number as in RM, and Pm is the mode + * value: + * 0 - not recognized + * 1 - set + * 2 - reset + * 3 - permanently set + * 4 - permanently reset + */ +Terminal.prototype.requestAnsiMode = function (params) { + ; +}; +/** + * CSI ? Ps$ p + * Request DEC private mode (DECRQM). For VT300 and up, reply is + * CSI ? Ps; Pm$ p + * where Ps is the mode number as in DECSET, Pm is the mode value + * as in the ANSI DECRQM. + */ +Terminal.prototype.requestPrivateMode = function (params) { + ; +}; +/** + * CSI Ps ; Ps " p + * Set conformance level (DECSCL). Valid values for the first + * parameter: + * Ps = 6 1 -> VT100. + * Ps = 6 2 -> VT200. + * Ps = 6 3 -> VT300. + * Valid values for the second parameter: + * Ps = 0 -> 8-bit controls. + * Ps = 1 -> 7-bit controls (always set for VT100). + * Ps = 2 -> 8-bit controls. + */ +Terminal.prototype.setConformanceLevel = function (params) { + ; +}; +/** + * CSI Ps q Load LEDs (DECLL). + * Ps = 0 -> Clear all LEDS (default). + * Ps = 1 -> Light Num Lock. + * Ps = 2 -> Light Caps Lock. + * Ps = 3 -> Light Scroll Lock. + * Ps = 2 1 -> Extinguish Num Lock. + * Ps = 2 2 -> Extinguish Caps Lock. + * Ps = 2 3 -> Extinguish Scroll Lock. + */ +Terminal.prototype.loadLEDs = function (params) { + ; +}; +/** + * CSI Ps SP q + * Set cursor style (DECSCUSR, VT520). + * Ps = 0 -> blinking block. + * Ps = 1 -> blinking block (default). + * Ps = 2 -> steady block. + * Ps = 3 -> blinking underline. + * Ps = 4 -> steady underline. + */ +Terminal.prototype.setCursorStyle = function (params) { + ; +}; +/** + * CSI Ps " q + * Select character protection attribute (DECSCA). Valid values + * for the parameter: + * Ps = 0 -> DECSED and DECSEL can erase (default). + * Ps = 1 -> DECSED and DECSEL cannot erase. + * Ps = 2 -> DECSED and DECSEL can erase. + */ +Terminal.prototype.setCharProtectionAttr = function (params) { + ; +}; +/** + * CSI ? Pm r + * Restore DEC Private Mode Values. The value of Ps previously + * saved is restored. Ps values are the same as for DECSET. + */ +Terminal.prototype.restorePrivateValues = function (params) { + ; +}; +/** + * CSI Pt; Pl; Pb; Pr; Ps$ r + * Change Attributes in Rectangular Area (DECCARA), VT400 and up. + * Pt; Pl; Pb; Pr denotes the rectangle. + * Ps denotes the SGR attributes to change: 0, 1, 4, 5, 7. + * NOTE: xterm doesn't enable this code by default. + */ +Terminal.prototype.setAttrInRectangle = function (params) { + var t = params[0], l = params[1], b = params[2], r = params[3], attr = params[4]; + var line, i; + for (; t < b + 1; t++) { + line = this.lines[this.ybase + t]; + for (i = l; i < r; i++) { + line[i] = [attr, line[i][1]]; + } + } + // this.maxRange(); + this.updateRange(params[0]); + this.updateRange(params[2]); +}; +/** + * CSI Pc; Pt; Pl; Pb; Pr$ x + * Fill Rectangular Area (DECFRA), VT420 and up. + * Pc is the character to use. + * Pt; Pl; Pb; Pr denotes the rectangle. + * NOTE: xterm doesn't enable this code by default. + */ +Terminal.prototype.fillRectangle = function (params) { + var ch = params[0], t = params[1], l = params[2], b = params[3], r = params[4]; + var line, i; + for (; t < b + 1; t++) { + line = this.lines[this.ybase + t]; + for (i = l; i < r; i++) { + line[i] = [line[i][0], String.fromCharCode(ch)]; + } + } + // this.maxRange(); + this.updateRange(params[1]); + this.updateRange(params[3]); +}; +/** + * CSI Ps ; Pu ' z + * Enable Locator Reporting (DECELR). + * Valid values for the first parameter: + * Ps = 0 -> Locator disabled (default). + * Ps = 1 -> Locator enabled. + * Ps = 2 -> Locator enabled for one report, then disabled. + * The second parameter specifies the coordinate unit for locator + * reports. + * Valid values for the second parameter: + * Pu = 0 <- or omitted -> default to character cells. + * Pu = 1 <- device physical pixels. + * Pu = 2 <- character cells. + */ +Terminal.prototype.enableLocatorReporting = function (params) { + var val = params[0] > 0; + //this.mouseEvents = val; + //this.decLocator = val; +}; +/** + * CSI Pt; Pl; Pb; Pr$ z + * Erase Rectangular Area (DECERA), VT400 and up. + * Pt; Pl; Pb; Pr denotes the rectangle. + * NOTE: xterm doesn't enable this code by default. + */ +Terminal.prototype.eraseRectangle = function (params) { + var t = params[0], l = params[1], b = params[2], r = params[3]; + var line, i, ch; + ch = [this.eraseAttr(), ' ', 1]; // xterm? + for (; t < b + 1; t++) { + line = this.lines[this.ybase + t]; + for (i = l; i < r; i++) { + line[i] = ch; + } + } + // this.maxRange(); + this.updateRange(params[0]); + this.updateRange(params[2]); +}; +/** + * CSI P m SP } + * Insert P s Column(s) (default = 1) (DECIC), VT420 and up. + * NOTE: xterm doesn't enable this code by default. + */ +Terminal.prototype.insertColumns = function () { + var param = params[0], l = this.ybase + this.rows, ch = [this.eraseAttr(), ' ', 1] // xterm? + , i; + while (param--) { + for (i = this.ybase; i < l; i++) { + this.lines[i].splice(this.x + 1, 0, ch); + this.lines[i].pop(); + } + } + this.maxRange(); +}; +/** + * CSI P m SP ~ + * Delete P s Column(s) (default = 1) (DECDC), VT420 and up + * NOTE: xterm doesn't enable this code by default. + */ +Terminal.prototype.deleteColumns = function () { + var param = params[0], l = this.ybase + this.rows, ch = [this.eraseAttr(), ' ', 1] // xterm? + , i; + while (param--) { + for (i = this.ybase; i < l; i++) { + this.lines[i].splice(this.x, 1); + this.lines[i].push(ch); + } + } + this.maxRange(); +}; +/** + * Character Sets + */ +Terminal.charsets = {}; +// DEC Special Character and Line Drawing Set. +// http://vt100.net/docs/vt102-ug/table5-13.html +// A lot of curses apps use this if they see TERM=xterm. +// testing: echo -e '\e(0a\e(B' +// The xterm output sometimes seems to conflict with the +// reference above. xterm seems in line with the reference +// when running vttest however. +// The table below now uses xterm's output from vttest. +Terminal.charsets.SCLD = { + '`': '\u25c6', + 'a': '\u2592', + 'b': '\u0009', + 'c': '\u000c', + 'd': '\u000d', + 'e': '\u000a', + 'f': '\u00b0', + 'g': '\u00b1', + 'h': '\u2424', + 'i': '\u000b', + 'j': '\u2518', + 'k': '\u2510', + 'l': '\u250c', + 'm': '\u2514', + 'n': '\u253c', + 'o': '\u23ba', + 'p': '\u23bb', + 'q': '\u2500', + 'r': '\u23bc', + 's': '\u23bd', + 't': '\u251c', + 'u': '\u2524', + 'v': '\u2534', + 'w': '\u252c', + 'x': '\u2502', + 'y': '\u2264', + 'z': '\u2265', + '{': '\u03c0', + '|': '\u2260', + '}': '\u00a3', + '~': '\u00b7' // '·' +}; +Terminal.charsets.UK = null; // (A +Terminal.charsets.US = null; // (B (USASCII) +Terminal.charsets.Dutch = null; // (4 +Terminal.charsets.Finnish = null; // (C or (5 +Terminal.charsets.French = null; // (R +Terminal.charsets.FrenchCanadian = null; // (Q +Terminal.charsets.German = null; // (K +Terminal.charsets.Italian = null; // (Y +Terminal.charsets.NorwegianDanish = null; // (E or (6 +Terminal.charsets.Spanish = null; // (Z +Terminal.charsets.Swedish = null; // (H or (7 +Terminal.charsets.Swiss = null; // (= +Terminal.charsets.ISOLatin = null; // /A +/** + * Helpers + */ +function on(el, type, handler, capture) { + if (!Array.isArray(el)) { + el = [el]; + } + el.forEach(function (element) { + element.addEventListener(type, handler, capture || false); + }); +} +function off(el, type, handler, capture) { + el.removeEventListener(type, handler, capture || false); +} +function cancel(ev, force) { + if (!this.cancelEvents && !force) { + return; + } + ev.preventDefault(); + ev.stopPropagation(); + return false; +} +function inherits(child, parent) { + function f() { + this.constructor = child; + } + f.prototype = parent.prototype; + child.prototype = new f; +} +// if bold is broken, we can't +// use it in the terminal. +function isBoldBroken(document) { + var body = document.getElementsByTagName('body')[0]; + var el = document.createElement('span'); + el.innerHTML = 'hello world'; + body.appendChild(el); + var w1 = el.scrollWidth; + el.style.fontWeight = 'bold'; + var w2 = el.scrollWidth; + body.removeChild(el); + return w1 !== w2; +} +function indexOf(obj, el) { + var i = obj.length; + while (i--) { + if (obj[i] === el) + return i; + } + return -1; +} +function isThirdLevelShift(term, ev) { + var thirdLevelKey = (term.browser.isMac && ev.altKey && !ev.ctrlKey && !ev.metaKey) || + (term.browser.isMSWindows && ev.altKey && ev.ctrlKey && !ev.metaKey); + if (ev.type == 'keypress') { + return thirdLevelKey; + } + // Don't invoke for arrows, pageDown, home, backspace, etc. (on non-keypress events) + return thirdLevelKey && (!ev.keyCode || ev.keyCode > 47); +} +function matchColor(r1, g1, b1) { + var hash = (r1 << 16) | (g1 << 8) | b1; + if (matchColor._cache[hash] != null) { + return matchColor._cache[hash]; + } + var ldiff = Infinity, li = -1, i = 0, c, r2, g2, b2, diff; + for (; i < Terminal.vcolors.length; i++) { + c = Terminal.vcolors[i]; + r2 = c[0]; + g2 = c[1]; + b2 = c[2]; + diff = matchColor.distance(r1, g1, b1, r2, g2, b2); + if (diff === 0) { + li = i; + break; + } + if (diff < ldiff) { + ldiff = diff; + li = i; + } + } + return matchColor._cache[hash] = li; +} +matchColor._cache = {}; +// http://stackoverflow.com/questions/1633828 +matchColor.distance = function (r1, g1, b1, r2, g2, b2) { + return Math.pow(30 * (r1 - r2), 2) + + Math.pow(59 * (g1 - g2), 2) + + Math.pow(11 * (b1 - b2), 2); +}; +function each(obj, iter, con) { + if (obj.forEach) + return obj.forEach(iter, con); + for (var i = 0; i < obj.length; i++) { + iter.call(con, obj[i], i, obj); + } +} +function keys(obj) { + if (Object.keys) + return Object.keys(obj); + var key, keys = []; + for (key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + keys.push(key); + } + } + return keys; +} +var wcwidth = (function (opts) { + // extracted from https://www.cl.cam.ac.uk/%7Emgk25/ucs/wcwidth.c + // combining characters + var COMBINING = [ + [0x0300, 0x036F], [0x0483, 0x0486], [0x0488, 0x0489], + [0x0591, 0x05BD], [0x05BF, 0x05BF], [0x05C1, 0x05C2], + [0x05C4, 0x05C5], [0x05C7, 0x05C7], [0x0600, 0x0603], + [0x0610, 0x0615], [0x064B, 0x065E], [0x0670, 0x0670], + [0x06D6, 0x06E4], [0x06E7, 0x06E8], [0x06EA, 0x06ED], + [0x070F, 0x070F], [0x0711, 0x0711], [0x0730, 0x074A], + [0x07A6, 0x07B0], [0x07EB, 0x07F3], [0x0901, 0x0902], + [0x093C, 0x093C], [0x0941, 0x0948], [0x094D, 0x094D], + [0x0951, 0x0954], [0x0962, 0x0963], [0x0981, 0x0981], + [0x09BC, 0x09BC], [0x09C1, 0x09C4], [0x09CD, 0x09CD], + [0x09E2, 0x09E3], [0x0A01, 0x0A02], [0x0A3C, 0x0A3C], + [0x0A41, 0x0A42], [0x0A47, 0x0A48], [0x0A4B, 0x0A4D], + [0x0A70, 0x0A71], [0x0A81, 0x0A82], [0x0ABC, 0x0ABC], + [0x0AC1, 0x0AC5], [0x0AC7, 0x0AC8], [0x0ACD, 0x0ACD], + [0x0AE2, 0x0AE3], [0x0B01, 0x0B01], [0x0B3C, 0x0B3C], + [0x0B3F, 0x0B3F], [0x0B41, 0x0B43], [0x0B4D, 0x0B4D], + [0x0B56, 0x0B56], [0x0B82, 0x0B82], [0x0BC0, 0x0BC0], + [0x0BCD, 0x0BCD], [0x0C3E, 0x0C40], [0x0C46, 0x0C48], + [0x0C4A, 0x0C4D], [0x0C55, 0x0C56], [0x0CBC, 0x0CBC], + [0x0CBF, 0x0CBF], [0x0CC6, 0x0CC6], [0x0CCC, 0x0CCD], + [0x0CE2, 0x0CE3], [0x0D41, 0x0D43], [0x0D4D, 0x0D4D], + [0x0DCA, 0x0DCA], [0x0DD2, 0x0DD4], [0x0DD6, 0x0DD6], + [0x0E31, 0x0E31], [0x0E34, 0x0E3A], [0x0E47, 0x0E4E], + [0x0EB1, 0x0EB1], [0x0EB4, 0x0EB9], [0x0EBB, 0x0EBC], + [0x0EC8, 0x0ECD], [0x0F18, 0x0F19], [0x0F35, 0x0F35], + [0x0F37, 0x0F37], [0x0F39, 0x0F39], [0x0F71, 0x0F7E], + [0x0F80, 0x0F84], [0x0F86, 0x0F87], [0x0F90, 0x0F97], + [0x0F99, 0x0FBC], [0x0FC6, 0x0FC6], [0x102D, 0x1030], + [0x1032, 0x1032], [0x1036, 0x1037], [0x1039, 0x1039], + [0x1058, 0x1059], [0x1160, 0x11FF], [0x135F, 0x135F], + [0x1712, 0x1714], [0x1732, 0x1734], [0x1752, 0x1753], + [0x1772, 0x1773], [0x17B4, 0x17B5], [0x17B7, 0x17BD], + [0x17C6, 0x17C6], [0x17C9, 0x17D3], [0x17DD, 0x17DD], + [0x180B, 0x180D], [0x18A9, 0x18A9], [0x1920, 0x1922], + [0x1927, 0x1928], [0x1932, 0x1932], [0x1939, 0x193B], + [0x1A17, 0x1A18], [0x1B00, 0x1B03], [0x1B34, 0x1B34], + [0x1B36, 0x1B3A], [0x1B3C, 0x1B3C], [0x1B42, 0x1B42], + [0x1B6B, 0x1B73], [0x1DC0, 0x1DCA], [0x1DFE, 0x1DFF], + [0x200B, 0x200F], [0x202A, 0x202E], [0x2060, 0x2063], + [0x206A, 0x206F], [0x20D0, 0x20EF], [0x302A, 0x302F], + [0x3099, 0x309A], [0xA806, 0xA806], [0xA80B, 0xA80B], + [0xA825, 0xA826], [0xFB1E, 0xFB1E], [0xFE00, 0xFE0F], + [0xFE20, 0xFE23], [0xFEFF, 0xFEFF], [0xFFF9, 0xFFFB], + [0x10A01, 0x10A03], [0x10A05, 0x10A06], [0x10A0C, 0x10A0F], + [0x10A38, 0x10A3A], [0x10A3F, 0x10A3F], [0x1D167, 0x1D169], + [0x1D173, 0x1D182], [0x1D185, 0x1D18B], [0x1D1AA, 0x1D1AD], + [0x1D242, 0x1D244], [0xE0001, 0xE0001], [0xE0020, 0xE007F], + [0xE0100, 0xE01EF] + ]; + // binary search + function bisearch(ucs) { + var min = 0; + var max = COMBINING.length - 1; + var mid; + if (ucs < COMBINING[0][0] || ucs > COMBINING[max][1]) + return false; + while (max >= min) { + mid = Math.floor((min + max) / 2); + if (ucs > COMBINING[mid][1]) + min = mid + 1; + else if (ucs < COMBINING[mid][0]) + max = mid - 1; + else + return true; + } + return false; + } + function wcwidth(ucs) { + // test for 8-bit control characters + if (ucs === 0) + return opts.nul; + if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0)) + return opts.control; + // binary search in table of non-spacing characters + if (bisearch(ucs)) + return 0; + // if we arrive here, ucs is not a combining or C0/C1 control character + return 1 + + (ucs >= 0x1100 && + (ucs <= 0x115f || + ucs == 0x2329 || + ucs == 0x232a || + (ucs >= 0x2e80 && ucs <= 0xa4cf && ucs != 0x303f) || + (ucs >= 0xac00 && ucs <= 0xd7a3) || + (ucs >= 0xf900 && ucs <= 0xfaff) || + (ucs >= 0xfe10 && ucs <= 0xfe19) || + (ucs >= 0xfe30 && ucs <= 0xfe6f) || + (ucs >= 0xff00 && ucs <= 0xff60) || + (ucs >= 0xffe0 && ucs <= 0xffe6) || + (ucs >= 0x20000 && ucs <= 0x2fffd) || + (ucs >= 0x30000 && ucs <= 0x3fffd))); + } + return wcwidth; +})({ nul: 0, control: 0 }); // configurable options +/** + * Expose + */ +Terminal.EventEmitter = EventEmitter_js_1.EventEmitter; +Terminal.inherits = inherits; +/** + * Adds an event listener to the terminal. + * + * @param {string} event The name of the event. TODO: Document all event types + * @param {function} callback The function to call when the event is triggered. + */ +Terminal.on = on; +Terminal.off = off; +Terminal.cancel = cancel; +module.exports = Terminal; + +},{"./CompositionHelper.js":1,"./EventEmitter.js":2,"./Viewport.js":3,"./handlers/Clipboard.js":4,"./utils/Browser":5}]},{},[7])(7) +}); +//# sourceMappingURL=xterm.js.map diff --git a/tags.md b/tags.md new file mode 100644 index 0000000..20c448f --- /dev/null +++ b/tags.md @@ -0,0 +1,29 @@ +--- +layout: page +title: Index +permalink: /tags/ +--- + +
+
+ {% for tag in site.tags %} + + {% endfor %} +
+
+
+ {% for tag in site.tags %} +

{{ tag[0] }}

+ + {% endfor %} +
+