diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8bb4d42 --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +all: + hugo -d /opt/www/new.coredns.io + +.PHONY: clean +clean: + rm -rf /opt/www/new.coredns.io/* + +.PHONY: test +test: + hugo server diff --git a/README.md b/README.md new file mode 100644 index 0000000..7cc8e5b --- /dev/null +++ b/README.md @@ -0,0 +1,41 @@ +# coredns.io + +Purpose: + +1. What is CoreDNS? +1. How to use it? +1. How to get involved and get help. + +The website is created with HUGO, you'll need to download and install that if you want to locally +work on the website. For creating new content it is not needed. + +We have three types of pages. + +* Home - `themes/coredns/layouts/index.html` +* Blog/News/Documentation - `content/blog/*` (depends on params, see `archetypes`) +* Middleware - `content/middleware/*` and `content/exmiddleware/*` + +Any blog post you'll tag with 'documentation' will also become visible on the "Documentation" +link on the website. + +Releases should be tagged with 'release = "number" and `data/coredns.toml` should be updated +with the number. + +`data/subtext.toml` controls the buttons for "Docs", "Middleware" and "External Middleware". + +Create: + +* new release: `hugo new -k release blog/coredns-.md` +* new blog: `hugo new -k blog blog/coredns-.md` +* new blog that will also be documentation: `hugo new -k doc blog/coredns-.md` + +## Colors + +Dark: #280071 (40, 0, 113) +Middle: #5F259F (95, 37, 159) +Light: #8246AF (130, 70, 175) + +## Popup + +See the top-level (i.e. not in the themes directory) layout/partials/popup.html for adjusting the +text. diff --git a/archetypes/blog.md b/archetypes/blog.md new file mode 100644 index 0000000..d5cdd5c --- /dev/null +++ b/archetypes/blog.md @@ -0,0 +1,8 @@ ++++ +title = "" +description = "" +tags = [""] +draft = false +date = "{{ .Date }}" +author = "joe" ++++ diff --git a/archetypes/default.md b/archetypes/default.md new file mode 100644 index 0000000..f5a9e45 --- /dev/null +++ b/archetypes/default.md @@ -0,0 +1,6 @@ +--- +title: "{{ replace .TranslationBaseName "-" " " | title }}" +date: {{ .Date }} +draft: true +--- + diff --git a/archetypes/docs.md b/archetypes/docs.md new file mode 100644 index 0000000..247187a --- /dev/null +++ b/archetypes/docs.md @@ -0,0 +1,8 @@ ++++ +title = "" +description = "" +tags = ["Documentation"] +draft = false +date = "{{ .Date }}" +author = "joe" ++++ diff --git a/archetypes/release.md b/archetypes/release.md new file mode 100644 index 0000000..4c58f68 --- /dev/null +++ b/archetypes/release.md @@ -0,0 +1,9 @@ ++++ +title = "" +description = "" +tags = [""] +draft = false +release = "001" +date = "{{ .Date }}" +author = "joe" ++++ diff --git a/bin/readme-to-hugo.sh b/bin/readme-to-hugo.sh new file mode 100755 index 0000000..680749e --- /dev/null +++ b/bin/readme-to-hugo.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# Copy the /README.md to middleware/.md, add +# some Hugo meta data end let Hugo render it. + +weight=1 +tags="middleware" + +function header() { + local middleware=$1 + local title=$2 + local description=$3 + + echo "+++" + echo "title = \"$title\"" + echo "description = \"$description\"" + echo "weight = $weight" + echo "tags = [ " \"$tags\" "," \"$middleware\" "]" + echo "categories = [ \"middleware\" ]" + echo "date = \"$(date --iso-8601=seconds)\"" + echo "+++" +} + +function parse() { + local file="$1" + local middleware=$(basename $(dirname $file)) + local state="title" + local description="" + local rest="" + + while IFS= read -r line; do + if [[ $state == "title" ]]; then + title=${line#\# } + state="skip" + continue + fi + + if [[ $state == "skip" ]]; then + [[ -z "$line" ]] && continue + state="description" + fi + + if [[ $state == "description" ]]; then + if [[ -z "$line" ]]; then + state="rest" + continue + fi + description+="$line " + fi + + if [[ $state == "rest" ]]; then + # stupid shell to-readd newline + rest+="$line +" + fi + done < $file + + header $middleware "$title" "$description" + echo + echo "$rest" +} + +if [[ -z "$1" ]]; then + echo $0: Need containing directory of CoreDNS middleware + exit 1 +fi + +content="../content/middleware" +if [[ ! -e "$content" ]]; then + echo $0: Need to be run from the site\'s bin directory + exit 1 +fi + +for dir in "$1"/*; do + file=$dir/README.md + if [[ ! -e $file ]]; then continue; fi + middleware=$(basename $(dirname $file)) + + echo $middleware.md >&2 + echo $file >&2 + parse $file > $content/$middleware.md + weight=$((weight + 1)) +done diff --git a/config.toml b/config.toml new file mode 100644 index 0000000..720f082 --- /dev/null +++ b/config.toml @@ -0,0 +1,59 @@ +baseurl = "https://new.coredns.io/" # CHANGE WHEN DONE TODO(miek) +languageCode = "en-us" +title = "CoreDNS: DNS and Service Discovery" +copyright = "CoreDNS - All Rights Reserved" +theme = "coredns" + +[permalinks] + blog = "/:year/:month/:day/:title/" + page = "/:title/" + +[params] + popup = "" # enable with non empty string to show banner on home page + logo = "/images/CoreDNS_Colour_Icon.png" + twitter = "https://twitter.com/corednsio" + github = "https://github.com/coredns/coredns" + email = "info@coredns.io" + +[params.authors.miek] + name = "Miek Gieben" + location = "London" + email = "miek@miek.nl" + twitter = "https://twitter.com/miekg" + github = "https://github.com/miekg" + +[params.authors.john] + name = "John Belamaric" + location = "Washington DC" + email = "jbelamaric@infoblox.com" + twitter = "https://twitter.com/johnbelamaric" + github = "https://github.com/johnbelamaric" + +[params.authors.chris] + name = "Chris O'Haver" + location = "Annapolis, MD" + email = "cohaver@infoblox.com" + twitter = "https://twitter.com/chrisohaver" + github = "https://github.com/chrisohaver" + +[[menu.main]] + name = "Middleware" + weight = -200 + url = "/middleware/" +[[menu.main]] + name = "External Middleware" + weight = -190 + url = "/exmiddleware/" + external = "" +[[menu.main]] + name = "Blog" + weight = -180 + url = "/blog/" +[[menu.main]] + name = "Docs" + weight = -160 + url = "/tags/documentation/" +[[menu.main]] + name = "Community" + weight = -120 + url = "/community/" diff --git a/content/.gitempty b/content/.gitempty new file mode 100644 index 0000000..e69de29 diff --git a/content/blog/add-external.md b/content/blog/add-external.md new file mode 100644 index 0000000..7696b82 --- /dev/null +++ b/content/blog/add-external.md @@ -0,0 +1,34 @@ ++++ +date = "2017-07-23T21:28:13Z" +description = "How to add a link to external middleware?" +tags = ["Middleware", "External", "Add"] +title = "Add External Middleware" +author = "miek" ++++ + +If you want to have your external middleware listed here send an email to the coredns-discuss email +list with the details or create [a pull request](https;//github.com/coredns/coredns.io). + +In that email or pull request you'll need to add a file to `content/blog/exmiddleware/` that looks +like this: + +~~~ txt ++++ +title = "" +description = "** is a ..." +weight = 10 +tags = [ "middleware" , "" ] +categories = [ "middleware", "external" ] +date = "2017-07-22T12:37:19+01:00" +repo = "link-to-your-repo" +home = "link-to-your-homepage" ++++ + +The ** middleware is a ... + + +~~~ + +See [example.md for an example] +(https://github.com/coredns/new.coredns.io/blob/master/content/exmiddleware/example.md) on how to do +this. diff --git a/content/blog/cncf.md b/content/blog/cncf.md new file mode 100644 index 0000000..1bb1a66 --- /dev/null +++ b/content/blog/cncf.md @@ -0,0 +1,32 @@ ++++ +date = "2017-03-02T18:00:00Z" +description = "CoreDNS is now a Cloud Native Computing Foundation project." +tags = ["Kubernetes", "Service", "Discovery", "Kube-DNS"] +title = "Why CNCF for CoreDNS?" +author = "john" ++++ + +CoreDNS has been accepted into the [Cloud Native Computing Foundation](https://cncf.io) as an +inception project! We figure some of you may be wondering why we proposed CoreDNS as a CNCF +project, so we wrote this blog entry. + +Our goal is to make CoreDNS *the* cloud-native DNS server and service discovery solution. The +CNCF as an organization is focused on the advancement of cloud-native architectures. So, to us, +this is an excellent match. Service discovery is a key component of the [CNCF cloud-native landscape](https://raw.githubusercontent.com/cncf/landscape/master/landscape/CloudNativeLandscape_v0.9.3.jpg), and this is +a role in which CoreDNS excels. + +We hope this added visibility will attract more users and contributors to grow the project. And we +will be active in promoting CoreDNS, like in the up coming +[CloudNative/KubeCon](http://events.linuxfoundation.org/events/cloudnativecon-and-kubecon-europe). + +CNCF provides a lot of support - evidence of which you can already see in our new logo, which was +designed by the team at the Linux Foundation (of which CNCF is a part). As a CNCF project, we will +have space at CloudNativeCon/KubeCon and other events to interact with users and get feedback on +how the community is using CoreDNS. Additionally, we gain access to deep experience and wide ranging use +cases of the CNCF end user community. This helps inform the future development of CoreDNS, ensuring +that we move in directions that solve meaningful problems in cloud-native architectures. + +We are also planning to take advantage of the [CNCF cluster](https://www.cncf.io/cluster), which will +allow us to really push the scale limits of CoreDNS when operating against large Kubernetes clusters +or other high-scale environments. We need that kind of battle-testing to ensure CoreDNS becomes the +best option for cloud-native DNS and service discovery. diff --git a/content/blog/coredns-001.md b/content/blog/coredns-001.md new file mode 100644 index 0000000..b84460b --- /dev/null +++ b/content/blog/coredns-001.md @@ -0,0 +1,61 @@ ++++ +date = "2016-09-18T11:40:37+01:00" +description = "CoreDNS-001 Release Notes" +release = "001" +tags = ["Release", "001", "Notes"] +title = "CoreDNS-001 Release" +author = "miek" ++++ + +CoreDNS-001 has been [released](https://github.com/coredns/coredns/releases). This is the first +release! It provides a complete DNS server, that also does DNSSEC and is useful for service +discovery in cloud setups. + +# What is CoreDNS? + +[CoreDNS](https://coredns.io) is a DNS server that started its life as a fork of the [Caddy +web(!)server](https://caddyserver.com). + +It chains [middleware](https://github.com/coredns/coredns/tree/master/middleware), +where each middleware implements some DNS feature. CoreDNS is a complete replacement +(with more features, and maybe less bugs) for [SkyDNS](https://github.com/skynetservices/skydns). + +It is also useful as a normal DNS server, featuring DNSSEC, on-the-fly signing and zone transfers. + +# What is New + +CoreDNS is now a (the first!) server type plugin in Caddy - this means we can leverage a lot of code +from Caddy without having to fork (and maintain) it all. By doing so we were able to remove 9000 +lines of code from CoreDNS. + +The core (ghe!) of CoreDNS is now in a good shape. Future work will focus on making the +middleware better, e.g. the proxy implementation is slow and needs to be +[faster](https://github.com/coredns/coredns/issues/184). + +## New Middlewares + +* There is now a [specific + middleware](https://github.com/coredns/coredns/tree/master/middleware/kubernetes) to deal with [Kubernetes](https://kubernetes.io). +* The *bind* [middleware](https://github.com/coredns/coredns/tree/master/middleware/bind) allows you to bind to a specific IP address, instead of using the wildcard + address. +* A *whoami* [middleware](https://github.com/coredns/coredns/tree/master/middleware/whoami) reports + back your address and port. +* All other middlewares are reworked to fit in the new plugin framework from Caddy version 0.9 (and + up). + +The *whoami* middleware is also used when CoreDNS starts up and can't find a Corefile. + +# Contributors + +The following people helped with getting this release done: + +Cricket Liu, elcore, Félix Cantournet, Ilya Dmitrichenko, Joe Blow, Lee, Matt Layher, +Michael Richmond, Miek Gieben, pixelbender, Yong Tang. + +If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/) and start coding! + +# Documentation and Help + +The forum on has section for +[CoreDNS](https://forum.caddyserver.com/c/coredns), where you can submit questions and get answers. +Or use [Twitter](https://twitter.com/corednsio). diff --git a/content/blog/coredns-002.md b/content/blog/coredns-002.md new file mode 100644 index 0000000..62e6a49 --- /dev/null +++ b/content/blog/coredns-002.md @@ -0,0 +1,108 @@ ++++ +date = "2016-10-19T19:09:32Z" +description = "CoreDNS-002 Release Notes" +release = "002" +tags = ["Release", "002", "Notes"] +title = "CoreDNS-002 Release" +author = "miek" ++++ + +CoreDNS-002 has been [released](https://github.com/coredns/coredns/releases)! + +CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature. + +## What is New + +* `-port` was renamed to `-dns.port` to avoid clashing with Caddy's `-port` (which was renamed to + `http.port`). +* Lumberjack logger was removed, this means no built in log rotation; use an external tool for that. +* Brushed up GoDoc for all packages. +* Brushed up all READMEs to be more standard and look like manual page. +* Golint-ed and go vet-ed the code - these can now (somewhat) useful tools before submitting PRs. +* Add more tests and show test coverage on submitting/PRs. +* Various Corefile parsing bugs fixed, better syntax error detection. + +## Middleware improvements: + +* middleware/root: a root middleware, same usage as in [Caddy](https://caddyserver.com/docs/root). + See middleware/root/README.md for its use in CoreDNS. + This makes stanzas like this shorter: + + ~~~ txt + .:53 { + file /etc/coredns/zones/db.example.net example.net + file /etc/coredns/zones/db.example.org example.org + file /etc/coredns/zones/db.example.com example.com + } + ~~~ + + Can be written as: + + ~~~ txt + .:53 { + root /etc/coredns/zones + file db.example.net example.net + file db.example.org example.org + file db.example.com example.com + } + ~~~ + +* middleware/auto: similar to the *file* middleware, but automatically picks up new zones. + The following Corefile will load all zones found under `/etc/coredns/org` and be authoritative + for `.org.`: + + ~~~ txt + .:53 { + auto org { + directory /etc/coredns/org + } + } + ~~~ +* middleware/file: handle wildcards better. +* middleware/kubernetes: TLS support for kubernetes and other improvements. +* middleware/cache: use an LRU cache to make it memory bounded. Added more option to have more + control on what is cached and for how long. The cache stanza was extended: + + ~~~ txt + cache { + success CAPACITY [TTL] + denial CAPACITY [TTL] + } + ~~~ + + See middleware/cache/README.md for more details. + +* middleware/dnssec: replaced go-cache with golang-lru in dnssec. Also adds a `cache_capacity`. + option in dnssec middleware so that the capacity of the LRU cache could be specified in the config + file. +* middleware/logging: allow a response classs to be specified on log on responses matching the name *and* + the response class. For instance only log denials for example.com: + + ~~~ txt + log example.com stdout { + class denial + } + ~~~ + +* middleware/proxy: performance improvements. + +# Contributors + +The following people helped with getting this release done: + +Chris O'Haver, +Manuel de Brito Fontes, +Miek Gieben, +Shawn Smith, +Silas Baronda, +Yong Tang, +Zhipeng Jiang. + +If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/) +and start coding! + +# Documentation and Help + +The forum on has section for +[CoreDNS](https://forum.caddyserver.com/c/coredns), where you can submit questions and get answers. +Use [Twitter](https://twitter.com/corednsio), or file an issue. diff --git a/content/blog/coredns-003.md b/content/blog/coredns-003.md new file mode 100644 index 0000000..14a8b78 --- /dev/null +++ b/content/blog/coredns-003.md @@ -0,0 +1,54 @@ ++++ +date = "2016-11-11T16:38:32Z" +description = "CoreDNS-003 Release Notes" +release = "003" +tags = ["Release", "003", "Notes"] +title = "CoreDNS-003 Release" +author = "miek" ++++ + +CoreDNS-003 has been [released](https://github.com/coredns/coredns/releases)! + +CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature. + +# What is New + +## Core + +Refused queries are properly logged and exported if metrics are enabled. + +## Middleware improvements + +* *proxy*: allow `/etc/resolv.conf` to be used in the configuration. +* *metrics*: add tests and normalize some of the metrics. Removed the AXFR size metrics. +* *cache*: Added size and capacity of the cache (for both `denial` and `success` cache types). + Don't cache meta data records and zone transfers. +* *dnssec*: metrics were unused, hooked them up: export size and capacity of the signature cache. +* *loadbalance*: balance MX records as well. +* *auto*: numerous bugfixes. +* *file*: fix data race in reload process and also reload a zone when it is `mv`ed (newly created) into place. + Also rewrite the zone lookup algorithm and be more standards compliant, esp. in the area of DNSSEC, wildcards and empty-non-terminals; handle secure delegations. +* *kubernetes*: vender the k8s dependency and updates to be compatible with Kubernetes 1.4 and 1.5. + Multiple cleanups and fixes. Kubernetes services can now be resolved. + +# Contributors + +The following people helped with getting this release done: + +Ben Kochie, +Chris O'Haver, +John Belamaric, +Jonathan Dickinson, +Manuel Alejandro de Brito Fontes, +Michael Grosser, +Miek Gieben, +Yong Tang. + +If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/) +and start coding! + +# Documentation and Help + +The forum on has section for +[CoreDNS](https://forum.caddyserver.com/c/coredns), where you can submit questions and get answers. +Use [Twitter](https://twitter.com/corednsio), or file an issue. diff --git a/content/blog/coredns-004.md b/content/blog/coredns-004.md new file mode 100644 index 0000000..1f3b954 --- /dev/null +++ b/content/blog/coredns-004.md @@ -0,0 +1,49 @@ ++++ +date = "2017-01-01T10:30:31Z" +description = "CoreDNS-004 Release Notes" +release = "004" +tags = ["Release", "004", "Notes"] +title = "CoreDNS-004 Release" +author = "miek" ++++ + +CoreDNS-004 has been [released](https://github.com/coredns/coredns/releases/tag/v004)! + +CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature. + +# What is New + +## Core + +We are now also releasing an ARM build that can run on Raspberry Pi. + +## Middleware improvements + +* *file|auto*: resolve external CNAME when an upstream (new option) is specified. +* *file|auto*: allow port numbers for transfer from/to to be specified. +* *file|auto*: include zone's NSset in positive responses. +* *auto*: close files and don't leak file descriptors. +* *httpproxy*: new middleware that proxies to and resolves your requests over an encrypted connection. This middleware will probably be morphed into proxy at some point in the feature. Consider it experimental for the time being. +* *metrics*: `reponse_size_bytes` and `request_size_bytes` export the actual length of the packet, not the advertised bufsize. +* *log*: `{size}` is now the length in bytes of the request, `{rsize}` for the reply. Default logging is changed to show both. + +# Contributors + +The following people helped with getting this release done: + +Chris O'Haver, +Dmytro Kislov, +John Belamaric, +Mark Nevill, +Michael Grosser, +Miek Gieben, +Yong Tang. + +If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/) +and start coding! + +# Documentation and Help + +The forum on has section for +[CoreDNS](https://forum.caddyserver.com/c/coredns), where you can submit questions and get answers. +Use [Twitter](https://twitter.com/corednsio), or file an issue. diff --git a/content/blog/coredns-005.md b/content/blog/coredns-005.md new file mode 100644 index 0000000..d6cd518 --- /dev/null +++ b/content/blog/coredns-005.md @@ -0,0 +1,69 @@ ++++ +date = "2017-02-09T18:50:31Z" +description = "CoreDNS-005 Release Notes" +tags = ["Release", "005", "Notes"] +release = "005" +title = "CoreDNS-005 Release" +author = "miek" ++++ + +CoreDNS-005 has been [released](https://github.com/coredns/coredns/releases/tag/v005)! + +CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature. + +# What is New + +# Core + +A way to configure (external) middleware was added. Edit `middleware.cfg` and do a `go gen && go +build` and your middleware has been added. This allows for out-of-tree middleware to be easily +added. Documentation can be found in +[middleware.cfg](https://github.com/coredns/coredns/blob/master/middleware.cfg). + +## Middleware improvements + +### New + +* *erratic*: a new middleware that can drop queries, limited in the current functionality, but useful for testing. +* *trace*: a new middleware that implements OpenTracing-based tracing using Zipkin. + +### Improvements/changes + +* *proxy*: fix a bug when a connection hangs and never gets release (#467) +* *proxy*: Fold *httpproxy* into it, which is now a normal proxy with a special `protocol`. For + Monitoring an extra label was added: `proxy_proto` that shows the protocol used (`dns` or `https_google`). + See the [proxy README.md](https://github.com/coredns/coredns/blob/master/middleware/proxy/README.md) for details. +* *httpproxy*: removed because functionality is moved to *proxy*. +* *kubernetes*: Now implements the full + [Kubernetes DNS Specification](https://github.com/kubernetes/dns/blob/master/docs/specification.md), + including regular and headless services, endpoint hostnames, A, SRV, and PTR records. +* *kubernetes*: Implements the `pod` type for requests in both a Kube-DNS compatible mode + (`insecure`) and a mode which validates that the IP in question belongs to a pod in the specified + namespace (`verified`) +* *kubernetes*: Simplified the configuration of reverse zones. Instead of listing the zones in the + zone list, you can just add a list of CIDRs using the `cidrs` option. +* *rewrite*: allow rewriting more bits of the incoming packet. This required some backward + *incompatible* changes, e.g. a new **FIELD** keyword is now required. See the + [rewrite README.md](https://github.com/coredns/coredns/blob/master/middleware/rewrite/README.md) for details. + + +# Contributors + +The following people helped with getting this release done: + +Bob Wasniak, +Chris O'Haver, +devnev, +Dmytro Kislov, +John Belamaric, +Miek Gieben, +Yong Tang. + +If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/) +and start coding! + +# Documentation and Help + +The forum on has section for +[CoreDNS](https://forum.caddyserver.com/c/coredns), where you can submit questions and get answers. +Use [Twitter](https://twitter.com/corednsio), or file an issue. diff --git a/content/blog/coredns-006.md b/content/blog/coredns-006.md new file mode 100644 index 0000000..46dcc50 --- /dev/null +++ b/content/blog/coredns-006.md @@ -0,0 +1,60 @@ ++++ +date = "2017-02-22T21:26:11Z" +description = "CoreDNS-006 Release Notes" +tags = ["Release", "006", "Notes"] +release = "006" +title = "CoreDNS-006 Release" +author = "miek" ++++ + +CoreDNS-006 has been [released](https://github.com/coredns/coredns/releases/tag/v006)! + +CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature. + +# What is New + +# Core + +Move CoreDNS to together with several other repos. This will be +the new home for CoreDNS development. + +Fixed: + +* Fix hot-reloading. This would fail with `[ERROR] SIGUSR1: listen tcp :53: bind: address already in + use`. +* Allow removal of core middleware, see comments in + [middleware.cfg](https://github.com/miekg/coredns/blob/master/middleware.cfg). + +## Middleware improvements + +### New + +* *reverse* middleware: allows CoreDNS to respond dynamicly to an PTR request and the related + A/AAAA request. + +### Improvements/changes + +* *proxy* a new `protocol`: `grpc`: speak DNS over gRPC. Server side impl. resides [in this out of + tree middleware](https://github.com/coredns/grpc). +* *file* additional section processing for MX and SRV queries. +* *prometheus* fix hot reloading +* *trace* various improvements + +# Contributors + +The following people helped with getting this release done: + +John Belamaric, +Miek Gieben, +Richard Hillmann, +Yong Tang, + +If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/) +and start coding! + +# Documentation and Help + +The forum on has section for +[CoreDNS](https://forum.caddyserver.com/c/coredns), where you can submit questions and get answers. +Use [Twitter](https://twitter.com/corednsio), or file an issue. + diff --git a/content/blog/coredns-007.md b/content/blog/coredns-007.md new file mode 100644 index 0000000..555da74 --- /dev/null +++ b/content/blog/coredns-007.md @@ -0,0 +1,76 @@ ++++ +date = "2017-05-03T19:26:11Z" +description = "CoreDNS-007 Release Notes" +release = "007" +tags = ["Release", "007", "Notes"] +title = "CoreDNS-007 Release" +author = "miek" ++++ + +CoreDNS-007 has been [released](https://github.com/coredns/coredns/releases/tag/v007)! + +CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature. + +# News + +CoreDNS is accepted as an inception project by the [CNCF](https://cncf.io)! Which means a lot to us. +See [this blog post](https://blog.coredns.io/2017/03/02/why-cncf-for-coredns/) on why we wanted/did this. + +Because of this we moved repos: is the main overarching repo. There is +an automatic redirect in place from the old repo. + +And... We have a new logo! We're also discussion a website redesign for and +this blog. + +Back to the release. + +# Core + +* `ServeDNS` is extended to take a context. This allows (for instance) tracing to start at an earlier entrypoint. +* gRPC and TLS are made first class citizens. See [the zone + specification](https://github.com/coredns/coredns/blob/master/README.md#zone-specification) on how + to use it. TL;DR using `grpc://` makes the server talk gRPC. The `tls` directive is used to + specify TLS certifcates. +* Zipkin tracing can be enabled for all middleware. + +# Middleware + +* *rewrite* now allows you to add or modify EDNS0 local or NSID options. The framework is in place to add additional EDNS0 types in the future. +* *etcd* when no upstreams are defined won't default to using 8.8.8.8, 8.8.4.4; it just does not resolve external names in that case. +* *erratic* now can also delay queries and send queries with Truncated set. +* *metrics* will happily start as many (different) listeners as you want (if you really need that). +* *startup* and *shutdown* allow for command to be run during startup or shutdown. These directly use the code from Caddy, see [Caddy's docs](https://caddyserver.com/docs/startup). +* *kubernetes* now implements a `fallthrough` option to pass queries that would result in NXDOMAIN + to the next middleware, even if the query is in the cluster domain. This enables custom DNS + entries in the cluster domain (as long as they do not overlap with a normal Kubernetes record). To + facilitate this the middleware ordering is also altered to put *kubernetes* in the chain before + other backends. +* *cache* will no longer cache RRSIGs that will expire while cached. + +# Contributors + +The following people helped with getting this release done: + +Chris Aniszczyk, +Chris O'Haver, +Christoph Görn, +Dominic, +John Belamaric, +Jonathan Boulle, +Michael, +Michael S. Fischer, +Miek Gieben, +Yong Tang, +Yue Ko. + +If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/) +and start coding! + +## Community + +You find CoreDNS's community in the following places: + +- Mailing list/group: +- Slack: #coredns on +- Twitter: [@corednsio](https://twitter.com/corednsio) +- Github: diff --git a/content/blog/coredns-008.md b/content/blog/coredns-008.md new file mode 100644 index 0000000..c7c5fb3 --- /dev/null +++ b/content/blog/coredns-008.md @@ -0,0 +1,73 @@ ++++ +date = "2017-06-14T22:52:11Z" +description = "CoreDNS-008 Release Notes" +release = "008" +tags = ["Release", "008", "Notes"] +title = "CoreDNS-008 Release" +author = "john" ++++ + +CoreDNS-008 has been [released](https://github.com/coredns/coredns/releases/tag/v008)! + +CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature. + +Release v008 has a lot of content, with new middleware and major features added to existing middleware. + +Please note there is an *incompatible* change to the `log` directive - it now only logs to `stdout` and so +only allows `stdout` as the file name (which of course may be omitted). + +# Core + +* `-log` flag was changed into a boolean as all logging will be written to standard output. + +# Middleware + +## New + +* *hosts* allows CoreDNS to read a `/etc/hosts` styled file and generate responses from that. +* *debug* can disable the `panic/recover` that is enabled by default. Mostly useful for testing/non-prod use cases to generate stack traces. + +## Updates + +* *chaos* now returns the correct `version.bind` `TXT` record. +* *kubernetes* + * Now returns a proper NS record for the cluster domain + * Supports `ExternalName` services, which was an oversight in the 1.0.0 version of the [Kubernetes dns spec](https://github.com/kubernetes/dns/blob/master/docs/specification.md) + * Now supports federation records + * Has had some other bug fixes. +* *file* + * Now supports DNAME [RFC 6672](https://tools.ietf.org/html/rfc6672) + * Refuse to load a zone without a SOA record. +* *file, auto* don't reload a zone when the SOA's serial hasn't changed. +* *secondary* now behaves properly if queried before the zone has been transferred +* *log, errors* output everything to *stdout* and let `journald` or `docker` (or whatever) that care of further handling. This is backwards **incompatible** change wrt to the Corefile: `log query.log` will return an error. +* *cache* got a new cache implementation to be more scalable and a new `prefetch` option for fetching records before the TTL expires. +* *proxy* does not use `singleinflight` anymore, removing a potential bottleneck on the single mutex in that implementation; it now forwards *all* queries it get to the upstream nameserver. + + +# Contributors + +The following people helped with getting this release done: + +Chris Aniszczyk, +Chris O'Haver, +cricketliu, +Eric Yan, +John Belamaric, +Jonas Östanbäck, +Manuel Alejandro de Brito Fontes, +Miek Gieben, +Pat Moroney, +Yong Tang + +If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/) +and start coding! + +## Community + +You find CoreDNS's community in the following places: + +- Mailing list/group: +- Slack: #coredns on +- Twitter: [@corednsio](https://twitter.com/corednsio) +- Github: diff --git a/content/blog/coredns-009.md b/content/blog/coredns-009.md new file mode 100644 index 0000000..10bfabc --- /dev/null +++ b/content/blog/coredns-009.md @@ -0,0 +1,54 @@ ++++ +date = "2017-07-13T22:52:11Z" +release = "009" +description = "CoreDNS-009 Release Notes" +tags = ["Release", "009", "Notes"] +title = "CoreDNS-009 Release" +author = "miek" ++++ + +CoreDNS-009 has been [released](https://github.com/coredns/coredns/releases/tag/v009)! + +CoreDNS is a DNS server that chains middleware, where each middleware implements a DNS feature. + +Release v009 is mostly a bugfix release, with a few new features in the middleware. + +# Core + +No changes. + +# Middleware + +* *secondary*: fix functionality and improve matching of notify queries. +* *cache*: fix data race. +* *proxy*: async healthchecks. +* *reverse*: new option `wildcard` that also catches all subdomains of a template. +* *kubernetes*: experimental new option `autopath` that optimizes the search path and ndots + combinatorial explosion, so clients with a large search path and high ndots will get a reply on + the first query. + +# Contributors + +The following people helped with getting this release done: + +Athir Nuaimi, +Chris O'Haver, +ghostflame, +jremond, +Mia Boulay, +Miek Gieben, +Ning Xie, +Roman Mazur, +Yong Tang. + +If you want to help, please check out one of the [issues](https://github.com/coredns/coredns/issues/) +and start coding! + +## Community + +You find CoreDNS's community in the following places: + +- Mailing list/group: +- Slack: #coredns on +- Twitter: [@corednsio](https://twitter.com/corednsio) +- Github: diff --git a/content/blog/coredns-and-caddy.md b/content/blog/coredns-and-caddy.md new file mode 100644 index 0000000..e1825cf --- /dev/null +++ b/content/blog/coredns-and-caddy.md @@ -0,0 +1,21 @@ ++++ +date = "2016-09-29T06:18:40Z" +description = "CoreDNS can now be downloaded from Caddy's download page" +tags = ["Caddy", "Bugs", "Questions"] +title = "CoreDNS and Caddy" +author = "miek" ++++ +[Caddy 0.9.3](https://forum.caddyserver.com/t/caddy-0-9-3-released/725) is released. On it's +[download page](https://caddyserver.com/download) you can now select the "DNS plugin" to be added +to Caddy! This is really nice and a culmination of all the work that has been put in to make this +happen. + +Note that if you select this option you get a binary that is *both* a DNS and webserver, during +startup you can select between the two with `-type=dns|http` flag. + +The CoreDNS developers will still provide their own (DNS only) binaries over [at +github](https://github.com/coredns/coredns/releases). + +Note that we *also* have a CoreDNS category on the [Caddy +forum](https://forum.caddyserver.com/c/coredns) where you can ask questions. Bugs and feature +requests are probably better directed to our [github](https://github.com/coredns/coredns). diff --git a/content/blog/coredns-history.md b/content/blog/coredns-history.md new file mode 100644 index 0000000..7cdaa5c --- /dev/null +++ b/content/blog/coredns-history.md @@ -0,0 +1,23 @@ ++++ +date = "2017-02-23T18:12:12Z" +title = "History of CoreDNS in four posts" +tags = ["CoreDNS","History","Caddy", "Documentation"] +description = "How CoreDNS Came Into Existence" +author = "miek" ++++ + +> Yes, at some point CoreDNS was actually a forked webserver doing DNS. + +This blog posts detail some of the early history of CoreDNS. + +Pondering if I should create someting ala Caddy, but then for DNS. I didn't have a name, +so it was "Caddy DNS" (or Daddy as some point): . + +This idea was good enough that I actually tried it out, resulting in the first queries answered +by "Caddy DNS": . + +Started to believe this "Caddy DNS" might actually be a thing I would work on: + + +Officially announcing CoreDNS: and dropping +the name "Caddy DNS". diff --git a/content/blog/coredns-middleware.md b/content/blog/coredns-middleware.md new file mode 100644 index 0000000..2cb5771 --- /dev/null +++ b/content/blog/coredns-middleware.md @@ -0,0 +1,185 @@ ++++ +date = "2016-12-19T08:00:24Z" +description = "A introduction into writing middleware for CoreDNS" +tags = ["middleware", "coredns", "plugins", "documentation"] +title = "Writing Middleware for CoreDNS" +author = "miek" ++++ + +As CoreDNS uses Caddy for setting up and using middleware, the process of writing middleware is +remarkably [similar](https://github.com/mholt/caddy/wiki/Writing-a-Plugin:-Directives). This post +slightly reworks (and simplifies in some cases) those pages. + +A new middleware adds new functionality to CoreDNS, i.e. *caching*, *metrics* and basic *zone* file +serving are all middlewares. + +If you want to write a new middleware and want it to be included by default, i.e. merged in the code +base please open an [issue](https://github.com/coredns/coredns/issues) first to discuss initial design +and other things that may come up. + +## How to Register a CoreDNS Middleware + +[Caddy](https://caddyserver.com) supports different type of plugins, CoreDNS, for instance, +registers itself as a Caddy server type plugin. CoreDNS currently supports one type of plugins; +a *middleware*. + +Start a new Go package with an init function. Then register your middleware: + +```go +import "github.com/mholt/caddy" + +func init() { + caddy.RegisterPlugin("foo", caddy.Plugin{ + ServerType: "dns", + Action: setup, + }) +} +``` + +Every middleware must have a name, `foo`, in this case. The *ServerType* must be `dns`. The *Action* +speficied here is to say it will call a function called `setup` whenever the *directive* `foo` is +encountered in the Corefile. + +### The Setup Function + +The *Action* field of the `caddy.Plugin` struct is what makes a directive plugin unique. This is the +function to run when CoreDNS is parsing and executing the Corefile. + +The action is simply a function that takes a caddy.Controller and returns an error: +(We use [middleware.Error](https://godoc.org/github.com/coredns/coredns/middleware#Error) to prefix +returned error with `middleware/foo: ` to improve error reporting). + +``` go +func setup(c *caddy.Controller) error { + if err != nil { + return middleware.Error("foo", err) + } + + return nil +} +``` + +It is the responsibility of the setup function to parse the directive's tokens and configure itself. +The [Controller struct](https://godoc.org/github.com/mholt/caddy#Controller) +makes this quite easy. If we expect a line in the Corefile such as: + +``` +foo gizmo +``` + +We can get the value of the first argument ("foobar") like so: + +```go +for c.Next() { // Skip the directive name. + if !c.NextArg() { // Expect at least one value. + return c.ArgErr() // Otherwise it's an error. + } + value := c.Val() // Use the value. +} +``` +You parse the tokens present for your directive by iterating over `c.Next()` which is true as long +as there are more tokens to parse. Since a directive may appear multiple times, you must iterate +over `c.Next()` to get all the appearances of your directive and consume the first token (which is the +directive name). + +### Adding to CoreDNS + +To plug your middleware into CoreDNS, import it. This is done in +[core/coredns.go](https://github.com/coredns/coredns/blob/master/core/coredns.go): + + +```go +import _ "your/plugin/package/path/here" +``` + +This makes CoreDNS compile your plugin, but it is still not available, so the second step is +to add it to [directives.go](https://github.com/coredns/coredns/blob/master/core/dnsserver/directives.go): + +Add the name (`foo`) of your middleware at the end of the file in the `directives` string slice. +Note the ordering is important, because this is determines how the plugins are chained together. + +## How DNS Middleware Works in CoreDNS + +Check out the [godoc for the middleware +package](http://godoc.org/github.com/coredns/coredns/middleware). The most important type is +[middleware.Handler](https://godoc.org/github.com/coredns/coredns/middleware#Handler). + +A `Handler` is a function that handles a DNS request. CoreDNS will do all the bookkeeping of setting +up an DNS server for you, but you need to implement these two types. + +### Writing a Handler + +`middleware.Handler` is an interface similar to `http.Handler` except that it deals with DNS and the +`ServeDNS` method returns `(int, error)`. The `int` is the DNS rcode, and the `error` is one that +should be handled and/or logged. Read the +[middleware.md](https://github.com/coredns/coredns/blob/master/middleware.md) doc for more details +about these return values. + +Handlers are usually a struct with at least one field, the next Handler in the chain: + +```go +type MyHandler struct { + Next middleware.Handler +} +``` + +To implement the `middleware.Handler` interface, we write a method called `ServeDNS`. +This method is the actual handler function, and, unless it fully handles the request by itself, it +should call the next handler in the chain: + +```go +func (h MyHandler) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + return h.Next.ServeDNS(ctx, w, r) +} +``` + +The interface also needs a method `func Name() string`, this is mainly used to see if an middleware +is active, i.e. the *auto* middleware used this to detect if *metrics* are active and if so, adds +updates the zone info. + +```go +func (h MyHandler) Name() string { return "foo" } +``` + +That's all there is to it. + +## How to Add the Handler to CoreDNS + +So, back in your setup function. You've just parsed the tokens and set up your middleware handler +with all the proper configuration: + +```go +func setup(c *caddy.Controller) error { + for c.Next() { + // Get configuration. + } + + // Now what? +} +``` + +To chain in your new handler, get the config for the current site from the dnsserver package. +Then wrap your handler in a middleware function: + +```go +cfg := dnsserver.GetConfig(c) +mid := func(next middleware.Handler) middleware.Handler { + return MyHandler{Next: next} +} +cfg.AddMiddleware(mid) +``` + +And you're done! Of course, in this example, we simply allocated a `MyHandler` with no special +configuration. It doesn't really matter as long as you chain in the `next` handler properly! + +## Examples + +Simple examples of middleware that can be found in CoreDNS are: + +* [root](https://godoc.org/github.com/coredns/coredns/middleware/root); does not register itself as + a middleware. It simply performs some setup. +* [chaos](https://godoc.org/github.com/coredns/coredns/middleware/chaos); a DNS middleware that + responds to `CH txt version.bind` requests. + +**Don't forget: the best documentation is the [godoc](https://godoc.org/github.com/coredns/coredns) +and the [code](https://github.com/coredns/coredns) itself!** diff --git a/content/blog/coredns-query-routing.md b/content/blog/coredns-query-routing.md new file mode 100644 index 0000000..a3de02c --- /dev/null +++ b/content/blog/coredns-query-routing.md @@ -0,0 +1,65 @@ ++++ +date = "2016-10-13T08:50:13Z" +description = "Which middleware will handle a query?" +tags = ["Corefile", "Query", "Routing", "Documentation"] +title = "Query Routing" +author = "miek" ++++ + +Quiz time, in the following Corefile: + +~~~ txt +. { + proxy . 8.8.8.8:53 + file db.example.com +} +~~~ + +Will a query for `www.google.com` be handled by the *proxy* or the *file* middleware? Answer below. + +What does this Corefile actually say? It specifies that queries for root (`.`) and *everything* +below it (so for all domain names) we should enter this stanza. + +Next *all* queries should be forwarded to 8.8.8.8:53. + +Then because the *file* middleware **does not** specify what zones should be answered from the +`db.example.com` file, the toplevel one applies, which is root (`.`) + +So we are left with a situation where both middlewares will be called for the same names (which can +be perfectly valid for middleware that calls other chained-in middleware). + +But *proxy* **will not** call *file* because the query will be answered and done with after +the middleware exists - the same is true for the opposite direction. + +To look what into what happens here we have to look the [directives +ordering](https://github.com/coredns/coredns/blob/master/core/dnsserver/directives.go#L75): + +~~~ +... +"dnssec", +"file", +"secondary", +"etcd", +"kubernetes", +"proxy", +"whoami" +... +~~~ + +And we see that *file* is first and *proxy* comes somewhat later. This means that in the example +above *all* queries are routed to the *file* middleware. It will happily answer those with SERVFAIL, +because it probably can't find `www.google.com` in a file that will mostly have `*.example.com` +names in it. + +In order to fix this, we should either have to separate stanza or specify the origin(s) for the +*file* middleware: + +~~~ txt +. { + proxy . 8.8.8.8:53 + file db.example.com example.com +} +~~~ + +To preempt a feature request: Yes, it would be nice of CoreDNS can detect and warn about this (it +does not do this now). diff --git a/content/blog/corefile.md b/content/blog/corefile.md new file mode 100644 index 0000000..968acc5 --- /dev/null +++ b/content/blog/corefile.md @@ -0,0 +1,102 @@ ++++ +date = "2017-07-23T21:28:13Z" +description = "How does the Corefile work?" +tags = ["Corefile", "Documentation"] +title = "Corefile Explained" +author = "miek" ++++ + +The `Corefile` is CoreDNS's configuration file. It defines: + +* What servers listen on what ports. +* For which zone each server is authoritative. +* What middleware is loaded in a server. + +To explain more, let take a look at this "Corefile": + +~~~ txt +ZONE:[PORT] { + [MIDDLEWARE]... +} +~~~ + +* **ZONE** defines the zone this server. The optional **PORT** defaults to 53, if not given (or + whatever the `-dns.port` flag has as a value. +* **MIDDLEWARE** defines the middleware we want to load. This is optional as well, but as server + with no middleware will just return SERVFAIL for all queries. + +So this is a minimum Corefile: + +~~~ txt +. { } +~~~ + +That defines a server to listen on port 53 and make it authoritative for the root zone *and* +everything below. Let's define another server that is authoritative for `.` (root zone) and load +that: + +~~~ txt +. { } +. { } +~~~ + +This will make CoreDNS exit with an error: +~~~ +2017/07/23 20:39:10 cannot serve dns://.:53 - zone already defined for dns://.:53 +~~~ + +Why? Because we already defined a server *on the same port* for this zone. If we change the port +number on the second server and thereby creating *another* server, it is OK: + +~~~ txt +. { } +.:54 { } +~~~ + +When defining a new zone, you either create a new server, or add it to an existing one - but you can +redefine the middleware for it. Here we define *one* server that handles two zones; that potentially +chain different middleware: + +~~~ txt +example.org { + whoami +} +org { + whoami +} +~~~ + +Note that most specific zone wins when a query comes in, so any `example.org` queries are going +through the middleware defined for `example.org` above. The rest is handled by `.`. + +## Default Corefile + +When CoreDNS starts up and can't find a Corefile, it will load a default one, defined as + +~~~ txt +. { + whoami +} +~~~ + +## Non Default Protocols + +Listening on TLS and for gRPC? Use: + +~~~ txt +tls://example.org grpc://example.org { + # ... +} +~~~ + +Specifying ports works in the same way, here when listening for gRPC packets. + +~~~ txt +grpc://example.org:1443 { + # ... +} +~~~ + +## Also See + +The Corefile is parsed like a [Caddyfile](https://caddyserver.com/docs/caddyfile). diff --git a/content/blog/custom-dns-and-kubernetes.md b/content/blog/custom-dns-and-kubernetes.md new file mode 100644 index 0000000..51e9408 --- /dev/null +++ b/content/blog/custom-dns-and-kubernetes.md @@ -0,0 +1,165 @@ ++++ +date = "2017-05-08T20:01:00Z" +description = "Creating custom DNS entries inside or outside the cluster domain using CoreDNS" +tags = ["Kubernetes", "Service", "Discovery", "Kube-DNS", "Custom", "DNS", "Documentation"] +title = "Custom DNS Entries For Kubernetes" +author = "john" ++++ + +As described in our [previous post](https://blog.coredns.io/2017/03/01/coredns-for-kubernetes-service-discovery-take-2/), +CoreDNS can be used in place of Kube-DNS for service discovery in Kubernetes clusters. Because of the flexible architecture +of CoreDNS, this can enable some interesting use cases. In this blog, we'll show how to solve a common problem - creating +custom DNS entries for your services. + +There are a couple of different possiblities here: + +* [Making an alias](https://github.com/kubernetes/kubernetes/issues/39792) for an external name +* [Dynamically adding services to another domain](https://github.com/kubernetes/dns/issues/55), without running another server +* Adding an arbitrary entry inside the cluster domain + +CoreDNS can solve all of these use cases. Let's start with the first one, which is pretty common. In this situation, you +want to be able to use the same name for a given service, whether you are accessing it inside or outside the cluster. This +is helpful, for example, when using TLS certificates that are bound to that name. + +Suppose we have a service, `foo.default.svc.cluster.local` that is available to outside clients as `foo.example.com`. +That is, when looked up outside the cluster, `foo.example.com` will resolve to the load balancer VIP - the external +IP address for the service. Inside the cluster, it will resolve to the same thing, and so using this name internally +will cause traffic to hairpin - travel out of the cluster and then back in via the external IP. Instead, we want it +to resolve to the internal ClusterIP, avoiding the hairpin. + +To do this in CoreDNS, we make use of the `rewrite` middleware. This middleware can modify a query before it is sent +down the chain to whatever backend is going to answer it. Recall the `Corefile` (CoreDNS configuration file) we +used in the last blog: + +~~~ txt +.:53 { + errors + log stdout + health + kubernetes cluster.local { + cidrs 10.0.0.0/24 + } + proxy . /etc/resolv.conf + cache 30 +} +~~~ + +To get the behavior we want, we just need to add a rewrite rule mapping `foo.example.com` to `foo.default.svc.cluster.local`: + +~~~ txt +.:53 { + errors + log stdout + health + rewrite name foo.example.com foo.default.svc.cluster.local + kubernetes cluster.local { + cidrs 10.0.0.0/24 + } + proxy . /etc/resolv.conf + cache 30 +} +~~~ + +Once we add that to the `ConfigMap` via `kubectl edit` or `kubectl apply`, we have to let CoreDNS know that the `Corefile` +has changed. You can send it a `SIGUSR1` to tell it to reload graceful - that is, without loss of service: + +~~~ txt +$ kubectl exec -n kube-system coredns-980047985-g2748 -- kill -SIGUSR1 1 +~~~ + +Running our test pod, we can see this works: + +~~~ txt +$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools +If you don't see a command prompt, try pressing enter. +/ # host foo +foo.default.svc.cluster.local has address 10.0.0.72 +/ # host foo.example.com +foo.default.svc.cluster.local has address 10.0.0.72 +/ # host bar.example.com +Host bar.example.com not found: 3(NXDOMAIN) +/ # +~~~ + +That's all there is to solving the first problem. + +The second problem is just as easy. Here, we just want to be able to serve DNS entries out of a different zone +than the cluster domain. Since CoreDNS is a general-purpose DNS server, there are many other ways +to serve up zones than just the `kubernetes` middleware. For simplicity, we'll use the `file` middleware along +with another `ConfigMap` entry to satisfy this use case. However, you could use the `etcd` middleware to store services +directly within an etcd instance, or the `auto` middleware to manage a set of zones (very nice when used along +with [git-sync](https://github.com/kubernetes/git-sync)). + +To create the new zone, we need to modify the `coredns.yaml` we have been using to create an additional file +in the pod. To do this we have to edit the `ConfigMap` by adding a `file` line to the `Corefile`, and also +by adding another key, `example.db`, for the zone file: + +~~~ yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: coredns + namespace: kube-system +data: + Corefile: | + .:53 { + errors + log stdout + health + rewrite name foo.example.com foo.default.svc.cluster.local + kubernetes cluster.local { + cidrs 10.0.0.0/24 + } + file /etc/coredns/example.db example.org + proxy . /etc/resolv.conf + cache 30 + } + example.db: | + ; example.org test file + example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2015082541 7200 3600 1209600 3600 + example.org. IN NS b.iana-servers.net. + example.org. IN NS a.iana-servers.net. + example.org. IN A 127.0.0.1 + a.b.c.w.example.org. IN TXT "Not a wildcard" + cname.example.org. IN CNAME www.example.net. + + service.example.org. IN SRV 8080 10 10 example.org. +~~~ + +and we also need to edit the `volumes` section of the `Pod` template spec: + +~~~ yaml + volumes: + - name: config-volume + configMap: + name: coredns + items: + - key: Corefile + path: Corefile + - key: example.db + path: example.db +~~~ + +Once we apply this using `kubectl apply -f`, a new CoreDNS pod will be built, because of the new file +in the volume. Later changes to the file won't require a new pod, just a graceful restart like we did before. +Let's take a look: + +~~~ txt +$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools +If you don't see a command prompt, try pressing enter. +/ # host foo +foo.default.svc.cluster.local has address 10.0.0.72 +/ # host foo.example.com +foo.default.svc.cluster.local has address 10.0.0.72 +/ # host example.org +example.org has address 127.0.0.1 +/ # +~~~ + +Perfect! We can now edit that `ConfigMap` and send `SIGUSR1` any time we want to add entries to `example.org`. Of course, +as mentioned earlier, we could also use the `etcd` backend and avoid the hassle of modifying the `ConfigMap` and +sending the signal. + +This brings us to the last problem. That one can be solved using the new support for `fallthrough` in the `kubernetes` +middleware. This functionality has been added in the recently released version 007 of CoreDNS - we'll come back with +another blog soon show how to use it. diff --git a/content/blog/how-to-add-middleware.md b/content/blog/how-to-add-middleware.md new file mode 100644 index 0000000..401c590 --- /dev/null +++ b/content/blog/how-to-add-middleware.md @@ -0,0 +1,252 @@ ++++ +date = "2017-03-01T20:23:48Z" +description = "How to add middleware to CoreDNS; a tutorial" +tags = ["Middleware", "Howto", "Tutorial", "Documentation"] +title = "How to Add Middleware to CoreDNS" +author = "miek" ++++ + +CoreDNS is a DNS server that chains middleware. Middleware is defined as a method `ServeDNS()` that +gets a request and either responds to the client or passes it on to the next middleware. If none of +the middleware handle the request a default response of SERVFAIL is returned. + +This blog post details how to add middleware to CoreDNS. We're using the example of the *whoami* +middleware which is a CoreDNS middleware and loaded by default if nothing is specified. + +> Note all the code examples here are in Go because CoreDNS is written in the Go language. + +First question should be: "What should my middleware do?". In the case of the *whoami* middleware +its purpose is to echo back the client's IP (IPv4 or IPv6), the transport used ("tcp" or "udp") and +the request port number. + +Next question is: "What is the name of this new middleware?" Try to find a short, descriptive name +for this. In this case, we already had a (good) name: *whoami*. + +## Middleware + +A middleware consists of a number of parts: + +1. The registration of the middleware +2. The setup function that parses the *whoami* directive and + possible options from the Corefile +3. The `ServeDNS()` and `Name()` methods + +After we've defined the parts, we can: + +4. Hook it up +5. Use it + +# 1. Registration + +Typically a middleware has a file called `setup.go` that handles the registration. +In there, the `init` function should look like: + +~~~ go +func init() { + caddy.RegisterPlugin("whoami", caddy.Plugin{ + ServerType: "dns", + Action: setupWhoami, + }) +} +~~~ +First you see that we're using `caddy.RegisterPlugin` which makes perfectly sense, because +CoreDNS uses the [Caddy](https://caddyserver.com) server framework. The first argument is the name +of the directive as used in the Corefile. + +The `ServerType` is "dns" because CoreDNS is a DNS server; Caddy supports HTTP servers as well. The +`Action` is the name of the setup function that takes care of the parsing of the Corefile. Its job +is to return a type that implements the `middleware.Handler` interface. + +So whenever the Corefile parser sees "whoami", `setupWhoami` is called. + +# 2. Setup function + +Because the *whoami* directive does not allow for any options, the setup function is relatively +simple: +~~~ go +func setupWhoami(c *caddy.Controller) error { + c.Next() // 'whoami' + if c.NextArg() { + return middleware.Error("whoami", c.ArgErr()) + } + + dnsserver.GetConfig(c).AddMiddleware(func(next middleware.Handler) middleware.Handler { + return Whoami{} + }) + + return nil +} +~~~ +We use the `*caddy.Controller` to receive tokens from the Corefile and act upon them. Here we only +check if there is nothing specified after the token `whoami`. If you need to do more there are +`c.Val()`, `c.Args()` and [friends](https://godoc.org/github.com/mholt/caddy/caddyfile#Dispenser). + +The full `setup.go` for *whoami* is [here](https://github.com/miekg/coredns/blob/master/middleware/whoami/setup.go). + +Note that you should test the parsing as well, see +[setup_test.go](https://github.com/miekg/coredns/blob/master/middleware/whoami/setup_test.go). + +# 3. ServeDNS() and Name() + +Let's start with the trivial `Name()` method which is used (mainly) to see if the metrics +middleware is loaded. CoreDNS does by this by name. The method just returns the string `whoami`. + +~~~ go +// Name implements the Handler interface. +func (wh Whoami) Name() string { return "whoami" } +~~~ + +Next, the meat of the whole thing, the `ServeDNS` method. We will look at this method line by line. + +~~~ +// ServeDNS implements the middleware.Handler interface. +func (wh Whoami) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { + state := request.Request{W: w, Req: r} +~~~ +As seen the function gets a couple of parameters of which `w` is the client side: writing to `w` +returns a response to the client. As you will see below all interesting properties of the client +connection can be retrieved from the +[dns.ResponseWriter](https://godoc.org/github.com/miekg/dns#ResponseWriter). `r` is the incoming +query. The `ServeDNS` method returns an integer and/or an error. The values the integer can take are +the DNS RCODEs, dns.RcodeServerFailure, dns.RcodeNotImplemented, dns.RcodeSuccess, etc.. +A successful return value indicates the middleware has written to the client. + +`request.Request` is a helper struct that abstracts and caches some client-side properties, like +EDNS0 records and the DNSSEC OK bit. + +Next we setup the reply message: +~~~ go +a := &dns.Msg{} +a.SetReply(r) +a.Compress = true +a.Authoritative = true +~~~ + +We create a new message and copy the relevant bits from the incoming reply to the one we're planning +to return. We fiddle with some message bits and turn on message compression. + +Then we are going to inspect the incoming message via the `state` helper struct to see what we +should return. + +~~~ go +ip := state.IP() +var rr dns.RR + +switch state.Family() { +case 1: + rr = &dns.A{} + rr.(*dns.A).Hdr = dns.RR_Header{Name: state.QName(), + Rrtype: dns.TypeA, Class: state.QClass()} + rr.(*dns.A).A = net.ParseIP(ip).To4() +case 2: + rr = &dns.AAAA{} + rr.(*dns.AAAA).Hdr = dns.RR_Header{Name: state.QName(), + Rrtype: dns.TypeAAAA, Class: state.QClass()} + rr.(*dns.AAAA).AAAA = net.ParseIP(ip) +} +~~~ +`IP()` returns the IP address of the client. `Family()` returns the IP version used. Depending on the +family we either create a A or AAAA record with the client's address. Note we don't specify a TTL +meaning it will be zero; indicating these records should not be cached. + +Next we want to encode the client's source port and transport protocol used. +~~~go +srv := &dns.SRV{} +srv.Hdr = dns.RR_Header{Name: "_" + state.Proto() + "." + state.QName(), + Rrtype: dns.TypeSRV, Class: state.QClass()} +port, _ := strconv.Atoi(state.Port()) +srv.Port = uint16(port) +srv.Target = "." +~~~ + +SRV records are ideal for that. The domain names are either prefixed with `_tcp` or `_udp`, and the +SRV record's port number re-used to echo back the clients's port number, meaning we create +something like this: `_tcp.example.org. 0 IN SRV 0 0 `. + +In the last bit of this method we create the full message and send it: + +~~~go +a.Extra = []dns.RR{rr, srv} + +state.SizeAndDo(a) +w.WriteMsg(a) + +return 0, nil +~~~ + +First we add the two created resource records (`rr` and `srv`) to the additional section of the +answer message: `a.Extra`. +Then we call `state.SizeOnDo(a)` which will set the correct EDNS0 record on the message and handle +setting the truncation bit). Then, +finally, we call the `WriteMsg` method on `w` which writes the message back to the client. +We indicate a successful (even though it might have failed - we didn't check the return value of +`WriteMsg`) write by returning 0 and `nil`. + +# 4. Hooking it up + +Next we need to tell CoreDNS to compile and use this new middleware. Adding a middleware was +recently simplified and only consists of editing `middleware.cfg` and adding the line: + +~~~ +210:whoami:whoami +~~~ +The initial number is used for sorting the middleware (more on that below), then the name of the +plugin as used in the registration and then the package inside the CoreDNS middleware directory. + +Each middleware has a place in the list of all other ones. For instance the caching +or the metrics middleware needs to come early, so that it can "see" the query and +response and do cachy or metricsy things with it. A *whoami* middleware is not that special and can +be placed relatively late in the list (hence the high number). + +Now do a `make` (or `go gen && go build`) to get a `coredns` binary that can be used with our shiny new middleware. +This binary should include `dns.whoami` when called with `-plugins`. + +# 5. Using it + +Write a Corefile: + +~~~ txt +. { + whoami +} +~~~ +In words this says: be authoritative for the root `.` and below, meaning all possible queries will +hit this stanza. And for each request call *whoami*. + +Start CoreDNS with: `coredns -conf Corefile -dns.port 1053`. Couple of notes here. CoreDNS +will look for a Corefile in the current directory so the `-conf Corefile` is only given here for +completeness. The `-dns.port` will start CoreDNS on port 1053, so we don't need to run as root. + +CoreDNS will output the following: +~~~ txt +.:1053 +2017/02/19 17:44:31 [INFO] CoreDNS-005 +CoreDNS-005 +~~~ +The `.:1053` indicates it has parsed our Corefile and is listening on port 1053 for queries for +the root `.` zone and below. + +So, lets send it a query with `dig`: + +~~~ sh +% dig +nocmd @localhost mx example.org -p1053 +noall +additional +example.org. 0 IN A 127.0.0.1 +_udp.example.org. 0 IN SRV 0 0 58359 . +~~~ +Beautiful. It is working. Checking the response, this request was sent with IPv4 over UDP +from port 58359. + +Let's try using TCP: +~~~ sh +% dig +nocmd @localhost a example.org -p1053 +noall +additional +tcp +example.org. 0 IN A 127.0.0.1 +_tcp.example.org. 0 IN SRV 0 0 33435 . +~~~ +Yes, it correctly sees we've used TCP this time (and of course a different port). + +There are already a lot of different middleware in CoreDNS. New, exciting ones, are always welcome. So if you +have an idea open an issue on the tracker. + +This is an updated version of the [previous +blog](https://blog.coredns.io/2016/12/19/writing-middleware-for-coredns/) about writing CoreDNS +middleware. diff --git a/content/blog/httpsproxy.md b/content/blog/httpsproxy.md new file mode 100644 index 0000000..171e1d6 --- /dev/null +++ b/content/blog/httpsproxy.md @@ -0,0 +1,56 @@ ++++ +date = "2016-11-26T17:22:44Z" +description = "Using Google's dns.google.com with CoreDNS" +tags = ["Encryption", "DNS", "Google", "Documentation"] +title = "DNS over HTTPS" +author = "miek" ++++ + +Since almost a year Google has a DNS service that can be queried over HTTPS: +. This means your queries are encrypted and can only be seen by you (and +Google(!)). Seeing all the press about the +[UK's snooper's charter](https://www.theguardian.com/technology/askjack/2016/nov/24/how-can-i-protect-myself-from-government-snoopers) +I though I should implement this as a middleware in CoreDNS. + +I'm (obviously) going to use this myself; which is perfect as it protects me and it allows me to +dog food CoreDNS as a DNS proxy in my home network. + +A note worthy other implementation is "dingo": . + +Also note that this a *different* protocol than "DNS over TLS" which has similar goals and is being +standardized by the IETF. + +> Currently you'll need to compile CoreDNS from source to play with this or wait until CoreDNS-004 +> is released. + +The configuration on the CoreDNS side is pretty straight forward. The following Corefile is all +you'll need: + +~~~ txt +. { + httpproxy . dns.google.com + cache + log stdout + errors stdout +} +~~~ + +Next start CoreDNS, and query it. + +~~~ sh +% ./coredns +.:53 +2016/11/26 17:11:07 [INFO] CoreDNS-003 +CoreDNS-003 +::1 - [26/Nov/2016:17:13:10 +0000] "MX IN miek.nl. udp false 4096" NOERROR 246 149.791162ms +::1 - [26/Nov/2016:17:13:11 +0000] "MX IN miek.nl. udp false 4096" NOERROR 170 156.432µs +~~~ + +The only unencrypted DNS used is from your laptop/phone/computer to CoreDNS, the rest is encrypted. + +By default, `dns.google.com` will be re-resolved every 30 seconds using 8.8.8.8 and 8.8.4.4 (you can +override these defaults). This is the only query not encrypted, but this will probably lead to +a very boring browser history. + +Next, *I* need to configure a Raspberry Pi and install CoreDNS on it. And as with all CoreDNS +developements [feedback is welcome](https://github.com/coredns/coredns/issues). diff --git a/content/blog/kubernetes-service-discovery-2.md b/content/blog/kubernetes-service-discovery-2.md new file mode 100644 index 0000000..405bdae --- /dev/null +++ b/content/blog/kubernetes-service-discovery-2.md @@ -0,0 +1,241 @@ ++++ +date = "2017-03-01T20:33:08Z" +description = "CoreDNS is now fully compliant with the Kubernetes DNS Service Discovery Specification" +tags = ["Kubernetes", "Service", "Discovery", "Kube-DNS", "Documentation"] +title = "CoreDNS for Kubernetes Service Discovery, Take 2" +author = "john" ++++ + +A couple months ago we published a blog post on [how to use CoreDNS instead of +kube-dns](https://community.infoblox.com/t5/Community-Blog/CoreDNS-for-Kubernetes-Service-Discovery/ba-p/8187) +in Kubernetes. Since then, we have made a lot of progress. We worked with the +community to define a specification for [Kubernetes DNS-Based Service Discovery] +(https://github.com/kubernetes/dns/blob/master/docs/specification.md), enabling us to ensure +compatibility across the existing Kube-DNS implementation +and our new one in CoreDNS. Version 1.0.0 of this specification mostly follows +the current behavior of Kube-DNS. Versions 005 and higher of CoreDNS implement the full +specification and more. + +At the time of that blog, the CoreDNS Kubernetes middleware only supported +serving `A` records with the cluster IP of an ordinary service. Now it includes: + +* `A`, `SRV`, and `PTR` records for regular and headless services +* `A` records for named endpoints that are part of a service (i.e., records for + 'pets') +* `A` records for pods (optional) as described in the spec +* `TXT` record for discovering the DNS schema version in use + +The pod `A` record support is not needed in all clusters, and is disabled by +default. Additionally, CoreDNS support for this use case goes beyond the +standard behavior you'll find in Kube-DNS. In Kube-DNS, these records do not +reflect the state of the cluster. Any query to `w-x-y-z.namespace.pod.cluster.local` +will return an `A` record with `w.x.y.z`, even if that IP does not belong to +specified namespace or even to the cluster address space. The original idea +behind this was to enable the use of wildcard SSL certificates for domains like +`*.namespace.pod.cluster.local`. CoreDNS can duplicate this behavior with the +configuration option `pods insecure`. We deem it "insecure" because this lack of +validation breaks the identity guarantee of the wildcard certificate. + +The CoreDNS integration offers the option `pods verified`, which will verify +that the IP address `w.x.y.z` returned is in fact the IP of a pod in the +specified namespace. This prevents the spoofing of a DNS name in the namespace. +It does however, potentially increase the memory footprint of the CoreDNS instances +substantially, since now it needs to watch all pods, not just service endpoints. + +Ok, enough intro - let's see how to deploy this. Like in the previous blog, we +use a ConfigMap and a Deployment. To make it even easier, we have created a little +[utility script](https://github.com/coredns/deployment/blob/master/kubernetes/deploy.sh) and +[deployment manifest template](https://github.com/coredns/deployment/blob/master/kubernetes/coredns.yaml.sed) +that you can use to deploy. To use it, simply put them both in the same directory +and then run the `deploy.sh` script, passing it the CIDR for your services. This will +generate the ConfigMap with the necessary Corefile. It will also lookup the cluster IP +of the existing kube-dns service. For example, running + + $ ./deploy.sh 10.3.0.0/24 cluster.local + +with `kubectl` pointing to a cluster that has kube-dns service with cluster IP 10.3.0.10 +results in the manifest file below.[^1] + +[^1]: *Important:* If you are using Google Container Engine, there are additional processes that will not allow you to replace the kube-dns deployment (or replication controller). If you try to apply the above, it will successfully alter the Service but will soon kill your CoreDNS deployment and restart the Kube DNS replication controller. Since the service is updated, you actually will lose DNS in your cluster, as the service selector for the service no longer points to the pods created by the Kube DNS replication controller. There is probably a way around this but I haven't had a chance to find the fix yet. + + +~~~yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: coredns + namespace: kube-system +data: + Corefile: | + .:53 { + errors + log stdout + health + kubernetes cluster.local { + cidrs 10.3.0.0/24 + } + proxy . /etc/resolv.conf + cache 30 + } +--- +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + name: coredns + namespace: kube-system + labels: + k8s-app: coredns + kubernetes.io/cluster-service: "true" + kubernetes.io/name: "CoreDNS" +spec: + replicas: 1 + selector: + matchLabels: + k8s-app: coredns + template: + metadata: + labels: + k8s-app: coredns + annotations: + scheduler.alpha.kubernetes.io/critical-pod: '' + scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]' + spec: + containers: + - name: coredns + image: coredns/coredns:latest + imagePullPolicy: Always + args: [ "-conf", "/etc/coredns/Corefile" ] + volumeMounts: + - name: config-volume + mountPath: /etc/coredns + ports: + - containerPort: 53 + name: dns + protocol: UDP + - containerPort: 53 + name: dns-tcp + protocol: TCP + livenessProbe: + httpGet: + path: /health + port: 8080 + scheme: HTTP + initialDelaySeconds: 60 + timeoutSeconds: 5 + successThreshold: 1 + failureThreshold: 5 + dnsPolicy: Default + volumes: + - name: config-volume + configMap: + name: coredns + items: + - key: Corefile + path: Corefile +--- +apiVersion: v1 +kind: Service +metadata: + name: kube-dns + namespace: kube-system + labels: + k8s-app: coredns + kubernetes.io/cluster-service: "true" + kubernetes.io/name: "CoreDNS" +spec: + selector: + k8s-app: coredns + clusterIP: 10.3.0.10 + ports: + - name: dns + port: 53 + protocol: UDP + - name: dns-tcp + port: 53 + protocol: TCP +~~~ + +Let's take a closer look at that Corefile. It's really very similar to the one in the +previous blog post. + +~~~txt +.:53 { + errors + log stdout + health + kubernetes cluster.local { + cidrs 10.3.0.0/24 + } + proxy . /etc/resolv.conf + cache 30 +} +~~~ + +The one difference though, is the `cidrs 10.3.0.0/24` directive. This tells the +Kubernetes middleware that it is responsible for serving `PTR` requests for the reverse +zone `0.3.10.in-addr.arpa.`. In other words, this is what allows reverse DNS +resolution of services. Let's give that a try: + +~~~txt +$ ./deploy.sh 10.3.0.0/24 | kubectl apply -f - +configmap "coredns" created +deployment "coredns" created +service "kube-dns" configured +$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools +Waiting for pod default/dnstools to be running, status is Pending, pod ready: false +If you don't see a command prompt, try pressing enter. +/ # host kubernetes +kubernetes.default.svc.cluster.local has address 10.3.0.1 +/ # host kube-dns.kube-system +kube-dns.kube-system.svc.cluster.local has address 10.3.0.10 +/ # host 10.3.0.1 +1.0.3.10.in-addr.arpa domain name pointer kubernetes.default.svc.cluster.local. +/ # host 10.3.0.10 +10.0.3.10.in-addr.arpa domain name pointer kube-dns.kube-system.svc.cluster.local. +/ # +~~~ + +Great, so it's working. Now, let's take a look at our CoreDNS logs: + +~~~txt +$ kubectl get --namespace kube-system pods +NAME READY STATUS RESTARTS AGE +coredns-3558181428-0zhnh 1/1 Running 0 2m +coredns-3558181428-xri9i 1/1 Running 0 2m +heapster-v1.2.0-4088228293-a8gkc 2/2 Running 0 126d +kube-apiserver-10.222.243.77 1/1 Running 2 126d +kube-controller-manager-10.222.243.77 1/1 Running 2 126d +kube-proxy-10.222.243.77 1/1 Running 2 126d +kube-proxy-10.222.243.78 1/1 Running 0 126d +kube-scheduler-10.222.243.77 1/1 Running 2 126d +kubernetes-dashboard-v1.4.1-gi2xr 1/1 Running 0 24d +tiller-deploy-3299276078-e8phb 1/1 Running 0 24d +$ kubectl logs --namespace kube-system coredns-3558181428-0zhnh +2017/02/23 14:48:29 [INFO] Kubernetes middleware configured without a label selector. No label-based filtering will be performed. +.:53 +2017/02/23 14:48:29 [INFO] CoreDNS-005 +CoreDNS-005 +10.2.6.127 - [23/Feb/2017:14:49:44 +0000] "AAAA IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR 107 544.128µs +10.2.6.127 - [23/Feb/2017:14:49:44 +0000] "MX IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR 107 7.576897ms +10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "A IN kube-dns.kube-system.default.svc.cluster.local. udp 64 false 512" NXDOMAIN 117 471.176µs +23/Feb/2017:14:49:52 +0000 [ERROR 0 kube-dns.kube-system.default.svc.cluster.local. A] no items found +10.2.6.127 - [23/Feb/2017:14:50:00 +0000] "PTR IN 10.0.3.10.in-addr.arpa. udp 40 false 512" NOERROR 92 752.956µs +$ kubectl logs --namespace kube-system coredns-3558181428-xri9i +2017/02/23 14:48:29 [INFO] Kubernetes middleware configured without a label selector. No label-based filtering will be performed. +.:53 +2017/02/23 14:48:29 [INFO] CoreDNS-005 +CoreDNS-005 +10.2.6.127 - [23/Feb/2017:14:49:44 +0000] "A IN kubernetes.default.svc.cluster.local. udp 54 false 512" NOERROR 70 1.10732ms +10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "A IN kube-dns.kube-system.svc.cluster.local. udp 56 false 512" NOERROR 72 409.74µs +10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "AAAA IN kube-dns.kube-system.svc.cluster.local. udp 56 false 512" NOERROR 109 210.817µs +10.2.6.127 - [23/Feb/2017:14:49:52 +0000] "MX IN kube-dns.kube-system.svc.cluster.local. udp 56 false 512" NOERROR 109 796.703µs +10.2.6.127 - [23/Feb/2017:14:49:56 +0000] "PTR IN 1.0.3.10.in-addr.arpa. udp 39 false 512" NOERROR 89 694.649µs +$ +~~~ + +Here, we can see that the queries were load-balanced across the two CoreDNS replicas. In production, it's a good idea +to disable the logging of all the queries, as logging slows down the query dramatically (often by an order of magnitude). +To do that, simply remove the `log stdout` line from the Corefile. + +That's all there is to it. Please feel free to submit any problems, questions, or feature ideas as issues on the +[CoreDNS GitHub](https://github.com/coredns/coredns). diff --git a/content/blog/kubernetes-service-discovery.md b/content/blog/kubernetes-service-discovery.md new file mode 100644 index 0000000..8d646ae --- /dev/null +++ b/content/blog/kubernetes-service-discovery.md @@ -0,0 +1,24 @@ ++++ +date = "2016-11-08T07:33:08Z" +description = "Using CoreDNS for service discovery in Kubernetes" +tags = ["Kubernetes", "Service", "Discovery", "Kube-DNS", "Documentation"] +title = "CoreDNS for Kubernetes Service Discovery" +author = "miek" ++++ + +[Infoblox](https://www.infoblox.com/)'s John Belamaric has published a +blog post on +[how to use CoreDNS instead of +kube-dns](https://community.infoblox.com/t5/Community-Blog/CoreDNS-for-Kubernetes-Service-Discovery/ba-p/8187) +in Kubernetes. + +A little excerpt: + +> Kubernetes includes a DNS server, Kube-DNS, for use in service discovery. This DNS server utilizes +> the libraries from SkyDNS to serve DNS requests for Kubernetes pods and services. The author of +> SkyDNS2, Miek Gieben, has a new DNS server, CoreDNS, that is built with a more modular, extensible +> framework. Infoblox has been working with Miek to adapt this DNS server as an alternative to +> Kube-DNS. + +Read more on their +[site](https://community.infoblox.com/t5/Community-Blog/CoreDNS-for-Kubernetes-Service-Discovery/ba-p/8187). diff --git a/content/blog/minikube.md b/content/blog/minikube.md new file mode 100644 index 0000000..57beea9 --- /dev/null +++ b/content/blog/minikube.md @@ -0,0 +1,67 @@ ++++ +date = "2017-04-28T12:30:00Z" +description = "Getting CoreDNS to work with Minikube" +tags = ["Kubernetes", "Service", "Discovery", "Kube-DNS", "Minikube", "DNS", "Documentation"] +title = "CoreDNS for Minikube" +author = "john" ++++ + +In our [previous post](https://blog.coredns.io/2017/03/01/coredns-for-kubernetes-service-discovery-take-2/), +we showed how CoreDNS can be used in place of Kube-DNS for service discovery in Kubernetes clusters. +In that blog, there is a footnote about issues trying to replace Kube-DNS when using Google Container Engine (GKE). +As it so happens, there is a similar issue with [minikube](https://github.com/kubernetes/minikube), which is a local +Kubernetes environment that is very useful for developers (see our +[DEV-README.md](https://github.com/coredns/coredns/blob/master/middleware/kubernetes/DEV-README.md) for more). + +When you try to replace Kube-DNS, you will find that shortly after you modify its service to point to CoreDNS, your +changes will be reverted. This is because Minikube has an _addon manager_ that periodically verifies the configuration +state of any installed addons, and Kube-DNS is one of those addons. + +Luckily, this is really easy to solve for Minikube. The `minikube` command allows you to modify the installed +plugins for Minikube. So, we simply need to disable the `kube-dns` addon before running our `kubectl apply -f` +that is described in the previous blog: + +~~~ txt +$ minikube addons list +- dashboard: enabled +- default-storageclass: enabled +- kube-dns: enabled +- heapster: disabled +- ingress: disabled +- registry-creds: disabled +- addon-manager: enabled +$ minikube addons disable kube-dns +kube-dns was successfully disabled +$ minikube addons list +- heapster: disabled +- ingress: disabled +- registry-creds: disabled +- addon-manager: enabled +- dashboard: enabled +- default-storageclass: enabled +- kube-dns: disabled +~~~ + +Now we can apply the `coredns.yaml`, and also delete the `kube-dns` `ReplicationController` which +will not be automatically deleted by disabling the addon. + +~~~ txt +$ kubectl apply -f coredns.yaml +serviceaccount "coredns" configured +clusterrole "system:coredns" configured +clusterrolebinding "system:coredns" configured +configmap "coredns" configured +deployment "coredns" configured +service "kube-dns" configured +$ kubectl get -n kube-system pods +NAME READY STATUS RESTARTS AGE +coredns-980047985-g2748 1/1 Running 1 36m +kube-addon-manager-minikube 1/1 Running 0 9d +kube-dns-v20-qzvr2 3/3 Running 0 1m +kubernetes-dashboard-ks1jp 1/1 Running 0 9d +$ kubectl delete -n kube-system rc kube-dns-v20 +replicationcontroller "kube-dns-v20" deleted +$ +~~~ + +And there we have it, CoreDNS is up and running and won't be overwritten by the addon manager. diff --git a/content/blog/query-processing.md b/content/blog/query-processing.md new file mode 100644 index 0000000..8c2b99b --- /dev/null +++ b/content/blog/query-processing.md @@ -0,0 +1,194 @@ ++++ +date = "2017-06-08T20:01:00Z" +description = "And how it applies to Kubernetes custom DNS entries inside the cluster domain" +tags = ["Kubernetes", "Service", "Discovery", "Kube-DNS", "Custom", "DNS", "middleware", "Documentation"] +title = "How Queries Are Processed in CoreDNS" +author = "john" ++++ + +In the [last post](https://blog.coredns.io/2017/05/08/custom-dns-entries-for-kubernetes/), we described three different use +cases for custom DNS entries in Kubernetes: + +* [Making an alias](https://github.com/kubernetes/kubernetes/issues/39792) for an external name +* [Dynamically adding services to another domain](https://github.com/kubernetes/dns/issues/55), without running another server +* Adding an arbitrary entry inside the cluster domain + +In that post we covered the first two. In this post, we'll show you how to use the `fallthrough` option of the `kubernetes` +middleware to satisfy the third case. + +To understand how this works, we first need to look at how CoreDNS processes requests. This was previously +addressed in [Query Routing](https://blog.coredns.io/2016/10/13/query-routing/), but we'll go into a bit +more detail here. + +We all know that CoreDNS chains middleware. But what exactly does that mean? To find out, we'll dissect a +Corefile and see how that translates into CoreDNS internals, and discuss how a query +is routed through these internals. + +Consider this Corefile: + +~~~ txt +coredns.io:5300 { + file /etc/coredns/zones/coredns.io.db +} + +example.io:53 { + errors + log + file /etc/coredns/zones/example.io.db +} + +example.net:53 { + file /etc/coredns/zones/example.net.db +} + +.:53 { + errors + log stdout + health + rewrite name foo.example.com foo.default.svc.cluster.local + kubernetes cluster.local { + cidrs 10.0.0.0/24 + } + file /etc/coredns/example.db example.org + proxy . /etc/resolv.conf + cache 30 +} +~~~ + +Notice here that there are two different ports: 5300 and 53. Internally, each of these ports will +result in a [`dnsserver.Server`](https://github.com/coredns/coredns/blob/master/core/dnsserver/server.go). +Even though there are four _server blocks_ (stanzas), we only get two actual servers. CoreDNS will gather up all of the +server blocks associated with the same port and combine them in to the same `dnsserver.Server`. The server will +multiplex the queries on the port, passing them to the different _middleware chains_ depending upon the zone. It chooses +the most specific matching server block for the zone. If no server block matches, `SERVFAIL` is returned. This is shown +visually in the diagram below. + +![Query Processing](/images/query-processing.png) + +So, any specific query will go through exactly one middleware chain. The ordering of the middleware is dictated +*at build time*, by the [`middleware.cfg`](https://github.com/coredns/coredns/blob/master/middleware.cfg) file, +although there is some [discussion](https://github.com/coredns/coredns/issues/632) about making this modifiable +at runtime. This is why even though `cache` appears at the end of the server block, it is not the end of the +middleware chain. + +Notice in the `.:53` server block, we define the `health` middleware, but it doesn't appear in the diagram. This is +because there are a few different types of middleware. "Normal" middleware perform request handling, and appear in the +middleware chain. However, there are a few middleware that just modify the configuration of the server or server block. +Since they don't have any request-time logic, they are not inserted in the middleware chain. Some middleware that work +this way are the `health`, `tls`, `startup`, `shutdown`, and `root` middleware. + +You can divide the middleware that do perform request-time processing into two groups: middleware that +_manipulate_ the request in some way, and _backend_ middleware. Backend middleware provide different sources +of zone and record data. The `etcd`, `file`, and `kubernetes` middleware are all examples of backends. + +Middleware that manipulate the request but are not backends - that is, they are not a source of zone data - generally +will pass the query to the next middleware after performing their logic. For example, the `rewrite` middleware makes +a change to the request, and then passes it on. When the result is returned from the later middleware, it reverts the +question section to the original (so that clients don't complain), but keeps the response and passes it back to the client. + +Any given backend is usually the final word for its zone - it either returns a result, or it returns NXDOMAIN for the +query. However, occasionally this is not the desired behavior, so some of the middleware support a `fallthrough` option. +When `fallthrough` is enabled, instead of returning NXDOMAIN when a record is not found, the middleware will pass the +request down the chain. A backend further down the chain then has the opportunity to handle the request. + +Coming back to our original discussion of the three use cases in Kubernetes, we can now understand how we can use +`fallthrough` to meet the third use case. Remember the initial Corefile from [that blog](https://blog.coredns.io/2017/05/08/custom-dns-entries-for-kubernetes/): + +~~~ txt +.:53 { + errors + log stdout + health + kubernetes cluster.local { + cidrs 10.0.0.0/24 + } + proxy . /etc/resolv.conf + cache 30 +} +~~~ + +This handles the standard in-cluster DNS service discovery. The third use case is to add an arbitrary entry to the existing +cluster domain. To do this, we define another backend for handling the `cluster.local` zone, and configure the `fallthrough` +option in the `kubernetes` middleware. For very dynamic entries, we could use the `etcd` middleware. But for demonstration +purposes it's simpler to use the `file` middleware, so that is what we will do. + +Since `kubernetes` comes before `file` in [`middleware.cfg`](https://github.com/coredns/coredns/blob/master/middleware.cfg), +using `fallthrough` in `kubernetes` will result in `file` handling any queries that `kubernetes` does not. This means that we +need to have a zone file as part of our ConfigMap, just like we did to handle the second use case in the previous blog. In this case, though, instead of being configured with a different zone (`example.org` in the other blog), the `file` middleware is +configured to use the `cluster.local` domain: + +~~~ yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: coredns + namespace: kube-system +data: + Corefile: | + .:53 { + errors + log stdout + health + kubernetes cluster.local { + cidrs 10.0.0.0/24 + fallthrough + } + file /etc/coredns/cluster.db cluster.local + proxy . /etc/resolv.conf + cache 30 + } + cluster.db: | + cluster.local. IN SOA ns.dns.cluster.local. hostmaster.cluster.local. 2015082541 7200 3600 1209600 3600 + something.cluster.local. IN A 10.0.0.1 + otherthing.cluster.local. IN CNAME google.com. +~~~ + +Remember to add the `cluster.db` file to the `config-volume` for the pod template: + +~~~ yaml + volumes: + - name: config-volume + configMap: + name: coredns + items: + - key: Corefile + path: Corefile + - key: cluster.db + path: cluster.db +~~~ + +and finally to signal CoreDNS to gracefully reload (each pod running): + +~~~ txt +$ kubectl -n coredns exec coredns-461002909-7mp96 -- kill -SIGUSR1 1 +~~~ + +Now let's try out our new DNS records. + +~~~ txt +$ kubectl run -it --rm --restart=Never --image=infoblox/dnstools:latest dnstools +If you don't see a command prompt, try pressing enter. +/ # host kubernetes +kubernetes.default.svc.cluster.local has address 10.0.0.1 +/ # host something +something.cluster.local has address 10.0.0.1 +/ # host otherthign +Host otherthign not found: 3(NXDOMAIN) +/ # host otherthing +otherthing.cluster.local is an alias for google.com. +google.com has IPv6 address 2607:f8b0:4005:805::200e +google.com mail is handled by 30 alt2.aspmx.l.google.com. +google.com mail is handled by 50 alt4.aspmx.l.google.com. +google.com mail is handled by 40 alt3.aspmx.l.google.com. +google.com mail is handled by 20 alt1.aspmx.l.google.com. +google.com mail is handled by 10 aspmx.l.google.com. +/ # +~~~ + +We can see if we put in an incorrect name, we still get NXDOMAIN as you would expect. However, a correct name will +resolve to the record from our zone file. So, we now have a way to create custom entries in the cluster domain. + +In the standard CoreDNS release, the `kubernetes` middleware comes before `file` and `etcd`. This means that it gets the +first chance to handle the query. You can rebuild CoreDNS to change that ordering if you wish - take a look at +Miek's post on [How to Add Middleware to CoreDNS](https://blog.coredns.io/2017/03/01/how-to-add-middleware-to-coredns/) +if you want to see how that's done. diff --git a/content/blog/quick-start.md b/content/blog/quick-start.md new file mode 100644 index 0000000..76c1f74 --- /dev/null +++ b/content/blog/quick-start.md @@ -0,0 +1,120 @@ ++++ +date = "2017-07-24T07:37:13Z" +description = "Quick Start Guide" +tags = ["Quick", "Start", "Documentation"] +title = "Quick Start" +author = "miek" ++++ + +First get CoreDNS, either + +* *Download the latest* release from [github](https://github.com/coredns/coredns/releases), unpack + it. You should now have a "coredns" executable. + +* *Compile from git* by getting the source code from [github](https://github.com/coredns/coredns). + Change directory to `coredns` and: + + * `go get` - to get a few dependencies, the other ones are vendored + * `go build` + + You should now have a "coredns" executable. + +If you want to use CoreDNS in Kubernetes, please check [this post about SD with the *kuberneters* +middleware](/2017/03/01/coredns-for-kubernetes-service-discovery-take-2/). + +The remainder of this quick start will focus and two different use cases + +1. Using CoreDNS to serve zone files. Optionally signing the zones as well. +2. Using CoreDNS as a forwarding proxy. + +## Serving from files + +When serving from zone files you will want to use the *file* middleware. Let's start with the zone +`example.org.` and zonefile we want to serve from: + +Create a file names `/etc/coredns/zones/example.org` with the following content: + +~~~ dns +$ORIGIN example.org. +@ 3600 IN SOA sns.dns.icann.org. noc.dns.icann.org. ( + 2017042745 ; serial + 7200 ; refresh (2 hours) + 3600 ; retry (1 hour) + 1209600 ; expire (2 weeks) + 3600 ; minimum (1 hour) + ) + + 3600 IN NS a.iana-servers.net. + 3600 IN NS b.iana-servers.net. + +www IN A 127.0.0.1 + IN AAAA ::1 +~~~ + +Create a Corefile, `/etc/coredns/Corefile`, with: + +~~~ txt +example.org { + file /etc/coredns/zones/example.org + prometheus # enable metrics + errors stdout # show errors + log stdout # show query logs +} +~~~ + +Note: you can put the last 3 directives in another file say "/etc/coredns/zone-default" and use +an `import`: `import /etc/coredns/zone-default`. + +Start CoreDNS on a non-standard port to check if everything is correct: `coredns -conf Corefile +-dns.port 1053` and send it a query with [dig](https://en.wikipedia.org/wiki/Dig_(command)): +~~~ +% dig -p 1053 @localhost AAAA www.example.org +noall +answer + +www.example.org. 3600 IN AAAA ::1 +~~~ + +As we've enabled logging the query should be show up there as well: +~~~ txt +::1 - [24/Jul/2017:10:10:44 +0000] "AAAA IN www.example.org. udp 45 false 4096" NOERROR 121 133.449µs +~~~ + +From here you can enable CoreDNS to run on port 53 and have it start from systemd (when on Linux), +see [the deployment repo](https://github.com/coredns/deployment) for example scripts. +Or read more about the *file* middleware on [this website](/middleware/file/). + +## CoreDNS as proxy + +Another way of running CoreDNS is as a proxy, for instance sending DNS request to Google using +HTTPS. Create a Corefile with: + +~~~ txt +. { + proxy . 8.8.8.8:53 { + protocol https_google + } + prometheus + errors stdout + log stdout +} +~~~ + +Start CoreDNS, just like above and send it a few queries. CoreDNS should logs those, in this case: +~~~ +::1 - [24/Jul/2017:10:44:15 +0000] "AAAA IN www.example.org. udp 45 false 4096" NOERROR 76 83.396955ms +::1 - [24/Jul/2017:10:44:17 +0000] "AAAA IN www.example.org. udp 45 false 4096" NOERROR 76 14.030914ms +::1 - [24/Jul/2017:10:44:19 +0000] "AAAA IN www.example.org. udp 45 false 4096" NOERROR 76 13.286384ms +~~~ + +If you look at the time each query took, we measure those in "ms", so it's quite slow. Let's add +caching, but enable the *caching* middleware. Just add the word "cache" to the Corefile and reload +CoreDNS: `kill -SIGUSR1 `. And query again: + +~~~ +::1 - [24/Jul/2017:11:33:54 +0000] "AAAA IN www.example.org. udp 45 false 4096" NOERROR 76 43.469743ms +::1 - [24/Jul/2017:11:33:55 +0000] "AAAA IN www.example.org. udp 45 false 4096" NOERROR 73 133.073µs +~~~ + +133 µs. That sounds better. + +Read more about the [*cache*](/middleware/cache) and [*proxy*](/middleware/proxy) middleware on +this website. And find all other documentation [here](/tags/documentation). diff --git a/content/blog/when-external.md b/content/blog/when-external.md new file mode 100644 index 0000000..05343ca --- /dev/null +++ b/content/blog/when-external.md @@ -0,0 +1,24 @@ ++++ +date = "2017-07-23T22:00:00Z" +description = "When should middleware be external?" +tags = ["Middleware", "External", "Out-of-Tree"] +title = "When Should Middleware be External?" +author = "miek" ++++ + +The `middleware.md` in the CoreDNS source tree has some pointers on what a middleware for CoreDNS +should have as minimum requirements. It basically boils down to: documentation, tests and working. + +It is easier to list when a middleware can be *included* in CoreDNS than to say it should stay +external, so we will do the first: + +* First, the middleware should be useful for *other* people. "Useful" is a subjective term, but the + middleware needs to fill a niche that appeals to more than one person. +* It should be sufficiently different from other middleware to warrant inclusion. +* Current internet standards need be supported: IPv4 and IPv6, so A and AAAA records should be + handled (if your middleware is in the business of dealing with address records that is). +* It must have tests. +* It must have a README.md for documentation. + +Middleware for CoreDNS can live out-of-tree, `middleware.cfg` defaults to CoreDNS' repo but other +repos work just as well, so it is pretty easy to use your middleware even though it is out-of-tree. diff --git a/content/community/index.md b/content/community/index.md new file mode 100644 index 0000000..9fb82d6 --- /dev/null +++ b/content/community/index.md @@ -0,0 +1,35 @@ ++++ +title = "Community" ++++ + +**Mailing list**: [coredns-discuss@googlegroups.com](coredns-discuss@googlegroups.com) - discussion +around CoreDNS usage, community support and developer discussion. + +**Slack**: #coredns on https://slack.cncf.io + +**Twitter**: [@corednsio](https://twitter.com/corednsio). + +**Issue tracker**: Use the [GitHub issue tracker](https://github.com/coredns/coredns/issues) +to file bugs and features request. If you need support, please send your questions to the +coredns-discuss mailing list rather than filing a GitHub issue. + +*Please do not ask individual project members for support. Use the channels above instead, where the +whole community can help you and benefit from the solutions provided.* + +# Contributing +We welcome community contributions! Please see the `CONTRIBUTING.md` file in the CoreDNS +repository for instructions on how to submit changes. If you are planning on making more elaborate +or controversial changes, please discuss them on the mailing list or on +[Github](https://github.com/coredns/coredns/issues/new) +before sending a pull request. + +# Project Governance +CoreDNS is an independent open-source project and not controlled by any single company. +To emphasize this and clarify our governance structure, we joined the [Cloud Native Computing +Foundation](https://cncf.io) in 2017. + + + +# Code of Conduct +To make CoreDNS a welcoming and harassment-free experience for everyone, we follow the [CNCF Code +of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md) diff --git a/content/exmiddleware/example.md b/content/exmiddleware/example.md new file mode 100644 index 0000000..02beeb1 --- /dev/null +++ b/content/exmiddleware/example.md @@ -0,0 +1,25 @@ ++++ +title = "example" +description = "*example* is a non-existent external middleware." +weight = 1000 # put it at the end +tags = [ "middleware" , "example" ] +categories = [ "middleware", "external" ] +date = "2017-07-22T12:37:19+01:00" +repo = "github.com/miekg/example" +home = "github.com/miekg/example" ++++ + +The *example* middleware is an example for an external middleware README.md. This middleware does +not actually exist. + +## Syntax + +~~~ +example +~~~ + +## Examples + +~~~ +example +~~~ diff --git a/content/exmiddleware/import.md b/content/exmiddleware/import.md new file mode 100644 index 0000000..15abd15 --- /dev/null +++ b/content/exmiddleware/import.md @@ -0,0 +1,41 @@ ++++ +title = "import" +description = "*import* allows you to use configuration from another file. It gets replaced with the contents of that file." +weight = 10 +tags = [ "middleware" , "import" ] +categories = [ "middleware", "external" ] +date = "2017-07-22T12:37:19+01:00" +repo = "https://github.com/mholt/caddy" +home = "https://caddyserver.com/docs/import" ++++ + +This is a unique directive in that *import* can appear outside of a server block. In other words, it +can appear at the top of a Corefile where an address would normally be. Like other directives, +however, it cannot be used inside of other directives. + +Note that the the import path is relative to the Corefile, not the current working directory. + +## Syntax + +~~~ +import PATTERN +~~~ + +* **PATTERN** is the file or glob pattern (`*`) to include. Its contents will replace this line, as + if that file's contents appeared here to begin with. This value is relative to the file's + location. It is an error if a specific file cannot be found, but an empty glob pattern is not an + error. + +## Examples + +Import a shared configuration: + +~~~ +import config/common.conf +~~~ + +Imports any files found in the zones directory: + +~~~ +import ../zones/* +~~~ diff --git a/content/exmiddleware/shutdown.md b/content/exmiddleware/shutdown.md new file mode 100644 index 0000000..7f4c3fc --- /dev/null +++ b/content/exmiddleware/shutdown.md @@ -0,0 +1,39 @@ ++++ +title = "shutdown" +description = "*shutdown* executes a command when the server exits." +weight = 10 +tags = [ "middleware" , "shutdown" ] +categories = [ "middleware", "external" ] +date = "2017-07-22T12:37:19+01:00" +repo = "https://github.com/mholt/caddy" +home = "https://caddyserver.com/docs/shutdown" ++++ + +This is useful for performing cleanup or stopping a background process. (Also see +[startup](/exmiddleware/startup).) + +Each command that is executed at shutdown is blocking. The output and error of the command go to +stdout and stderr, respectively. There is no stdin. + +Note that shutdown commands will not execute if CoreDNS is force-terminated, for example, by using +a "Force Quit" feature provided by your operating system. However, a typical SIGINT (Ctrl+C) will +allow the shutdown commands to execute. + +Even if this directive is shared by more than one host, the command will only execute once per +appearance in the Corefile. + +## Syntax + +~~~ +shutdown COMMAND +~~~ + +* **COMMAND** is the command to execute; it may be followed by arguments. + +## Examples + +Stop command when the server quits: + +~~~ +shutdown /etc/init.d/command stop +~~~ diff --git a/content/exmiddleware/startup.md b/content/exmiddleware/startup.md new file mode 100644 index 0000000..17ebe75 --- /dev/null +++ b/content/exmiddleware/startup.md @@ -0,0 +1,41 @@ ++++ +title = "startup" +description = "*startup* executes a command when the server begins." +weight = 10 +tags = [ "middleware" , "startup" ] +categories = [ "middleware", "external" ] +date = "2017-07-22T12:37:19+01:00" +repo = "https://github.com/mholt/caddy" +home = "https://caddyserver.com/docs/startup" ++++ + +This is useful for preparing to serve a zone by running a script or starting a background process. +(Also see [shutdown](/exmiddleware/shutdown).) + +Each command that is executed at startup is blocking, unless you suffix the command with a space and +`&`, which will cause the command to be run in the background. The output and error of the command go +to stdout and stderr, respectively. There is no stdin. + +A command will only be executed once for each time it appears in the Corefile. + +## Syntax + +~~~ +startup COMMAND +~~~ + +* **COMMAND** is the command to execute; it may be followed by arguments. + +## Examples + +Start command before the server starts listening: + +~~~ +startup /etc/init.d/command start +~~~ + +On windows, you might need to use quotes when the command path contains spaces: + +~~~ +startup "\"C:\Program Files\command.exe\" -b 127.0.0.1:9123" & +~~~ diff --git a/content/middleware/auto.md b/content/middleware/auto.md new file mode 100644 index 0000000..21da064 --- /dev/null +++ b/content/middleware/auto.md @@ -0,0 +1,72 @@ ++++ +title = "auto" +description = "*auto* enables serving zone data from an RFC 1035-style master file which is automatically picked up from disk. " +weight = 1 +tags = [ "middleware" , "auto" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +The *auto* middleware is used for an "old-style" DNS server. It serves from a preloaded file that exists +on disk. If the zone file contains signatures (i.e. is signed, i.e. DNSSEC) correct DNSSEC answers +are returned. Only NSEC is supported! If you use this setup *you* are responsible for resigning the +zonefile. New zones or changed zone are automatically picked up from disk. + +## Syntax + +~~~ +auto [ZONES...] { + directory DIR [REGEXP ORIGIN_TEMPLATE [TIMEOUT]] + no_reload + upstream ADDRESS... +} +~~~ + +**ZONES** zones it should be authoritative for. If empty, the zones from the configuration block +are used. + +* `directory` loads zones from the speficied **DIR**. If a file name matches **REGEXP** it will be + used to extract the origin. **ORIGIN_TEMPLATE** will be used as a template for the origin. Strings + like `{}` are replaced with the respective matches in the file name, i.e. `{1}` is the + first match, `{2}` is the second, etc.. The default is: `db\.(.*) {1}` e.g. from a file with the + name `db.example.com`, the extracted origin will be `example.com`. **TIMEOUT** specifies how often + CoreDNS should scan the directory, the default is every 60 seconds. This value is in seconds. + The minimum value is 1 second. +* `no_reload` by default CoreDNS will reload a zone from disk whenever it detects a change to the + file. This option disables that behavior. +* `upstream` defines upstream resolvers to be used resolve external names found (think CNAMEs) + pointing to external names. + +All directives from the *file* middleware are supported. Note that *auto* will load all zones found, +even though the directive might only receive queries for a specific zone. I.e: + +~~~ +auto example.org { + directory /etc/coredns/zones +} +~~~ +Will happily pick up a zone for `example.COM`, except it will never be queried, because the *auto* +directive only is authoritative for `example.ORG`. + +## Examples + +Load `org` domains from `/etc/coredns/zones/org` and allow transfers to the internet, but send +notifies to 10.240.1.1 + +~~~ +auto org { + directory /etc/coredns/zones/org + transfer to * + transfer to 10.240.1.1 +} +~~~ + +Load `org` domains from `/etc/coredns/zones/org` and looks for file names as `www.db.example.org`, +where `example.org` is the origin. Scan every 45 seconds. + +~~~ +auto org { + directory /etc/coredns/zones/org www\.db\.(.*) {1} 45 +} +~~~ + diff --git a/content/middleware/bind.md b/content/middleware/bind.md new file mode 100644 index 0000000..88e2eb1 --- /dev/null +++ b/content/middleware/bind.md @@ -0,0 +1,28 @@ ++++ +title = "bind" +description = "*bind* overrides the host to which the server should bind. " +weight = 2 +tags = [ "middleware" , "bind" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +Normally, the listener binds to the wildcard host. However, you may force the listener to bind to +another IP instead. This directive accepts only an address, not a port. + +## Syntax + +~~~ txt +bind ADDRESS +~~~ + +**ADDRESS** is the IP address to bind to. + +## Examples + +To make your socket accessible only to that machine, bind to IP 127.0.0.1 (localhost): + +~~~ txt +bind 127.0.0.1 +~~~ + diff --git a/content/middleware/cache.md b/content/middleware/cache.md new file mode 100644 index 0000000..0774103 --- /dev/null +++ b/content/middleware/cache.md @@ -0,0 +1,74 @@ ++++ +title = "cache" +description = "*cache* enables a frontend cache. It will cache all records except zone transfers and metadata records. " +weight = 3 +tags = [ "middleware" , "cache" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +## Syntax + +~~~ txt +cache [TTL] [ZONES...] +~~~ + +* **TTL** max TTL in seconds. If not specified, the maximum TTL will be used which is 3600 for + noerror responses and 1800 for denial of existence ones. + Setting a TTL of 300 *cache 300* would cache the record up to 300 seconds. +* **ZONES** zones it should cache for. If empty, the zones from the configuration block are used. + +Each element in the cache is cached according to its TTL (with **TTL** as the max). +For the negative cache, the SOA's MinTTL value is used. A cache can contain up to 10,000 items by +default. A TTL of zero is not allowed. + +If you want more control: + +~~~ txt +cache [TTL] [ZONES...] { + success CAPACITY [TTL] + denial CAPACITY [TTL] + prefetch AMOUNT [[DURATION] [PERCENTAGE%]] +} +~~~ + +* **TTL** and **ZONES** as above. +* `success`, override the settings for caching successful responses, **CAPACITY** indicates the maximum + number of packets we cache before we start evicting (*randomly*). **TTL** overrides the cache maximum TTL. +* `denial`, override the settings for caching denial of existence responses, **CAPACITY** indicates the maximum + number of packets we cache before we start evicting (LRU). **TTL** overrides the cache maximum TTL. + There is a third category (`error`) but those responses are never cached. +* `prefetch`, will prefetch popular items when they are about to be expunged from the cache. + Popular means **AMOUNT** queries have been seen no gaps of **DURATION** or more between them. + **DURATION** defaults to 1m. Prefetching will happen when the TTL drops below **PERCENTAGE**, + which defaults to `10%`. Values should be in the range `[10%, 90%]`. Note the percent sign is + mandatory. **PERCENTAGE** is treated as an `int`. + +The minimum TTL allowed on resource records is 5 seconds. + +## Metrics + +If monitoring is enabled (via the *prometheus* directive) then the following metrics are exported: + +* coredns_cache_size{type} - Total elements in the cache by cache type. +* coredns_cache_capacity{type} - Total capacity of the cache by cache type. +* coredns_cache_hits_total{type} - Counter of cache hits by cache type. +* coredns_cache_misses_total - Counter of cache misses. + +Cache types are either "denial" or "success". + +## Examples + +Enable caching for all zones, but cap everything to a TTL of 10 seconds: + +~~~ +cache 10 +~~~ + +Proxy to Google Public DNS and only cache responses for example.org (or below). + +~~~ +proxy . 8.8.8.8:53 +cache example.org +~~~ + diff --git a/content/middleware/chaos.md b/content/middleware/chaos.md new file mode 100644 index 0000000..9ee278b --- /dev/null +++ b/content/middleware/chaos.md @@ -0,0 +1,30 @@ ++++ +title = "chaos" +description = "The *chaos* middleware allows CoreDNS to respond to TXT queries in the CH class. " +weight = 4 +tags = [ "middleware" , "chaos" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +This is useful for retrieving version or author information from the server. + +## Syntax + +~~~ +chaos [VERSION] [AUTHORS...] +~~~ + +* **VERSION** is the version to return. Defaults to `CoreDNS-`, if not set. +* **AUTHORS** is what authors to return. No default. + +Note that you have to make sure that this middleware will get actual queries for the +following zones: `version.bind`, `version.server`, `authors.bind`, `hostname.bind` and +`id.server`. + +## Examples + +~~~ +chaos CoreDNS-001 "Miek Gieben" miek@miek.nl +~~~ + diff --git a/content/middleware/debug.md b/content/middleware/debug.md new file mode 100644 index 0000000..006257c --- /dev/null +++ b/content/middleware/debug.md @@ -0,0 +1,26 @@ ++++ +title = "debug" +description = "*debug* disables the automatic recovery upon a CoreDNS crash so that you'll get a nice stack trace. " +weight = 5 +tags = [ "middleware" , "debug" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +Note that the *errors* middleware (if loaded) will also set a `recover` negating this setting. +The main use of *debug* is to help testing. + +## Syntax + +~~~ txt +debug +~~~ + +## Examples + +Disable CoreDNS' ability to recover from crashes: + +~~~ txt +debug +~~~ + diff --git a/content/middleware/dnssec.md b/content/middleware/dnssec.md new file mode 100644 index 0000000..8e0f7fd --- /dev/null +++ b/content/middleware/dnssec.md @@ -0,0 +1,55 @@ ++++ +title = "dnssec" +description = "*dnssec* enables on-the-fly DNSSEC signing of served data. " +weight = 6 +tags = [ "middleware" , "dnssec" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +## Syntax + +~~~ +dnssec [ZONES...] +~~~ + +* **ZONES** zones that should be signed. If empty, the zones from the configuration block + are used. + +If keys are not specified (see below), a key is generated and used for all signing operations. The +DNSSEC signing will treat this key a CSK (common signing key), forgoing the ZSK/KSK split. All +signing operations are done online. Authenticated denial of existence is implemented with NSEC black +lies. Using ECDSA as an algorithm is preferred as this leads to smaller signatures (compared to +RSA). NSEC3 is *not* supported. + +A single signing key can be specified by using the `key` directive. + +NOTE: Key generation has not been implemented yet. + +TODO(miek): think about key rollovers, and how to do them automatically. + +~~~ +dnssec [ZONES... ] { + key file KEY... + cache_capacity CAPACITY +} +~~~ + +* `key file` indicates that key file(s) should be read from disk. When multiple keys are specified, RRsets + will be signed with all keys. Generating a key can be done with `dnssec-keygen`: `dnssec-keygen -a + ECDSAP256SHA256 `. A key created for zone *A* can be safely used for zone *B*. + +* `cache_capacity` indicates the capacity of the LRU cache. The dnssec middleware uses LRU cache to manage + objects and the default capacity is 10000. + +## Metrics + +If monitoring is enabled (via the *prometheus* directive) then the following metrics are exported: + +* coredns_dnssec_cache_size{type} - total elements in the cache, type is "signature". +* coredns_dnssec_cache_capacity{type} - total capacity of the cache, type is "signature". +* coredns_dnssec_cache_hits_total - Counter of cache hits. +* coredns_dnssec_cache_misses_total - Counter of cache misses. + +## Examples + diff --git a/content/middleware/erratic.md b/content/middleware/erratic.md new file mode 100644 index 0000000..6ae248f --- /dev/null +++ b/content/middleware/erratic.md @@ -0,0 +1,78 @@ ++++ +title = "erratic" +description = "*erratic* is a middleware useful for testing client behavior. It returns a static response to all queries, but the responses can be delayed, dropped or truncated. " +weight = 7 +tags = [ "middleware" , "erratic" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +The *erratic* middleware will respond to every A or AAAA query. For any other type it will return +a SERVFAIL response. The reply for A will return 192.0.2.53 (see RFC 5737), for AAAA it returns +2001:DB8::53 (see RFC 3849). + +## Syntax + +~~~ txt +erratic { + drop [AMOUNT] + truncate [AMOUNT] + delay [AMOUNT [DURATION]] +} +~~~ + +* `drop`: drop 1 per **AMOUNT** of queries, the default is 2. +* `truncate`: truncate 1 per **AMOUNT** of queries, the default is 2. +* `delay`: delay 1 per **AMOUNT** of queries for **DURATION**, the default for **AMOUNT** is 2 and + the default for **DURATION** is 100ms. + +## Examples + +~~~ txt +.:53 { + erratic { + drop 3 + } +} +~~~ + +Or even shorter if the defaults suits you. Note this only drops queries, it does not delay them. + +~~~ txt +. { + erratic +} +~~~ + +Delay 1 in 3 queries for 50ms + +~~~ txt +. { + erratic { + delay 3 50ms + } +} +~~~ + +Delay 1 in 3 and truncate 1 in 5. + +~~~ txt +. { + erratic { + delay 3 5ms + truncate 5 + } +} +~~~ + +Drop every second query. + +~~~ txt +. { + erratic { + drop 2 + truncate 2 + } +} +~~~ + diff --git a/content/middleware/errors.md b/content/middleware/errors.md new file mode 100644 index 0000000..3764400 --- /dev/null +++ b/content/middleware/errors.md @@ -0,0 +1,33 @@ ++++ +title = "errors" +description = "*errors* enables error logging. " +weight = 8 +tags = [ "middleware" , "errors" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +Any errors encountered during the query processing will be printed on standard output. + +## Syntax + +~~~ +errors [FILE] +~~~ + +* **FILE** is the log file to create (or append to). The *only* valid name for **FILE** is *stdout* + +## Examples + +Log errors to *stdout*. + +~~~ +errors +~~~ + +Log errors to *stdout*. + +~~~ +errors stdout +~~~ + diff --git a/content/middleware/etcd.md b/content/middleware/etcd.md new file mode 100644 index 0000000..7263348 --- /dev/null +++ b/content/middleware/etcd.md @@ -0,0 +1,155 @@ ++++ +title = "etcd" +description = "*etcd* enables reading zone data from an etcd instance. The data in etcd has to be encoded as a [message](https://github.com/skynetservices/skydns/blob/2fcff74cdc9f9a7dd64189a447ef27ac354b725f/msg/service.go#L26) like [SkyDNS](https://github.com/skynetservices/skydns). It should also work just like SkyDNS. " +weight = 9 +tags = [ "middleware" , "etcd" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +The etcd middleware makes extensive use of the proxy middleware to forward and query other servers +in the network. + +## Syntax + +~~~ +etcd [ZONES...] +~~~ + +* **ZONES** zones etcd should be authoritative for. + +The path will default to `/skydns` the local etcd proxy (http://localhost:2379). +If no zones are specified the block's zone will be used as the zone. + +If you want to `round robin` A and AAAA responses look at the `loadbalance` middleware. + +~~~ +etcd [ZONES...] { + stubzones + path PATH + endpoint ENDPOINT... + upstream ADDRESS... + tls CERT KEY CACERt + debug +} +~~~ + +* `stubzones` enables the stub zones feature. The stubzone is *only* done in the etcd tree located + under the *first* zone specified. +* **PATH** the path inside etcd. Defaults to "/skydns". +* **ENDPOINT** the etcd endpoints. Defaults to "http://localhost:2397". +* `upstream` upstream resolvers to be used resolve external names found in etcd (think CNAMEs) + pointing to external names. If you want CoreDNS to act as a proxy for clients, you'll need to add + the proxy middleware. **ADDRESS** can be an IP address, and IP:port or a string pointing to a file + that is structured as /etc/resolv.conf. +* `tls` followed by: + * no arguments, if the server certificate is signed by a system-installed CA and no client cert is needed + * a single argument that is the CA PEM file, if the server cert is not signed by a system CA and no client cert is needed + * two arguments - path to cert PEM file, the path to private key PEM file - if the server certificate is signed by a system-installed CA and a client certificate is needed + * three arguments - path to cert PEM file, path to client private key PEM file, path to CA PEM file - if the server certificate is not signed by a system-installed CA and client certificate is needed +* `debug` allows for debug queries. Prefix the name with `o-o.debug.` to retrieve extra information in the + additional section of the reply in the form of TXT records. + +## Examples + +This is the default SkyDNS setup, with everying specified in full: + +~~~ +.:53 { + etcd skydns.local { + stubzones + path /skydns + endpoint http://localhost:2379 + upstream 8.8.8.8:53 8.8.4.4:53 + } + prometheus + cache 160 skydns.local + loadbalance + proxy . 8.8.8.8:53 8.8.4.4:53 +} +~~~ + +Or a setup where we use `/etc/resolv.conf` as the basis for the proxy and the upstream +when resolving external pointing CNAMEs. + +~~~ +.:53 { + etcd skydns.local { + path /skydns + upstream /etc/resolv.conf + } + cache 160 skydns.local + proxy . /etc/resolv.conf +} +~~~ + + +### Reverse zones + +Reverse zones are supported. You need to make CoreDNS aware of the fact that you are also +authoritative for the reverse. For instance if you want to add the reverse for 10.0.0.0/24, you'll +need to add the zone `0.0.10.in-addr.arpa` to the list of zones. (The fun starts with IPv6 reverse zones +in the ip6.arpa domain.) Showing a snippet of a Corefile: + +~~~ + etcd skydns.local 0.0.10.in-addr.arpa { + stubzones + ... +~~~ + +Next you'll need to populate the zone with reverse records, here we add a reverse for +10.0.0.127 pointing to reverse.skydns.local. + +~~~ +% curl -XPUT http://127.0.0.1:4001/v2/keys/skydns/arpa/in-addr/10/0/0/127 \ + -d value='{"host":"reverse.skydns.local."}' +~~~ + +Querying with dig: + +~~~ +% dig @localhost -x 10.0.0.127 +short +reverse.atoom.net. +~~~ + +Or with *debug* queries enabled: + +~~~ +% dig @localhost -p 1053 o-o.debug.127.0.0.10.in-addr.arpa. PTR + +;; OPT PSEUDOSECTION: +; EDNS: version: 0, flags:; udp: 4096 +;; QUESTION SECTION: +;o-o.debug.127.0.0.10.in-addr.arpa. IN PTR + +;; ANSWER SECTION: +127.0.0.10.in-addr.arpa. 300 IN PTR reverse.atoom.net. + +;; ADDITIONAL SECTION: +127.0.0.10.in-addr.arpa. 300 CH TXT "reverse.atoom.net.:0(10,0,,false)[0,]" +~~~ + +## Debug queries + +When debug queries are enabled CoreDNS will return errors and etcd records encountered during the resolution +process in the response. The general form looks like this: + + skydns.test.skydns.dom.a. 0 CH TXT "127.0.0.1:0(10,0,,false)[0,]" + +This shows the complete key as the owername, the rdata of the TXT record has: +`host:port(priority,weight,txt content,mail)[targetstrip,group]`. + +Errors when communicating with an upstream will be returned as: `host:0(0,0,error message,false)[0,]`. + +An example: + + www.example.org. 0 CH TXT "www.example.org.:0(0,0, IN A: unreachable backend,false)[0,]" + +Signalling that an A record for www.example.org. was sought, but it failed with that error. + +Any errors seen doing parsing will show up like this: + + . 0 CH TXT "/skydns/local/skydns/r/a: invalid character '.' after object key:value pair" + +which shows `a.r.skydns.local.` has a json encoding problem. + diff --git a/content/middleware/file.md b/content/middleware/file.md new file mode 100644 index 0000000..22f734a --- /dev/null +++ b/content/middleware/file.md @@ -0,0 +1,60 @@ ++++ +title = "file" +description = "*file* enables serving zone data from an RFC 1035-style master file. " +weight = 10 +tags = [ "middleware" , "file" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +The file middleware is used for an "old-style" DNS server. It serves from a preloaded file that exists +on disk. If the zone file contains signatures (i.e. is signed, i.e. DNSSEC) correct DNSSEC answers +are returned. Only NSEC is supported! If you use this setup *you* are responsible for resigning the +zonefile. + +## Syntax + +~~~ +file DBFILE [ZONES...] +~~~ + +* **DBFILE** the database file to read and parse. If the path is relative the path from the *root* + directive will be prepended to it. +* **ZONES** zones it should be authoritative for. If empty, the zones from the configuration block + are used. + +If you want to round robin A and AAAA responses look at the *loadbalance* middleware. + +TSIG key configuration is TODO; directive format for transfer will probably be extended with +TSIG key information, something like `transfer out [ADDRESS...] key [NAME[:ALG]] [BASE64]` + +~~~ +file DBFILE [ZONES... ] { + transfer to ADDRESS... + no_reload + upstream ADDRESS... +} +~~~ + +* `transfer` enables zone transfers. It may be specified multiples times. `To` or `from` signals + the direction. **ADDRESS** must be denoted in CIDR notation (127.0.0.1/32 etc.) or just as plain + addresses. The special wildcard `*` means: the entire internet (only valid for 'transfer to'). + When an address is specified a notify message will be send whenever the zone is reloaded. +* `no_reload` by default CoreDNS will reload a zone from disk whenever it detects a change to the + file. This option disables that behavior. +* `upstream` defines upstream resolvers to be used resolve external names found (think CNAMEs) + pointing to external names. This is only really useful when CoreDNS is configured as a proxy, for + normal authoritative serving you don't need *or* want to use this. + +## Examples + +Load the `example.org` zone from `example.org.signed` and allow transfers to the internet, but send +notifies to 10.240.1.1 + +~~~ +file example.org.signed example.org { + transfer to * + transfer to 10.240.1.1 +} +~~~ + diff --git a/content/middleware/health.md b/content/middleware/health.md new file mode 100644 index 0000000..9ba392f --- /dev/null +++ b/content/middleware/health.md @@ -0,0 +1,26 @@ ++++ +title = "health" +description = "This module enables a simple health check endpoint. By default it will listen on port 8080. " +weight = 11 +tags = [ "middleware" , "health" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +## Syntax + +~~~ +health [ADDRESS] +~~~ + +Optionally takes an address; the default is `:8080`. The health path is fixed to `/health`. It +will just return "OK" when CoreDNS is healthy, which currently mean: it is up and running. + +This middleware only needs to be enabled once. + +## Examples + +~~~ +health localhost:8091 +~~~ + diff --git a/content/middleware/hosts.md b/content/middleware/hosts.md new file mode 100644 index 0000000..fbde214 --- /dev/null +++ b/content/middleware/hosts.md @@ -0,0 +1,51 @@ ++++ +title = "hosts" +description = "*hosts* enables serving zone data from a `/etc/hosts` style file. " +weight = 12 +tags = [ "middleware" , "hosts" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +The hosts middleware is useful for serving zones from a /etc/hosts file. It serves from a preloaded +file that exists on disk. It checks the file for changes and updates the zones accordingly. This +middleware only supports A, AAAA, and PTR records. The hosts middleware can be used with readily +available hosts files that block access to advertising servers. + +## Syntax + +~~~ +hosts [FILE [ZONES...]] { + fallthrough +} +~~~ + +* **FILE** the hosts file to read and parse. If the path is relative the path from the *root* + directive will be prepended to it. Defaults to /etc/hosts if omitted +* **ZONES** zones it should be authoritative for. If empty, the zones from the configuration block + are used. +* `fallthrough` If zone matches and no record can be generated, pass request to the next middleware. + +## Examples + +Load `/etc/hosts` file. + +~~~ +hosts +~~~ + +Load `example.hosts` file in the current directory. + +~~~ +hosts example.hosts +~~~ + +Load example.hosts file and only serve example.org and example.net from it and fall through to the +next middleware if query doesn't match. + +~~~ +hosts example.hosts example.org example.net { + fallthrough +} +~~~ + diff --git a/content/middleware/kubernetes.md b/content/middleware/kubernetes.md new file mode 100644 index 0000000..0e665d8 --- /dev/null +++ b/content/middleware/kubernetes.md @@ -0,0 +1,273 @@ ++++ +title = "kubernetes" +description = "The *kubernetes* middleware enables the reading zone data from a Kubernetes cluster. It implements the [Kubernetes DNS-Based Service Discovery Specification](https://github.com/kubernetes/dns/blob/master/docs/specification.md). " +weight = 13 +tags = [ "middleware" , "kubernetes" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +CoreDNS running the kubernetes middleware can be used as a replacement of kube-dns in a kubernetes cluster. See the [deployment](https://github.com/coredns/deployment) repository for details on [how to deploy CoreDNS in Kubernetes](https://github.com/coredns/deployment/tree/master/kubernetes). + +## Syntax + +``` +kubernetes ZONE [ZONE...] [{ + [resyncperiod DURATION] + [endpoint URL + [tls CERT-FILE KEY-FILE CACERT-FILE]] + [namespaces NAMESPACE [NAMESPACE...]] + [labels EXPRESSION] + [pods POD-MODE] + [cidrs CIDR [CIDR...]] + [upstream ADDRESS [ADDRESS...]] + [federation NAME DOMAIN] + [autopath [NDOTS [RESPONSE [RESOLV-CONF]]] + [fallthrough] +}] +``` + +* `resyncperiod` **DURATION** + + The Kubernetes data API resynchronization period. Default is 5m. Example values: 60s, 5m, 1h + + Example: + + ``` + kubernetes cluster.local. { + resyncperiod 15m + } + ``` + +* `endpoint` **URL** + + Use **URL** for a remote k8s API endpoint. If omitted, it will connect to k8s in-cluster using the cluster service account. + + Example: + + ``` + kubernetes cluster.local. { + endpoint http://k8s-endpoint:8080 + } + ``` + +* `tls` **CERT-FILE KEY-FILE CACERT-FILE** + + The TLS cert, key and the CA cert file names for remote k8s connection. This option is ignored if connecting in-cluster (i.e. endpoint is not +specified). + + Example: + + ``` + kubernetes cluster.local. { + endpoint https://k8s-endpoint:8443 + tls cert key cacert + } + ``` + +* `namespaces` **NAMESPACE [NAMESPACE...]** + + Only expose the k8s namespaces listed. If this option is omitted all namespaces are exposed + + Example: + + ``` + kubernetes cluster.local. { + namespaces demo default + } + ``` + +* `labels` **EXPRESSION** + + Only expose the records for Kubernetes objects that match this label selector. The label selector syntax is described in the [Kubernetes User Guide - Labels](http://kubernetes.io/docs/user-guide/labels/). + + Example: + + The following example only exposes objects labeled as "application=nginx" in the "staging" or "qa" environments. + + ``` + kubernetes cluster.local. { + labels environment in (staging, qa),application=nginx + } + ``` + +* `pods` **POD-MODE** + + Set the mode for handling IP-based pod A records, e.g. `1-2-3-4.ns.pod.cluster.local. in A 1.2.3.4`. This option is provided to facilitate use of SSL certs when connecting directly to pods. + + Valid values for **POD-MODE**: + + * `disabled`: Default. Do not process pod requests, always returning `NXDOMAIN` + + * `insecure`: Always return an A record with IP from request (without checking k8s). This option is is vulnerable to abuse if used maliciously in conjunction with wildcard SSL certs. This option is provided for backward compatibility with kube-dns. + + * `verified`: Return an A record if there exists a pod in same namespace with matching IP. This option requires substantially more memory than in insecure mode, since it will maintain a watch on all pods. + + Example: + + + ``` + kubernetes cluster.local. { + pods verified + } + ``` + +* `cidrs` **CIDR [CIDR...]** + + Expose cidr ranges to reverse lookups. Include any number of space delimited cidrs, and/or multiple cidrs options on separate lines. The Kubernetes middleware will respond to PTR requests for ip addresses that fall within these ranges. + + Example: + + + ``` + kubernetes cluster.local. { + cidrs 10.0.0.0/24 10.0.10.0/25 + } + + ``` + +* `upstream` **ADDRESS [ADDRESS...]** + + Defines upstream resolvers used for resolving services that point to external hosts (External Services). **ADDRESS** can be an ip, an ip:port, or a path to a file structured like resolv.conf. + + Example: + + ``` + kubernetes cluster.local. { + upstream 12.34.56.78:5053 + } + + ``` + +* `federation` **NAME DOMAIN** + + Defines federation membership. One line for each federation membership. Each line consists of the name of the federation, and the domain. + + Example: + + ``` + kubernetes cluster.local. { + federation myfed foo.example.com + } + ``` + +* `autopath` **[NDOTS [RESPONSE [RESOLV-CONF]]** + + Enables server side search path lookups for pods. When enabled, the kubernetes middleware will identify search path queries from pods and perform the remaining lookups in the path on the pod's behalf. The search path used mimics the resolv.conf search path deployed to pods by the "cluster-first" dns-policy. E.g. + + ``` + search ns1.svc.cluster.local svc.cluster.local cluster.local foo.com + ``` + + If no domains in the path produce an answer, a lookup on the bare question will be attempted. + + A successful response will contain a question section with the original question, and an answer section containing the record for the question that actually had an answer. This means that the question and answer will not match. To avoid potential client confusion, a dynamically generated CNAME entry is added to join the two. For example: + + ``` + # host -v -t a google.com + Trying "google.com.default.svc.cluster.local" + ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50957 + ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 + + ;; QUESTION SECTION: + ;google.com.default.svc.cluster.local. IN A + + ;; ANSWER SECTION: + google.com.default.svc.cluster.local. 175 IN CNAME google.com. + google.com. 175 IN A 216.58.194.206 + ``` + + **Fully Qualified Queries:** There is a known limitation of the autopath feature involving fully qualified queries. When the kubernetes middleware receives a query from a client, it cannot tell the difference between a query that was fully qualified by the user, and one that was expanded by the first search path on the client side. + + This means that the kubernetes middleware with autopath enabled will perform a server-side path search for the query `google.com.default.svc.cluster.local.` as if the client had queried just `google.com`. In other words, a query for `google.com.default.svc.cluster.local.` will produce the IP address for `google.com` as seen below. + + ``` + # host -t a google.com + google.com has address 216.58.194.206 + google.com.default.svc.cluster.local is an alias for google.com. + + # host -t a google.com.default.svc.cluster.local. + google.com has address 216.58.194.206 + google.com.default.svc.cluster.local is an alias for google.com. + ``` + + **NDOTS** (default: `0`) This provides an adjustable threshold to prevent server side lookups from triggering. If the number of dots before the first search domain is less than this number, then the search path will not executed on the server side. When autopath is enabled with default settings, the search path is always conducted when the query is in the first search domain `.svc..`. + + **RESPONSE** (default: `NOERROR`) This option causes the kubernetes middleware to return the given response instead of NXDOMAIN when the all searches in the path produce no results. Valid values: `NXDOMAIN`, `SERVFAIL` or `NOERROR`. Setting this to `SERVFAIL` or `NOERROR` should prevent the client from fruitlessly continuing the client side searches in the path after the server already checked them. + + **RESOLV-CONF** (default: `/etc/resolv.conf`) If specified, the kubernetes middleware uses this file to get the host's search domains. The kubernetes middleware performs a lookup on these domains if the in-cluster search domains in the path fail to produce an answer. If not specified, the values will be read from the local resolv.conf file (i.e the resolv.conf file in the pod containing CoreDNS). In practice, this option should only need to be used if running CoreDNS outside of the cluster and the search path in /etc/resolv.conf does not match the cluster's "default" dns-policiy. + + Enabling autopath requires more memory, since it needs to maintain a watch on all pods. If autopath and `pods verified` mode are both enabled, they will share the same watch. Enabling both options should have an equivalent memory impact of just one. + + Example: + + ``` + kubernetes cluster.local. { + autopath 0 NXDOMAIN /etc/resolv.conf + } + ``` + +* `fallthrough` + + If a query for a record in the cluster zone results in NXDOMAIN, normally that is what the response will be. However, if you specify this option, the query will instead be passed on down the middleware chain, which can include another middleware to handle the query. + + +## Examples + +**Example 1:** This is a minimal configuration with no options other than zone. It will handle all queries in the `cluster.local` zone and connect to Kubernetes in-cluster, but it will not provide PTR records for services, or A records for pods. + + kubernetes cluster.local + +**Example 2:** Handle all queries in the `cluster.local` zone. Connect to Kubernetes in-cluster. Handle all `PTR` requests in the `10.0.0.0/16` cidr block. Verify the existence of pods when answering pod requests. Resolve upstream records against `10.102.3.10`. Enable the autopath feature. + + kubernetes cluster.local { + cidrs 10.0.0.0/16 + pods verified + upstream 10.102.3.10:53 + autopath + } + +**Selective Exposure Example:** Handle all queries in the `cluster.local` zone. Connect to Kubernetes in-cluster. Only expose objects in the test and staging namespaces. Handle all `PTR` requests that fall between `10.0.0.100` and `10.0.0.255` (expressed as CIDR blocks in the example below). Resolve upstream records using the servers configured in `/etc/resolv.conf`. + + kubernetes cluster.local { + namespaces test staging + cidrs 10.0.0.100/30 10.0.0.104/29 + cidrs 10.0.0.112/28 10.0.0.128/25 + upstream /etc/resolv.conf + } + +**Federation Example:** Handle all queries in the `cluster.local` zone. Connect to Kubernetes in-cluster. Handle federated service requests in the `prod` and `stage` federations. Handle all `PTR` requests in the `10.0.0.0/24` cidr block. Resolve upstream records using the servers configured in `/etc/resolv.conf`. + + kubernetes cluster.local { + federation prod prod.feddomain.com + federation stage stage.feddomain.com + cidrs 10.0.0.0/24 + upstream /etc/resolv.conf + } + +**Out-Of-Cluster Example:** Handle all queries in the `cluster.local` zone. Connect to Kubernetes from outside the cluster. Handle all `PTR` requests in the `10.0.0.0/24` cidr block. Verify the existence of pods when answering pod requests. Resolve upstream records against `10.102.3.10`. Enable the autopath feature, using the `cluster.conf` file instead of `/etc/resolv.conf`. + + kubernetes cluster.local { + endpoint https://k8s-endpoint:8443 + tls cert key cacert + cidrs 10.0.0.0/24 + pods verified + upstream 10.102.3.10:53 + autopath 0 NOERROR cluster.conf + } + + + +## Wildcards + +Some query labels accept a wildcard value to match any value. If a label is a valid wildcard (\*, or the word "any"), then that label will match all values. The labels that accept wildcards are: + + * _service_ in an `A` record request: _service_.namespace.svc.zone. + * e.g. `*.ns.svc.myzone.local` + * _namespace_ in an `A` record request: service._namespace_.svc.zone. + * e.g. `nginx.*.svc.myzone.local` + * _port and/or protocol_ in an `SRV` request: __port_.__protocol_.service.namespace.svc.zone. + * e.g. `_http.*.service.ns.svc.` + * multiple wild cards are allowed in a single query. + * e.g. `A` Request `*.*.svc.zone.` or `SRV` request `*.*.*.*.svc.zone.` + diff --git a/content/middleware/loadbalance.md b/content/middleware/loadbalance.md new file mode 100644 index 0000000..62c86e8 --- /dev/null +++ b/content/middleware/loadbalance.md @@ -0,0 +1,23 @@ ++++ +title = "loadbalance" +description = "*loadbalance* acts as a round-robin DNS loadbalancer by randomizing the order of A and AAAA records in the answer. See [Wikipedia](https://en.wikipedia.org/wiki/Round-robin_DNS) about the pros and cons on this setup. It will take care to sort any CNAMEs before any address records, because some stub resolver implementations (like glibc) are particular about that. " +weight = 14 +tags = [ "middleware" , "loadbalance" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +## Syntax + +~~~ +loadbalance [POLICY] +~~~ + +* **POLICY** is how to balance, the default is "round_robin" + +## Examples + +~~~ +loadbalance round_robin +~~~ + diff --git a/content/middleware/log.md b/content/middleware/log.md new file mode 100644 index 0000000..0558737 --- /dev/null +++ b/content/middleware/log.md @@ -0,0 +1,106 @@ ++++ +title = "log" +description = "*log* enables query logging to standard output. " +weight = 15 +tags = [ "middleware" , "log" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +## Syntax + +~~~ txt +log +~~~ + +* With no arguments, a query log entry is written to *stdout* in the common log format for all requests + +~~~ txt +log FILE +~~~ + +* **FILE** is the log file to create (or append to). The *only* valid name for **FILE** is *stdout*. + +~~~ txt +log [NAME] FILE [FORMAT] +~~~ + +* `NAME` is the name to match in order to be logged +* `FILE` is the log file (again only *stdout* is allowed here). +* `FORMAT` is the log format to use (default is Common Log Format) + +You can further specify the class of responses that get logged: + +~~~ txt +log [NAME] FILE [FORMAT] { + class [success|denial|error|all] +} +~~~ + +Here `success` `denial` and `error` denotes the class of responses that should be logged. The +classes have the following meaning: + +* `success`: successful response +* `denial`: either NXDOMAIN or NODATA (name exists, type does not) +* `error`: SERVFAIL, NOTIMP, REFUSED, etc. Anything that indicates the remote server is not willing to + resolve the request. +* `all`: the default - nothing is specified. + +If no class is specified, it defaults to *all*. + +## Log File + +The "log file" can only be *stdout*. CoreDNS expects another service to pick up this output and deal +with it, i.e. journald when using systemd or Docker's logging capabilities. + +## Log Format + +You can specify a custom log format with any placeholder values. Log supports both request and +response placeholders. + +The following place holders are supported: + +* `{type}`: qtype of the request. +* `{name}`: qname of the request. +* `{class}`: qclass of the request. +* `{proto}`: protocol used (tcp or udp). +* `{when}`: time of the query. +* `{remote}`: client's IP address. +* `{size}`: request size in bytes. +* `{port}`: client's port. +* `{duration}`: response duration. +* `{>bufsize}`: the EDNS0 buffer size advertised. +* `{>do}`: is the EDNS0 DO (DNSSEC OK) bit set. +* `{>id}`: query ID +* `{>opcode}`: query OPCODE. +* `{rcode}`: response RCODE. +* `{rsize}`: response size. + +The default Common Log Format is: + +~~~ txt +`{remote} - [{when}] "{type} {class} {name} {proto} {size} {>do} {>bufsize}" {rcode} {rsize} {duration}` +~~~ + +## Examples + +Log all requests to stdout + +~~~ +log stdout +~~~ + +Custom log format, for all zones (`.`) + +~~~ +log . stdout "{proto} Request: {name} {type} {>id}" +~~~ + +Only log denials for example.org (and below to a file) + +~~~ +log example.org stdout { + class denial +} +~~~ + diff --git a/content/middleware/metrics.md b/content/middleware/metrics.md new file mode 100644 index 0000000..ac83d28 --- /dev/null +++ b/content/middleware/metrics.md @@ -0,0 +1,59 @@ ++++ +title = "prometheus" +description = "This module enables prometheus metrics for CoreDNS. " +weight = 16 +tags = [ "middleware" , "metrics" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +The default location for the metrics is `localhost:9153`. The metrics path is fixed to `/metrics`. +The following metrics are exported: + +* coredns_dns_request_count_total{zone, proto, family} +* coredns_dns_request_duration_milliseconds{zone} +* coredns_dns_request_size_bytes{zone, proto} +* coredns_dns_request_do_count_total{zone} +* coredns_dns_request_type_count_total{zone, type} +* coredns_dns_response_size_bytes{zone, proto} +* coredns_dns_response_rcode_count_total{zone, rcode} + +Each counter has a label `zone` which is the zonename used for the request/response. + +Extra labels used are: + +* `proto` which holds the transport of the response ("udp" or "tcp") +* The address family (`family`) of the transport (1 = IP (IP version 4), 2 = IP6 (IP version 6)). +* `type` which holds the query type. It holds most common types (A, AAAA, MX, SOA, CNAME, PTR, TXT, + NS, SRV, DS, DNSKEY, RRSIG, NSEC, NSEC3, IXFR, AXFR and ANY) and "other" which lumps together all + other types. +* The `response_rcode_count_total` has an extra label `rcode` which holds the rcode of the response. + +If monitoring is enabled, queries that do not enter the middleware chain are exported under the fake +name "dropped" (without a closing dot - this is never a valid domain name). + + +## Syntax + +~~~ +prometheus [ADDRESS] +~~~ + +For each zone that you want to see metrics for. + +It optionally takes an address to which the metrics are exported; the default +is `localhost:9153`. The metrics path is fixed to `/metrics`. + +## Examples + +Use an alternative address: + +~~~ +prometheus localhost:9253 +~~~ + +# Bugs + +When reloading, we keep the handler running, meaning that any changes to the handler's address +aren't picked up. You'll need to restart CoreDNS for that to happen. + diff --git a/content/middleware/pprof.md b/content/middleware/pprof.md new file mode 100644 index 0000000..929cee0 --- /dev/null +++ b/content/middleware/pprof.md @@ -0,0 +1,47 @@ ++++ +title = "pprof" +description = "*pprof* publishes runtime profiling data at endpoints under /debug/pprof. " +weight = 17 +tags = [ "middleware" , "pprof" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +You can visit `/debug/pprof` on your site for an index of the available endpoints. By default it +will listen on localhost:6053. + +> This is a debugging tool. Certain requests (such as collecting execution traces) can be slow. If +> you use pprof on a live site, consider restricting access or enabling it only temporarily. + +For more information, please see [Go's pprof +documentation](https://golang.org/pkg/net/http/pprof/) and read +[Profiling Go Programs](https://blog.golang.org/profiling-go-programs). + +## Syntax + +~~~ +pprof [ADDRESS] +~~~ + +If not specified, ADDRESS defaults to localhost:6053. + +## Examples + +Enable pprof endpoints: + +~~~ +pprof +~~~ + +Listen on an alternate address: + +~~~ +pprof 10.9.8.7:6060 +~~~ + +Listen on an all addresses on port 6060: + +~~~ +pprof :6060 +~~~ + diff --git a/content/middleware/proxy.md b/content/middleware/proxy.md new file mode 100644 index 0000000..2d8fc26 --- /dev/null +++ b/content/middleware/proxy.md @@ -0,0 +1,181 @@ ++++ +title = "proxy" +description = "*proxy* facilitates both a basic reverse proxy and a robust load balancer. " +weight = 18 +tags = [ "middleware" , "proxy" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +The proxy has support for multiple backends. The load balancing features include multiple policies, +health checks, and failovers. If all hosts fail their health check the proxy middleware will fail +back to randomly selecting a target and sending packets to it. + +## Syntax + +In its most basic form, a simple reverse proxy uses this syntax: + +~~~ +proxy FROM TO +~~~ + +* **FROM** is the base domain to match for the request to be proxied. +* **TO** is the destination endpoint to proxy to. + +However, advanced features including load balancing can be utilized with an expanded syntax: + +~~~ +proxy FROM TO... { + policy random|least_conn|round_robin + fail_timeout DURATION + max_fails INTEGER + health_check PATH:PORT [DURATION] + except IGNORED_NAMES... + spray + protocol [dns [force_tcp]|https_google [bootstrap ADDRESS...]|grpc [insecure|CA-PEM|KEY-PEM CERT-PEM|KEY-PEM CERT-PEM CA-PEM]] +} +~~~ + +* **FROM** is the name to match for the request to be proxied. +* **TO** is the destination endpoint to proxy to. At least one is required, but multiple may be + specified. **TO** may be an IP:Port pair, or may reference a file in resolv.conf format +* `policy` is the load balancing policy to use; applies only with multiple backends. May be one of + random, least_conn, or round_robin. Default is random. +* `fail_timeout` specifies how long to consider a backend as down after it has failed. While it is + down, requests will not be routed to that backend. A backend is "down" if CoreDNS fails to + communicate with it. The default value is 10 seconds ("10s"). +* `max_fails` is the number of failures within fail_timeout that are needed before considering + a backend to be down. If 0, the backend will never be marked as down. Default is 1. +* `health_check` will check path (on port) on each backend. If a backend returns a status code of + 200-399, then that backend is marked healthy for double the healthcheck duration. If it doesn't, + it is marked as unhealthy and no requests are routed to it. If this option is not provided then + health checks are disabled. The default duration is 30 seconds ("30s"). +* **IGNORED_NAMES** in `except` is a space-separated list of domains to exclude from proxying. + Requests that match none of these names will be passed through. +* `spray` when all backends are unhealthy, randomly pick one to send the traffic to. (This is + a failsafe.) +* `protocol` specifies what protocol to use to speak to an upstream, `dns` (the default) is plain + old DNS, and `https_google` uses `https://dns.google.com` and speaks a JSON DNS dialect. Note when + using this **TO** will be ignored. The `grpc` option will talk to a server that has implemented + the [DnsService](https://github.com/coredns/coredns/pb/dns.proto). + An out-of-tree middleware that implements the server side of this can be found at + [here](https://github.com/infobloxopen/coredns-grpc). + +## Policies + +There are three load-balancing policies available: +* `random` (default) - Randomly select a backend +* `least_conn` - Select the backend with the fewest active connections +* `round_robin` - Select the backend in round-robin fashion + +All polices implement randomly spraying packets to backend hosts when *no healthy* hosts are +available. This is to preeempt the case where the healthchecking (as a mechanism) fails. + +## Upstream Protocols + +Currently `protocol` supports `dns` (i.e., standard DNS over UDP/TCP) and `https_google` (JSON +payload over HTTPS). Note that with `https_google` the entire transport is encrypted. Only *you* and +*Google* can see your DNS activity. + +* `dns`: uses the standard DNS exchange. You can pass `force_tcp` to make sure that the proxied connection is performed + over TCP, regardless of the inbound request's protocol. +* `https_google`: bootstrap **ADDRESS...** is used to (re-)resolve `dns.google.com` to an address to + connect to. This happens every 300s. If not specified the default is used: 8.8.8.8:53/8.8.4.4:53. + Note that **TO** is *ignored* when `https_google` is used, as its upstream is defined as + `dns.google.com`. + + Debug queries are enabled by default and currently there is no way to turn them off. When CoreDNS + receives a debug query (i.e. the name is prefixed with `o-o.debug.`) a TXT record with Comment + from `dns.google.com` is added. Note this is not always set. +* `grpc`: options are used to control how the TLS connection is made to the gRPC server. + * None - No client authentication is used, and the system CAs are used to verify the server certificate. + * `insecure` - TLS is not used, the connection is made in plaintext (not good in production). + * CA-PEM - No client authentication is used, and the file CA-PEM is used to verify the server certificate. + * KEY-PEM CERT-PEM - Client authentication is used with the specified key/cert pair. The server + certificate is verified with the system CAs. + * KEY-PEM CERT-PEM CA-PEM - Client authentication is used with the specified key/cert pair. The + server certificate is verified using the CA-PEM file. + + An out-of-tree middleware that implements the server side of this can be found at + [here](https://github.com/infobloxopen/coredns-grpc). + +## Metrics + +If monitoring is enabled (via the *prometheus* directive) then the following metric is exported: + +* coredns_proxy_request_count_total{proto, proxy_proto, from} + +Where `proxy_proto` is the protocol used (`dns`, `grpc`, or `https_google`) and `from` is **FROM** +specified in the config, `proto` is the protocol used by the incoming query ("tcp" or "udp"). + +## Examples + +Proxy all requests within example.org. to a backend system: + +~~~ +proxy example.org localhost:9005 +~~~ + +Load-balance all requests between three backends (using random policy): + +~~~ +proxy . dns1.local:53 dns2.local:1053 dns3.local +~~~ + +Same as above, but round-robin style: + +~~~ +proxy . dns1.local:53 dns2.local:1053 dns3.local { + policy round_robin +} +~~~ + +With health checks and proxy headers to pass hostname, IP, and scheme upstream: + +~~~ +proxy . dns1.local:53 dns2.local:53 dns3.local:53 { + policy round_robin + health_check /health:8080 +} +~~~ + +Proxy everything except requests to miek.nl or example.org + +~~~ +proxy . backend:1234 { + except miek.nl example.org +} +~~~ + +Proxy everything except example.org using the host resolv.conf nameservers: + +~~~ +proxy . /etc/resolv.conf { + except miek.nl example.org +} +~~~ + +Proxy all requests within example.org to Google's dns.google.com. + +~~~ +proxy example.org 1.2.3.4:53 { + protocol https_google +} +~~~ + +Proxy everything with HTTPS to `dns.google.com`, except `example.org`. Then have another proxy in +another stanza that uses plain DNS to resolve names under `example.org`. + +~~~ +. { + proxy . 1.2.3.4:53 { + except example.org + protocol https_google + } +} + +example.org { + proxy . 8.8.8.8:53 +} +~~~ + diff --git a/content/middleware/reverse.md b/content/middleware/reverse.md new file mode 100644 index 0000000..fc3a970 --- /dev/null +++ b/content/middleware/reverse.md @@ -0,0 +1,92 @@ ++++ +title = "reverse" +description = "The *reverse* middleware allows CoreDNS to respond dynamically to a PTR request and the related A/AAAA request. " +weight = 19 +tags = [ "middleware" , "reverse" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +## Syntax + +~~~ +reverse NETWORK... { + hostname TEMPLATE + [ttl TTL] + [fallthrough] + [wildcard] +~~~ + +* **NETWORK** one or more CIDR formatted networks to respond on. +* `hostname` injects the IP and zone to a template for the hostname. Defaults to "ip-{IP}.{zone[1]}". See below for template. +* `ttl` defaults to 60 +* `fallthrough` if zone matches and no record can be generated, pass request to the next middleware. +* `wildcard` allows matches to catch all subdomains as well. + +### Template Syntax + +The template for the hostname is used for generating the PTR for a reverse lookup and matching the +forward lookup back to an IP. + +#### `{ip}` + +The `{ip}` symbol is **required** to make reverse work. +For IPv4 lookups the IP is directly extracted +With IPv6 lookups the ":" is removed, and any zero ranged are expanded, e.g., +"ffff::ffff" results in "ffff000000000000000000000000ffff" + +#### `{zone[i]}` + +The `{zone[i]}` symbol is **optional** and can be replaced by a fixed (zone) string. +The zone will be matched by the zones listed in *this* configuration stanza. +`i` needs to be replaced with the index of the configured listener zones, starting with 1. + +## Examples + +~~~ txt +arpa compute.internal { + # proxy unmatched requests + proxy . 8.8.8.8 + + # answer requests for IPs in this network + # PTR 1.0.32.10.in-addr.arpa. 3600 ip-10.0.32.1.compute.internal. + # A ip-10.0.32.1.compute.internal. 3600 10.0.32.1 + # v6 is also possible + # PTR 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.d.f.ip6.arpa. 3600 ip-fd010000000000000000000000000001.compute.internal. + # AAAA ip-fd010000000000000000000000000001.compute.internal. 3600 fd01::1 + reverse 10.32.0.0/16 fd01::/16 { + # template of the ip injection to hostname, zone resolved to compute.internal. + hostname ip-{ip}.{zone[2]} + + ttl 3600 + + # Forward unanswered or unmatched requests to proxy + # without this flag, requesting A/AAAA records on compute.internal. will end here. + fallthrough + } +} +~~~ + + +~~~ txt +32.10.in-addr.arpa.arpa arpa.company.org { + + reverse 10.32.0.0/16 { + # template of the ip injection to hostname, zone resolved to arpa.company.org. + hostname "ip-{ip}.v4.{zone[2]}" + + ttl 3600 + + # fallthrough is not required, v4.arpa.company.org. will be only answered here + } + + # cidr closer to the ip wins, so we can overwrite the "default" + reverse 10.32.2.0/24 { + # its also possible to set fix domain suffix + hostname ip-{ip}.fix.arpa.company.org. + + ttl 3600 + } +} +~~~ + diff --git a/content/middleware/rewrite.md b/content/middleware/rewrite.md new file mode 100644 index 0000000..9f00d65 --- /dev/null +++ b/content/middleware/rewrite.md @@ -0,0 +1,66 @@ ++++ +title = "rewrite" +description = "*rewrite* performs internal message rewriting. " +weight = 20 +tags = [ "middleware" , "rewrite" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +Rewrites are invisible to the client. There are simple rewrites (fast) and complex rewrites +(slower), but they're powerful enough to accommodate most dynamic back-end applications. + +## Syntax + +~~~ +rewrite FIELD FROM TO +~~~ + +* **FIELD** is (`type`, `class`, `name`, ...) +* **FROM** is the exact name of type to match +* **TO** is the destination name or type to rewrite to + +When the FIELD is `type` and FROM is (`A`, `MX`, etc.), the type of the message will be rewritten; +e.g., to rewrite ANY queries to HINFO, use `rewrite type ANY HINFO`. + +When the FIELD is `class` and FROM is (`IN`, `CH`, or `HS`) the class of the message will be +rewritten; e.g., to rewrite CH queries to IN use `rewrite class CH IN`. + +When the FIELD is `name` the query name in the message is rewritten; this +needs to be a full match of the name, e.g., `rewrite name miek.nl example.org`. + +When the FIELD is `edns0` an EDNS0 option can be appended to the request as described below. + +If you specify multiple rules and an incoming query matches on multiple (simple) rules, only +the first rewrite is applied. + +## EDNS0 Options + +Using FIELD edns0, you can set, append, or replace specific EDNS0 options on the request. + +* `replace` will modify any matching (what that means may vary based on EDNS0 type) option with the specified option +* `append` will add the option regardless of what options already exist +* `set` will modify a matching option or add one if none is found + +Currently supported are `EDNS0_LOCAL` and `EDNS0_NSID`. + +### `EDNS0_LOCAL` + +This has two fields, code and data. A match is defined as having the same code. Data may be a string, or if +it starts with `0x` it will be treated as hex. Example: + +~~~ +rewrite edns0 local set 0xffee 0x61626364 +~~~ + +rewrites the first local option with code 0xffee, setting the data to "abcd". Equivalent: + +~~~ +rewrite edns0 local set 0xffee abcd +~~~ + +### `EDNS0_NSID` + +This has no fields; it will add an NSID option with an empty string for the NSID. If the option already exists +and the action is `replace` or `set`, then the NSID in the option will be set to the empty string. + diff --git a/content/middleware/root.md b/content/middleware/root.md new file mode 100644 index 0000000..ca28310 --- /dev/null +++ b/content/middleware/root.md @@ -0,0 +1,28 @@ ++++ +title = "root" +description = "*root* simply specifies the root of where CoreDNS finds (e.g.) zone files. " +weight = 21 +tags = [ "middleware" , "root" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +The default root is the current working directory of CoreDNS. A relative root path is relative to +the current working directory. + +## Syntax + +~~~ txt +root PATH +~~~ + +**PATH** is the directory to set as CoreDNS' root. + +## Examples + +Serve zone data (when the *file* middleware is used) from `/etc/coredns/zones`: + +~~~ txt +root /etc/coredns/zones +~~~ + diff --git a/content/middleware/secondary.md b/content/middleware/secondary.md new file mode 100644 index 0000000..b013a30 --- /dev/null +++ b/content/middleware/secondary.md @@ -0,0 +1,44 @@ ++++ +title = "secondary" +description = "*secondary* enables serving a zone retrieved from a primary server. " +weight = 22 +tags = [ "middleware" , "secondary" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +## Syntax + +~~~ +secondary [ZONES...] +~~~ + +* **ZONES** zones it should be authoritative for. If empty, the zones from the configuration block + are used. Note that without a remote address to *get* the zone from, the above is not that useful. + +A working syntax would be: + +~~~ +secondary [zones...] { + transfer from ADDRESS + transfer to ADDRESS + upstream ADDRESS... +} +~~~ + +* `transfer from` specifies from which address to fetch the zone. It can be specified multiple times; + if one does not work, another will be tried. +* `transfer to` can be enabled to allow this secondary zone to be transferred again. +* `upstream` defines upstream resolvers to be used resolve external names found (think CNAMEs) + pointing to external names. This is only really useful when CoreDNS is configured as a proxy, for + normal authoritative serving you don't need *or* want to use this. + +## Examples + +~~~ +secondary example.org { + transfer from 10.0.1.1 + transfer from 10.1.2.1 +} +~~~ + diff --git a/content/middleware/tls.md b/content/middleware/tls.md new file mode 100644 index 0000000..d509ca6 --- /dev/null +++ b/content/middleware/tls.md @@ -0,0 +1,36 @@ ++++ +title = "tls" +description = "*tls* allows you to configure the server certificates for the TLS and gRPC servers. For other types of servers it is ignored. " +weight = 23 +tags = [ "middleware" , "tls" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +## Syntax + +~~~ txt +tls CERT KEY CA +~~~ + +## Examples + +Start a DNS-over-TLS server. + +~~~ +tls://.:4453 { + tls cert.pem key.pem ca.pem + proxy . /etc/resolv.conf +} +~~~ + +Start a DNS-over-gRPC server. If the `tls` directive were omitted, then +it would use plain HTTP not HTTPS. + +~~~ +grpc://.:443 { + tls cert.pem key.pem ca.pem + proxy . /etc/resolv.conf +} +~~~ + diff --git a/content/middleware/trace.md b/content/middleware/trace.md new file mode 100644 index 0000000..0399014 --- /dev/null +++ b/content/middleware/trace.md @@ -0,0 +1,78 @@ ++++ +title = "trace" +description = "This module enables OpenTracing-based tracing of DNS requests as they go through the middleware chain. " +weight = 24 +tags = [ "middleware" , "trace" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +## Syntax + +The simplest form is just: + +~~~ +trace [ENDPOINT-TYPE] [ENDPOINT] +~~~ + +* **ENDPOINT-TYPE** is the type of tracing destination. Currently only `zipkin` is supported + and that is what it defaults to. +* **ENDPOINT** is the tracing destination, and defaults to `localhost:9411`. For Zipkin, if + ENDPOINT does not begin with `http`, then it will be transformed to `http://ENDPOINT/api/v1/spans`. + +With this form, all queries will be traced. + +Additional features can be enabled with this syntax: + +~~~ +trace [ENDPOINT-TYPE] [ENDPOINT] { + every AMOUNT + service NAME + client_server +} +~~~ + +* `every` **AMOUNT** will only trace one query of each AMOUNT queries. For example, to trace 1 in every + 100 queries, use AMOUNT of 100. The default is 1. +* `service` **NAME** allows you to specify the service name reported to the tracing server. + Default is `coredns`. +* `client_server` will enable the `ClientServerSameSpan` OpenTracing feature. + +## Zipkin +You can run Zipkin on a Docker host like this: + +``` +docker run -d -p 9411:9411 openzipkin/zipkin +``` + +## Examples + +Use an alternative Zipkin address: + +~~~ +trace tracinghost:9253 +~~~ + +or + +~~~ +trace zipkin tracinghost:9253 +~~~ + +If for some reason you are using an API reverse proxy or something and need to remap +the standard Zipkin URL you can do something like: + +~~~ +trace http://tracinghost:9411/zipkin/api/v1/spans +~~~ + +Trace one query every 10000 queries, rename the service, and enable same span: + +~~~ +trace tracinghost:9411 { + every 10000 + service dnsproxy + client_server +} +~~~ + diff --git a/content/middleware/whoami.md b/content/middleware/whoami.md new file mode 100644 index 0000000..6822226 --- /dev/null +++ b/content/middleware/whoami.md @@ -0,0 +1,43 @@ ++++ +title = "whoami" +description = "*whoami* returns your local IP address, port and transport used. Your local IP address is returned in the additional section as either an A or AAAA record. " +weight = 25 +tags = [ "middleware" , "whoami" ] +categories = [ "middleware" ] +date = "2017-07-24T15:25:40+00:00" ++++ + +The port and transport are included in the additional section as a SRV record, transport can be +"tcp" or "udp". + +~~~ txt +._.qname. 0 IN SRV 0 0 . +~~~ + +The *whoami* middleware will respond to every A or AAAA query, regardless of the query name. + +## Syntax + +~~~ txt +whoami +~~~ + +## Examples + +~~~ txt +.:53 { + whoami +} +~~~ + +When queried for "example.org A", CoreDNS will respond with: + +~~~ txt +;; QUESTION SECTION: +;example.org. IN A + +;; ADDITIONAL SECTION: +example.org. 0 IN A 10.240.0.1 +_udp.example.org. 0 IN SRV 0 0 40212 +~~~ + diff --git a/data/.gitempty b/data/.gitempty new file mode 100644 index 0000000..e69de29 diff --git a/data/coredns.toml b/data/coredns.toml new file mode 100644 index 0000000..0ed5e14 --- /dev/null +++ b/data/coredns.toml @@ -0,0 +1,2 @@ +[release] + version = "009" diff --git a/data/subtext.toml b/data/subtext.toml new file mode 100644 index 0000000..28402fa --- /dev/null +++ b/data/subtext.toml @@ -0,0 +1,27 @@ +# Oneliners for subtext on the different pages. +# Don't create new paragraphs, because each

adds a read line. + +[docs] + content = """ +How to use CoreDNS. + """ + +[blog] + content = """ +News covering CoreDNS. + """ + +[middleware] + content = """ +Here you can find all [in-tree](https://github.com/coredns/coredns/tree/master/middleware) middleware for CoreDNS. + """ + +[exmiddleware] + content = """ +Here you can find all out-of-tree middleware for CoreDNS. + """ + +[community] + content = """ +CoreDNS is developed in the open. Here are some of the channels we use to communicate and contribute. + """ diff --git a/layouts/.gitempty b/layouts/.gitempty new file mode 100644 index 0000000..e69de29 diff --git a/layouts/partials/popup.html b/layouts/partials/popup.html new file mode 100644 index 0000000..5f14aab --- /dev/null +++ b/layouts/partials/popup.html @@ -0,0 +1,10 @@ +{{ if .Site.Params.popup }} + +

+ Currently we are aware of issues with CoreDNS. + See this page for more info. +
+ +{{else}} + +{{ end }} diff --git a/static/.gitempty b/static/.gitempty new file mode 100644 index 0000000..e69de29 diff --git a/static/images/CoreDNS_Colour_Horizontal.png b/static/images/CoreDNS_Colour_Horizontal.png new file mode 100644 index 0000000..d8f4df0 Binary files /dev/null and b/static/images/CoreDNS_Colour_Horizontal.png differ diff --git a/static/images/cncf-logo.png b/static/images/cncf-logo.png new file mode 100644 index 0000000..4a1cefa Binary files /dev/null and b/static/images/cncf-logo.png differ diff --git a/static/images/favicon.png b/static/images/favicon.png new file mode 100644 index 0000000..803960c Binary files /dev/null and b/static/images/favicon.png differ diff --git a/static/images/query-processing.png b/static/images/query-processing.png new file mode 100644 index 0000000..3c07ff0 Binary files /dev/null and b/static/images/query-processing.png differ diff --git a/themes/coredns/.gitignore b/themes/coredns/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/themes/coredns/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/themes/coredns/LICENSE.md b/themes/coredns/LICENSE.md new file mode 100644 index 0000000..ff11aa1 --- /dev/null +++ b/themes/coredns/LICENSE.md @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 mohamed jebli + +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. diff --git a/themes/coredns/README.md b/themes/coredns/README.md new file mode 100644 index 0000000..3086b38 --- /dev/null +++ b/themes/coredns/README.md @@ -0,0 +1,176 @@ +# kube Theme for Hugo + +`kube` Kube is a professional and a responsive Hugo theme for developers and designers that offers a documentation section mixed with a landing page and a blog. + +I create this theme based on the `Version 6.5.2` [Kube Framework](https://imperavi.com/kube/). + +![kube hugo landingPage](https://cldup.com/RjWtdJZNae.png) + +# Demo + +To see this theme in action, check out [kube project](http://kube.elemnts.org) which is rendered with this theme and some conetnt for documentation and blog posts. + +## Features + +- Mobile-first Design : Every element in kube is mobile-first and fully embraces latest and greatest tech. +- Responsive Design : Optimized for mobile, tablet, desktop +- Horizontal Rhythm : Like Kube framework this theme is based on a 4px vertical grid. +- Typography : beautiful typographie choice +- Google Analytics : Google Analytics using the internal async template +- Disqus Commenting : Post comments with Disqus using the internal template +- OpenGraph support : SEO-optimized using OpenGraph +- Schema Structured Data : Schema Structured Data and Meta tags +- Paginated Lists : Simple list pagination with page indicators +- Reading Time : Post reading time and update notice set user expectations +- Meta data for all blog article : Rich post data including links to category and tag taxonomy listings, author and word count +- Related Posts : Related Content for increased page views and reader loyalty +- Block Templates : Block Templates for foolproof layout extensions +- Table of Contents : Accessible Table of Contents for documentation +- SEO Site Verification : Site verification with Google, Bing Alexa and Yandex +- 404 page : 404 page with animated background + +## Installation + +Inside the folder of your Hugo site run: + + $ mkdir themes + $ cd themes + $ git clone https://github.com/jeblister/kube.git + +For more information read the official [setup guide](//gohugo.io/overview/installing/) for Hugo. + + +Copy custom archetypes to your site: + +```shell +cp themes/kube/archetypes/* archetypes +``` + + +Next, take a look in the `exampleSite` folder at. This directory contains an example config file and the content for the demo. It serves as an example setup for your blog. + +Copy at least the `config.toml` in the root directory of your website. Overwrite the existing config file if necessary. + +Hugo includes a development server, so you can view your changes as you go : + +``` sh +hugo server -w +``` + +Now you can go to [localhost:1313](http://localhost:1313) and the `kube` +theme should be visible. + + +## Getting Started + +There are a few concepts this theme employs to make a personal documentation site. It's important to read this as you may not see what you expect upon launching. It assumes you want to call your documentation posts `docs` and organizes them as such. For example, creating a new docs with Hugo would require you typing: + +``` + $ hugo new --kind docs docs/my-new-doc.md + +``` + +It also assumes you want to display three types of content `docs` and `blog` and some pages : the `faq`, `company` and `sign-in` pages and and display links to this pages in the menu. This guide will take you through the steps to configure your documentation site to use the theme. + +### Configuring you website + +#### Where should blog post markdown files be stored? + +The theme works with other content types, but docs pages work best when grouped under `docs`. When using the `docs` content type you'll have a customized list page sorted by `weight` and the default list page for all documentation. Here's an example: + +![Custom List docs Page](https://cldup.com/8k1nU8TLuU.png) + + + +#### Defining yourself as the Author + +In this case you would want to add `author = "your name"` variable like your name to your post's Front Matter. + + +#### Webmaster Verification + +Verify your site with several webmaster tools including Google, Bing, Alexa and Yandex. To allow verification of your site with any or all of these providers simply add the following to your `config.toml` and fill in their respective values: + +```toml +[params.seo.webmaster_verifications] + google = "" # Optional, Google verification code + bing = "" # Optional, Bing verification code + alexa = "" # Optional, Alexa verification code + yandex = "" # Optional, Yandex verification code +``` + +### Index Blocking + +Just because a page appears in your `sitemap.xml` does not mean you want it to appear in a SERP. Examples of pages which will appear in your `sitemap.xml` that you typically do not want indexed by crawlers include error pages, search pages, legal pages, and pages that simply list summaries of other pages. + +Though it's possible to block search indexing from a `robots.txt` file, kube makes it possible to block page indexing using Hugo configuration as well. By default the following page types will be blocked: + +- Section Pages (e.g. Post listings) +- Taxonomy Pages (e.g. Category and Tag listings) +- Taxonomy Terms Pages (e.g. Pages listing taxonomies) + +To customize default blocking configure the `noindex_kinds` setting in the `[params]` section of your `config.toml`. For example, if you want to enable crawling for sections appearing in [Section Menu](#adding-a-section-menu) add the following to your configuration file: + +``` +[params] + noindex_kinds = [ + "taxonomy", + "taxonomyTerm" + ] +``` + +To block individual pages from being indexed add `nofollow` to your page's front matter and set the value to `true`, like: + +```toml +noindex = true +``` + +And, finally, if you're using Hugo `v0.18` or better, you can also add an `_index.md` file with the `noindex` front matter to control indexing for specific section list layouts: + +```shell +├── content +│ ├── modules +│ │ ├── starry-night.md +│ │ └── flying-toilets.md +│ └── news +│ ├── _index.md +│ └── return-flying-toasters.md +``` + +To learn more about how crawlers use this feature read [block search indexing with meta tags](https://support.google.com/webmasters/answer/93710). + +### Custom CSS + +To add your own theme css or override existing CSS without having to change theme files do the following: + +1. Create a `style.css` in your site's `layouts/static/css directory` or use `custom.css` file in 'themes/kube/static/css/custom.css` +1. Add link to this file in 'themes/kube/layouts/_default/baseof.html'. + +Default `style block` : + +```html + + + +``` + + +## Contributing + +Did you find a bug or have an ideas for new features? Feel free to use the issue tracker to let me know or make a pull request. + +There's only one rule...there are no rules. + +## License + +MIT + +## Credit +[kube framework]: https://imperavi.com/kube/ +[after dark]: https://github.com/comfusion/after-dark + +## Contact + +This is the second theme I've made for Hugo, so I'm sure I've done some things wrong or assumed too much. If you have ideas or things that should be fixed, please let me know. + +- [Mohamed JEBLI](http://findme.surge.sh) [@jebli_7](http://twitter.com/jebli_7) diff --git a/themes/coredns/archetypes/blog.md b/themes/coredns/archetypes/blog.md new file mode 100644 index 0000000..fa57ae6 --- /dev/null +++ b/themes/coredns/archetypes/blog.md @@ -0,0 +1,9 @@ ++++ +title = "" +description = "" +weight = 20 +draft = false +tags = "" +slug = "" +author = "joe" ++++ diff --git a/themes/coredns/archetypes/docs.md b/themes/coredns/archetypes/docs.md new file mode 100644 index 0000000..fa23e66 --- /dev/null +++ b/themes/coredns/archetypes/docs.md @@ -0,0 +1,8 @@ ++++ +title = "" +description = "" +weight = 20 +draft = false +bref = "" +toc = true ++++ diff --git a/themes/coredns/exampleSite/config.toml b/themes/coredns/exampleSite/config.toml new file mode 100644 index 0000000..280e9e4 --- /dev/null +++ b/themes/coredns/exampleSite/config.toml @@ -0,0 +1,25 @@ +baseURL = "/" +languageCode = "en-us" +title = "Kube for Hugo" +theme = "kube" +description = "Kube is a professional and a responsive Hugo theme for developers and designers that offers a documentation section mixed with a landing page and a blog" +Paginate = 4 +[Params] + RSSLink = "/index.xml" + author = "newpixcom" # add your company name + github = "" # add your github profile name + twitter = "" # add your twitter profile + email = "myemail@myaddress.xxx" + +[[menu.main]] + name = "Docs" + weight = -100 + url = "/docs/" +[[menu.main]] + name = "Blog" + weight = -100 + url = "/blog/" +[[menu.main]] + name = "Faq" + weight = -100 + url = "/faq/" diff --git a/themes/coredns/exampleSite/content/account.md b/themes/coredns/exampleSite/content/account.md new file mode 100644 index 0000000..ad1f583 --- /dev/null +++ b/themes/coredns/exampleSite/content/account.md @@ -0,0 +1,20 @@ ++++ +title = "Sign In" ++++ +
+ +
+ + +
+ +
+ + +
+ +

+

Forgot password?

+

If you have any questions about authorization or you're our customer but haven't receive your login credentials, just send us a short email at support@company.com and we'll fix it right away.

+ +
diff --git a/themes/coredns/exampleSite/content/blog/collapse.md b/themes/coredns/exampleSite/content/blog/collapse.md new file mode 100644 index 0000000..55e431b --- /dev/null +++ b/themes/coredns/exampleSite/content/blog/collapse.md @@ -0,0 +1,207 @@ ++++ +date = "2017-04-10T16:42:50+01:00" +draft = false +weight = 180 +description = "Smoothly and reliably collapse elements for extra convenience" +title = "Collapse" +bref = "A demo to collapsable elements" + ++++ + +

Base

+
+
+

Item 1

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+

Item 2

+
+

I look active on load.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+

Item 3

+
+
Important Heading
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+ +
<div id="my-collapse" data-component="collapse">
+
+    <h4><a href="#box-1" class="collapse-toggle">...</a></h4>
+    <div class="collapse-box hide" id="box-1">...</div>
+
+    <h4><a href="#box-2" class="collapse-toggle">...</a></h4>
+    <div class="collapse-box" id="box-2">...</div>
+
+    <h4><a href="#box-3" class="collapse-toggle">...</a></h4>
+    <div class="collapse-box hide" id="box-3">...</div>
+
+</div>
+
+
+

Navigation Example

+

Here you can see a list of items forming a navigation menu, with a nested list which acts as a collapsable element

+
+ +
<ul>
+    <li><a href="#">...</a></li>
+    <li data-component="collapse">
+        <a href="#toggle-box" class="collapse-toggle">
+            Toggle
+            <span class="caret down"></span>
+        </a>
+        <ul id="toggle-box" class="collapse-box">
+            <li><a href="#">...</a></li>
+        </ul>
+    </li>
+    <li><a href="#">...</a></li>
+</ul>
+
+
+

Settings

+

Settings are pretty straightforward: you can toggle, denote active element, turn animation on and off, and more.

+
toggle
+
    +
  • Type: boolean
  • +
  • Default: true
  • +
+
active
+
    +
  • Type: string or boolean
  • +
  • Default: false
  • +
+
toggleClass
+
    +
  • Type: string
  • +
  • Default: 'collapse-toggle'
  • +
+

Sets a class of a collapsable object.

+
boxClass
+
    +
  • Type: string
  • +
  • Default: 'collapse-box'
  • +
+

Sets a class for collapsable object's content

+
animation
+
    +
  • Type: boolean
  • +
  • Default: true
  • +
+

Turns animation on and off.

+

Callbacks

+
open
+
$('#my-collapse').on('open.collapse', function()
+{
+    // do something...
+});
+
+
opened
+
$('#my-collapse').on('opened.collapse', function()
+{
+    // do something...
+});
+
+
close
+
$('#my-collapse').on('close.collapse', function()
+{
+    // do something...
+});
+
+
closed
+
$('#my-collapse').on('closed.collapse', function()
+{
+    // do something...
+});
+
+

API

+

We love APIs, and for interactive elements such as collapsable elements we offer ways to programmatically open and close individual elements, or all at once.

+
+


+
+

Item 1

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+

Item 2

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+

Item 3

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
<button onclick="$('#my-collapse-api').collapse('open', '#box-2');">Open</button>
+<button onclick="$('#my-collapse-api').collapse('close', '#box-2');">Close</button>
+<button onclick="$('#my-collapse-api').collapse('openAll');">Open All</button>
+<button onclick="$('#my-collapse-api').collapse('closeAll');">Close All</button>
+
+<div id="my-collapse-api" data-component="collapse">
+
+    <h4><a href="#box-1" class="collapse-toggle">...</a></h4>
+    <div class="collapse-box hide" id="box-1">...</div>
+
+    <h4><a href="#box-2" class="collapse-toggle">...</a></h4>
+    <div class="collapse-box hide" id="box-2">...</div>
+
+    <h4><a href="#box-3" class="collapse-toggle">...</a></h4>
+    <div class="collapse-box hide" id="box-3">...</div>
+
+</div>
+
+
+
open
+
$('#my-collapse').collapse('open');
+
+
close
+
$('#my-collapse').collapse('close');
+
+
openAll
+
$('#my-collapse').collapse('openAll');
+
+
closeAll
+
$('#my-collapse').collapse('closeAll');
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/blog/inline-style.md b/themes/coredns/exampleSite/content/blog/inline-style.md new file mode 100644 index 0000000..02623be --- /dev/null +++ b/themes/coredns/exampleSite/content/blog/inline-style.md @@ -0,0 +1,10 @@ ++++ +date = "2017-04-02T21:56:55+01:00" +title = "Inline 🐣Text Styles" +tags = ["markdown","example"] +categories = ["general"] +draft = false +description = "This article is just a demo." ++++ + +Chocolate tiramisu pastry a link cotton candy sesame snaps. Dessert cake chocolate bar a bold part sugar plum bonbon marshmallow lollipop toffee soufflé. Donut caramels chocolate bar. Oat cake cookie a marked part cheesecake donut. Jelly-o $code marzipan cake. Bonbon sesame snaps chocolate an italic part oat cake pudding sweet roll caramels bonbon. Soufflé muffin 👻 gummies sugar plum dessert bonbon bear claw. Sweet ice cream jujubes. Marzipan sugar plum pastry chocolate ⌘+A bar fruitcake. Lollipop lollipop brownie. \ No newline at end of file diff --git a/themes/coredns/exampleSite/content/blog/messages.md b/themes/coredns/exampleSite/content/blog/messages.md new file mode 100644 index 0000000..5b884b7 --- /dev/null +++ b/themes/coredns/exampleSite/content/blog/messages.md @@ -0,0 +1,158 @@ ++++ +date = "2017-04-10T16:41:34+01:00" +draft = false +weight = 90 +description = "Versatile and refined messages, ideal for daily use" +title = "Messages" +bref = "Messages are an essential part of modern web and messages in Kube look nice" ++++ + +

Usage

+
+
+ You have 2 modules waiting to installation. Install +
+
<div class="message" data-component="message"> ...  <span class="close small"></span></div>
+
+
+
+ You have 2 modules waiting to installation. Install +
+
<div class="message error" data-component="message"> ...  <span class="close small"></span></div>
+
+
+
+ You have 2 modules waiting to installation. Install +
+
<div class="message success" data-component="message"> ...  <span class="close small"></span></div>
+
+
+
+
Warning!
You have 2 modules waiting to installation. Install +
+
<div class="message warning" data-component="message">
+    <h5>...</h5>
+    ...
+    <span class="close small"></span>
+</div>
+
+
+
+
+ You have 2 modules waiting to installation. Install +
+
<div class="message focus" data-component="message"> ...  <span class="close small"></span></div>
+
+
+
+ You have 2 modules waiting to installation. Install +
+
<div class="message black" data-component="message"> ...  <span class="close small"></span></div>
+
+
+
+ You have 2 modules waiting to installation. Install +
+
<div class="message inverted" data-component="message"> ...  <span class="close small"></span></div>
+
+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefault
closeSelectorstring.close
closeEventstringclick
animationOpenstringfadeIn
animationClosestringfadeOut
+

Set an option

+

Via data attribute:

+
<div class="message" data-component="message" data-close-selector=".my-custom-close">
+    ... <span class="my-custom-close small"></span>
+</div>
+
+

Via Javascript:

+
$('#my-message').message({
+    closeSelector: '.my-custom-close'
+});
+
+

Methods

+

+
+ You have 2 modules waiting to installation. Install +
+ + + + + + + + + + + + + + + + + +
MethodDescription
closeManually closes a message.
openOpens a message if it has been closed.
+

Example

+
$('#my-message').message('close');
+

Callbacks

+ + + + + + + + + + + + + + + + + + + + + + + + + +
CallbackDescription
openThis event fires immediately when the open instance method is called.
openedThis event is fired when the message has been opened, will wait for CSS animation to complete.
closeThis event fires immediately when the close instance method is called.
closedThis event is fired when the message has been closed, will wait for CSS animation to complete.
+

Example

+
$('#my-message').on('closed.message', function()
+{
+    // do something
+})
+
diff --git a/themes/coredns/exampleSite/content/blog/prototyping.md b/themes/coredns/exampleSite/content/blog/prototyping.md new file mode 100644 index 0000000..f55d46a --- /dev/null +++ b/themes/coredns/exampleSite/content/blog/prototyping.md @@ -0,0 +1,23 @@ ++++ +date = "2017-04-02T22:01:15+01:00" +title = "Prototyping with markdown" +tags = ["markdown","prototype", "hugo"] +categories = ["design"] +description = "An idea to make website protoype with markdown" +draft = false +weight = 30 ++++ + + + +I have been working on a large set of documentation for a prototype that will eventually make it into a product. One issue with the publishing system at my company is that it makes doing prototypes, or really anything not within the rigidly and narrowly scoped model, difficult to set up. It takes a lot of work just to get to the point where you can begin writing. + +Since time was of the essence and writing is expensive, I decided to do the prototype outside of the publishing system. I also decided to avoid using the rigid DocBook variant we use. Instead, **I figured I do the prototype in Markdown using Hugo generator**. It gives me reasonably ~full featured Markdown support, flexibility to work wherever I want, easy HTML~ ,nd the stack/sheet metaphor fits nicely with topic based writing. + + +I wasn't sure how well the experiment was going to work when I started, but a few weeks in I think it is great. ~I was able to rapidly prototype fifteen topics in about ten days.~ The prototype pages look fairly close to what our actual system generates. ~I can quickly make changes to the content as needed and republish.~ ~The fact that I can work multi-platform is great. I am not chained to my desk. I can demo changes easily.~ + + +~The fact that I am working in text that doesn't have to be structured in a rigid format makes the work flow faster~. It provides flexibility for quick changes, yet also allows for topic orientation. +For final production and long term maintenance, unstructured Markdown is not a great solution. There the benefits of the rigidity outweigh the cost. The rigidity enforces uniformity that large groups of variously skilled writers need to create and maintain content at scale. +> For small, fast projects or prototyping Markdown, with Hugo, have proven to be an excellent solution. \ No newline at end of file diff --git a/themes/coredns/exampleSite/content/blog/typography.md b/themes/coredns/exampleSite/content/blog/typography.md new file mode 100644 index 0000000..e5b631b --- /dev/null +++ b/themes/coredns/exampleSite/content/blog/typography.md @@ -0,0 +1,452 @@ ++++ +title = "Typography with kube" +weight = 25 +draft = false +description = "Always precise spacing and perfect font size" +bref = "Typography is perhaps one of the most important and most visible things on a web page. Even slightest imperfection can ruin otherwise perfect website. With Kube, you will have perfect typography with ideal spacing, font sizes and proportions, regardless of the exact style or font you choose for your site." + ++++ + +

Get Started

+

Typography of Kube based on the 4px horizontal grid, it means that for the headers, paragraphs, quotes and any other texts chosen are a combination of line-height, that fit into the 4px grid and help set the horizontal rhythm of design by default.

+
+ 4px horizontal rhythm +
+ 4px grid for typography - the magic of the horizontal rhythm +
+
+

With this feature, you can quickly and easily make a solid and harmonious-looking website and UI design. You do not need to do complicated calculations to find the size and proportions of the text baseline, no need to look for the magic formula to build a horizontal rhythm. Magic is already in Kube.

+

You can use all the default settings of typography and it will always look balanced. But also you can easily change any font sizes, just try to set the value of line-height fold for 4px and your texts will still look great.

+

Additional balance and harmony, creates a classic typography scale, used in Kube.

+
+ the typography scale +
+ The typography scale helps to build a balance between the size of headings and text elements +
+
+

Headings

+

Use h1-h6 tags or .h1-.h6 classes to define headers and class="title" for the title, which is suitable for the most important inscriptions, for example, in the hero or covers.

+
+

Title

+

Heading 1

+

Heading 2

+

Heading 3

+

Heading 4

+
Heading 5
+
Heading 6
+
<h1 class="title">...</h1>
+<h1>...</h1>
+...
+<h6>...</h6>
+
+

Paragraphs

+

The base pragraph has an ideal ratio of font size and baseline. This text is easy to read in most cases.

+
+

16px/24px

+

By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.

+
<p>...</p>
+
+

In special cases, you can use modifiers which increase or decrease the text size. It is useful for building a variety of websites and UI, when you need to make a lead text or signatures with a small font size .

+
+

20px/32px

+

By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.

+
<p class="large">...</p>
+
+
+

18px/28px

+

By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.

+
<p class="big">...</p>
+
+
+

14px/20px

+

By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.

+
<p class="small">...</p>
+
+
+

12px/20px

+

By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.

+
<p class="smaller">...</p>
+
+

Columns

+

Kube has three classes of .columns-2 through .columns-4 to create a multi-column layout. All multi-column layouts will be in a single column on mobile.

+
+

2 columns

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
<div class="columns-2">
+    <p>...</p>
+</div>
+
+
+
+

3 columns

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
<div class="columns-3">
+    <p>...</p>
+</div>
+
+
+
+

4 columns

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
<div class="columns-4">
+    <p>...</p>
+</div>
+
+
+

Quotes

+

Quotes in the text stand out for contrast and added variety to the text. In the quotes you can mark text as a paragraph tag and without it.

+
+
+

No, she'll probably make me do it. Goodbye, friends. I never thought I'd die like this. But I always really hoped. I saw you with those two "ladies of the evening" at Elzars. Explain that. I never loved you.

+
+
<blockquote>...</blockquote>
+
+

Use small tag for attribution. It's a prefer way for semantic code.

+
+
+

Who's brave enough to fly into something we all keep calling a death sphere? Yes. You gave me a dollar and some candy. I just want to talk. It has nothing to do with mating. Fry, that doesn't make sense.

— Bender +
+
<blockquote>
+    <p>Quotation content</p>
+    <small>Author attribution</small>
+</blockquote>
+
+
+

Pre-formatted

+

Pre-formatted text most often used to display code snippets or other text elements, for which you wish to preserve the exact formatting they've got.

+
+
Function.prototype.inherits = function(parent)
+{
+    for (var key in parent.prototype)
+    {
+        this.prototype[key] = parent.prototype[key];
+    }
+};
+
+
<pre>...</pre>
+
+

You feel free to use code tag inside pre.

+
+
Function.prototype.inherits = function(parent)
+{
+    for (var key in parent.prototype)
+    {
+        this.prototype[key] = parent.prototype[key];
+    }
+};
+
+
<pre><code>...</code></pre>
+
+

Inline Elements

+

Kube features various inline formatting elements. They all have their own semantic meaning, but you're free to use them just for their style.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExampleTagExampleTag
CSS<abbr>Cite<cite>
Code<code>Sample<samp>
Variable<var>Mark<mark>
Shortcut<kbd> + Deleted + <del>
Italic<i>Emphasis<em>
Highlighted<strong>Bold<b>
xsuperscript<sup>xsubscript<sub>
Small<small> + Inserted + <ins>
+

Modifiers

+

Modifiers - a set of helper classes for creating accents in the text and for the solution of useful tasks without writing CSS code, for example, the alignment of the text in the center.

+

Modifiers can be applied to any tags as inline elements, links or block tags.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExampleModifier
Muted.muted
+ Muted link + .muted
+ Black link + .black
Highlight.highlight
upper.upper
LOWER.lower
Italic.italic
Strong.strong
Not strong.normal
Monospace.monospace
Nowrap.nowrap
Remove margin bottom.end
Highlight.highlight
Small.small
Smaller.smaller
Large.large
Big.big
Text left.text-left
Text center.text-center
Text right.text-right
+

Figure

+

A figure tag features an image, a video or a code plus a caption. It is a good accessibility practice. It also helps serve responsive video to various devices when you wrap video into .video-container class.

+
Images
+
+ Image +
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit... +
+
+

HTML

+
<figure>
+    <img src="image.jpg">
+    <figcaption>...</figcaption>
+</figure>
+
+
Video
+
+
+ +
+
+ Journey Through The Ice | National Geographic +
+
+

HTML

+
<figure>
+    <div class="video-container">
+        <iframe>...</iframe>
+    </div>
+    <figcaption>...</figcaption>
+</figure>
+
+
Code
+
+
Function.prototype.inherits = function(parent)
+{
+    for (var key in parent.prototype)
+    {
+        this.prototype[key] = parent.prototype[key];
+    }
+};
+
+
+ One of the implementations of inheritance +
+
+

HTML

+
<figure>
+    <pre>...</pre>
+    <figcaption>...</figcaption>
+</figure>
+
+

Lists

+

Although you most likely will not ever need to do so, you can still nest as many list levels as you like.

+
+
+
+
    +
  • list item 1
  • +
  • list item 2 +
      +
    • list item 2.1
    • +
    • list item 2.2 +
        +
      • list item 2.2.1
      • +
      • list item 2.2.2
      • +
      +
    • +
    • list item 2.3
    • +
    • list item 2.4
    • +
    +
  • +
  • list item 3
  • +
  • list item 4
  • +
+
<ul>
+    <li>...</li>
+</ul>
+
+
+
+
+
+
    +
  1. list item 1
  2. +
  3. list item 2 +
      +
    1. list item 2.1
    2. +
    3. list item 2.2 +
        +
      1. list item 2.2.1
      2. +
      3. list item 2.2.2
      4. +
      +
    4. +
    5. list item 2.3
    6. +
    7. list item 2.4
    8. +
    +
  4. +
  5. list item 3
  6. +
  7. list item 4
  8. +
+
<ol>
+    <li>...</li>
+</ol>
+
+
+
+
+
Unstyled List
+

To remove default list styling, use .unstyled.

+
+
    +
  • list item 1
  • +
  • list item 2 +
      +
    • list item 2.1
    • +
    • list item 2.2
    • +
    +
  • +
  • list item 3
  • +
  • list item 4
  • +
+
<ul class="unstyled">
+    <li>...</li>
+</ul>
+
+
+
Definition List
+

From time to time, you may need to produce a list of definitions, and there's one nicely built-in into Kube. We love semantic things. And lists. We love lists.

+
+
+
Term 1
+
Description 1
+
Term 2
+
Description 2
+
Term 3
+
Description 3
+
+
<dl>
+    <dt>Term</dt>
+    <dd>Description</dd>
+</dl>
+
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/blog/welcome.md b/themes/coredns/exampleSite/content/blog/welcome.md new file mode 100644 index 0000000..9d8217f --- /dev/null +++ b/themes/coredns/exampleSite/content/blog/welcome.md @@ -0,0 +1,85 @@ ++++ +date = "2017-03-02T21:56:55+01:00" +title = "Welcome to Kube" +tags = ["markdown","example"] +categories = ["general"] +draft = false +description = "This article is just a demo post and shows you the style of common used elements writing in pure markdown without HTML code." +weight = 10 ++++ + +# Welcome to Kube – an open source documentation like theme for Hugo + +Hi there and welcome to kube - my two theme for the static site generator [hugo](https://gohugo.io/). kube is open source and can be found on [kube](https://kube.elemnts.org/). This article is just a demo post and shows you the style of common used elements. + +Bear claw danish chocolate lollipop soufflé jelly. Apple pie chocolate cake +jelly-o icing bonbon. Gingerbread pastry fruitcake muffin chocolate bar +cheesecake. Sugar plum bonbon bonbon lemon drops gummies. + +## Inline 🦄 Text Styles [a link](http://kube.elemnts.org) + +Chocolate tiramisu pastry [a link](http://zutrinken.com) cotton candy sesame snaps. Dessert cake chocolate bar **a bold part** sugar plum bonbon 🐓💨 marshmallow lollipop toffee soufflé. Donut caramels chocolate bar. Oat cake cookie a marked part cheesecake donut. Jelly-o ` $code` marzipan cake. Bonbon sesame snaps chocolate _an italic part_ oat cake pudding sweet roll caramels bonbon. Soufflé muffin 👻 gummies sugar plum dessert bonbon bear claw. Sweet ice cream jujubes. Marzipan sugar plum pastry chocolate +A bar fruitcake. Lollipop lollipop brownie. + +## Ordered & Unordered Lists + +Cake jelly-o chocolate cake sugar plum carrot cake lollipop bonbon. Jelly beans pudding oat cake pie. + +* Jelly beans pudding oat cake pie. +* Cupcake cupcake oat cake candy lemon +* Drops marzipan icing. Dessert topping croissant fruitcake sesame snaps cotton candy sweet danish +* Sweet roll sweet sugar plum donut + * Bear claw gingerbread cake donut chocolate bar + * Topping cake fruitcake fruitcake +* Ice cream icing chupa chups cupcake jelly-o candy +* Croissant jujubes topping tart soufflé pudding + * Cheesecake caramels icing + * Cake jelly-o chocolate cake sugar plum carrot cake lollipop bonbon + +Ice cream icing chupa chups cupcake jelly-o candy. Croissant jujubes topping tart soufflé pudding. Cheesecake caramels icing. + +1. Drops marzipan icing. Dessert topping croissant fruitcake sesame snaps cotton candy sweet danish +* Sweet roll sweet sugar plum donut + * Bear claw gingerbread cake donut chocolate bar + * Topping cake fruitcake fruitcake +3. Ice cream icing chupa chups cupcake jelly-o candy + +Liquorice marshmallow sweet macaroon. Cotton candy pastry ice cream fruitcake tiramisu jelly beans dragée. + +
Ice cream
icing chupa chups cupcake jelly-o candy. Croissant jujubes topping tart soufflé pudding
Cake
Jelly beans pudding oat cake pie
Drops marzipan icing
Cake jelly-o chocolate cake sugar plum carrot cake lollipop
+ +Soufflé tart topping gummi bears jujubes lollipop ice cream pudding. Apple pie jelly-o powder powder sweet. + +Cake soufflé icing gingerbread topping jujubes. Chocolate cake pudding sweet biscuit cake. Soufflé tart topping gummi bears jujubes lollipop ice cream pudding. Apple pie jelly-o powder powder sweet. Halvah chocolate bar cotton candy sugar plum cake. + +## Tables, Blockquotes and Codeblocks + +Apple pie chocolate cake jelly-o icing bonbon. Gingerbread pastry fruitcake muffin chocolate bar cheesecake. Sugar plum bonbon bonbon lemon drops gummies. + +| RGB | WMYN | +|---|---| +| Red | Cyan | +| Green | Magenta | +| Yellow | Black | + + +Brownie oat cake tart caramels croissant lollipop pastry soufflé lemon drops. Cotton candy pastry ice cream fruitcake tiramisu jelly beans dragée. + +> Jelly beans dessert toffee caramels brownie ice cream croissant chupa chups liquorice. Danish sweet roll croissant. Powder sugar plum powder danish wafer cake. +> +> Candy jelly beans jujubes muffin. Bear claw danish chocolate lollipop soufflé jelly. + +Cake soufflé icing gingerbread topping jujubes. Chocolate cake pudding sweet biscuit cake. Soufflé tart topping gummi bears jujubes lollipop ice cream pudding. + +Apple pie jelly-o powder powder sweet. Halvah chocolate bar cotton candy sugar plum cake. Liquorice marshmallow sweet macaroon. + +
+

For example.

+
+ +Macaroon jelly toffee cheesecake muffin lollipop dragée cake gummies. Cotton candy biscuit cupcake. Cupcake chupa chups carrot cake. Chocolate bar donut gummies wafer pastry sesame snaps oat cake. + +* * * + +Apple pie chocolate cake jelly-o icing bonbon. Gingerbread pastry fruitcake muffin chocolate bar cheesecake. Sugar plum bonbon bonbon lemon drops gummies. Brownie oat cake tart caramels croissant lollipop pastry soufflé lemon drops. Jelly beans dessert toffee caramels brownie ice cream croissant chupa chups liquorice. Danish sweet roll croissant. Powder sugar plum powder danish wafer cake. Candy jelly beans jujubes muffin. Bear claw danish chocolate lollipop soufflé jelly. + + diff --git a/themes/coredns/exampleSite/content/company.md b/themes/coredns/exampleSite/content/company.md new file mode 100644 index 0000000..bc2cdf2 --- /dev/null +++ b/themes/coredns/exampleSite/content/company.md @@ -0,0 +1,4 @@ ++++ +title = "Company" +description = "We create apps and websites since 2009. We aim for minimalism and efficiency in everything we do. Our products are simple yet beautiful. They help you focus on your goals, not on your tools." ++++ diff --git a/themes/coredns/exampleSite/content/docs/animation.md b/themes/coredns/exampleSite/content/docs/animation.md new file mode 100644 index 0000000..3ff71e4 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/animation.md @@ -0,0 +1,163 @@ ++++ +description = "Add some motion, shaking, pulsing, sliding and more" +title = "Animation" +date = "2017-04-10T16:43:08+01:00" +draft = false +weight = 200 +bref="Although it is quite easy to overuse animation effects, Kube makes it pretty easy to create meaningful, smooth and overall nice looking animation. Feel free to click every button below to see what it does, and then only use those effects that are essential to your project" +toc = true +script = 'animation' ++++ + +

Slide

+
+
+
+
+ slideUp +
+
+
+
+ slideDown +
+
+
Slide Up Slide Down +
$('#element').animation('slideUp');
+$('#element').animation('slideDown');
+
+

Fade

+
+
+
+
+ fadeIn +
+
+
+
+ fadeOut +
+
+
Fade In Fade Out +
$('#element').animation('fadeIn');
+$('#element').animation('fadeOut');
+
+

Flip

+
+
+
+
+ flipIn +
+
+
+
+ flipOut +
+
+
Flip In Flip Out +
$('#element').animation('flipIn');
+$('#element').animation('flipOut');
+
+

Zoom

+
+
+
+
+ zoomIn +
+
+
+
+ zoomOut +
+
+
Zoom In Zoom Out +
$('#element').animation('zoomIn');
+$('#element').animation('zoomOut');
+
+

Rotate

+
+
+
+
+ rotate +
+
+
Rotate +
$('#element').animation('rotate');
+
+

Shake

+
+
+
+
+ shake +
+
+
Shake +
$('#element').animation('shake');
+
+

Pulse

+
+
+
+
+ pulse +
+
+
Pulse +
$('#element').animation('pulse');
+
+

Slide In

+
+
+
+
+ slideInRight +
+
+
+
+ slideInLeft +
+
+
+
+ slideInDown +
+
+
Slide In Right Slide In Left Slide In Down +
$('#element').animation('slideInRight');
+$('#element').animation('slideInLeft');
+$('#element').animation('slideInDown');
+
+

Slide Out

+
+
+
+
+ slideOutRight +
+
+
+
+ slideOutLeft +
+
+
+
+ slideOutUp +
+
+
Slide Out Right Slide Out Left Slide Out Up +
$('#element').animation('slideOutRight');
+$('#element').animation('slideOutLeft');
+$('#element').animation('slideOutUp');
+
+

Callback

+
$('#element').animation('fadeIn', function()
+{
+    // code ...
+});
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/breadcrumbs.md b/themes/coredns/exampleSite/content/docs/breadcrumbs.md new file mode 100644 index 0000000..b195c9e --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/breadcrumbs.md @@ -0,0 +1,99 @@ ++++ +date = "2017-04-10T16:41:54+01:00" +weight = 110 +description = "Traces for the users so they won't get lost" +title = "Breadcrumbs" +draft = false +bref= "Breadcrumbs in Kube are formed as lists with default separator. This separator can be customized with ease by simply changing a single CSS line" +toc = true ++++ + +

Base

+
+ +
<nav class="breadcrumbs">
+    <ul>
+        <li><a href="">...</a></li>
+        <li><span>...</span></li>
+    </ul>
+</nav>
+
+
+

Centered

+
+ +
<nav class="breadcrumbs push-center">
+    <ul>
+        <li><a href="">...</a></li>
+        <li class="active"><a href="">...</a></li>
+    </ul>
+</nav>
+
+
+

Custom Separator

+
+ +
// css
+#breadcrumbs-custom-separator li:after {
+    content: '>';
+}
+
+// html
+<nav id="breadcrumbs-custom-separator" class="breadcrumbs">
+    <ul>
+        <li><a href="">...</a></li>
+        <li><span>...</span></li>
+    </ul>
+</nav>
+
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/buttons.md b/themes/coredns/exampleSite/content/docs/buttons.md new file mode 100644 index 0000000..3027dc7 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/buttons.md @@ -0,0 +1,108 @@ ++++ +date = "2017-04-10T16:41:16+01:00" +weight = 70 +description = "Full variety of pressible, clickable and pushable buttons" +title = "Buttons" +draft = false +bref = "Buttons in Kube are minimalistic, designed for instant and convenient customization, and are ready to be pushed, pressed, clicked and manipulated in whichever ways. A lot of interactive components use buttons, and you should too!" +toc = true ++++ + +

Primary

+
+ Button +
<button class="button">Button</button>
+<a href="#" class="button">Button</a>
+
+

Secondary

+
+ Button +
<button class="button secondary">Button</button>
+<a href="#" class="button secondary">Button</a>
+
+

Outline

+

Outline class does exactly what it is supposed to do: styles a button with an outline with no fill color.

+
+ +
<button class="button outline">Button</button>
+<button class="button secondary outline">Button</button>
+
+

Disabled

+

Disabled buttons are automatically styles with muted colors, inactive and not clickable. As you can see, there's no need to set disabled class for the button element, and disabled argument is enough. Having this said, both a link and a button input require disabled class.

+
+ Link +
+
<a href="#" class="button disabled" role="button">Link</a>
+<button class="button secondary" disabled>Button</button>
+

Small

+

Buttons come in all sizes and shapes.

+
+ Link +
+
<a href="#" class="button small" role="button">Link</a>
+<button class="button secondary small">Button</button>
+

Big

+
+ Link +
+
<a href="#" class="button big" role="button">Link</a>
+<button class="button secondary big">Button</button>
+

Large

+
+ Link +
+
<a href="#" class="button large" role="button">Link</a>
+<button class="button secondary large">Button</button>
+

Upper

+
+ Link Link +
+
<a href="#" class="button upper" role="button">Link</a>
+<button class="button secondary upper">Button</button>
+<a href="#" class="button upper outline" role="button">Link</a>
+<button class="button secondary upper outline">Button</button>
+

Round

+
+ Link Link +
+
<a href="#" class="button round" role="button">Link</a>
+<button class="button secondary round">Button</button>
+<a href="#" class="button round outline" role="button">Link</a>
+<button class="button secondary round outline">Button</button>
+

Inverted

+

For use on darker backgrounds, you can just introduce inverted class to have your button flip its color to the opposite one.

+
+ Link     +
<a href="#" class="button inverted" role="button">Link</a>
+<button class="button inverted outline">Button</button>
+
+

Width

+
+

+

+
<button class="button w100">...</button>
+<button class="button secondary w50">...</button>
+
+

Icons

+
+ +
<button class="button"><i class="kube-calendar"></i></button>
+<button class="button secondary"><i class="kube-calendar"></i> Change</button>
+
+<button class="button outline"><i class="kube-search"></i></button>
+<button class="button secondary outline"><i class="kube-search"></i> Search</button>
+
+

Custom

+

With some Sass magic, you can customize your buttons in a snap. Just include a color class declaration and set the color itself, and you're done.

+
+ +
// scss
+.button.red {
+    // $text-color, $back-color
+    @include button(#fff, #ff3366);
+}
+
+// html
+<button class="button red">Button</button>
+<button class="button red outline">Button</button>
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/collapse.md b/themes/coredns/exampleSite/content/docs/collapse.md new file mode 100644 index 0000000..fdc4029 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/collapse.md @@ -0,0 +1,207 @@ ++++ +date = "2017-04-10T16:42:50+01:00" +draft = false +weight = 180 +description = "Smoothly and reliably collapse elements for extra convenience" +title = "Collapse" +bref="Collapsable elements are horizontally aligned tabs, in a way. Jokes aside, collapsable elements are useful and easy to setup, both for direct purpose of switching between content while collapsing everything else, and for navigation use cases" +toc = true ++++ + +

Base

+
+
+

Item 1

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+

Item 2

+
+

I look active on load.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+

Item 3

+
+
Important Heading
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+ +
<div id="my-collapse" data-component="collapse">
+
+    <h4><a href="#box-1" class="collapse-toggle">...</a></h4>
+    <div class="collapse-box hide" id="box-1">...</div>
+
+    <h4><a href="#box-2" class="collapse-toggle">...</a></h4>
+    <div class="collapse-box" id="box-2">...</div>
+
+    <h4><a href="#box-3" class="collapse-toggle">...</a></h4>
+    <div class="collapse-box hide" id="box-3">...</div>
+
+</div>
+
+
+

Navigation Example

+

Here you can see a list of items forming a navigation menu, with a nested list which acts as a collapsable element

+
+ +
<ul>
+    <li><a href="#">...</a></li>
+    <li data-component="collapse">
+        <a href="#toggle-box" class="collapse-toggle">
+            Toggle
+            <span class="caret down"></span>
+        </a>
+        <ul id="toggle-box" class="collapse-box">
+            <li><a href="#">...</a></li>
+        </ul>
+    </li>
+    <li><a href="#">...</a></li>
+</ul>
+
+
+

Settings

+

Settings are pretty straightforward: you can toggle, denote active element, turn animation on and off, and more.

+
toggle
+
    +
  • Type: boolean
  • +
  • Default: true
  • +
+
active
+
    +
  • Type: string or boolean
  • +
  • Default: false
  • +
+
toggleClass
+
    +
  • Type: string
  • +
  • Default: 'collapse-toggle'
  • +
+

Sets a class of a collapsable object.

+
boxClass
+
    +
  • Type: string
  • +
  • Default: 'collapse-box'
  • +
+

Sets a class for collapsable object's content

+
animation
+
    +
  • Type: boolean
  • +
  • Default: true
  • +
+

Turns animation on and off.

+

Callbacks

+
open
+
$('#my-collapse').on('open.collapse', function()
+{
+    // do something...
+});
+
+
opened
+
$('#my-collapse').on('opened.collapse', function()
+{
+    // do something...
+});
+
+
close
+
$('#my-collapse').on('close.collapse', function()
+{
+    // do something...
+});
+
+
closed
+
$('#my-collapse').on('closed.collapse', function()
+{
+    // do something...
+});
+
+

API

+

We love APIs, and for interactive elements such as collapsable elements we offer ways to programmatically open and close individual elements, or all at once.

+
+


+
+

Item 1

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+

Item 2

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+

Item 3

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
<button onclick="$('#my-collapse-api').collapse('open', '#box-2');">Open</button>
+<button onclick="$('#my-collapse-api').collapse('close', '#box-2');">Close</button>
+<button onclick="$('#my-collapse-api').collapse('openAll');">Open All</button>
+<button onclick="$('#my-collapse-api').collapse('closeAll');">Close All</button>
+
+<div id="my-collapse-api" data-component="collapse">
+
+    <h4><a href="#box-1" class="collapse-toggle">...</a></h4>
+    <div class="collapse-box hide" id="box-1">...</div>
+
+    <h4><a href="#box-2" class="collapse-toggle">...</a></h4>
+    <div class="collapse-box hide" id="box-2">...</div>
+
+    <h4><a href="#box-3" class="collapse-toggle">...</a></h4>
+    <div class="collapse-box hide" id="box-3">...</div>
+
+</div>
+
+
+
open
+
$('#my-collapse').collapse('open');
+
+
close
+
$('#my-collapse').collapse('close');
+
+
openAll
+
$('#my-collapse').collapse('openAll');
+
+
closeAll
+
$('#my-collapse').collapse('closeAll');
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/colors.md b/themes/coredns/exampleSite/content/docs/colors.md new file mode 100644 index 0000000..d59e0fc --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/colors.md @@ -0,0 +1,141 @@ ++++ +date = "2017-04-10T16:43:14+01:00" +draft = false +weight = 210 +description = "The basic set of colors" +title = "Colors" +bref="Kube has a basic set of colors for text, links, buttons, states and gray palette. These colors help to create uniformity and harmony in the look of UI elements. All colors are carefully selected and combined with each other. Of course, you can change the color scheme to your choice in the framework settings." +toc = true ++++ + +

Text

+

Contrasting black color for headings and less intense dark gray for the text helps to improve readability.

+
+
+
+ +
Headings
+

$color-headings

+
+
+ +
Text
+

$color-text

+
+
+
+ +

Classic blue links and soft red for the hover state makes links visible and predictable.

+
+
+
+ +
Link
+

$color-link

+
+
+ +
Hover
+

$color-link-hover

+
+
+
+

Buttons

+

Blue color for primary buttons for greater consistency with links. Black color for secondary buttons allows you build a variety of UI.

+
+
+
+ +
Primary
+

$color-button-primary

+
+
+ +
Secondary
+

$color-button-secondary

+
+
+
+

States

+

All possible states of the UI are in the simple and intuitive color scheme helps to focus the user's attention when creating an interactive UI.

+
+
+
+ +
Error
+

$color-error

+
+
+ +
Focus
+

$color-focus

+
+
+ +
Success
+

$color-success

+
+
+ +
Warning
+

$color-warning

+
+
+
+

Extra

+

Special color to highlight areas of interaction with the interface. And the white color for all cases.

+
+
+
+ +
Highlight
+

$color-highlight

+
+
+ +
Inverted
+

$color-inverted

+
+
+
+

Grayscale

+

Harmonious and well-thought-out scheme of gray for a broad range of tasks in the designing of the interface from controls to backgrounds.

+
+
+
+ +
Black
+

$color-black

+
+
+ +
Darkgray
+

$color-darkgray

+
+
+ +
Midgray
+

$color-midgray

+
+
+ +
Gray
+

$color-gray

+
+
+ +
Lightgray
+

$color-lightgray

+
+
+ +
Silver
+

$color-silver

+
+
+ +
Aluminum
+

$color-aluminum

+
+
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/custom-plugins.md b/themes/coredns/exampleSite/content/docs/custom-plugins.md new file mode 100644 index 0000000..49e0b67 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/custom-plugins.md @@ -0,0 +1,96 @@ ++++ +title = "Custom Plugins" +description = "Flexible and extensible way to add custom features" +weight = 20 +draft = false +toc = true +bref = "Kube has a lot to offer in terms of extensibility and flexibility, and plugins are the way of doing incredible things without bloating the core. With plugins, you can extend existing features, make them more interactive, or you can crate completely new functionality." ++++ + +

Plugin Template

+

Here's what a generic plugin looks like. This template gives an overall idea of what you can do with plugins in Kube. Feel free to use this one as a boilerplate for your custom plugins.

+
(function(Kube)
+{
+    Kube.Myplugin = function(element, options)
+    {
+        this.namespace = 'myplugin';
+
+        // default settings
+        this.defaults = {
+            mysetting: true
+        };
+
+        // Parent Constructor
+        Kube.apply(this, arguments);
+
+        // Initialization
+        this.start();
+    };
+
+    // Functionality
+    Kube.Myplugin.prototype = {
+        start: function()
+        {
+            // plugin element
+            console.log(this.$element);
+
+            // call options
+            console.log(this.opts.mysetting);
+
+            // call methods
+            this.method();
+        },
+        method: function()
+        {
+            // do something...
+
+            // callback
+            this.callback('show');
+
+            // callback with arguments
+            this.callback('show', value1, value2);
+        }
+    };
+
+    // Inheritance
+    Kube.Myplugin.inherits(Kube);
+
+    // Plugin
+    Kube.Plugin.create('Myplugin');
+    Kube.Plugin.autoload('Myplugin');
+
+}(Kube));
+
+

Call

+

Calling a plugin is very easy, just add the data-component with the name of your plugin and it will start automatic.

+
<div data-component="myplugin"></div>
+

Or call manually

+
<div id="my-element"></div>
+
+<script>
+    $('#my-element').myplugin();
+</script>
+
+

Callbacks

+

Kube plugins can react on events with callbacks. Whenever you need your plugin to do something in response to an action or an event, just use a callback.

+
<div id="myplugin" data-component="myplugin"></div>
+
+<script>
+$('#myplugin').on('show.myplugin', function()
+{
+    // do something...
+});
+</script>
+
+

All plugin methods and variables are available within the plugin via this:

+
<script>
+$('#myplugin').on('show.myplugin', function()
+{
+    // plugin element
+    console.log(this.$element);
+
+    // call plugin method
+    this.method();
+});
+</script>
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/dropdown.md b/themes/coredns/exampleSite/content/docs/dropdown.md new file mode 100644 index 0000000..2c2eaf5 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/dropdown.md @@ -0,0 +1,172 @@ ++++ +date = "2017-04-10T16:42:12+01:00" +draft = false +weight = 140 +description = "Popular and adjustable menu and navigation option" +title = "Dropdown" +bref= "Dropdown menus in Kube are simple and intuitive. You've got a link with data-component='dropdown' and a div with some kind of HTML content. Clicking outside of the dropdown or hitting Esc closes dropdown" +toc = true ++++ + +

Demo

+
+

Show Dropdown

+ +
// Toggle
+<a href="#" data-component="dropdown" data-target="#my-dropdown">Show <span class="caret down"></span></a>
+
+// Dropdown
+<div class="dropdown hide" id="my-dropdown">
+    <a href="" class="close show-sm"></a>
+    <ul>
+        <li><a href="">...</a></li>
+    </ul>
+</div>
+
+
+
+

+ +
// Toggle
+<button data-component="dropdown" data-target="#my-dropdown">Show Dropdown <span class="caret down"></span></button>
+
+// Dropdown
+<div class="dropdown hide" id="my-dropdown">
+
+    <p>...</p>
+    <a href="#" data-action="dropdown-close">Close</a>
+
+</div>
+
+
+

Navigation Fixed

+

Scroll down a bit to make a fixed navigation bar appear at the top of the page, and then try out "Account" dropdown.

+
+ + +
<div id="navbar-demo" data-component="sticky">
+    <nav>
+        <ul>
+            <li><a href="">...</a></li>
+            <li>
+                <a href="" data-component="dropdown" data-target="#dropdown-fixed">
+                    Account
+                    <span class="caret down"></span>
+                </a>
+            </li>
+        </ul>
+    </nav>
+</div>
+
+// Dropdown
+<div class="dropdown hide" id="dropdown-fixed">
+    <ul>
+        <li><a href="">...</a></li>
+    </ul>
+</div>
+
+
+

Settings

+
target
+
    +
  • Type: string
  • +
  • Default: null
  • +
+

Sets an ID of a target dropdown layer.

+
height
+
    +
  • Type: int
  • +
  • Default: false
  • +
+

Sets dropdown height.

+
width
+
    +
  • Type: int
  • +
  • Default: false
  • +
+

Sets dropdown width.

+
animation
+
    +
  • Type: boolean
  • +
  • Default: true
  • +
+

Turns opening and closing animation on and off.

+

Callbacks

+
open
+
$('#my-dropdown').on('open.dropdown', function()
+{
+    // do something...
+});
+
opened
+
$('#my-dropdown').on('opened.dropdown', function()
+{
+    // do something...
+});
+
close
+
$('#my-dropdown').on('close.dropdown', function()
+{
+    // do something...
+});
+
closed
+
$('#my-dropdown').on('closed.dropdown', function()
+{
+    // do something...
+});
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/forms.md b/themes/coredns/exampleSite/content/docs/forms.md new file mode 100644 index 0000000..2055793 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/forms.md @@ -0,0 +1,800 @@ ++++ +date = "2017-04-10T16:40:50+01:00" +title = "Forms" +draft = false +weight = 60 +description = "Rows and columns for all sorts of tables" +bref = 'Forms come in all forms and shapes in Kube, and you can do all sorts of things with them, especially when combining with custom plugins for extra interactivity. These forms are ideal building material for your awesome projects!' +toc = true ++++ + +

Base

+

This is the most basic form with all the basic inputs.

+
+
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
<form method="post" action="" class="form">
+
+    <div class="form-item">
+        <label>Email</label>
+        <input type="email" name="email" class="w50">
+    </div>
+
+    <div class="form-item">
+        <label>Country</label>
+        <select>
+            <option value="">---</option>
+        </select>
+    </div>
+
+    <div class="form-item">
+        <label class="checkbox"><input type="checkbox"> Check me</label>
+        <label class="checkbox"><input type="radio"> Radio me</label>
+    </div>
+
+    <div class="form-item">
+        <textarea rows="6"></textarea>
+    </div>
+
+    <div class="form-item">
+        <button>Log in</button>
+        <button class="button secondary outline">Cancel</button>
+    </div>
+
+</form>
+
+ +
+ +

Inputs

+

Here's a standard input field with type set as text. Label serves as input's label, and the following div with class desc serves as an optional description.

+
+
+
+ +
+ This information helps us deliver orders on time. +
+
+
+
<form class="form">
+    <div class="form-item">
+        <label>City</label>
+        <input type="text">
+        <div class="desc">...</div>
+    </div>
+</form>
+
+
+

Here are two text input fields, one with a placeholder and another one disabled, both set to be 6 grid columns wide.

+
+
+
+
+
+ +
+
+
+
+ +
+
+
+
+
<form class="form">
+    <div class="row gutters">
+        <div class="col col-6">
+            <div class="form-item">
+                <input type="text" placeholder="Email">
+            </div>
+        </div>
+        <div class="col col-6">
+            <div class="form-item">
+                <input type="text" disabled="true" value="Disabled">
+            </div>
+        </div>
+    </div>
+</form>
+
+
+

Here's how you denote required fields with req class, and add descriptions to labels using span with class desc.

+
+
+
+
+
+ +
+
+
+
+ +
+ This information helps us deliver orders on time. +
+
+
+
+
+
<form class="form">
+    <div class="row gutters">
+        <div class="col col-6">
+            <div class="form-item">
+                <label>City <span class="req">*</span></label>
+                <input type="text">
+            </div>
+        </div>
+        <div class="col col-6">
+            <div class="form-item">
+                <label>City <span class="desc">...</span></label>
+                <input type="text">
+                <div class="desc">...</div>
+            </div>
+        </div>
+    </div>
+</form>
+
+
+ +
+
+
+ +
+
+
<form class="form">
+    <div class="form-item">
+        <input type="text" class="search">
+    </div>
+</form>
+
+
+

Checkboxes & Radio

+

Kube features full variety of stylish checkboxes and radio buttons. You can feature them on your pages by defining input type as checkbox or radio. There's also a neat option to place checkboxes inline by adding form-checkboxes class to the container (works for both checkboxes and radio buttons)

+
+
+ +
+ +
+
+
<form method="post" action="" class="form">
+    <div class="form-item form-checkboxes">
+        <label class="checkbox"><input type="checkbox"> Check 1</label>
+        ...
+    </div>
+</form>
+
+
+
+
+ +
+ +
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <label class="checkbox"><input type="checkbox"> Check 1</label>
+        ...
+    </div>
+</form>
+
+
+
+
+ +
+ +
+
+
<form method="post" action="" class="form">
+    <div class="form-item form-checkboxes">
+        <label class="checkbox"><input type="radio"> Check 1</label>
+        ...
+    </div>
+</form>
+
+
+
+
+ +
+ +
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <label class="checkbox"><input type="radio"> Check 1</label>
+        ...
+    </div>
+</form>
+
+
+

Fieldset

+

Fieldsets in Kube are nicely pre-formatted and ready to go. Just wrap your form in a fieldset tag and you're good to go.

+
+ +
+ Login data +
+ +
+
+ +
+
+
<fieldset>
+    <legend>Login data</legend>
+    <div class="form-item">
+        <label>Email</label>
+        <input type="email" name="user-email" class="w50">
+    </div>
+    <div class="form-item">
+        <label>Password</label>
+        <input type="password" name="user-password" class="w50">
+    </div>
+</fieldset>
+
+
+ About +
+ +
+
+ +
+
+
+
<fieldset>
+    <legend>About</legend>
+    <div class="form-item">
+        <textarea name="user-about" rows="5"></textarea>
+    </div>
+    <div class="form-item">
+        <button>Submit</button>
+    </div>
+</fieldset>
+
+

Small

+

Simple class .small makes your selects and fields, well, smaller.

+
+
+
+ +
+
+ +
+
+
<form class="form">
+    <div class="form-item">
+        <input type="text" class="small" placeholder="Title">
+    </div>
+    <div class="form-item">
+        <select class="small">
+            <option>...</option>
+        </select>
+    </div>
+</form>
+
+
+

Big

+

Simple class .big makes your selects and fields, well, bigger.

+
+
+
+ +
+
+ +
+
+
<form class="form">
+    <div class="form-item">
+        <input type="text" class="big" placeholder="Title">
+    </div>
+    <div class="form-item">
+        <select class="big">
+            <option>...</option>
+        </select>
+    </div>
+</form>
+
+
+

Width

+

Following framework-wide rules, it is very easy to manipulate form fields sizes. Just use w50 class to make a field 50% wide or w25 to a 25% wide.

+
+
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <input type="text" class="w25">
+    </div>
+    <div class="form-item">
+        <input type="text" class="w50">
+    </div>
+    <div class="form-item">
+        <input type="text" class="w75">
+    </div>
+    <div class="form-item">
+        <input type="text" value="100% by default">
+    </div>
+</form>
+
+
+

States

+

By default, Kube features two different states: success and failure.

+
+
+ +
+ +
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <label>Your height <span class="success">...</span></label>
+        <input type="text" class="success">
+    </div>
+</form>
+
+
+
+
+ +
+ +
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <label>Enter your weight <span class="error">...</span></label>
+        <input type="text" class="error">
+    </div>
+</form>
+
+
+

Required

+

Along with making a field actually required, you can add a visual clue for the users using a span with req class.

+
+
+ +
+ +
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <label>Email <span class="req">*</span></label>
+        <input type="email" name="user-email">
+    </div>
+</form>
+
+
+

Descriptions

+

Descriptions are simple: as long as form's element has desc class, Kube will treat it as a description.

+
+
+ +
+ +
+
+ +
+ Please enter your email. +
+
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <label>Name <span class="desc">...</span></label>
+        <input type="text" name="user-name">
+    </div>
+    <div class="form-item">
+        <label>Email</label>
+        <input type="email" name="user-email">
+        <div class="desc">...</div>
+    </div>
+</form>
+
+
+

Disabled

+

Not only text inputs can be disabled, but checkboxes and radio buttons as well. Just add disabled attribute or .disabled class to the input.

+
+

+

+

+

+

+

+
<input type="text" value="" disabled>
+<input type="checkbox" class="disabled">
+<input type="radio" disabled>
+<textarea disabled></textarea>
+<select disabled>
+    <option>...</option>
+</select>
+
+
+

Append & Prepend

+

You can prepend or append certain elements within your input fields, such as currency characters.

+
+
+ +
+ +
+ $ +
+
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <label>How much is it?</label>
+        <div class="prepend w50">
+            <span>$</span>
+            <input type="text">
+        </div>
+    </div>
+</form>
+
+
+
+
+ +
+ +
+ $ +
+
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <label>It is much how?</label>
+        <div class="append">
+            <input type="text"><span>$</span>
+        </div>
+    </div>
+</form>
+
+
+

Button Append

+

Appending works for buttons as well. Here you can see a button that has been appended and included withing a text input field.

+
+
+ +
+ +
+ +
+
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <label>Label</label>
+        <div class="append w50">
+            <input type="text" name="search" placeholder="Search">
+            <button class="button outline">Go</button>
+        </div>
+    </div>
+</form>
+
+
+

More Examples

+

The examples below are quite self explanatory and they cover multiple selections, selecting dates, filling in phone numbers, a ready feedback form template and more. Feel free to use any of these examples as templates for your sites.

+
+
+ +
+ +
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <label>Select multiple</label>
+        <select class="w50" multiple="multiple" size="10">
+            <optgroup label="Group 1">
+                <option value="">...</option>
+            </optgroup>
+        </select>
+    </div>
+</form>
+
+
+
+
+ +
+
+
+ +
+ Month +
+
+
+
+
+ +
+ Day +
+
+
+
+
+ +
+ Year +
+
+
+
+
+
<form method="post" action="" class="form">
+    <label>Choose date</label>
+    <div class="row gutters">
+        <div class="col col-3">
+            <div class="form-item">
+                <select><option>---</option></select>
+                <div class="desc">Month</div>
+            </div>
+        </div>
+        <div class="col col-3">
+            <div class="form-item">
+                <select><option>---</option></select>
+                <div class="desc">Day</div>
+            </div>
+        </div>
+        <div class="col col-6">
+            <div class="form-item">
+                <select><option>---</option></select>
+                <div class="desc">Year</div>
+            </div>
+        </div>
+    </div>
+</form>
+
+
+
+
+ +
+ ( )  ext: +
+ Needed if there are questions about your order +
+
+
+
<form method="post" action="" class="form form-inline">
+    <div class="form-item">
+        <label>Phone number</label>
+        ( <input type="text" name="phone-prefix" size="3" class="small"> )
+        <input type="text" name="phone-number" class="small w50">
+        &nbsp;ext: <input type="text" name="phone-ext" size="3" class="small">
+        <div class="desc">...</div>
+    </div>
+</form>
+
+
+
+
+ +
+
+
+ +
+
+
+
+ +
+
+
+
+ + +
+
+
<form method="post" class="form">
+    <div class="row gutters">
+        <div class="col col-6">
+            <div class="form-item">
+                <label>Email</label>
+                <input type="email">
+            </div>
+        </div>
+        <div class="col col-6">
+            <div class="form-item">
+                <label>Topic</label>
+                <select>
+                    <option value="">...</option>
+                </select>
+            </div>
+        </div>
+    </div>
+    <div class="form-item">
+        <label>Message</label>
+        <textarea rows="6"></textarea>
+    </div>
+</form>
+
+
+
+
+ +
+
+
+ +
+ Where are you from? +
+
+
+
+
+ +
+
+
+
+
<form method="post" action="" class="form">
+    <div class="row gutters">
+        <div class="col col-6">
+            <div class="form-item">
+                <label>Country</label>
+                <select>
+                    <option>---</option>
+                </select>
+                <div class="desc">...</div>
+            </div>
+        </div>
+        <div class="col col-6">
+            <div class="form-item">
+                <label><br></label>
+                <button>Submit</button>
+            </div>
+        </div>
+    </div>
+</form>
+
+
+
+
+ +
+ + +
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <label>Text</label>
+        <textarea rows="4"></textarea>
+    </div>
+</form>
+
+
+
+
+ +
+ + +
+
+
<form method="post" action="" class="form">
+    <div class="form-item">
+        <label>Text</label>
+        <textarea rows="4" class="w50"></textarea>
+    </div>
+</form>
+
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/grid.md b/themes/coredns/exampleSite/content/docs/grid.md new file mode 100644 index 0000000..f750657 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/grid.md @@ -0,0 +1,588 @@ ++++ +draft = false +weight = 30 +description = "Flexible, fully responsive and ready to use" +title = "Grid" +bref = "Kube uses fully responsive, flexbox-enabled 12-column grid. You can combine or divide columns, nest them, center them horizontally or vertically, and do all sorts of things. Here are a few examples of what you can do with Kube's grid." +toc = true ++++ + +
+

Columns

+

Columns are building blocks for many websites. Here's how columns are formed in Kube, and here's how you can use them right away.

+
+
+
+ 1 +
+
+ 11 +
+
+
+
+ 2 +
+
+ 10 +
+
+
+
+ 3 +
+
+ 9 +
+
+
+
+ 4 +
+
+ 8 +
+
+
+
+ 5 +
+
+ 7 +
+
+
+
+ 6 +
+
+ 6 +
+
+
+
+ 7 +
+
+ 5 +
+
+
+
+ 8 +
+
+ 4 +
+
+
+
+ 9 +
+
+ 3 +
+
+
+
+ 10 +
+
+ 2 +
+
+
+
+ 11 +
+
+ 1 +
+
+
+
+ 12 +
+
+
<div class="row">
+    <div class="col col-4">...</div>
+    <div class="col col-8">...</div>
+</div>
+
+
+

Gutters

+
+
+
+ 3 +
+
+ 9 +
+
+
<div class="row gutters">
+    <div class="col col-3">...</div>
+    <div class="col col-9">...</div>
+</div>
+
+
+

Auto Width

+
+
+
+ auto +
+
+ auto +
+
+ auto +
+
+
<div class="row auto">
+    <div class="col">...</div>
+    <div class="col">...</div>
+    <div class="col">...</div>
+</div>
+
+
+
Auto + Gutters
+
+
+
+ auto +
+
+ auto +
+
+ auto +
+
+ auto +
+
+
<div class="row gutters auto">
+    <div class="col">...</div>
+    <div class="col">...</div>
+    <div class="col">...</div>
+    <div class="col">...</div>
+</div>
+
+
+

Bricks

+
+
+
+ 50% +
+
+ 50% +
+
+ 50% +
+
+ 50% +
+
+
<div class="row">
+    <div class="col col-6">...</div>
+    <div class="col col-6">...</div>
+    <div class="col col-6">...</div>
+    <div class="col col-6">...</div>
+</div>
+
+
+
Bricks + Gutters
+
+
+
+ 33% +
+
+ 33% +
+
+ 33% +
+
+ 33% +
+
+ 33% +
+
+ 33% +
+
+
<div class="row gutters">
+    <div class="col col-4">...</div>
+    <div class="col col-4">...</div>
+    <div class="col col-4">...</div>
+    <div class="col col-4">...</div>
+</div>
+
+
+

Offset

+

Offsetting columns is very simple in Kube. Just use column's class as usual, for example, col col-2 and then add the offset value offset-4. This will offset this column and all following columns by 4.

+
+
+
+ 2 +
+
+ 6 +
+
+
<div class="row">
+    <div class="col col-2">...</div>
+    <div class="col col-6 offset-4">...</div>
+</div>
+
+
+

Nested

+

Here's an example of nesting columns within columns. In this example, we have a single row, with two columns .col col-6, a div nested within the second column, with .row end class to denote where to inject nested columns, and the three nested columns.

+
+
+
+ 6 +
+
+
+
+ 4 +
+
+ 4 +
+
+ 4 +
+
+
+
+
<div class="row">
+    <div class="col col-6">...</div>
+    <div class="col col-6">
+        <div class="row">
+            <div class="col col-4">...</div>
+            <div class="col col-4">...</div>
+            <div class="col col-4">...</div>
+        </div>
+    </div>
+</div>
+
+
+

Equal Height Columns

+

Columns are equal height by default in Kube

+
+
+
+ 1 +
+
+ 1
+ 2
+ 3 +
+
+
<div class="row">
+    <div class="col col-6">
+        ...
+    </div>
+    <div class="col col-6">
+        ...
+        ...
+        ...
+    </div>
+</div>
+
+
+

Reordering

+
First
+
+
+
+ 4 +
+
+ 8 +
+
+
<div class="row">
+    <div class="col col-4">...</div>
+    <div class="col col-8 first">...</div>
+</div>
+
+
+
Last
+
+
+
+ 3 +
+
+ 9 +
+
+
<div class="row">
+    <div class="col col-3 last">...</div>
+    <div class="col col-9">...</div>
+</div>
+
+
+

Around

+

When you want your columns to be surrounded by an even margins on both sides, just use .around class.

+
+
+
+ 3 +
+
+ 3 +
+
+ 3 +
+
+
<div class="row around">
+    <div class="col col-3">...</div>
+    <div class="col col-3">...</div>
+    <div class="col col-3">...</div>
+</div>
+
+
+

Between

+

Sometime you just need space between columns, and not around them. Well, there's a class for that: .between

+
+
+
+ 3 +
+
+ 3 +
+
+ 3 +
+
+
<div class="row between">
+    <div class="col col-3">...</div>
+    <div class="col col-3">...</div>
+    <div class="col col-3">...</div>
+</div>
+
+
+

Alignment

+
Align Center
+
+
+
+ 6 +
+
+
<div class="row align-center">
+    <div class="col col-6">...</div>
+</div>
+
+
+
Align Right
+
+
+
+ 3 +
+
+ 3 +
+
+
<div class="row align-right">
+    <div class="col col-3">...</div>
+    <div class="col col-3">...</div>
+</div>
+
+
+
Align Middle
+
+
+
+ 4 +
+
+ 4 +
+
+ 4 +
+
+
<div class="row align-middle">
+    <div class="col col-4">...</div>
+    <div class="col col-4">...</div>
+    <div class="col col-4">...</div>
+</div>
+
+
+

Push

+
Push Center
+
+
+
+ .push-center +
+
+
<div class="row">
+    <div class="col col-4 push-center">...</div>
+</div>
+
+
+
Push Right
+
+
+
+ ... +
+
+ .push-right +
+
+
<div class="row">
+    <div class="col col-6">...</div>
+    <div class="col col-4 push-right">...</div>
+</div>
+
+
+
Push Middle
+
+
+
+ .push-middle +
+
+
<div class="row">
+    <div class="col col-8 push-middle">...</div>
+</div>
+
+
+
Push Mixed
+
+
+
+ .push-middle.push-center +
+
+
<div class="row">
+    <div class="col col-8 push-middle push-center">...</div>
+</div>
+
+
+
Push Bottom
+
+
+
+ .push-bottom +
+
+
<div class="row">
+    <div class="col col-8 push-bottom">...</div>
+</div>
+
+
+

Fixed Width Column

+

Here's one more bit of magic. You can set a fixed width column and still have a responsive and flexible layout right beside this fixed width column.

+
+
+
+ sidebar +
+
+ content +
+
+
<!-- scss -->
+#container {
+    @include grid-row;
+}
+#sidebar {
+    @include flex-item-width(300px);
+}
+#content {
+    @include flex-item-auto;
+}
+
+<!-- html -->
+<div id="container">
+    <div id="sidebar">Sidebar</div>
+    <div id="content">Content</div>
+</div>
+
+
+
+

Media Grid

+

Media grid is a great example of Kube's flexibility and versatility. Whenever you have some media to display, you can choose to use Media grid. This type of grid is ideal for featuring photos; it adds some visual music and slight randomness to your layout.

+
+
+
+ 1 +
+
+ 2 +
+
+ 3 +
+
+ 4 +
+
+ 5 +
+
+ 6 +
+
+ 7 +
+
+ 8 +
+
+ 9 +
+
+ 10 +
+
+
<!-- scss -->
+#media-grid {
+
+    @include grid-media-columns(2);
+
+    & > div {
+        margin-bottom: 20px;
+        height: 80px;
+    }
+    & > div:nth-child(2n) {
+      height: 200px;
+    }
+    & > div:nth-child(5n) {
+      height: 120px;
+    }
+}
+
+<!-- html -->
+<div id="media-grid">
+  <div>1</div>
+  <div>2</div>
+  <div>3</div>
+  <div>4</div>
+  <div>5</div>
+  <div>6</div>
+  <div>7</div>
+  <div>8</div>
+  <div>9</div>
+  <div>10</div>
+</div>
+
+
+
diff --git a/themes/coredns/exampleSite/content/docs/labels.md b/themes/coredns/exampleSite/content/docs/labels.md new file mode 100644 index 0000000..2069ff6 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/labels.md @@ -0,0 +1,51 @@ ++++ +date = "2017-04-10T16:40:43+01:00" +title = "Labels" +draft = false +weight = 80 +description = "Label things with all sorts of labels" +bref = "Labels have all standard Kube styling options available: outline, states (success, error, warning), inverted color, and more. You can also customize labels to your requirements, and place them inside other elements, such as buttons, for example" +toc = true ++++ + +

Base

+
+ Default   Success   Error   Warning   Focus   Black   Inverted +
+

Outline

+
+ Default   Success   Error   Warning   Focus   Black   Inverted +
+

Upper

+
+ Default   Success   Error   Warning   Focus   Black   Inverted +
+

Tag

+
+ Default   Success   Error   Warning   Focus   Black   Inverted +
+

Badges

+

Labels are ideal for use as badges with badge class.

+
+ 1 2 3 4 5 6 7 +
+

Outline Badges

+
+ 1 2 3 4 5 6 7 +
+

Custom

+

You can use mixins to customize your labels and badges.

+
+ Label   1   Tag +
<!-- scss -->
+.label.custom {
+    // $text-color, $back-color
+    @include label(#fff, #ea48a7);
+}
+
+<!-- html -->
+<span class="label custom">Label</span>
+<span class="label badge custom">1</span>
+<span class="label tag custom">Tag</span>
+
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/messages.md b/themes/coredns/exampleSite/content/docs/messages.md new file mode 100644 index 0000000..11bc2ec --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/messages.md @@ -0,0 +1,159 @@ ++++ +date = "2017-04-10T16:41:34+01:00" +draft = false +weight = 90 +description = "Versatile and refined messages, ideal for daily use" +title = "Messages" +bref = "Messages are an essential part of modern web, and they can provide invaluable feedback to the users. Messages in Kube look nice, they are informative, simple and very easy to set up to whatever requirements you may have, style-wise or otherwise. Take a div, give it an message class, add a color using meaningful classes like error or success and you're practically done!" +toc = true ++++ + +

Usage

+
+
+ You have 2 modules waiting to installation. Install +
+
<div class="message" data-component="message"> ...  <span class="close small"></span></div>
+
+
+
+ You have 2 modules waiting to installation. Install +
+
<div class="message error" data-component="message"> ...  <span class="close small"></span></div>
+
+
+
+ You have 2 modules waiting to installation. Install +
+
<div class="message success" data-component="message"> ...  <span class="close small"></span></div>
+
+
+
+
Warning!
You have 2 modules waiting to installation. Install +
+
<div class="message warning" data-component="message">
+    <h5>...</h5>
+    ...
+    <span class="close small"></span>
+</div>
+
+
+
+
+ You have 2 modules waiting to installation. Install +
+
<div class="message focus" data-component="message"> ...  <span class="close small"></span></div>
+
+
+
+ You have 2 modules waiting to installation. Install +
+
<div class="message black" data-component="message"> ...  <span class="close small"></span></div>
+
+
+
+ You have 2 modules waiting to installation. Install +
+
<div class="message inverted" data-component="message"> ...  <span class="close small"></span></div>
+
+

Options

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeDefault
closeSelectorstring.close
closeEventstringclick
animationOpenstringfadeIn
animationClosestringfadeOut
+

Set an option

+

Via data attribute:

+
<div class="message" data-component="message" data-close-selector=".my-custom-close">
+    ... <span class="my-custom-close small"></span>
+</div>
+
+

Via Javascript:

+
$('#my-message').message({
+    closeSelector: '.my-custom-close'
+});
+
+

Methods

+

+
+ You have 2 modules waiting to installation. Install +
+ + + + + + + + + + + + + + + + + +
MethodDescription
closeManually closes a message.
openOpens a message if it has been closed.
+

Example

+
$('#my-message').message('close');
+

Callbacks

+ + + + + + + + + + + + + + + + + + + + + + + + + +
CallbackDescription
openThis event fires immediately when the open instance method is called.
openedThis event is fired when the message has been opened, will wait for CSS animation to complete.
closeThis event fires immediately when the close instance method is called.
closedThis event is fired when the message has been closed, will wait for CSS animation to complete.
+

Example

+
$('#my-message').on('closed.message', function()
+{
+    // do something
+})
+
diff --git a/themes/coredns/exampleSite/content/docs/mixins.md b/themes/coredns/exampleSite/content/docs/mixins.md new file mode 100644 index 0000000..70a3b93 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/mixins.md @@ -0,0 +1,268 @@ ++++ +weight = 230 +description = "Mixins save countless hours and bring results faster" +date = "2017-04-10T16:43:36+01:00" +title = "Mixins" +draft = false +bref="Mixins are a great way to produce things and effects way faster with Sass then with pure CSS. Kube has a lot to offer in this respect; feel free to use any of these mixins with any Kube components." +toc = true ++++ + +

Get Started

+

Kube has been designed to help you with web development, that's why it's so easy to use Kube when building websites. To move forward quickly and efficiently, just link kube.scss from Kube package: this file contains variables, mixins and everything you need to simplify daily routine tasks.

+

For example, import kube.scss into your master.scss styles file, which you will later compile into master.css

+
// master.scss
+@import "dist/scss/kube.scss";
+
+

Now all Kube's variables and mixins are readily available in master.scss, and you can use them whenever needed.

+
// master.scss
+@import "dist/scss/kube.scss";
+
+// use mixins
+#my-layout {
+    @include flex;
+}
+
+// use variables
+#my-layout {
+    padding: $base-line;
+}
+
+

Fonts

+

Generates a font-family declarations for text, headings, buttons or inputs.

+
// import Kube
+@import "dist/scss/kube.scss";
+
+// use mixins
+@include text-font("Lato, 'Helvetica Neue', sans-serif");
+@include headings-font("Lato, 'Helvetica Neue', sans-serif");
+@include buttons-font("Lato, 'Helvetica Neue', sans-serif");
+@include inputs-font("Lato, 'Helvetica Neue', sans-serif");
+
+

CSS Output

+
// Text
+body {
+    font-family: Lato, 'Helvetica Neue', sans-serif;
+}
+
+// Headings
+h1.title, h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
+    font-family: Lato, 'Helvetica Neue', sans-serif;
+}
+
+// Buttons
+button, .button {
+    font-family: Lato, 'Helvetica Neue', sans-serif;
+}
+
+// Inputs
+input, textarea, select {
+    font-family: Lato, 'Helvetica Neue', sans-serif;
+}
+
+

Breakpoints

+

Breakpoint for small screens (max-width 768px by default).

+
@include breakpoint(sm) {
+    .span {
+        display: none;
+    }
+}
+
+

Breakpoint for medium screens (min-width 1024px by default).

+
@include breakpoint(md) {
+    .span {
+        display: none;
+    }
+}
+
+

Breakpoint for large screens (min-width 1200px by default).

+
@include breakpoint(lg) {
+    .span {
+        display: none;
+    }
+}
+
+

Custom breakpoints:

+
// min-width 768px;
+@include breakpoint(768px) {}
+
+// min-width 768px and max-width 1024px;
+@include breakpoint(768px, 1024px) {}
+
+// max-width 1024px;
+@include breakpoint(0, 1024px) {}
+
+

Grid

+
Row
+

Generates a grid row.

+
.my-row {
+    @include grid-row;
+}
+
+

CSS Output

+
.my-row {
+    display: -ms-flexbox;
+    display: -webkit-flex;
+    display: flex;
+
+    -ms-flex-direction: row;
+    -webkit-flex-direction: row;
+    flex-direction: row;
+
+    -ms-flex-wrap: wrap;
+    -webkit-flex-wrap: wrap;
+    flex-wrap: wrap;
+}
+
+
Media Grid
+

Generates a media grid. See live example.

+
.my-media-grid {
+    @include grid-media-columns(3);
+}
+
+

CSS Output

+
.my-media-grid {
+    -webkit-column-count: 3;
+    -moz-column-count: 3;
+    column-count: 3;
+
+    // column gap is specified
+    // in the grid settings (variables.scss) as $grid-gutter
+    -webkit-column-gap: 2%;
+    -moz-column-gap: 2%;
+    column-gap: 2%;
+}
+
+.my-media-grid > div {
+    display: inline-block;
+    width: 100%;
+}
+
+@media (max-width: 768px) {
+    .my-media-grid {
+        -webkit-column-count: 1;
+        -moz-column-count: 1;
+        column-count: 1;
+    }
+}
+
+

Flex

+
@include flex;
+@include flex-basis($basis);
+
+// items
+@include flex-items-wrap;
+@include flex-items-nowrap;
+@include flex-items-row
+@include flex-items-column;
+@include flex-items-left;
+@include flex-items-right;
+@include flex-items-center;
+@include flex-items-space-between;
+@include flex-items-space-around;
+@include flex-items-top;
+@include flex-items-middle;
+@include flex-items-bottom;
+
+// item
+@include flex-item-grow($grow);
+@include flex-item-auto;
+@include flex-item-one;
+@include flex-item-shrink($shrink);
+@include flex-item-width($width);
+
+

Gradients

+
Vertical
+
@include gradient-vertical($startColor, $endColor);
+
+
@include gradient-vertical-to-opacity($startColor, $opacity);
+
+
Horizontal
+
@include gradient-horizontal($startColor, $endColor);
+
+
@include gradient-horizontal-to-opacity($startColor, $opacity);
+
+
Radial
+
@include gradient-radial($innerColor, $outerColor);
+
+

Utils

+
Clearfix
+

Provides an easy way to include a clearfix for containing floats.

+
.layout {
+    @include clearfix;
+}
+
+

CSS Output

+
.layout:after {
+    content: '';
+    display: table;
+    clear: both;
+}
+
+
Transition
+

This mixin provides a shorthand syntax for transitions.

+
// by default 'all linear .2s'
+@include transition;
+
+// custom transitions
+@include transition(all .2s ease-in-out);
+@include transition(opacity 1s ease-in, width .2s ease-in);
+
+
Transform
+

Provides a shorthand syntax for transforms.

+
.span {
+    @include transform(rotate(90deg));
+}
+
+

CSS Output

+
.span {
+    -webkit-transform: rotate(90deg);
+    -moz-transform: rotate(90deg);
+    -ms-transform: rotate(90deg);
+    transform: rotate(90deg);
+}
+
+
Blur
+

Provides a shorthand syntax for blur filter.

+
.span {
+    @include blur(5px);
+}
+
+

CSS Output

+
.span {
+    -webkit-filter: blur(5px);
+    -moz-filter: blur(5px);
+    -ms-filter: blur(5px);
+    filter: blur(5px);
+}
+
+
Retina Image
+

Retina image must have a suffix -2x, for example: image-2x.jpg

+
@include retina-background-image($image-url, $image-type, $image-width, $image-height);
+
+// $image-type - jpg, png, gif
+// $image-height - optional
+
+

Example:

+
.brand {
+    @include retina-background-image('../logo', 'png', 100px);
+}
+
+

CSS Output

+
.brand {
+    background-repeat: no-repeat;
+    background-image: url("../logo.png");
+}
+@media only screen and (-webkit-min-device-pixel-ratio: 2),
+       only screen and (min--moz-device-pixel-ratio: 2),
+       only screen and (-o-min-device-pixel-ratio: 2 / 1),
+       only screen and (min-device-pixel-ratio: 2),
+       only screen and (min-resolution: 192dpi),
+       only screen and (min-resolution: 2dppx)
+       {
+            .brand {
+                background-image: url("../logo-2x.png");
+                background-size: 100px auto;
+            }
+       }
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/modal.md b/themes/coredns/exampleSite/content/docs/modal.md new file mode 100644 index 0000000..1321b83 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/modal.md @@ -0,0 +1,189 @@ ++++ +title = "Modal" +draft = false +weight = 150 +date = "2017-04-10T16:42:18+01:00" +description = "Clean, functional, and extensible modal window dialogs" +bref="Modal windows are used for various reasons and purposes. Kube makes the way you design and operate modal windows very straightforward. First, you set a div which will represent the content of the modal window, then you set up a way to open and close this window, and finally you add a way to call the modal from the page" +toc = true ++++ + +

Calling

+

Here you add an actual call to the modal window. Clicking the "Open" button below will launch a modal with content of a #my-modal div. You can use buttons or links to open modals in Kube. Clicking anywhere outside of the modal or hitting ESC will close the window.

+
+

+
// Call
+<button data-component="modal" data-target="#my-modal">Open</button>
+
+// Markup
+<div id="my-modal" class="modal-box hide">
+    <div class="modal">
+        <span class="close"></span>
+        <div class="modal-header">Modal Header</div>
+        <div class="modal-body">...</div>
+    </div>
+</div>
+
+
+

Open from url

+
+

+
// Call
+<button data-component="modal" data-target="#ui-modal" data-url="modal.html">Open</button>
+
+// Markup
+<div id="ui-modal" class="modal-box hide">
+    <div class="modal">
+        <span class="close"></span>
+        <div class="modal-header">UI Modal</div>
+        <div class="modal-body">... content from modal.html ...</div>
+    </div>
+</div>
+
+// modal.html
+<p>...</p>
+<a href="#" data-action="modal-close">Close</a>
+
+
+

Direct open

+
+

+
// Call
+<button onclick="$.modalwindow({ target: '#ui-modal', url: 'modal.html' });">Open</button>
+
+
+ + +

Actions

+

Using modal-close action you now introducing a way to close you window, using a link or a button.

+
<div id="my-modal" class="modal-box hide">
+    <div class="modal">
+        <span class="close"></span>
+        <div class="modal-header">Modal Header</div>
+        <div class="modal-body">
+            ...
+            <a href="#" data-action="modal-close">Close</a>
+        </div>
+    </div>
+</div>
+
+

Settings

+
target
+
    +
  • Type: string
  • +
  • Default: null
  • +
+

Defines a content layer for the modal window

+
url
+
    +
  • Type: string
  • +
  • Default: false
  • +
+

Defines a URL in case your modal is opening via a URL.

+
header
+
    +
  • Type: string
  • +
  • Default: false
  • +
+

Sets the header for the modal window. Optional, and is false by default.

+
width
+
    +
  • Type: string
  • +
  • Default: '600px'
  • +
+
height
+
    +
  • Type: string
  • +
  • Default: false
  • +
+
maxHeight
+
    +
  • Type: string
  • +
  • Default: false
  • +
+

This setting defines the maximum height of the window. A scrollbar will be introduced in case there's more text than maxHeight can accommodate.

+
position
+
    +
  • Type: string
  • +
  • Default: 'center'
  • +
+

This is where your modal appears when opened.

+
overlay
+
    +
  • Type: boolean
  • +
  • Default: true
  • +
+

When this is set to false, you modal window will just appear on top ow your page, without an overlay effect. By default, your page will be "covered" with a semi-transparent layer when you open a modal.

+
animation
+
    +
  • Type: boolean
  • +
  • Default: true
  • +
+

Turns opening and closing animation on and off.

+

Callbacks

+
open
+
$('#my-modal').on('open.modal', function()
+{
+    // do something...
+});
+
+
opened
+
$('#my-modal').on('opened.modal', function()
+{
+    // do something...
+});
+
+
close
+
$('#my-modal').on('close.modal', function()
+{
+    // do something...
+});
+
+
closed
+
$('#my-modal').on('closed.modal', function()
+{
+    // do something...
+});
+
+

API

+

You can use these API methods to programmatically operate and modify modal windows.

+
close
+
$('#my-modal').modal('close');
+
+
setHeader
+
$('#my-modal').modal('setHeader', 'My Header');
+
+

This is another way to set a header for the modal on the fly without introducing a div with a modal-header class.

+
setContent
+
$('#my-modal').modal('setContent', 'My Content');
+
+

Content of the modal window can be set up on the fly as well. No need for a div with modal class.

+
setWidth
+
$('#my-modal').modal('setWidth', '800px');
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/offcanvas.md b/themes/coredns/exampleSite/content/docs/offcanvas.md new file mode 100644 index 0000000..37ed858 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/offcanvas.md @@ -0,0 +1,140 @@ ++++ +date = "2017-04-10T16:42:43+01:00" +draft = false +weight = 180 +description = "Navigation, menus and content sliding from outside the page" +title = "Offcanvas" +bref="Offcanvas makes it look like a menu is sliding from the outside of the page. This may be useful in many different cases, one of them being when you need to save space on screen and don't have to display sidebar at all times" +toc= true ++++ + +

Demo

+

This feature is very easy to set up. It is based on data-component set to offcanvas, data-target set to the menu layer (#offcanvas-right in example below) and a feature-specific data-direction which is required for right menu to be set to right.

+

Open Left Open Right

+
+ +
+
+ + +
+
// Left
+<a href="#" data-component="offcanvas" data-target="#offcanvas-left">Open Left</a>
+
+<div id="offcanvas-left" class="hide">
+    <nav>
+        <ul>
+            <li>...</li>
+        </ul>
+    </nav>
+</div>
+
+// Right + Close
+<a href="#" data-component="offcanvas" data-target="#offcanvas-right" data-direction="right">Open Right</a>
+
+<div id="offcanvas-right" class="hide">
+    <a href="#" class="close"></a>
+    <nav>
+        <ul>
+            <li>...</li>
+        </ul>
+    </nav>
+</div>
+
+

Settings

+
target
+
    +
  • Type: string
  • +
  • Default: null
  • +
+

Sets ID selector of an element that will slide from the side.

+
push
+
    +
  • Type: boolean
  • +
  • Default: true
  • +
+
direction
+
    +
  • Type: string
  • +
  • Default: 'left'
  • +
+

The direction in which page will shift to give way for the sidebar menu. Default is left and is not required for left-side navigation, however, right value must be set for the right-side menu to work.

+
clickOutside
+
    +
  • Type: boolean
  • +
  • Default: true
  • +
+

Unless set to false, clicking anywhere on a page will make side menu to close.

+
width
+
    +
  • Type: string
  • +
  • Default: '250px'
  • +
+

Sidebar width in pixels.

+
animation
+
    +
  • Type: boolean
  • +
  • Default: true
  • +
+

Setting this to false turns off opening and closing animation.

+

Callbacks

+
open
+
$('#my-offcanvas').on('open.offcanvas', function()
+{
+    // do something...
+});
+
+
opened
+
$('#my-offcanvas').on('opened.offcanvas', function()
+{
+    // do something...
+});
+
+
close
+
$('#my-offcanvas').on('close.offcanvas', function()
+{
+    // do something...
+});
+
+
closed
+
$('#my-offcanvas').on('closed.offcanvas', function()
+{
+    // do something...
+});
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/pagination.md b/themes/coredns/exampleSite/content/docs/pagination.md new file mode 100644 index 0000000..e5a3d05 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/pagination.md @@ -0,0 +1,196 @@ ++++ +date = "2017-04-10T16:42:03+01:00" +draft = false +weight = 130 +description = "Various flexible pagination options for your site" +title = "Pagination" +bref= "Default pagination in Kube is organized using lists, with visual cues for the user what is the current page, and page numbers for easier navigation. Pagination buttons and multiline formats are available out-of-the-box as well" +toc =true ++++ + +

Base

+
+ +
<nav class="pagination">
+    <ul>
+        <li class="prev"><a href="">&larr;</a></li>
+        <li>
+            <ul>
+                <li><span>...</span></li>
+                <li><a href="">...</a></li>
+            </ul>
+        </li>
+        <li class="next"><a href="">&rarr;</a></li>
+    </ul>
+</nav>
+
+
+

Centered

+
+ +
<nav class="pagination align-center">
+    <ul>
+        <li class="prev"><a href="">&larr;</a></li>
+        <li>
+            <ul>
+                <li class="active"><a href="#">...</a></li>
+                <li><a href="">...</a></li>
+            </ul>
+        </li>
+        <li class="next"><a href="">&rarr;</a></li>
+    </ul>
+</nav>
+
+
+

Wide

+

Here you can see an example where previous and next buttons are aligned to the left and to the right, with a link in the center of the page.

+
+ +
<nav class="pagination align-center upper strong">
+    <ul>
+        <li class="prev"><a href="">&lt; Prev</a></li>
+        <li class="w100">
+            <ul>
+                <li><a href="">...</a></li>
+            </ul>
+        </li>
+        <li class="next"><a href="">Next &gt;</a></li>
+    </ul>
+</nav>
+
+
+

Pager

+
+ +
<nav class="pagination pager">
+    <ul>
+        <li class="prev"><a href="">Previous</a></li>
+        <li class="next"><a href="">Next</a></li>
+    </ul>
+</nav>
+
+
+
+ +
<nav class="pagination pager align-center">
+    <ul>
+        <li class="prev"><a href="">Previous</a></li>
+        <li class="next"><a href="">Next</a></li>
+    </ul>
+</nav>
+
+
+

Elements within a single list item can be stacked to create a clean and intuitive pagination elements.

+
+ +
<nav class="pagination pager flat">
+    <ul>
+        <li class="prev">
+            <span class="label tag">Prev</span>
+            <a href="">...</a>
+        </li>
+        <li class="next">
+            <span class="label tag">Next</span>
+            <a href="">...</a>
+        </li>
+    </ul>
+</nav>
+
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/quick-start.md b/themes/coredns/exampleSite/content/docs/quick-start.md new file mode 100644 index 0000000..dc75490 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/quick-start.md @@ -0,0 +1,81 @@ ++++ +title = "Quick Start" +description = "Up and running in under a minute" +weight = 10 +draft = false +toc = true +bref = "As a complete and self-sufficient web framework, Kube is here to help you get the most out of your daily work. Kube takes care of routine stuff, saving you precious time for things that you love. Starting up with Kube is ridiculously fast you can start in under a minute. Here's how to set up Kube, and what basic customization are available out-of-the-box." ++++ + +

Basic Template

+ +

With Kube, you can set up your web framework and be on your way in under a minute. Just add this code to your web page for the basic template to take effect immediately.

+ +
<!DOCTYPE html>
+<html>
+<head>
+    <title>Basic Template</title>
+
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1">
+
+    <!-- Kube CSS -->
+    <link rel="stylesheet" href="assets/css/kube.css">
+
+</head>
+<body>
+    <h1>Hello, world!</h1>
+
+    <!-- Kube JS + jQuery are used for some functionality, but are not required for the basic setup -->
+    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
+    <script src="assets/js/kube.js"></script>
+</body>
+</html>
+ + +

Supported Browsers

+ +

Kube supports the latest, stable releases of all major browsers:

+
    +
  • Latest Chrome
  • +
  • Latest Firefox
  • +
  • Latest Safari
  • +
  • Latest Opera
  • +
  • Microsoft Edge
  • +
  • Internet Explorer 11
  • +
+ + +

Development with Kube

+ +

Kube has been designed to help you with web development, that's why it's so easy to use Kube when building websites. To move forward quickly and efficiently, just link kube.scss from Kube package: this file contains variables, mixins and everything you need to simplify daily routine tasks. +

+ +

+ For example, import kube.scss into your master.scss styles file, which you will later compile into master.css: +

+ +
// master.scss
+@import "dist/scss/kube.scss";
+ +

+ Now all Kube's variables and mixins are readily available in master.scss, + and you can use them whenever needed. For instance, here's how one of examples: +

+ +
// master.scss
+@import "dist/scss/kube.scss";
+
+#sidebar {
+    @include flex-item-width(200px);
+}
+ +

Also, you could use settings from variables.scss:

+ + +
// master.scss
+@import "dist/scss/kube.scss";
+
+#my-layout {
+    padding: $base-line;
+}
diff --git a/themes/coredns/exampleSite/content/docs/sizing.md b/themes/coredns/exampleSite/content/docs/sizing.md new file mode 100644 index 0000000..be164b9 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/sizing.md @@ -0,0 +1,99 @@ ++++ +title = "Sizing" +date = "2017-04-10T16:43:21+01:00" +draft = false +weight = 220 +description = "Helper tools for elements width and height" +bref="Helper tools for elements width and height." +toc = true ++++ + +

Width

+
+
+ w5 +
+
+ w10 +
+
+ w15 +
+
+ w20 +
+
+ w25 +
+
+ w30 +
+
+ w35 +
+
+ w40 +
+
+ w45 +
+
+ w50 +
+
+ w55 +
+
+ w60 +
+
+ w65 +
+
+ w70 +
+
+ w75 +
+
+ w80 +
+
+ w85 +
+
+ w90 +
+
+ w95 +
+
+ w100 +
+
<div class="w5">w5</div>
+...
+<div class="w100">w100</div>
+
+
+
+

100% width on small devices.

+
+ w100-sm +
+
<div class="w50 w100-sm">...</div>
+
+
+

Auto Width

+
+ .w-auto
+ .w-auto-sm +
+

Max Width

+
+ .max-w5 — .max-w100
+ .max-w-auto-sm +
+

Min Width

+
+ .min-w5 — .min-w100 +
diff --git a/themes/coredns/exampleSite/content/docs/sticky.md b/themes/coredns/exampleSite/content/docs/sticky.md new file mode 100644 index 0000000..9779ed5 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/sticky.md @@ -0,0 +1,66 @@ ++++ +date = "2017-04-10T16:42:26+01:00" +title = "Sticky" +draft = false +weight = 160 +description = "Make navigation menus stick to the top on scroll" +bref="Sticky navigation makes it easy to affix menus to the top of the page whenever a user scrolls the page down. This could be very helpful and useful on long pages. Sticky is disabled on mobile devices to avoid unwanted content overlaps and to preserve valuable screen real estate" +toc = true ++++ + +

Demo

+

Scroll down to fix the navigation.

+ +
<div data-component="sticky">...</div>
+
+

Settings

+
offset
+
    +
  • Type: int
  • +
  • Default: 0
  • +
+

Sets top offset in pixels when navigation is fixed.

+

Callbacks

+
fixed
+

Using this callback, you can act upon menu becoming fixed at the top of the page.

+
$('#my-nav').on('fixed.sticky', function()
+{
+    // do something...
+});
+
+
unfixed
+

Whenever fixed position of the menu is released, you can do something with this callback.

+
$('#my-nav').on('unfixed.sticky', function()
+{
+    // do something...
+});
+

+
+

Some scrollable material

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/tables.md b/themes/coredns/exampleSite/content/docs/tables.md new file mode 100644 index 0000000..0bc6c26 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/tables.md @@ -0,0 +1,196 @@ ++++ +date = "2017-04-10T16:40:43+01:00" +title = "Tables" +draft = false +weight = 50 +description = "Rows and columns for all sorts of tables" +toc = true +bref = "Tables are an essential part of many different contexts. Kube serves them all and delivers full variety of tables, preformatted to save you time. Whatever your requirements are, tables are completely customizable to match them." ++++ + +

Base

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NamePoints
JillSmith50
EveJackson94
Total points223
+
<table>...</table>
+
+

Bordered

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NamePoints
JillSmith50
EveJackson94
Total points223
+
<table class="bordered">...</table>
+
+

Striped

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NamePoints
JillSmith50
EveJackson94
Total points223
+
<table class="striped">...</table>
+
+

Unstyled

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NamePoints
JillSmith50
EveJackson94
Total points223
+
<table class="unstyled">...</table>
+
+

Mixed

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
First NameLast NamePoints
JillSmith50
EveJackson94
Total points223
+
<table class="bordered striped">...</table>
+
+

Width

+
+ + + + + + + + + + + + + + + + + + + + +
First NameLast NamePoints
JillSmith50
EveJackson94
+
<table>
+<tr>
+    <td class="w40">...</td>
+    <td class="w40">...</td>
+    <td class="w20">...</td>
+</tr>
+</table>
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/tabs.md b/themes/coredns/exampleSite/content/docs/tabs.md new file mode 100644 index 0000000..95b6e23 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/tabs.md @@ -0,0 +1,286 @@ ++++ +title = "Tabs" +date = "2017-04-10T16:41:40+01:00" +draft = false +weight = 100 +description = "User-friendly navigation for your content or app" +bref= "Tabs in Kube are crafted the way one would expect from the world's best CSS framework. With versatile API, wide range of settings an options, with callbacks and live examples. Take a look!" +toc= true ++++ + +

Base

+

Here's an example of basic tabs setup. Tabs bar is an unordered list, and each tab in tabs bar is a list item. For each tab there's a corresponding div, which contains the body of the tab (it can be any kind of HTML).

+
+ +
+
Home
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
Shop
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
Catalog
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
T-Shirts
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
Brand
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
<nav class="tabs" data-component="tabs">
+    <ul>
+        <li class="active"><a href="#tab1">...</a></li>
+        <li><a href="#tab2">...</a></li>
+    </ul>
+</nav>
+
+<div id="tab1">...</div>
+<div id="tab2">...</div>
+    
+
+

JavaScript behavior

+

Tabs are interactive elements, and can be opened, closed, switched, destroyed and selected programmatically via JavaScript. Try this example, poke around and then have a look at the self-explanatory code example below.

+
+


+ +
+
Home
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
Shop
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
Catalog
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
T-Shirts
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
Brand
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
<button onclick="$('#tabs').tabs('destroy');">destroy</button>
+<button onclick="$('#tabs').tabs('prev');">prev</button>
+<button onclick="$('#tabs').tabs('next');">next</button>
+<button onclick="$('#tabs').tabs('open', 4);">open</button>
+<button onclick="$('#tabs').tabs('close', '#tab4');">close</button>
+<button onclick="$('#tabs').tabs('closeAll');">closeAll</button>
+
+<nav id="tabs" class="tabs" data-component="tabs">
+    <ul>
+        <li><a href="#tab1">Home</a></li>
+        <li class="active"><a href="#tab2">Shop</a></li>
+        <li><a href="#tab3">Catalog</a></li>
+        <li><a href="#tab4">T-Shirts</a></li>
+        <li><a href="#tab5">Brand</a></li>
+    </ul>
+</nav>
+
+<div id="tab1">...</div>
+<div id="tab2">...</div>
+<div id="tab3">...</div>
+<div id="tab4">...</div>
+<div id="tab4">...</div>
+
+
+

Equals

+

Often it is important to create tabs that are equal in width regardless of content. data-equals is here to help you with this task.

+
+ +
+
Tab 1
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
Tab 2
+

...

+
+
<nav class="tabs" data-component="tabs" data-equals="true">
+    <ul>
+        <li class="active"><a href="#tab1">...</a></li>
+        <li><a href="#tab12">...</a></li>
+    </ul>
+</nav>
+
+<div id="tab1">...</div>
+<div id="tab2">...</div>
+
+
+

Livetabs

+

Livetabs provide a very seamless and smooth experience by blending content and tabs in this kind of live manner. Set up data-live class, and make sure your tabs have this same class. It's that simple.

+
+ +
+
General
+

This is very General Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+
Additional
+

Quite an additional is displayed here: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
<nav id="livetabs" data-component="tabs" data-live=".tab-live"></nav>
+
+<div id="tab-general" data-title="General" class="tab-live">...</div>
+<div id="tab-additional" data-title="Additional" class="tab-live">...</div>
+
+
+

Active

+

To denote active tab, and to let users know where they are, use class active.

+
<nav class="tabs">
+    <ul>
+        <li><a href="">...</a></li>
+        <li class="active"><a href="">...</a></li>
+        <li><a href="">...</a></li>
+    </ul>
+</nav>
+
+

Settings

+
equals
+
    +
  • Type: boolean
  • +
  • Default: false
  • +
+

Making all tabs in a set equal width

+
active
+
    +
  • Type: string
  • +
  • Default: false
  • +
+

Responsible for denoting active tab.

+
live
+
    +
  • Type: string
  • +
  • Default: false
  • +
+

Responsible for live tabs (see Livetabs example)

+
hash
+
    +
  • Type: boolean
  • +
  • Default: true
  • +
+

This will add a hash and an ID to the URL.

+

Callbacks

+
init
+
$('#tabs').on('init.tabs', function()
+{
+    // do something...
+});
+
+
next
+
$('#tabs').on('next.tabs', function($item)
+{
+    // do something...
+});
+
+
prev
+
$('#tabs').on('prev.tabs', function($item)
+{
+    // do something...
+});
+
+
open
+
$('#tabs').on('open.tabs', function()
+{
+    // do something...
+});
+
+
opened
+
$('#tabs').on('opened.tabs', function()
+{
+    // do something...
+});
+
+
close
+
$('#tabs').on('close.tabs', function()
+{
+    // do something...
+});
+
+
closed
+
$('#tabs').on('closed.tabs', function()
+{
+    // do something...
+});
+
+

API

+
open
+
$('#tabs').tabs('open', 1);
+
+// or
+
+$('#tabs').tabs('open', '#tab1');
+
+
close
+
$('#tabs').tabs('close', 1);
+
+// or
+
+$('#tabs').tabs('close', '#tab1');
+
+
closeAll
+
$('#tabs').tabs('closeAll');
+
+
next
+
$('#tabs').tabs('next');
+
+
prev
+
$('#tabs').tabs('prev');
+
+
destroy
+
$('#tabs').tabs('destroy');
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/toggleme.md b/themes/coredns/exampleSite/content/docs/toggleme.md new file mode 100644 index 0000000..8f42250 --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/toggleme.md @@ -0,0 +1,157 @@ ++++ +title = "Toggleme" +date = "2017-04-10T16:42:59+01:00" +draft = false +weight = 190 +description = "Display or hide elements with simple toggle" +bref= "Toggleme is a great way to add a binary option to either display some content or hide it. It works like a charm for menus, disclaimers and so much more!" +toc = true ++++ + +

Demo

+

Toggleme works on mobile devices as well as on desktops. To see Toggleme in action, just resize this window or open this page on a mobile device.

+
+
+ Toggle +
+ +
<div class="show-sm">
+    <a href="#" data-component="toggleme" data-target="#navbar">Toggle</a>
+</div>
+
+<nav id="navbar" class="hide-sm">
+    <ul>
+        <li><a href="#">...</a></li>
+    </ul>
+</nav>
+
+
+

Usage

+
+

+
+

Ok, I'm opened. Now hide me

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
<button data-component="toggleme" data-target="#togglebox-target" data-text="Hide Me">Show Me</button>
+
+<div id="togglebox-target" class="hide">
+    ...
+</div>
+
+
+

Multiple targets

+
+

+
+

Ok, I'm opened. Now hide me

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
+

... and, I'm opened too. Now hide me

+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
<button data-component="toggleme" data-target="#togglebox-target-3, #togglebox-target-4" data-text="Hide Me">Show Me</button>
+
+<div id="togglebox-target-1" class="hide">
+    ...
+</div>
+
+<div id="togglebox-target-2" class="hide">
+    ...
+</div>
+
+
+

Settings

+
target
+
    +
  • Type: string
  • +
  • Default: null
  • +
  • Possible values: selector/selectors
  • +
+

Defines which layer or layers should be displayed upon clicking the "open" button.

+
<button data-component="toggleme" data-target="#togglebox-target">Show Me</button>
+
+<button data-component="toggleme" data-target="#togglebox-target-1, #togglebox-target-2">Show Me</button>
+
+<button data-component="toggleme" data-target=".togglebox-target">Show Me</button>
+
+
+
text
+
    +
  • Type: string
  • +
  • Default: ''
  • +
+

Defines what text should a button have after the layer has been opened. If not set, button text will not change.

+
<button data-component="toggleme" data-target="#togglebox-target" data-text="Hide Me">Show Me</button>
+
+
+

Callbacks

+
open
+
$('#togglebox-target').on('open.toggleme', function()
+{
+    // do something...
+});
+
+
opened
+
$('#togglebox-target').on('opened.toggleme', function()
+{
+    // do something...
+});
+
+
close
+
$('#togglebox-target').on('close.toggleme', function()
+{
+    // do something...
+});
+
+
closed
+
$('#togglebox-target').on('closed.toggleme', function()
+{
+    // do something...
+});
+
+

API

+
toggle
+
$('#togglebox-target').toggleme('toggle');
+
+
open
+
$('#togglebox-target').toggleme('open');
+
+
close
+
$('#togglebox-target').toggleme('close');
+
+
isOpened
+
var isOpened = $('#togglebox-target').toggleme('isOpened');
+
+
isClosed
+
var isClosed = $('#togglebox-target').toggleme('isClosed');
+
+
destroy
+
$('#togglebox-target').toggleme('destroy');
+
diff --git a/themes/coredns/exampleSite/content/docs/typography.md b/themes/coredns/exampleSite/content/docs/typography.md new file mode 100644 index 0000000..40f30ef --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/typography.md @@ -0,0 +1,452 @@ ++++ +title = "Typography" +weight = 25 +draft = false +description = "Always precise spacing and perfect font size" +bref = "Typography is perhaps one of the most important and most visible things on a web page. Even slightest imperfection can ruin otherwise perfect website. With Kube, you will have perfect typography with ideal spacing, font sizes and proportions, regardless of the exact style or font you choose for your site." +toc = true ++++ + +

Get Started

+

Typography of Kube based on the 4px horizontal grid, it means that for the headers, paragraphs, quotes and any other texts chosen are a combination of line-height, that fit into the 4px grid and help set the horizontal rhythm of design by default.

+
+ 4px horizontal rhythm +
+ 4px grid for typography - the magic of the horizontal rhythm +
+
+

With this feature, you can quickly and easily make a solid and harmonious-looking website and UI design. You do not need to do complicated calculations to find the size and proportions of the text baseline, no need to look for the magic formula to build a horizontal rhythm. Magic is already in Kube.

+

You can use all the default settings of typography and it will always look balanced. But also you can easily change any font sizes, just try to set the value of line-height fold for 4px and your texts will still look great.

+

Additional balance and harmony, creates a classic typography scale, used in Kube.

+
+ the typography scale +
+ The typography scale helps to build a balance between the size of headings and text elements +
+
+

Headings

+

Use h1-h6 tags or .h1-.h6 classes to define headers and class="title" for the title, which is suitable for the most important inscriptions, for example, in the hero or covers.

+
+

Title

+

Heading 1

+

Heading 2

+

Heading 3

+

Heading 4

+
Heading 5
+
Heading 6
+
<h1 class="title">...</h1>
+<h1>...</h1>
+...
+<h6>...</h6>
+
+

Paragraphs

+

The base pragraph has an ideal ratio of font size and baseline. This text is easy to read in most cases.

+
+

16px/24px

+

By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.

+
<p>...</p>
+
+

In special cases, you can use modifiers which increase or decrease the text size. It is useful for building a variety of websites and UI, when you need to make a lead text or signatures with a small font size .

+
+

20px/32px

+

By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.

+
<p class="large">...</p>
+
+
+

18px/28px

+

By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.

+
<p class="big">...</p>
+
+
+

14px/20px

+

By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.

+
<p class="small">...</p>
+
+
+

12px/20px

+

By the same illusion which lifts the horizon of the sea to the level of the spectator on a hillside, the sable cloud beneath was dished out, and the car seemed to float in the middle of an immense dark sphere, whose upper half was strewn with silver.

+
<p class="smaller">...</p>
+
+

Columns

+

Kube has three classes of .columns-2 through .columns-4 to create a multi-column layout. All multi-column layouts will be in a single column on mobile.

+
+

2 columns

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
<div class="columns-2">
+    <p>...</p>
+</div>
+
+
+
+

3 columns

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
<div class="columns-3">
+    <p>...</p>
+</div>
+
+
+
+

4 columns

+
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+
<div class="columns-4">
+    <p>...</p>
+</div>
+
+
+

Quotes

+

Quotes in the text stand out for contrast and added variety to the text. In the quotes you can mark text as a paragraph tag and without it.

+
+
+

No, she'll probably make me do it. Goodbye, friends. I never thought I'd die like this. But I always really hoped. I saw you with those two "ladies of the evening" at Elzars. Explain that. I never loved you.

+
+
<blockquote>...</blockquote>
+
+

Use small tag for attribution. It's a prefer way for semantic code.

+
+
+

Who's brave enough to fly into something we all keep calling a death sphere? Yes. You gave me a dollar and some candy. I just want to talk. It has nothing to do with mating. Fry, that doesn't make sense.

— Bender +
+
<blockquote>
+    <p>Quotation content</p>
+    <small>Author attribution</small>
+</blockquote>
+
+
+

Pre-formatted

+

Pre-formatted text most often used to display code snippets or other text elements, for which you wish to preserve the exact formatting they've got.

+
+
Function.prototype.inherits = function(parent)
+{
+    for (var key in parent.prototype)
+    {
+        this.prototype[key] = parent.prototype[key];
+    }
+};
+
+
<pre>...</pre>
+
+

You feel free to use code tag inside pre.

+
+
Function.prototype.inherits = function(parent)
+{
+    for (var key in parent.prototype)
+    {
+        this.prototype[key] = parent.prototype[key];
+    }
+};
+
+
<pre><code>...</code></pre>
+
+

Inline Elements

+

Kube features various inline formatting elements. They all have their own semantic meaning, but you're free to use them just for their style.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExampleTagExampleTag
CSS<abbr>Cite<cite>
Code<code>Sample<samp>
Variable<var>Mark<mark>
Shortcut<kbd> + Deleted + <del>
Italic<i>Emphasis<em>
Highlighted<strong>Bold<b>
xsuperscript<sup>xsubscript<sub>
Small<small> + Inserted + <ins>
+

Modifiers

+

Modifiers - a set of helper classes for creating accents in the text and for the solution of useful tasks without writing CSS code, for example, the alignment of the text in the center.

+

Modifiers can be applied to any tags as inline elements, links or block tags.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ExampleModifier
Muted.muted
+ Muted link + .muted
+ Black link + .black
Highlight.highlight
upper.upper
LOWER.lower
Italic.italic
Strong.strong
Not strong.normal
Monospace.monospace
Nowrap.nowrap
Remove margin bottom.end
Highlight.highlight
Small.small
Smaller.smaller
Large.large
Big.big
Text left.text-left
Text center.text-center
Text right.text-right
+

Figure

+

A figure tag features an image, a video or a code plus a caption. It is a good accessibility practice. It also helps serve responsive video to various devices when you wrap video into .video-container class.

+
Images
+
+ Image +
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit... +
+
+

HTML

+
<figure>
+    <img src="image.jpg">
+    <figcaption>...</figcaption>
+</figure>
+
+
Video
+
+
+ +
+
+ Journey Through The Ice | National Geographic +
+
+

HTML

+
<figure>
+    <div class="video-container">
+        <iframe>...</iframe>
+    </div>
+    <figcaption>...</figcaption>
+</figure>
+
+
Code
+
+
Function.prototype.inherits = function(parent)
+{
+    for (var key in parent.prototype)
+    {
+        this.prototype[key] = parent.prototype[key];
+    }
+};
+
+
+ One of the implementations of inheritance +
+
+

HTML

+
<figure>
+    <pre>...</pre>
+    <figcaption>...</figcaption>
+</figure>
+
+

Lists

+

Although you most likely will not ever need to do so, you can still nest as many list levels as you like.

+
+
+
+
    +
  • list item 1
  • +
  • list item 2 +
      +
    • list item 2.1
    • +
    • list item 2.2 +
        +
      • list item 2.2.1
      • +
      • list item 2.2.2
      • +
      +
    • +
    • list item 2.3
    • +
    • list item 2.4
    • +
    +
  • +
  • list item 3
  • +
  • list item 4
  • +
+
<ul>
+    <li>...</li>
+</ul>
+
+
+
+
+
+
    +
  1. list item 1
  2. +
  3. list item 2 +
      +
    1. list item 2.1
    2. +
    3. list item 2.2 +
        +
      1. list item 2.2.1
      2. +
      3. list item 2.2.2
      4. +
      +
    4. +
    5. list item 2.3
    6. +
    7. list item 2.4
    8. +
    +
  4. +
  5. list item 3
  6. +
  7. list item 4
  8. +
+
<ol>
+    <li>...</li>
+</ol>
+
+
+
+
+
Unstyled List
+

To remove default list styling, use .unstyled.

+
+
    +
  • list item 1
  • +
  • list item 2 +
      +
    • list item 2.1
    • +
    • list item 2.2
    • +
    +
  • +
  • list item 3
  • +
  • list item 4
  • +
+
<ul class="unstyled">
+    <li>...</li>
+</ul>
+
+
+
Definition List
+

From time to time, you may need to produce a list of definitions, and there's one nicely built-in into Kube. We love semantic things. And lists. We love lists.

+
+
+
Term 1
+
Description 1
+
Term 2
+
Description 2
+
Term 3
+
Description 3
+
+
<dl>
+    <dt>Term</dt>
+    <dd>Description</dd>
+</dl>
+
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/docs/utils.md b/themes/coredns/exampleSite/content/docs/utils.md new file mode 100644 index 0000000..3e58bcc --- /dev/null +++ b/themes/coredns/exampleSite/content/docs/utils.md @@ -0,0 +1,124 @@ ++++ +date = "2017-04-10T16:43:30+01:00" +draft = false +weight = 280 +description = "A dozen of useful utilities that come with Kube" +title = "Utils" +bref= "Here you can find over a dozen of examples of little tiny utilities, that can make developer's life that much easier, and your project progress that much faster." +toc = true ++++ + +

Group

+

Combines float elements to group with a clearfix.

+
+
+
+ This text is visibly floating left +
+
+ This text looks like a case of right float +
+
+
<div class="group">
+    <div class="float-left">...</div>
+    <div class="float-right">...</div>
+</div>
+
+
+

Visibility

+

Below is an invisible div with class invisible. You can't see it, because it is invisible. You can't see invisible things.

+
+ +
+ But you can see this div because it has visible class. +
+
<div class="invisible">...</div>
+<div class="visible">...</div>
+
+
+

Display

+

This is a very useful little bit. Whenever you need to hide some text or an element on a small screen, just throw in hide-sm class. Or, if you need to specifically show something only on small screens, show-sm class is yours for the job. You can also just plain hide stuff with hide class. Can you see red words "I'm hidden" below? Exactly.

+
+
+ I'm hidden +
+
+ This text will not show up on a small screen. +
+

Resize your window and trust us on this  

+
+ This text will only show up on a small screen +
+
<div class="hide">I'm hidden</div>
+<div class="hide-sm">This text will not show up on a small screen.</div>
+<div class="show-sm">This will only show up on a small screen</div>
+
+
+

Print

+

One more neat feature of Kube. It helps you produce better ready-to-print pages by simply hiding irrelevant things.

+
+
+ This will be hidden on print, because it is some sort of web-specific thing. +
+
+ This will be printed, because this text is somehow more relevant on paper than on screen. +
+
<div class="hide-print">...</div>
+<div class="show-print">...</div>
+
+
+

Video Container

+

Helps to serve responsive video to various devices.

+
+
+ +
+
<div class="video-container">
+    <iframe>...</iframe>
+</div>
+
+
+

Close

+

Closing icon to close anything you want.

+
+ +
<span class="close small"></span>
+
+
+ +
<span class="close"></span>
+
+
+ +
<span class="close big"></span>
+
+

Caret

+

Kube has already built-in four-direction caret.

+
+ +
<span class="caret down"></span>
+<span class="caret up"></span>
+<span class="caret left"></span>
+<span class="caret right"></span>
+
+
+

Example of usage:

+
+     Link     Text     +
+

Icons

+

Some useful icons are already built-in to Kube.

+
+ +
<i class="kube-search"></i>
+
+
+ +
<i class="kube-menu"></i>
+
+
+ +
<i class="kube-calendar"></i>
+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/content/faq/_index.md b/themes/coredns/exampleSite/content/faq/_index.md new file mode 100644 index 0000000..17c8963 --- /dev/null +++ b/themes/coredns/exampleSite/content/faq/_index.md @@ -0,0 +1,39 @@ ++++ +draft= false +title = "FAQ" +description = "Asked and answered" ++++ + +## Kube looks awesome. Who is it for? + +We designed Kube as a small and inconspicuous helper for the professional developers and designers. Why an emphasis on “professional”? Well, because Kube is neither a kit of ready elements nor a set of templates; Kube is mainly a tool, which helps to keep routine tasks to a minimum. Kube doesn’t impose its own styles and doesn’t require following any specific design rules or practices. It makes Kube ideal for creative and challenging tasks of making unique websites with the unique design. For those who know HTML/CSS/JS inside out, Kube may become an irreplaceable tool that saves countless hours of work. + +If you are new to HTML/CSS/JS, then you may have a hard time implementing Kube in your projects, and it may just not be a tool for you yet. But certainly feel free to download and explore Kube, and see where this journey will take you! + +## What? Where’s the Nav Bar and other navigation? + +With over 15 years of web development experience under the belt, we can assure you that Nav Bars and all other sorts of navigational elements are always faster and easier to build for a project from scratch than to modify, customize and rebuild an existing solution. + +Each and every project has its unique navigational needs and often requires more of a custom approach. Vast experience shows that writing code for navigation from ground up is less time-consuming and more efficient, than tweaking and creating the navigation based on a boilerplate solution. + +## Isn’t it a great idea to add some awesome features to Kube? + +Nope. We want to keep Kube minimalistic, small and flexible. So, actually, there’s more chance of us removing stuff from the code and functions while preserving features, than adding new code and new stuff. + +## What Does the Future Hold for Kube? What’s the plan? + +Right now, Kube is a self-sufficient, modern and complete product. We have no specific plans of adding any new components anytime soon; we do not plan to extend Kube as well. Our goal is to improve the things that make Kube so awesome by squashing bugs, refactoring the code and improving overall performance. + +Having this said, we are keeping our eyes on what’s new in the world of HTML, CSS, and JS, and if something truly exciting happens in future with these technologies (comparable, let’s say, to flexbox emergence), we most certainly will consider these changes and will be first to go ahead and implement them as soon as possible. + +## I’m using old Kube. How do I download it again, and where do I find old Documentation? + +Old versions of Kube are critically outdated, and we strongly encourage you to stop using them as soon as you can. We do not offer old versions for download, and we do not provide old documentation. We realize that this may be an inconvenience, however, we also deeply believe that upgrading to the new Kube will bring way greater positive effect to your projects than the ability to support legacy versions. + +## How do I migrate from an older version to the latest one? + +Basically, you take the new Kube and start afresh from scratch. The old Kube had been built on a completely different set of principles and technologies, and it is pretty much incompatible with the new Kube in every way. Starting anew with the new Kube will also give you an opportunity to reevaluate your project in a new light and improve it in general. + +## Can I create design themes for sale based on Kube? + +You absolutely can! You have our permission to use Kube in whatever projects you wish commercial, for sale, or otherwise, in whichever way you like. \ No newline at end of file diff --git a/themes/coredns/exampleSite/content/password-recovery.md b/themes/coredns/exampleSite/content/password-recovery.md new file mode 100644 index 0000000..73ae263 --- /dev/null +++ b/themes/coredns/exampleSite/content/password-recovery.md @@ -0,0 +1,17 @@ + ++++ +title = "Password Recovery" ++++ +
+ +
+ + +
+ +

+ +

+ +

Back to Log In

+
\ No newline at end of file diff --git a/themes/coredns/exampleSite/static/.gitkeep b/themes/coredns/exampleSite/static/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/themes/coredns/images/docs.png b/themes/coredns/images/docs.png new file mode 100644 index 0000000..d1f3d2f Binary files /dev/null and b/themes/coredns/images/docs.png differ diff --git a/themes/coredns/images/faq.png b/themes/coredns/images/faq.png new file mode 100644 index 0000000..c6f423e Binary files /dev/null and b/themes/coredns/images/faq.png differ diff --git a/themes/coredns/images/list-docs.png b/themes/coredns/images/list-docs.png new file mode 100644 index 0000000..22cba88 Binary files /dev/null and b/themes/coredns/images/list-docs.png differ diff --git a/themes/coredns/images/post.png b/themes/coredns/images/post.png new file mode 100644 index 0000000..83c7d61 Binary files /dev/null and b/themes/coredns/images/post.png differ diff --git a/themes/coredns/images/screenshot.png b/themes/coredns/images/screenshot.png new file mode 100644 index 0000000..b6447d9 Binary files /dev/null and b/themes/coredns/images/screenshot.png differ diff --git a/themes/coredns/images/signin.png b/themes/coredns/images/signin.png new file mode 100644 index 0000000..0a385c6 Binary files /dev/null and b/themes/coredns/images/signin.png differ diff --git a/themes/coredns/images/tn.png b/themes/coredns/images/tn.png new file mode 100644 index 0000000..67fb679 Binary files /dev/null and b/themes/coredns/images/tn.png differ diff --git a/themes/coredns/layouts/404.html b/themes/coredns/layouts/404.html new file mode 100644 index 0000000..73455c7 --- /dev/null +++ b/themes/coredns/layouts/404.html @@ -0,0 +1,17 @@ +{{ define "title"}} {{ .Site.Title}} {{end}} +{{ define "header"}} {{ partial "header" .}} {{end}} +{{ define "main"}} + +
+
+

{{.Title}}

+

{{.Description}}

+
+ +
    + Or, as we call it, NXPAGE. +
+ +
+{{ end }} +{{ define "footer"}} {{ partial "footer" .}} {{end}} diff --git a/themes/coredns/layouts/_default/baseof.html b/themes/coredns/layouts/_default/baseof.html new file mode 100644 index 0000000..f08f356 --- /dev/null +++ b/themes/coredns/layouts/_default/baseof.html @@ -0,0 +1,69 @@ + + + + + {{ .Hugo.Generator }} + + + + {{ block "title" . }}{{ .Title }} | {{ .Site.Title }}{{ end }} + + {{ with .Description }} + {{ end }} + + {{ $default_noindex_kinds := slice "section" "taxonomy" "taxonomyTerm" }} + {{ $noindex_kinds := .Site.Params.noindex_kinds | default $default_noindex_kinds }} + {{ $is_noindex_true := and (isset .Params "noindex") .Params.noindex }} + {{ if or (in $noindex_kinds .Kind) ($is_noindex_true) }} + + {{ end }} + + {{ partial "meta/name-author" . }} + {{ template "_internal/opengraph.html" . }} + {{ partial "meta/ogimage" . }} + + {{ if .IsHome }} {{ partial "site-verification" . }} {{ end }} + + {{ template "_internal/google_analytics_async.html" . }} + {{ if .RSSLink }} + {{ end }} + + {{ if (isset .Params "prev") }} + {{ end }} {{ if (isset .Params "next") }} + {{ end }} + + + + {{ partial "favicon" . }} + + + + + + + + + + + + + + + + + +
{{ block "header" . }}{{ end }}
+
{{ block "main" . }}{{ end }}
+
{{ block "footer" . }}{{ end }}
+ + + + + + + + diff --git a/themes/coredns/layouts/_default/list.html b/themes/coredns/layouts/_default/list.html new file mode 100644 index 0000000..913e034 --- /dev/null +++ b/themes/coredns/layouts/_default/list.html @@ -0,0 +1,44 @@ +{{ define "title"}} {{ .Title}} {{end}} +{{ define "header"}} {{ partial "header" .}} {{end}} + +{{ define "main" }} + +
+ {{ if eq .Type "blog" }} +

Blog

+ {{ .Site.Data.subtext.blog.content | markdownify }} +

+ {{ end }} + + + {{ if eq .Data.Singular "tag" }} + {{ $last := index (last 1 (split (delimit (split .URL "/") "," "") ",")) 0 }} + {{ if eq $last "documentation" }} +

Documentation

+ {{ end }} + {{ .Site.Data.subtext.docs.content | markdownify }} +

+ + {{ .Scratch.Add "url1" "/2017/07/23/corefile-explained/" }} + {{ .Scratch.Add "link1" "Corefile Explained" }} + {{ .Scratch.Add "class1" "primary" }} + + {{ .Scratch.Add "url2" "/2017/06/08/how-queries-are-processed-in-coredns/" }} + {{ .Scratch.Add "link2" "Query Processing" }} + {{ .Scratch.Add "class2" "outline" }} + + {{ partial "middleware-action-button" . }} + + + {{ end }} +

+ +
    + + {{ range .Paginator.Pages.ByWeight }} {{ partial "page-summary" . }} {{ end }} +
    {{ partial "pagination" .}}
    + +
+ +{{ end }} +{{ define "footer" }} {{ partial "footer" . }} {{ end }} diff --git a/themes/coredns/layouts/_default/single.html b/themes/coredns/layouts/_default/single.html new file mode 100644 index 0000000..ed6341c --- /dev/null +++ b/themes/coredns/layouts/_default/single.html @@ -0,0 +1,18 @@ +{{ define "title"}} {{ .Title}} {{end}} +{{ define "header"}} {{ partial "header" .}} {{end}} + +{{ define "main" }} + +
+

{{.Title }}

+

{{.Params.description}}

+
+
    + + {{ .Content }} + +
+{{ end }} +{{ define "footer" }} + {{ partial "footer" . }} +{{ end }} \ No newline at end of file diff --git a/themes/coredns/layouts/blog/single.html b/themes/coredns/layouts/blog/single.html new file mode 100644 index 0000000..344735a --- /dev/null +++ b/themes/coredns/layouts/blog/single.html @@ -0,0 +1,35 @@ +{{ define "title"}} {{ .Title}} {{end}} +{{ define "header"}} {{ partial "header" .}} {{end}} + +{{ define "main"}} +
+ {{ template "_internal/schema.html" . }} +
+

{{.Title}}

+ {{ if .Description }} +
{{ .Description }}
+{{ end }} + +
+
+
+ + {{.Content | safeHTML}} + +
+ +
+ {{ partial "post/byauthor" . }} + {{ partial "post/related-content" . }} +
+ + {{ if .Site.DisqusShortname }} +
+ {{ template "_internal/disqus.html" . }} +
+ {{ end }} + +
+
+{{ end }} +{{ define "footer"}} {{ partial "footer.html" .}} {{ end }} diff --git a/themes/coredns/layouts/community/single.html b/themes/coredns/layouts/community/single.html new file mode 100644 index 0000000..cbc9f1a --- /dev/null +++ b/themes/coredns/layouts/community/single.html @@ -0,0 +1,29 @@ +{{ define "title"}} {{ .Title}} {{end}} +{{ define "header"}} {{ partial "header" .}} {{end}} + +{{ define "main"}} +
+ {{ template "_internal/schema.html" . }} +
+

{{.Title}}

+ {{ .Site.Data.subtext.community.content | markdownify }} +

+ +
+
+
+ + {{.Content | safeHTML}} + +
+ + {{ if .Site.DisqusShortname }} +
+ {{ template "_internal/disqus.html" . }} +
+ {{ end }} + +
+
+{{ end }} +{{ define "footer"}} {{ partial "footer.html" .}} {{ end }} diff --git a/themes/coredns/layouts/docs/single.html b/themes/coredns/layouts/docs/single.html new file mode 100644 index 0000000..ed942e9 --- /dev/null +++ b/themes/coredns/layouts/docs/single.html @@ -0,0 +1,23 @@ +{{ define "title"}} {{ .Title}} {{end}} +{{ define "header"}} {{ partial "header" .}} {{end}} +{{ define "main"}} +
+
+

{{ .Title}}

+

+ {{ .Params.bref | safeHTML }}. +

+ +
+
+ {{ partial "toc" .}} + + {{ .Content}} + + {{if .Params.script}} + {{ $script := (delimit (slice "scripts" .Params.script) "/")}} + {{ partial (string $script) .}} + {{end }} +
+
+{{ end }} diff --git a/themes/coredns/layouts/exmiddleware/single.html b/themes/coredns/layouts/exmiddleware/single.html new file mode 100644 index 0000000..1436d70 --- /dev/null +++ b/themes/coredns/layouts/exmiddleware/single.html @@ -0,0 +1,23 @@ +{{ define "title"}} {{ .Title}} {{end}} +{{ define "header"}} {{ partial "header" .}} {{end}} +{{ define "main"}} +
+
+

{{ .Title}}

+

+ {{ .Params.description | markdownify }} +

+ +
+
+ {{ partial "toc" .}} + + {{ .Content}} + + {{if .Params.script}} + {{ $script := (delimit (slice "scripts" .Params.script) "/")}} + {{ partial (string $script) .}} + {{end }} +
+
+{{ end }} diff --git a/themes/coredns/layouts/index.html b/themes/coredns/layouts/index.html new file mode 100644 index 0000000..53fd6e1 --- /dev/null +++ b/themes/coredns/layouts/index.html @@ -0,0 +1,101 @@ +{{ define "title"}} {{ .Site.Title}} {{end}} +{{ define "header"}} {{ partial "header" .}} {{end}} +{{ define "main"}} + +
+
+

{{.Title}}

+

{{.Description}}

+
+ +
+ Download + View on Github + Quick Start +

+ {{ range where .Site.Pages "Params.release" "eq" .Site.Data.coredns.release.version }} + Version {{ .Params.release }} released {{ dateFormat "January 2, 2006" .Date }}. + Release notes. + {{ end }} +

+
+ + {{ partial "popup.html" . }} + +
+ +
+
+ +
+ +

Middleware

+

+ CoreDNS (written in Go) + chains middleware. + Each middleware performs a DNS function, such as + Kubernetes service discovery, + Prometheus metrics or + rewriting queries. + And many more. +

+
+ +
+
+ +
+

Simplicity

+

+ We strive keep things a simple as possible and have sane defaults. + Here the Corefile for coredns.io: +

+
+coredns.io {
+    file coredns.io.signed {
+        transfer to * 185.49.140.62
+    }
+    prometheus
+    errors stdout
+    log stdout
+}
+        
+
+ +
+
+ +
+

Service Discovery

+

+ CoreDNS integrates with Kubernetes via the + Kubernetes middleware, + or directly with etcd with the + etcd middleware. +

+
+ +
+ +
+ +
+ +
+
+ Cloud Native Computing Foundation Logo +
+

CNCF

+

+ We are a Cloud Native Computing + Foundation member project. +

+
+ +
+ +
+ +
+{{ end }} +{{ define "footer"}} {{ partial "footer" .}} {{end}} diff --git a/themes/coredns/layouts/middleware/single.html b/themes/coredns/layouts/middleware/single.html new file mode 100644 index 0000000..1436d70 --- /dev/null +++ b/themes/coredns/layouts/middleware/single.html @@ -0,0 +1,23 @@ +{{ define "title"}} {{ .Title}} {{end}} +{{ define "header"}} {{ partial "header" .}} {{end}} +{{ define "main"}} +
+
+

{{ .Title}}

+

+ {{ .Params.description | markdownify }} +

+ +
+
+ {{ partial "toc" .}} + + {{ .Content}} + + {{if .Params.script}} + {{ $script := (delimit (slice "scripts" .Params.script) "/")}} + {{ partial (string $script) .}} + {{end }} +
+
+{{ end }} diff --git a/themes/coredns/layouts/partials/favicon.html b/themes/coredns/layouts/partials/favicon.html new file mode 100644 index 0000000..3ffdba4 --- /dev/null +++ b/themes/coredns/layouts/partials/favicon.html @@ -0,0 +1 @@ + diff --git a/themes/coredns/layouts/partials/footer.html b/themes/coredns/layouts/partials/footer.html new file mode 100644 index 0000000..ca06f2d --- /dev/null +++ b/themes/coredns/layouts/partials/footer.html @@ -0,0 +1,32 @@ + + +

+ Copyright © {{now.Year }} The CoreDNS Authors.
+ Copyright © {{now.Year}} The Linux Foundation®.
+ All rights reserved.
+ The Linux Foundation has registered trademarks and uses trademarks.
+ For a list of trademarks of The + Linux Foundation please see our Trademark Usage page. +

+ +

+ Built with Hugo, resolved via + CoreDNS, served from Caddy. + It basically is Go all the way down. +

diff --git a/themes/coredns/layouts/partials/header.html b/themes/coredns/layouts/partials/header.html new file mode 100644 index 0000000..0cd801c --- /dev/null +++ b/themes/coredns/layouts/partials/header.html @@ -0,0 +1,47 @@ +
+ +
+
+
+ + CoreDNS logo + +
+ + +
diff --git a/themes/coredns/layouts/partials/meta/name-author.html b/themes/coredns/layouts/partials/meta/name-author.html new file mode 100644 index 0000000..ac6d33f --- /dev/null +++ b/themes/coredns/layouts/partials/meta/name-author.html @@ -0,0 +1,5 @@ +{{ if isset .Params "author" }} + +{{ else }} + +{{ end }} diff --git a/themes/coredns/layouts/partials/meta/ogimage.html b/themes/coredns/layouts/partials/meta/ogimage.html new file mode 100644 index 0000000..7a87ff4 --- /dev/null +++ b/themes/coredns/layouts/partials/meta/ogimage.html @@ -0,0 +1,8 @@ + +{{ if and (.IsNode) (.Site.Params.images) }} + +{{ end }} + +{{ if and (.IsPage) (not .Params.images) (.Site.Params.images) }} + +{{ end }} diff --git a/themes/coredns/layouts/partials/middleware-action-button.html b/themes/coredns/layouts/partials/middleware-action-button.html new file mode 100644 index 0000000..de94bfb --- /dev/null +++ b/themes/coredns/layouts/partials/middleware-action-button.html @@ -0,0 +1,30 @@ + + +
+ {{ $a := len (string (.Scratch.Get "url1")) }} + {{ if ne $a 0 }} + + {{ .Scratch.Get "link1" }} + + {{ end }} + + {{ $a := len (string (.Scratch.Get "url2")) }} + {{ if ne $a 0 }} + + {{ .Scratch.Get "link2" }} + + {{ end }} + + {{ $a := len (string (.Scratch.Get "url3")) }} + {{ if ne $a 0 }} + + {{ .Scratch.Get "link3" }} + + {{ end }} +
diff --git a/themes/coredns/layouts/partials/page-summary.html b/themes/coredns/layouts/partials/page-summary.html new file mode 100644 index 0000000..0242343 --- /dev/null +++ b/themes/coredns/layouts/partials/page-summary.html @@ -0,0 +1,12 @@ +

+ {{ .Title }} +

+{{ if .Description }} +

{{ .Description }}

+{{ end }} + + + +
diff --git a/themes/coredns/layouts/partials/pagination.html b/themes/coredns/layouts/partials/pagination.html new file mode 100644 index 0000000..94ea0cc --- /dev/null +++ b/themes/coredns/layouts/partials/pagination.html @@ -0,0 +1,14 @@ + diff --git a/themes/coredns/layouts/partials/post/byauthor.html b/themes/coredns/layouts/partials/post/byauthor.html new file mode 100644 index 0000000..3fda4d3 --- /dev/null +++ b/themes/coredns/layouts/partials/post/byauthor.html @@ -0,0 +1,28 @@ +

+ {{ $author := index .Site.Params.authors .Params.author }} + + Published + {{ if ne .Site.Params.hide_author true }} + {{ with .Params.author }} + {{ with $author }} + + + {{ end }} + + {{ else }} + + by + + {{ end }} + {{ end }} + + {{ with .Params.categories }} + in {{ delimit (apply (apply (sort .) "partial" "post/category-link" ".") "chomp" ".") ", " " and " }} + {{ end }} + {{ with .Params.tags }} + and tagged {{ delimit (apply (apply (sort .) "partial" "post/tag-link" ".") "chomp" ".") ", " " and " }} + {{ end }} + using {{ .WordCount }} words. +

diff --git a/themes/coredns/layouts/partials/post/category-link.html b/themes/coredns/layouts/partials/post/category-link.html new file mode 100644 index 0000000..6bee96b --- /dev/null +++ b/themes/coredns/layouts/partials/post/category-link.html @@ -0,0 +1 @@ +{{ . }} diff --git a/themes/coredns/layouts/partials/post/meta.html b/themes/coredns/layouts/partials/post/meta.html new file mode 100644 index 0000000..62b4b45 --- /dev/null +++ b/themes/coredns/layouts/partials/post/meta.html @@ -0,0 +1,14 @@ + + + +{{ .ReadingTime }} minute read + + + +{{ if .PublishDate.IsZero }} + Published: +{{ else if lt .PublishDate .Lastmod }} + Modified: +{{ else }} + Published: +{{ end }} diff --git a/themes/coredns/layouts/partials/post/related-content.html b/themes/coredns/layouts/partials/post/related-content.html new file mode 100644 index 0000000..98c4d59 --- /dev/null +++ b/themes/coredns/layouts/partials/post/related-content.html @@ -0,0 +1,16 @@ +{{ range first 1 (where (where .Site.Pages ".Params.tags" "intersect" .Params.tags) "Permalink" "!=" .Permalink) }} + {{ $.Scratch.Set "has_related" true }} +{{ end }} + +{{ if $.Scratch.Get "has_related" }} + +{{ end }} diff --git a/themes/coredns/layouts/partials/post/tag-link.html b/themes/coredns/layouts/partials/post/tag-link.html new file mode 100644 index 0000000..8c03421 --- /dev/null +++ b/themes/coredns/layouts/partials/post/tag-link.html @@ -0,0 +1 @@ +{{ . }} diff --git a/themes/coredns/layouts/partials/scripts/animation.html b/themes/coredns/layouts/partials/scripts/animation.html new file mode 100644 index 0000000..19cfc90 --- /dev/null +++ b/themes/coredns/layouts/partials/scripts/animation.html @@ -0,0 +1,127 @@ + \ No newline at end of file diff --git a/themes/coredns/layouts/partials/site-verification.html b/themes/coredns/layouts/partials/site-verification.html new file mode 100644 index 0000000..c4d8b05 --- /dev/null +++ b/themes/coredns/layouts/partials/site-verification.html @@ -0,0 +1,12 @@ +{{ if .Site.Params.seo.webmaster_verifications.google }} + +{{ end }} +{{ if .Site.Params.seo.webmaster_verifications.bing }} + +{{ end }} +{{ if .Site.Params.seo.webmaster_verifications.alexa }} + +{{ end }} +{{ if .Site.Params.seo.webmaster_verifications.yandex }} + +{{ end }} diff --git a/themes/coredns/layouts/partials/toc.html b/themes/coredns/layouts/partials/toc.html new file mode 100644 index 0000000..b57a187 --- /dev/null +++ b/themes/coredns/layouts/partials/toc.html @@ -0,0 +1,21 @@ +{{ if and (isset .Params "toc") .Params.toc }} + + + +{{ end }} diff --git a/themes/coredns/layouts/section/docs.html b/themes/coredns/layouts/section/docs.html new file mode 100644 index 0000000..6c44bf2 --- /dev/null +++ b/themes/coredns/layouts/section/docs.html @@ -0,0 +1,22 @@ +{{ define "title"}} {{ .Title}} {{end}} +{{ define "header"}} {{ partial "header" .}} {{end}} +{{ define "main"}} +
+
+

Documentation

+
+
+
+ {{ range .Data.Pages.ByWeight }} +
+

{{ .Title }}

+

{{ .Params.description }}

+
+ {{ end }} + +
+
+
+{{ end }} + +{{ define "footer"}} {{ partial "footer" .}} {{end}} \ No newline at end of file diff --git a/themes/coredns/layouts/section/exmiddleware.html b/themes/coredns/layouts/section/exmiddleware.html new file mode 100644 index 0000000..16a72e5 --- /dev/null +++ b/themes/coredns/layouts/section/exmiddleware.html @@ -0,0 +1,43 @@ +{{ define "title"}} External Middleware {{end}} +{{ define "header"}} {{ partial "header" .}} {{end}} +{{ define "main"}} +
+
+

External Middleware

+ {{ .Site.Data.subtext.exmiddleware.content | markdownify }} +

+ + {{ .Scratch.Add "url1" "/2016/12/19/writing-middleware-for-coredns/" }} + {{ .Scratch.Add "link1" "How to Write Middleware" }} + {{ .Scratch.Add "class1" "primary" }} + + {{ .Scratch.Add "url2" "/2017/07/23/when-should-middleware-be-external/" }} + {{ .Scratch.Add "link2" "When External" }} + {{ .Scratch.Add "class2" "outline" }} + + {{ .Scratch.Add "url3" "/2017/07/23/add-external-middleware/" }} + {{ .Scratch.Add "link3" "Add Yours" }} + {{ .Scratch.Add "class3" "outline" }} + + {{ partial "middleware-action-button" . }} + +
+
+
+ {{ range .Data.Pages.ByWeight }} +
+

{{ .Title }}

+

{{ .Params.description | markdownify }}

+

+ Source + Home +

+
+ {{ end }} + +
+
+
+{{ end }} + +{{ define "footer"}} {{ partial "footer" .}} {{end}} diff --git a/themes/coredns/layouts/section/middleware.html b/themes/coredns/layouts/section/middleware.html new file mode 100644 index 0000000..04eb092 --- /dev/null +++ b/themes/coredns/layouts/section/middleware.html @@ -0,0 +1,35 @@ +{{ define "title"}} {{ .Title}} {{end}} +{{ define "header"}} {{ partial "header" .}} {{end}} +{{ define "main"}} +
+
+

Middleware

+ {{ .Site.Data.subtext.middleware.content | markdownify }} +

+ + {{ .Scratch.Add "url1" "/2016/12/19/writing-middleware-for-coredns/" }} + {{ .Scratch.Add "link1" "How to Write Middleware (1)" }} + {{ .Scratch.Add "class1" "primary" }} + + {{ .Scratch.Add "url2" "/2017/03/01/how-to-add-middleware-to-coredns/" }} + {{ .Scratch.Add "link2" "How to Write Middleware (2)" }} + {{ .Scratch.Add "class2" "outline" }} + + {{ partial "middleware-action-button" . }} + +
+
+
+ {{ range .Data.Pages.ByWeight }} +
+

{{ .Title }}

+

{{ .Params.description | markdownify }}

+
+ {{ end }} + +
+
+
+{{ end }} + +{{ define "footer"}} {{ partial "footer" .}} {{end}} diff --git a/themes/coredns/static/css/custom.css b/themes/coredns/static/css/custom.css new file mode 100644 index 0000000..d8fe3a6 --- /dev/null +++ b/themes/coredns/static/css/custom.css @@ -0,0 +1,12 @@ +footer a { + color: white; +} +footer nav ul li a { + color: white; +} + +.external:after { + font-family: FontAwesome; + font-size: x-small; + content: " \f08e"; +} diff --git a/themes/coredns/static/css/font.css b/themes/coredns/static/css/font.css new file mode 100644 index 0000000..9f19ed4 --- /dev/null +++ b/themes/coredns/static/css/font.css @@ -0,0 +1,68 @@ +@font-face { + font-family: 'Lato'; + src: url('../font/Lato-Light.woff') format('woff'); + font-weight: 300; + font-style: normal; +} + +@font-face { + font-family: 'Lato'; + src: url('../font/Lato-LightItalic.woff') format('woff'); + font-weight: 300; + font-style: italic; +} +@font-face { + font-family: 'Lato'; + src: url('../font/Lato-Black.woff') format('woff'); + font-weight: 900; + font-style: normal; +} + +@font-face { + font-family: 'Lato'; + src: url('../font/Lato-BlackItalic.woff') format('woff'); + font-weight: 900; + font-style: italic; +} + +@font-face { + font-family: 'Lato'; + src: url('../font/Lato-Bold.woff') format('woff'); + font-weight: bold; + font-style: normal; +} + +@font-face { + font-family: 'Lato'; + src: url('../font/Lato-BoldItalic.woff') format('woff'); + font-weight: bold; + font-style: italic; +} + +@font-face { + font-family: 'Lato'; + src: url('../font/Lato-Semibold.woff') format('woff'); + font-weight: 500; + font-style: normal; +} + +@font-face { + font-family: 'Lato'; + src: url('../font/Lato-SemiboldItalic.woff') format('woff'); + font-weight: 500; + font-style: italic; +} + +@font-face { + font-family: 'Lato'; + src: url('../font/Lato-Italic.woff') format('woff'); + font-weight: normal; + font-style: italic; +} + +@font-face { + font-family: 'Lato'; + src: url('../font/Lato-Regular.woff') format('woff'); + font-weight: normal; + font-style: normal; +} \ No newline at end of file diff --git a/themes/coredns/static/css/highlight.css b/themes/coredns/static/css/highlight.css new file mode 100644 index 0000000..7d8be18 --- /dev/null +++ b/themes/coredns/static/css/highlight.css @@ -0,0 +1 @@ +.hljs{display:block;overflow-x:auto;padding:0.5em;background:#F0F0F0}.hljs,.hljs-subst{color:#444}.hljs-comment{color:#888888}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#880000}.hljs-title,.hljs-section{color:#880000;font-weight:bold}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-selector-pseudo{color:#BC6060}.hljs-literal{color:#78A960}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta-string{color:#4d99bf}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold} \ No newline at end of file diff --git a/themes/coredns/static/css/kube.css b/themes/coredns/static/css/kube.css new file mode 100644 index 0000000..37088c2 --- /dev/null +++ b/themes/coredns/static/css/kube.css @@ -0,0 +1,2156 @@ +/* + Kube. CSS & JS Framework + Version 6.5.2 + Updated: February 2, 2017 + + http://imperavi.com/kube/ + + Copyright (c) 2009-2017, Imperavi LLC. + License: MIT +*/ +html { + box-sizing: border-box; } + +*, +*:before, +*:after { + box-sizing: inherit; } + +* { + margin: 0; + padding: 0; + outline: 0; + -webkit-overflow-scrolling: touch; } + +img, +video, +audio { + max-width: 100%; } + +img, +video { + height: auto; } + +svg { + max-height: 100%; } + +iframe { + border: none; } + +::-moz-focus-inner { + border: 0; + padding: 0; } + +input[type="radio"], +input[type="checkbox"] { + vertical-align: middle; + position: relative; + bottom: 0.15rem; + font-size: 115%; + margin-right: 3px; } + +input[type="search"] { + -webkit-appearance: textfield; } + +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; } + +.black { + color: #0d0d0e; } + +.inverted { + color: #fff; } + +.error { + color: #f03c69; } + +.success { + color: #35beb1; } + +.warning { + color: #f7ba45; } + +.focus { + color: #1c86f2; } + +.aluminum { + color: #f8f8f8; } + +.silver { + color: #e0e1e1; } + +.lightgray { + color: #d4d4d4; } + +.gray { + color: #bdbdbd; } + +.midgray { + color: #676b72; } + +.darkgray { + color: #313439; } + +.bg-black { + background-color: #0d0d0e; } + +.bg-inverted { + background-color: #fff; } + +.bg-error { + background-color: #f03c69; } + +.bg-success { + background-color: #35beb1; } + +.bg-warning { + background-color: #f7ba45; } + +.bg-focus { + background-color: #1c86f2; } + +.bg-aluminum { + background-color: #f8f8f8; } + +.bg-silver { + background-color: #e0e1e1; } + +.bg-lightgray { + background-color: #d4d4d4; } + +.bg-gray { + background-color: #bdbdbd; } + +.bg-midgray { + background-color: #676b72; } + +.bg-darkgray { + background-color: #313439; } + +.bg-highlight { + background-color: #edf2ff; } + +html, +body { + font-size: 16px; + line-height: 24px; } + +body { + font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; + color: #313439; + background-color: transparent; } + +a { + color: #8246af; } + +a:hover { + color: #280071; } + +h1.title, h1, h2, h3, h4, h5, h6 { + font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; + font-weight: bold; + color: #0d0d0e; + text-rendering: optimizeLegibility; + margin-bottom: 16px; } + +h1.title { + font-size: 60px; + line-height: 64px; + margin-bottom: 8px; } + +h1, +.h1 { + font-size: 48px; + line-height: 52px; } + +h2, +.h2 { + font-size: 36px; + line-height: 40px; } + +h3, +.h3 { + font-size: 24px; + line-height: 32px; } + +h4, +.h4 { + font-size: 21px; + line-height: 32px; } + +h5, +.h5 { + font-size: 18px; + line-height: 28px; } + +h6, +.h6 { + font-size: 16px; + line-height: 24px; } + +h1 a, .h1 a, +h2 a, .h2 a, +h3 a, .h3 a, +h4 a, .h4 a, +h5 a, .h5 a, +h6 a, .h6 a { + color: inherit; } + +p + h2, +p + h3, +p + h4, +p + h5, +p + h6, +ul + h2, +ul + h3, +ul + h4, +ul + h5, +ul + h6, +ol + h2, +ol + h3, +ol + h4, +ol + h5, +ol + h6, +dl + h2, +dl + h3, +dl + h4, +dl + h5, +dl + h6, +blockquote + h2, +blockquote + h3, +blockquote + h4, +blockquote + h5, +blockquote + h6, +hr + h2, +hr + h3, +hr + h4, +hr + h5, +hr + h6, +pre + h2, +pre + h3, +pre + h4, +pre + h5, +pre + h6, +table + h2, +table + h3, +table + h4, +table + h5, +table + h6, +form + h2, +form + h3, +form + h4, +form + h5, +form + h6, +figure + h2, +figure + h3, +figure + h4, +figure + h5, +figure + h6 { + margin-top: 24px; } + +ul, +ul ul, +ul ol, +ol, +ol ul, +ol ol { + margin: 0 0 0 24px; } + +ol ol li { + list-style-type: lower-alpha; } + +ol ol ol li { + list-style-type: lower-roman; } + +nav ul, +nav ol { + margin: 0; + list-style: none; } + nav ul ul, + nav ul ol, + nav ol ul, + nav ol ol { + margin-left: 24px; } + +dl dt { + font-weight: bold; } + +dd { + margin-left: 24px; } + +p, blockquote, hr, pre, ol, ul, dl, table, fieldset, figure, address, form { + margin-bottom: 16px; } + +hr { + border: none; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + margin-top: -1px; } + +blockquote { + padding-left: 1rem; + border-left: 4px solid rgba(0, 0, 0, 0.1); + font-style: italic; + color: rgba(49, 52, 57, 0.65); } + blockquote p { + margin-bottom: .5rem; } + +time, cite, small, figcaption { + font-size: 87.5%; } + +cite { + opacity: .6; } + +abbr[title], dfn[title] { + border-bottom: 1px dotted rgba(0, 0, 0, 0.5); + cursor: help; } + +var { + font-size: 16px; + opacity: .6; + font-style: normal; } + +mark, code, samp, kbd { + position: relative; + top: -1px; + padding: 4px 4px 2px 4px; + display: inline-block; + line-height: 1; + color: rgba(49, 52, 57, 0.85); } + +code { + background: #e0e1e1; } + +mark { + background: #f7ba45; } + +samp { + color: #fff; + background: #1c86f2; } + +kbd { + border: 1px solid rgba(0, 0, 0, 0.1); } + +sub, +sup { + font-size: x-small; + line-height: 0; + margin-left: 1rem/4; + position: relative; } + +sup { + top: 0; } + +sub { + bottom: 1px; } + +pre, code, samp, var, kbd { + font-family: Consolas, Monaco, "Courier New", monospace; } + +pre, code, samp, var, kbd, mark { + font-size: 87.5%; } + +pre, +pre code { + background: #f8f8f8; + padding: 0; + top: 0; + display: block; + line-height: 20px; + color: rgba(49, 52, 57, 0.85); + overflow: none; + white-space: pre-wrap; } + +pre { + padding: 1rem; } + +figcaption { + opacity: .6; } + +figure figcaption { + position: relative; + top: -1rem/2; } + +figure pre { + background: none; + border: 1px solid rgba(0, 0, 0, 0.1); + border-radius: 4px; } + +figure .video-container, +figure pre { + margin-bottom: 8px; } + +.text-left { + text-align: left; } + +.text-center { + text-align: center; } + +.text-right { + text-align: right; } + +ul.unstyled { + margin-left: 0; } + +ul.unstyled, +ul.unstyled ul { + list-style: none; } + +.monospace { + font-family: Consolas, Monaco, "Courier New", monospace; } + +.upper { + text-transform: uppercase; } + +.lower { + text-transform: lowercase; } + +.italic { + font-style: italic !important; } + +.strong { + font-weight: bold !important; } + +.normal { + font-weight: normal !important; } + +.muted { + opacity: .55; } + +a.muted { + color: #0d0d0e; } + +a.muted:hover { + opacity: 1; } + +.black { + color: #0d0d0e; } + +.smaller { + font-size: 12px; + line-height: 20px; } + +.small { + font-size: 14px; + line-height: 20px; } + +.big { + font-size: 18px; + line-height: 28px; } + +.large { + font-size: 20px; + line-height: 32px; } + +.end { + margin-bottom: 0 !important; } + +.highlight { + background-color: #edf2ff; } + +.nowrap, +.nowrap td { + white-space: nowrap; } + +@media (min-width: 768px) and (max-width: 1024px) { + .columns-2, + .columns-3, + .columns-4 { + column-gap: 24px; } + .columns-2 { + column-count: 2; } + .columns-3 { + column-count: 3; } + .columns-4 { + column-count: 4; } } + +.row { + display: flex; + flex-direction: row; + flex-wrap: wrap; } + @media (max-width: 768px) { + .row { + flex-direction: column; + flex-wrap: nowrap; } } + .row.gutters, + .row.gutters > .row { + margin-left: -2%; } + @media (max-width: 768px) { + .row.gutters, + .row.gutters > .row { + margin-left: 0; } } + .row.gutters > .col, + .row.gutters > .row > .col { + margin-left: 2%; } + @media (max-width: 768px) { + .row.gutters > .col, + .row.gutters > .row > .col { + margin-left: 0; } } + .row.around { + justify-content: space-around; } + .row.between { + justify-content: space-between; } + .row.auto .col { + flex-grow: 1; } + +.col-1 { + width: 8.33333%; } + +.offset-1 { + margin-left: 8.33333%; } + +.col-2 { + width: 16.66667%; } + +.offset-2 { + margin-left: 16.66667%; } + +.col-3 { + width: 25%; } + +.offset-3 { + margin-left: 25%; } + +.col-4 { + width: 33.33333%; } + +.offset-4 { + margin-left: 33.33333%; } + +.col-5 { + width: 41.66667%; } + +.offset-5 { + margin-left: 41.66667%; } + +.col-6 { + width: 50%; } + +.offset-6 { + margin-left: 50%; } + +.col-7 { + width: 58.33333%; } + +.offset-7 { + margin-left: 58.33333%; } + +.col-8 { + width: 66.66667%; } + +.offset-8 { + margin-left: 66.66667%; } + +.col-9 { + width: 75%; } + +.offset-9 { + margin-left: 75%; } + +.col-10 { + width: 83.33333%; } + +.offset-10 { + margin-left: 83.33333%; } + +.col-11 { + width: 91.66667%; } + +.offset-11 { + margin-left: 91.66667%; } + +.col-12 { + width: 100%; } + +.offset-12 { + margin-left: 100%; } + +.gutters > .col-1 { + width: calc(8.33333% - 2%); } + +.gutters > .offset-1 { + margin-left: calc(8.33333% + 2%) !important; } + +.gutters > .col-2 { + width: calc(16.66667% - 2%); } + +.gutters > .offset-2 { + margin-left: calc(16.66667% + 2%) !important; } + +.gutters > .col-3 { + width: calc(25% - 2%); } + +.gutters > .offset-3 { + margin-left: calc(25% + 2%) !important; } + +.gutters > .col-4 { + width: calc(33.33333% - 2%); } + +.gutters > .offset-4 { + margin-left: calc(33.33333% + 2%) !important; } + +.gutters > .col-5 { + width: calc(41.66667% - 2%); } + +.gutters > .offset-5 { + margin-left: calc(41.66667% + 2%) !important; } + +.gutters > .col-6 { + width: calc(50% - 2%); } + +.gutters > .offset-6 { + margin-left: calc(50% + 2%) !important; } + +.gutters > .col-7 { + width: calc(58.33333% - 2%); } + +.gutters > .offset-7 { + margin-left: calc(58.33333% + 2%) !important; } + +.gutters > .col-8 { + width: calc(66.66667% - 2%); } + +.gutters > .offset-8 { + margin-left: calc(66.66667% + 2%) !important; } + +.gutters > .col-9 { + width: calc(75% - 2%); } + +.gutters > .offset-9 { + margin-left: calc(75% + 2%) !important; } + +.gutters > .col-10 { + width: calc(83.33333% - 2%); } + +.gutters > .offset-10 { + margin-left: calc(83.33333% + 2%) !important; } + +.gutters > .col-11 { + width: calc(91.66667% - 2%); } + +.gutters > .offset-11 { + margin-left: calc(91.66667% + 2%) !important; } + +.gutters > .col-12 { + width: calc(100% - 2%); } + +.gutters > .offset-12 { + margin-left: calc(100% + 2%) !important; } + +@media (max-width: 768px) { + [class^='offset-'], + [class*=' offset-'] { + margin-left: 0; } } + +.first { + order: -1; } + +.last { + order: 1; } + +@media (max-width: 768px) { + .row .col { + margin-left: 0; + width: 100%; } + .row.gutters .col { + margin-bottom: 16px; } + .first-sm { + order: -1; } + .last-sm { + order: 1; } } + +table { + border-collapse: collapse; + border-spacing: 0; + max-width: 100%; + width: 100%; + empty-cells: show; + font-size: 15px; + line-height: 24px; } + +table caption { + text-align: left; + font-size: 14px; + font-weight: 500; + color: #676b72; } + +th { + text-align: left; + font-weight: 700; + vertical-align: bottom; } + +td { + vertical-align: top; } + +tr.align-middle td, +td.align-middle { + vertical-align: middle; } + +th, +td { + padding: 1rem 1rem; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); } + th:first-child, + td:first-child { + padding-left: 0; } + th:last-child, + td:last-child { + padding-right: 0; } + +tfoot th, +tfoot td { + color: rgba(49, 52, 57, 0.5); } + +table.bordered td, +table.bordered th { + border: 1px solid rgba(0, 0, 0, 0.05); } + +table.striped tr:nth-child(odd) td { + background: #f8f8f8; } + +table.bordered td:first-child, +table.bordered th:first-child, +table.striped td:first-child, +table.striped th:first-child { + padding-left: 1rem; } + +table.bordered td:last-child, +table.bordered th:last-child, +table.striped td:last-child, +table.striped th:last-child { + padding-right: 1rem; } + +table.unstyled td, +table.unstyled th { + border: none; + padding: 0; } + +fieldset { + font-family: inherit; + border: 1px solid rgba(0, 0, 0, 0.1); + padding: 2rem; + margin-bottom: 2rem; + margin-top: 2rem; } + +legend { + font-weight: bold; + font-size: 12px; + text-transform: uppercase; + padding: 0 1rem; + margin-left: -1rem; + top: 2px; + position: relative; + line-height: 0; } + +input, +textarea, +select { + display: block; + width: 100%; + font-family: inherit; + font-size: 15px; + height: 40px; + outline: none; + vertical-align: middle; + background-color: #fff; + border: 1px solid #d4d4d4; + border-radius: 3px; + box-shadow: none; + padding: 0 12px; } + +input.small, +textarea.small, +select.small { + height: 36px; + font-size: 13px; + padding: 0 12px; + border-radius: 3px; } + +input.big, +textarea.big, +select.big { + height: 48px; + font-size: 17px; + padding: 0 12px; + border-radius: 3px; } + +input:focus, +textarea:focus, +select:focus { + outline: none; + background-color: #fff; + border-color: #1c86f2; + box-shadow: 0 0 1px #1c86f2 inset; } + +input.error, +textarea.error, +select.error { + background-color: rgba(240, 60, 105, 0.1); + border: 1px solid #f583a0; } + input.error:focus, + textarea.error:focus, + select.error:focus { + border-color: #f03c69; + box-shadow: 0 0 1px #f03c69 inset; } + +input.success, +textarea.success, +select.success { + background-color: rgba(53, 190, 177, 0.1); + border: 1px solid #6ad5cb; } + input.success:focus, + textarea.success:focus, + select.success:focus { + border-color: #35beb1; + box-shadow: 0 0 1px #35beb1 inset; } + +input:disabled, input.disabled, +textarea:disabled, +textarea.disabled, +select:disabled, +select.disabled { + resize: none; + opacity: 0.6; + cursor: default; + font-style: italic; + color: rgba(0, 0, 0, 0.5); } + +select { + -webkit-appearance: none; + background-image: url('data:image/svg+xml;utf8,'); + background-repeat: no-repeat; + background-position: right 1rem center; } + +select[multiple] { + background-image: none; + height: auto; + padding: .5rem .75rem; } + +textarea { + height: auto; + padding: 8px 12px; + line-height: 24px; + vertical-align: top; } + +input[type="file"] { + width: auto; + border: none; + padding: 0; + height: auto; + background: none; + box-shadow: none; + display: inline-block; } + +input[type="search"], +input.search { + background-repeat: no-repeat; + background-position: 8px 53%; + background-image: url('data:image/svg+xml;utf8,'); + padding-left: 32px; } + +input[type="radio"], +input[type="checkbox"] { + display: inline-block; + width: auto; + height: auto; + padding: 0; } + +label { + display: block; + color: #313439; + margin-bottom: 4px; + font-size: 15px; } + label.checkbox, + label .desc, + label .success, + label .error { + text-transform: none; + font-weight: normal; } + label.checkbox { + font-size: 16px; + line-height: 24px; + cursor: pointer; + color: inherit; } + label.checkbox input { + margin-top: 0; } + +.form-checkboxes label.checkbox { + display: inline-block; + margin-right: 16px; } + +.req { + position: relative; + top: 1px; + font-weight: bold; + color: #f03c69; + font-size: 110%; } + +.desc { + color: rgba(40, 0, 113, 0.5); + font-size: 12px; + line-height: 20px; } + +span.desc { + margin-left: 4px; } + +div.desc { + margin-top: 4px; + margin-bottom: -8px; } + +.form-buttons button, +.form-buttons .button { + margin-right: 8px; } + +form, +.form-item { + margin-bottom: 2rem; } + +.form > .form-item:last-child { + margin-bottom: 0; } + +.form .row:last-child .form-item { + margin-bottom: 0; } + +.form span.success, +.form span.error { + font-size: 12px; + line-height: 20px; + margin-left: 4px; } + +.form-inline input, +.form-inline textarea, +.form-inline select { + display: inline-block; + width: auto; } + +.append, +.prepend { + display: flex; } + .append input, + .prepend input { + flex: 1; } + .append .button, + .append span, + .prepend .button, + .prepend span { + flex-shrink: 0; } + .append span, + .prepend span { + display: flex; + flex-direction: column; + justify-content: center; + font-weight: normal; + border: 1px solid #d4d4d4; + background-color: #f8f8f8; + padding: 0 .875rem; + color: rgba(0, 0, 0, 0.5); + font-size: 12px; + white-space: nowrap; } + +.prepend input { + border-radius: 0 3px 3px 0; } + +.prepend .button { + margin-right: -1px; + border-radius: 3px 0 0 3px !important; } + +.prepend span { + border-right: none; + border-radius: 3px 0 0 3px; } + +.append input { + border-radius: 3px 0 0 3px; } + +.append .button { + margin-left: -1px; + border-radius: 0 3px 3px 0 !important; } + +.append span { + border-left: none; + border-radius: 0 3px 3px 0; } + +button, +.button { + font-family: Arial, "Helvetica Neue", Helvetica, sans-serif; + font-size: 15px; + color: #fff; + background-color: #280071; + border-radius: 3px; + min-height: 40px; + padding: 8px 20px; + font-weight: 500; + text-decoration: none; + cursor: pointer; + display: inline-block; + line-height: 20px; + border: 1px solid transparent; + vertical-align: middle; + -webkit-appearance: none; } + button i, + .button i { + position: relative; + top: 1px; + margin: 0 2px; } + +input[type="submit"] { + width: auto; } + +button:hover, +.button:hover { + outline: none; + text-decoration: none; + color: #fff; + background-color: #8246af; } + +.button:disabled, +.button.disabled { + cursor: default; + font-style: normal; + color: rgba(255, 255, 255, 0.7); + background-color: rgba(28, 134, 242, 0.7); } + +.button.small { + font-size: 13px; + min-height: 36px; + padding: 6px 20px; + border-radius: 3px; } + +.button.big { + font-size: 17px; + min-height: 48px; + padding: 13px 24px; + border-radius: 3px; } + +.button.large { + font-size: 19px; + min-height: 56px; + padding: 20px 36px; + border-radius: 3px; } + +.button.outline { + background: none; + border-width: 2px; + border-color: #280071; + color: #280071; } + .button.outline:hover { + background: none; + color: rgba(130, 70, 175, 0.6); + border-color: rgba(130, 70, 175, 0.5); } + .button.outline:disabled, .button.outline.disabled { + background: none; + color: rgba(130, 70, 175, 0.7); + border-color: rgba(130, 70, 175, 0.5); } + +.button.inverted { + color: #000; + background-color: #fff; } + .button.inverted:hover { + color: #000; + background-color: white; } + .button.inverted:disabled, .button.inverted.disabled { + color: rgba(0, 0, 0, 0.7); + background-color: rgba(255, 255, 255, 0.7); } + .button.inverted.outline { + background: none; + color: #fff; + border-color: #fff; } + .button.inverted.outline:hover { + color: rgba(255, 255, 255, 0.6); + border-color: rgba(255, 255, 255, 0.5); } + .button.inverted.outline:disabled, .button.inverted.outline.disabled { + background: none; + color: rgba(255, 255, 255, 0.7); + border-color: rgba(255, 255, 255, 0.5); } + .button.inverted:hover { + opacity: .7; } + +.button.round { + border-radius: 56px; } + +.button.raised { + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); } + +.button.upper { + text-transform: uppercase; + letter-spacing: .04em; + font-size: 13px; } + .button.upper.small { + font-size: 11px; } + .button.upper.big { + font-size: 13px; } + .button.upper.large { + font-size: 15px; } + +.button.secondary { + color: #fff; + background-color: #313439; } + .button.secondary:hover { + color: #fff; + background-color: #606670; } + .button.secondary:disabled, .button.secondary.disabled { + color: rgba(255, 255, 255, 0.7); + background-color: rgba(49, 52, 57, 0.7); } + .button.secondary.outline { + background: none; + color: #313439; + border-color: #313439; } + .button.secondary.outline:hover { + color: rgba(49, 52, 57, 0.6); + border-color: rgba(49, 52, 57, 0.5); } + .button.secondary.outline:disabled, .button.secondary.outline.disabled { + background: none; + color: rgba(49, 52, 57, 0.7); + border-color: rgba(49, 52, 57, 0.5); } + +.label { + display: inline-block; + font-size: 13px; + background: #e0e1e1; + line-height: 18px; + padding: 0 10px; + font-weight: 500; + color: #313439; + border: 1px solid transparent; + vertical-align: middle; + text-decoration: none; + border-radius: 4px; } + .label a, + .label a:hover { + color: inherit; + text-decoration: none; } + +.label.big { + font-size: 14px; + line-height: 24px; + padding: 0 12px; } + +.label.upper { + text-transform: uppercase; + font-size: 11px; } + +.label.outline { + background: none; + border-color: #bdbdbd; } + +.label.badge { + text-align: center; + border-radius: 64px; + padding: 0 6px; } + .label.badge.big { + padding: 0 8px; } + +.label.tag { + padding: 0; + background: none; + border: none; + text-transform: uppercase; + font-size: 11px; } + .label.tag.big { + font-size: 13px; } + +.label.success { + background: #35beb1; + color: #fff; } + .label.success.tag, .label.success.outline { + background: none; + border-color: #35beb1; + color: #35beb1; } + +.label.error { + background: #f03c69; + color: #fff; } + .label.error.tag, .label.error.outline { + background: none; + border-color: #f03c69; + color: #f03c69; } + +.label.warning { + background: #f7ba45; + color: #0d0d0e; } + .label.warning.tag, .label.warning.outline { + background: none; + border-color: #f7ba45; + color: #f7ba45; } + +.label.focus { + background: #1c86f2; + color: #fff; } + .label.focus.tag, .label.focus.outline { + background: none; + border-color: #1c86f2; + color: #1c86f2; } + +.label.black { + background: #0d0d0e; + color: #fff; } + .label.black.tag, .label.black.outline { + background: none; + border-color: #0d0d0e; + color: #0d0d0e; } + +.label.inverted { + background: #fff; + color: #0d0d0e; } + .label.inverted.tag, .label.inverted.outline { + background: none; + border-color: #fff; + color: #fff; } + +.breadcrumbs { + font-size: 14px; + margin-bottom: 24px; } + .breadcrumbs ul { + display: flex; + align-items: center; } + .breadcrumbs.push-center ul { + justify-content: center; } + .breadcrumbs span, + .breadcrumbs a { + font-style: normal; + padding: 0 10px; + display: inline-block; + white-space: nowrap; } + .breadcrumbs li:after { + display: inline-block; + content: '/'; + color: rgba(0, 0, 0, 0.3); } + .breadcrumbs li:last-child:after { + display: none; } + .breadcrumbs li:first-child span, + .breadcrumbs li:first-child a { + padding-left: 0; } + .breadcrumbs li.active a { + color: #313439; + text-decoration: none; + cursor: text; } + +.pagination { + margin: 24px 0; + font-size: 14px; } + .pagination ul { + display: flex; + margin: 0; } + .pagination.align-center ul { + justify-content: center; } + .pagination span, + .pagination a { + border-radius: 3px; + display: inline-block; + padding: 8px 12px; + line-height: 1; + white-space: nowrap; + border: 1px solid transparent; } + .pagination a { + text-decoration: none; + color: #313439; } + .pagination a:hover { + color: rgba(0, 0, 0, 0.5); + border-color: #e0e1e1; } + .pagination span, + .pagination li.active a { + color: rgba(0, 0, 0, 0.5); + border-color: #e0e1e1; + cursor: text; } + .pagination.upper { + font-size: 12px; } + +.pager span { + line-height: 24px; } + +.pager span, +.pager a { + padding-left: 16px; + padding-right: 16px; + border-radius: 64px; + border-color: rgba(0, 0, 0, 0.1); } + +.pager li { + flex-basis: 50%; } + +.pager li.next { + text-align: right; } + +.pager.align-center li { + flex-basis: auto; + margin-left: 4px; + margin-right: 4px; } + +.pager.flat span, +.pager.flat a { + border: none; + display: block; + padding: 0; } + +.pager.flat a { + font-weight: bold; } + .pager.flat a:hover { + background: none; + text-decoration: underline; } + +@media (max-width: 768px) { + .pager.flat ul { + flex-direction: column; } + .pager.flat li { + flex-basis: 100%; + margin-bottom: 8px; + text-align: left; } } + +@font-face { + font-family: 'Kube'; + src: url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBfgAAAC8AAAAYGNtYXAXVtKOAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5ZsMn2SAAAAF4AAADeGhlYWQMP9EUAAAE8AAAADZoaGVhB8IDzQAABSgAAAAkaG10eCYABd4AAAVMAAAAMGxvY2EFWASuAAAFfAAAABptYXhwABcAmwAABZgAAAAgbmFtZfMJxocAAAW4AAABYnBvc3QAAwAAAAAHHAAAACAAAwPHAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpBwPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6Qf//f//AAAAAAAg6QD//f//AAH/4xcEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAAKAAAAAAQAA8AADwAUACQANABEAFYAaAB4AIgAmAAAEyIGFREUFjMhMjY1ETQmIwUhESEREzgBMSIGFRQWMzI2NTQmIzM4ATEiBhUUFjMyNjU0JiMzOAExIgYVFBYzMjY1NCYjATIWHQEUBiMiJj0BNDYzOAExITIWHQEUBiMiJj0BNDYzOAExATgBMSIGFRQWMzI2NTQmIzM4ATEiBhUUFjMyNjU0JiMzOAExIgYVFBYzMjY1NCYjwFBwcFACgFBwcFD9IQM+/MKrHioqHh4qKh70HioqHh4qKh70HisrHh0rKh7+MBQdHRQUHBwUAbgUHBwUFB0dFP4wHioqHh4qKh70HioqHh4qKh70HisrHh0rKh4DYHBQ/iBQcHBQAeBQcF/9XwKh/n8qHh4qKh4eKioeHioqHh4qKh4eKioeHioCQBwVjhUcHBWOFRwcFY4VHBwVjhUc/rAqHh4qKh4eKioeHioqHh4qKh4eKioeHioAAAABAQAAwAMAAcAACwAAAQcXBycHJzcnNxc3AwDMAjMDAzMCzDTMzAGVqAIrAgIrAqgrqKgAAQGAAEACgAJAAAsAACUnByc3JzcXNxcHFwJVqAIrAgIrAqgrqKhAzAIzAwMzAsw0zMwAAAEBgABAAoACQAALAAABFzcXBxcHJwcnNycBq6gCKwICKwKoK6ioAkDMAjMDAzMCzDTMzAABAQAAwAMAAcAACwAAJTcnNxc3FwcXBycHAQDMAjMDAzMCzDTMzOuoAisCAisCqCuoqAAAAgAP/+UD1AOqAAQACAAAEwEHATcFAScBSwOJPPx3PAOJ/Hc8A4kDqvx3PAOJPDz8dzwDiQAAAAADAIAAgAOAAwAAAwAHAAsAADc1IRUBIRUhESEVIYADAP0AAwD9AAMA/QCAgIABgIABgIAAAgBPAA8DsgNxABgALQAAJQcBDgEjIi4CNTQ+AjMyHgIVFAYHAQEiDgIVFB4CMzI+AjU0LgIjA7JY/t4lWTBBc1YxMVZzQUFzVTIcGQEi/dgxVkAlJUBWMTFWQCUlQFYxZ1gBIRkcMlVzQUFzVjExVnNBMFkm/uACuyVAVjExVkAlJUBWMTFWQCUAAAABAAAAAQAABhlWm18PPPUACwQAAAAAANSQRjkAAAAA1JBGOQAA/+UEAAPAAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAQAAAEAAAAAAAAAAAAAAAAAAAAMBAAAAAAAAAAAAAAAAgAAAAQAAAAEAAEABAABgAQAAYAEAAEABAAADwQAAIAEAABPAAAAAAAKABQAHgDYAPIBDAEmAUABXAF2AbwAAAABAAAADACZAAoAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAADgCuAAEAAAAAAAEABAAAAAEAAAAAAAIABwBFAAEAAAAAAAMABAAtAAEAAAAAAAQABABaAAEAAAAAAAUACwAMAAEAAAAAAAYABAA5AAEAAAAAAAoAGgBmAAMAAQQJAAEACAAEAAMAAQQJAAIADgBMAAMAAQQJAAMACAAxAAMAAQQJAAQACABeAAMAAQQJAAUAFgAXAAMAAQQJAAYACAA9AAMAAQQJAAoANACAS3ViZQBLAHUAYgBlVmVyc2lvbiAxLjAAVgBlAHIAcwBpAG8AbgAgADEALgAwS3ViZQBLAHUAYgBlS3ViZQBLAHUAYgBlUmVndWxhcgBSAGUAZwB1AGwAYQByS3ViZQBLAHUAYgBlRm9udCBnZW5lcmF0ZWQgYnkgSWNvTW9vbi4ARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAYgB5ACAASQBjAG8ATQBvAG8AbgAuAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==") format("truetype"); + font-weight: normal; + font-style: normal; } + +[class^="kube-"], [class*=" kube-"], .close, .caret { + /* use !important to prevent issues with browser extensions that change fonts */ + font-family: 'Kube' !important; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } + +.kube-calendar:before { + content: "\e900"; } + +.caret.down:before, +.kube-caret-down:before { + content: "\e901"; } + +.caret.left:before, +.kube-caret-left:before { + content: "\e902"; } + +.caret.right:before, +.kube-caret-right:before { + content: "\e903"; } + +.caret.up:before, +.kube-caret-up:before { + content: "\e904"; } + +.close:before, +.kube-close:before { + content: "\e905"; } + +.kube-menu:before { + content: "\e906"; } + +.kube-search:before { + content: "\e907"; } + +.gutters .column.push-left, +.push-left { + margin-right: auto; } + +.gutters .column.push-right, +.push-right { + margin-left: auto; } + +.gutters .column.push-center, +.push-center { + margin-left: auto; + margin-right: auto; } + +.gutters .column.push-middle, +.push-middle { + margin-top: auto; + margin-bottom: auto; } + +.push-bottom { + margin-top: auto; } + +@media (max-width: 768px) { + .gutters .column.push-left-sm, + .push-left-sm { + margin-left: 0; } + .gutters .column.push-center-sm, + .push-center-sm { + margin-left: auto; + margin-right: auto; } + .push-top-sm { + margin-top: 0; } } + +.align-middle { + align-items: center; } + +.align-right { + justify-content: flex-end; } + +.align-center { + justify-content: center; } + +@media (max-width: 768px) { + .align-left-sm { + justify-content: flex-start; } } + +.float-right { + float: right; } + +.float-left { + float: left; } + +@media (max-width: 768px) { + .float-right { + float: none; } + .float-left { + float: none; } } + +.fixed { + position: fixed; + top: 0; + left: 0; + z-index: 100; + width: 100%; } + +.w5 { + width: 5%; } + +.w10 { + width: 10%; } + +.w15 { + width: 15%; } + +.w20 { + width: 20%; } + +.w25 { + width: 25%; } + +.w30 { + width: 30%; } + +.w35 { + width: 35%; } + +.w40 { + width: 40%; } + +.w45 { + width: 45%; } + +.w50 { + width: 50%; } + +.w55 { + width: 55%; } + +.w60 { + width: 60%; } + +.w65 { + width: 65%; } + +.w70 { + width: 70%; } + +.w75 { + width: 75%; } + +.w80 { + width: 80%; } + +.w85 { + width: 85%; } + +.w90 { + width: 90%; } + +.w95 { + width: 95%; } + +.w100 { + width: 100%; } + +.w-auto { + width: auto; } + +.w-small { + width: 480px; } + +.w-medium { + width: 600px; } + +.w-big { + width: 740px; } + +.w-large { + width: 840px; } + +@media (max-width: 768px) { + .w-auto-sm { + width: auto; } + .w100-sm, + .w-small, + .w-medium, + .w-big, + .w-large { + width: 100%; } } + +.max-w5 { + max-width: 5%; } + +.max-w10 { + max-width: 10%; } + +.max-w15 { + max-width: 15%; } + +.max-w20 { + max-width: 20%; } + +.max-w25 { + max-width: 25%; } + +.max-w30 { + max-width: 30%; } + +.max-w35 { + max-width: 35%; } + +.max-w40 { + max-width: 40%; } + +.max-w45 { + max-width: 45%; } + +.max-w50 { + max-width: 50%; } + +.max-w55 { + max-width: 55%; } + +.max-w60 { + max-width: 60%; } + +.max-w65 { + max-width: 65%; } + +.max-w70 { + max-width: 70%; } + +.max-w75 { + max-width: 75%; } + +.max-w80 { + max-width: 80%; } + +.max-w85 { + max-width: 85%; } + +.max-w90 { + max-width: 90%; } + +.max-w95 { + max-width: 95%; } + +.max-w100 { + max-width: 100%; } + +.max-w-small { + max-width: 480px; } + +.max-w-medium { + max-width: 600px; } + +.max-w-big { + max-width: 740px; } + +.max-w-large { + max-width: 840px; } + +@media (max-width: 768px) { + .max-w-auto-sm, + .max-w-small, + .max-w-medium, + .max-w-big, + .max-w-large { + max-width: auto; } } + +.min-w5 { + min-width: 5%; } + +.min-w10 { + min-width: 10%; } + +.min-w15 { + min-width: 15%; } + +.min-w20 { + min-width: 20%; } + +.min-w25 { + min-width: 25%; } + +.min-w30 { + min-width: 30%; } + +.min-w35 { + min-width: 35%; } + +.min-w40 { + min-width: 40%; } + +.min-w45 { + min-width: 45%; } + +.min-w50 { + min-width: 50%; } + +.min-w55 { + min-width: 55%; } + +.min-w60 { + min-width: 60%; } + +.min-w65 { + min-width: 65%; } + +.min-w70 { + min-width: 70%; } + +.min-w75 { + min-width: 75%; } + +.min-w80 { + min-width: 80%; } + +.min-w85 { + min-width: 85%; } + +.min-w90 { + min-width: 90%; } + +.min-w95 { + min-width: 95%; } + +.min-w100 { + min-width: 100%; } + +.h25 { + height: 25%; } + +.h50 { + height: 50%; } + +.h100 { + height: 100%; } + +.group:after { + content: ''; + display: table; + clear: both; } + +.flex { + display: flex; } + +@media (max-width: 768px) { + .flex-column-sm { + flex-direction: column; } + .flex-w100-sm { + flex: 0 0 100%; } } + @media (max-width: 768px) and (max-width: 768px) { + .flex-w100-sm { + flex: 0 0 100% !important; } } + +.invisible { + visibility: hidden; } + +.visible { + visibility: visible; } + +.display-block { + display: block; } + +.hide { + display: none !important; } + +@media (max-width: 768px) { + .hide-sm { + display: none !important; } } + +@media (min-width: 768px) { + .show-sm { + display: none !important; } } + +@media print { + .hide-print { + display: none !important; } + .show-print { + display: block !important; } } + +.no-scroll { + overflow: hidden; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100% !important; } + +.scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; } + +.video-container { + height: 0; + padding-bottom: 56.25%; + position: relative; + margin-bottom: 16px; } + .video-container iframe, + .video-container object, + .video-container embed { + position: absolute; + top: 0; + left: 0; + width: 100% !important; + height: 100% !important; } + +.close { + display: inline-block; + min-height: 16px; + min-width: 16px; + line-height: 16px; + vertical-align: middle; + text-align: center; + font-size: 12px; + opacity: .6; } + .close:hover { + opacity: 1; } + .close.small { + font-size: 8px; } + .close.big { + font-size: 18px; } + .close.white { + color: #fff; } + +.caret { + display: inline-block; } + +.button .caret { + margin-right: -8px; } + +.overlay { + position: fixed; + z-index: 200; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(255, 255, 255, 0.95); } + .overlay > .close { + position: fixed; + top: 1rem; + right: 1rem; } + +@media print { + * { + background: transparent !important; + color: black !important; + box-shadow: none !important; + text-shadow: none !important; } + a, + a:visited { + text-decoration: underline; } + pre, blockquote { + border: 1px solid #999; + page-break-inside: avoid; } + p, h2, h3 { + orphans: 3; + widows: 3; } + thead { + display: table-header-group; } + tr, img { + page-break-inside: avoid; } + img { + max-width: 100% !important; } + h2, h3, h4 { + page-break-after: avoid; } + @page { + margin: 0.5cm; } } + +@keyframes slideUp { + to { + height: 0; + padding-top: 0; + padding-bottom: 0; } } + +@keyframes slideDown { + from { + height: 0; + padding-top: 0; + padding-bottom: 0; } } + +@keyframes fadeIn { + from { + opacity: 0; } + to { + opacity: 1; } } + +@keyframes fadeOut { + from { + opacity: 1; } + to { + opacity: 0; } } + +@keyframes flipIn { + from { + opacity: 0; + transform: scaleY(0); } + to { + opacity: 1; + transform: scaleY(1); } } + +@keyframes flipOut { + from { + opacity: 1; + transform: scaleY(1); } + to { + opacity: 0; + transform: scaleY(0); } } + +@keyframes zoomIn { + from { + opacity: 0; + transform: scale3d(0.3, 0.3, 0.3); } + 50% { + opacity: 1; } } + +@keyframes zoomOut { + from { + opacity: 1; } + 50% { + opacity: 0; + transform: scale3d(0.3, 0.3, 0.3); } + to { + opacity: 0; } } + +@keyframes slideInRight { + from { + transform: translate3d(100%, 0, 0); + visibility: visible; } + to { + transform: translate3d(0, 0, 0); } } + +@keyframes slideInLeft { + from { + transform: translate3d(-100%, 0, 0); + visibility: visible; } + to { + transform: translate3d(0, 0, 0); } } + +@keyframes slideInDown { + from { + transform: translate3d(0, -100%, 0); + visibility: visible; } + to { + transform: translate3d(0, 0, 0); } } + +@keyframes slideOutLeft { + from { + transform: translate3d(0, 0, 0); } + to { + visibility: hidden; + transform: translate3d(-100%, 0, 0); } } + +@keyframes slideOutRight { + from { + transform: translate3d(0, 0, 0); } + to { + visibility: hidden; + transform: translate3d(100%, 0, 0); } } + +@keyframes slideOutUp { + from { + transform: translate3d(0, 0, 0); } + to { + visibility: hidden; + transform: translate3d(0, -100%, 0); } } + +@keyframes rotate { + from { + transform: rotate(0deg); } + to { + transform: rotate(360deg); } } + +@keyframes pulse { + from { + transform: scale3d(1, 1, 1); } + 50% { + transform: scale3d(1.03, 1.03, 1.03); } + to { + transform: scale3d(1, 1, 1); } } + +@keyframes shake { + 15% { + transform: translateX(0.5rem); } + 30% { + transform: translateX(-0.4rem); } + 45% { + transform: translateX(0.3rem); } + 60% { + transform: translateX(-0.2rem); } + 75% { + transform: translateX(0.1rem); } + 90% { + transform: translateX(0); } + 90% { + transform: translateX(0); } } + +.fadeIn { + animation: fadeIn 250ms; } + +.fadeOut { + animation: fadeOut 250ms; } + +.zoomIn { + animation: zoomIn 200ms; } + +.zoomOut { + animation: zoomOut 500ms; } + +.slideInRight { + animation: slideInRight 500ms; } + +.slideInLeft { + animation: slideInLeft 500ms; } + +.slideInDown { + animation: slideInDown 500ms; } + +.slideOutLeft { + animation: slideOutLeft 500ms; } + +.slideOutRight { + animation: slideOutRight 500ms; } + +.slideOutUp { + animation: slideOutUp 500ms; } + +.slideUp { + overflow: hidden; + animation: slideUp 200ms ease-in-out; } + +.slideDown { + overflow: hidden; + animation: slideDown 80ms ease-in-out; } + +.flipIn { + animation: flipIn 250ms cubic-bezier(0.5, -0.5, 0.5, 1.5); } + +.flipOut { + animation: flipOut 500ms cubic-bezier(0.5, -0.5, 0.5, 1.5); } + +.rotate { + animation: rotate 500ms; } + +.pulse { + animation: pulse 250ms 2; } + +.shake { + animation: shake 500ms; } + +.dropdown { + position: absolute; + z-index: 100; + top: 0; + right: 0; + width: 280px; + color: #000; + font-size: 15px; + background: #fff; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); + border-radius: 3px; + max-height: 300px; + margin: 0; + padding: 0; + overflow: hidden; } + .dropdown.dropdown-mobile { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + width: 100%; + max-height: none; + border: none; } + .dropdown .close { + margin: 20px auto; } + .dropdown.open { + overflow: auto; } + .dropdown ul { + list-style: none; + margin: 0; } + .dropdown ul li { + border-bottom: 1px solid rgba(0, 0, 0, 0.07); } + .dropdown ul li:last-child { + border-bottom: none; } + .dropdown ul a { + display: block; + padding: 12px; + text-decoration: none; + color: #000; } + .dropdown ul a:hover { + background: rgba(0, 0, 0, 0.05); } + +.message { + font-family: Consolas, Monaco, "Courier New", monospace; + font-size: 14px; + line-height: 20px; + background: #e0e1e1; + color: #313439; + padding: 1rem; + padding-right: 2.5em; + padding-bottom: .75rem; + margin-bottom: 24px; + position: relative; } + .message a { + color: inherit; } + .message h2, + .message h3, + .message h4, + .message h5, + .message h6 { + margin-bottom: 0; } + .message .close { + position: absolute; + right: 1rem; + top: 1.1rem; } + +.message.error { + background: #f03c69; + color: #fff; } + +.message.success { + background: #35beb1; + color: #fff; } + +.message.warning { + background: #f7ba45; } + +.message.focus { + background: #8246AF; + color: #fff; } + +.message.black { + background: #0d0d0e; + color: #fff; } + +.message.inverted { + background: #fff; } + +.modal-box { + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + overflow-x: hidden; + overflow-y: auto; + z-index: 200; } + +.modal { + position: relative; + margin: auto; + margin-top: 16px; + padding: 0; + background: #fff; + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15); + border-radius: 8px; + color: #000; } + @media (max-width: 768px) { + .modal input, + .modal textarea { + font-size: 16px; } } + .modal .close { + position: absolute; + top: 18px; + right: 16px; + opacity: .3; } + .modal .close:hover { + opacity: 1; } + +.modal-header { + padding: 24px 32px; + font-size: 18px; + font-weight: bold; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); } + .modal-header:empty { + display: none; } + +.modal-body { + padding: 36px 56px; } + +@media (max-width: 768px) { + .modal-header, + .modal-body { + padding: 24px; } } + +.offcanvas { + background: #fff; + position: fixed; + padding: 24px; + height: 100%; + top: 0; + left: 0; + z-index: 300; + overflow-y: scroll; } + +.offcanvas .close { + position: absolute; + top: 8px; + right: 8px; } + +.offcanvas-left { + border-right: 1px solid rgba(0, 0, 0, 0.1); } + +.offcanvas-right { + left: auto; + right: 0; + border-left: 1px solid rgba(0, 0, 0, 0.1); } + +.offcanvas-push-body { + position: relative; } + +.tabs { + margin-bottom: 24px; + font-size: 14px; } + .tabs li em, + .tabs li.active a { + color: #313439; + border: 1px solid rgba(0, 0, 0, 0.1); + cursor: default; + text-decoration: none; + background: none; } + .tabs em, + .tabs a { + position: relative; + top: 1px; + font-style: normal; + display: block; + padding: .5rem 1rem; + border: 1px solid transparent; + color: rgba(0, 0, 0, 0.5); + text-decoration: none; } + .tabs a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: #313439; + text-decoration: underline; + background-color: #e0e1e1; } + +@media (min-width: 768px) { + .tabs ul { + display: flex; + margin-top: -1px; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); } + .tabs li em, + .tabs li.active a { + border-bottom: 1px solid #fff; } } diff --git a/themes/coredns/static/css/kube.demo.css b/themes/coredns/static/css/kube.demo.css new file mode 100644 index 0000000..f4abaec --- /dev/null +++ b/themes/coredns/static/css/kube.demo.css @@ -0,0 +1,404 @@ +body { + font-family: Lato, sans-serif; } + +h1.title, h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { + font-family: Lato, sans-serif; } + +button, .button { + font-family: Lato, sans-serif; } + +.media { + padding: 24px; + border: 1px solid rgba(0, 0, 0, 0.07); + border-radius: 3px; + margin-bottom: 24px; + max-width: 400px; + display: flex; + align-items: flex-start; } + .media img { + margin: 4px 0; } + .media .media-body { + margin-left: 16px; } + .media .media-body h5 { + margin-bottom: 0; } + .media .media-body p { + margin-bottom: 0; } + +.section-head { + font-size: 24px; + line-height: 32px; + margin-top: 48px; + font-weight: 900; } + .section-head:after { + content: '#'; + font-size: 15px; + font-weight: normal; + line-height: 1; + color: rgba(0, 0, 0, 0.3); + margin-left: 8px; + position: relative; + top: -1px; } + .section-head a { + text-decoration: none; } + +.section-item-desc { + font-family: Consolas, Monaco, "Courier New", monospace; + font-size: 12px; + color: rgba(0, 0, 0, 0.5); } + +.example { + border: 1px solid rgba(0, 0, 0, 0.07); + padding: 32px; + margin-bottom: 16px; } + .example pre.code { + margin-top: 40px; + margin-bottom: 0; + background: none; + padding: 0; } + .example.bg-darkgray { + background: #313439; } + .example.bg-darkgray pre.code { + color: rgba(255, 255, 255, 0.85); } + +.demo-muted-link, +.demo-muted-link:hover { + text-decoration: none; + color: rgba(0, 0, 0, 0.3); } + +.demo-animation-wrap { + margin-bottom: 24px; } + .demo-animation-wrap:after { + content: ''; + display: table; + clear: both; } + +.demo-animation-box { + float: left; + margin-right: 16px; + width: 202px; + height: 82px; + border: 1px dashed rgba(0, 0, 0, 0.15); } + .demo-animation-box > div { + width: 200px; + height: 80px; + background: #f8f8f8; + text-align: center; + line-height: 80px; + color: rgba(0, 0, 0, 0.4); + font-size: 18px; } + +.demo-animation-btn { + font-size: 13px; + text-transform: uppercase; + font-weight: bold; + display: inline-block; + width: 200px; + margin-right: 16px; } + +.demo-sizing > div { + font-family: Consolas, Monaco, "Courier New", monospace; + font-size: 11px; + padding-left: 4px; + background: #d8e9fa; + margin-bottom: 4px; } + +.demo-grid .row { + margin-bottom: 4px; + background: #ebf4fc; } + +.demo-grid .row.gutters { + background: none; } + +.demo-grid .col { + font-family: Consolas, Monaco, "Courier New", monospace; + font-size: 12px; + padding: 8px 12px; + background: #d8e9fa; + border-left: 1px solid rgba(0, 0, 0, 0.1); } + +.demo-grid .demo-col-nested { + border-left: none; + padding: 0; } + .demo-grid .demo-col-nested .row { + margin-bottom: 0; } + +#demo-container { + display: flex; + flex-direction: row; + flex-wrap: wrap; } + +#demo-sidebar { + flex: 0 0 300px; + background: #c4def7; } + +#demo-content { + flex: auto; + background: #ebf4fc; } + +#demo-sidebar, +#demo-content { + font-family: Consolas, Monaco, "Courier New", monospace; + font-size: 12px; + padding: 8px 12px; + min-height: 80px; } + +#demo-media-grid { + -webkit-column-count: 2; + -moz-column-count: 2; + column-count: 2; + -webkit-column-gap: 2%; + -moz-column-gap: 2%; + column-gap: 2%; } + #demo-media-grid > div { + display: inline-block; + width: 100%; } + @media (max-width: 768px) { + #demo-media-grid { + -webkit-column-count: 1; + -moz-column-count: 1; + column-count: 1; } } + #demo-media-grid > div { + font-family: Consolas, Monaco, "Courier New", monospace; + font-size: 12px; + padding: 8px 12px; + background: #eae2f2; + text-align: center; + margin-bottom: 20px; + height: 80px; } + #demo-media-grid > div:nth-child(2n) { + height: 200px; } + #demo-media-grid > div:nth-child(5n) { + height: 120px; } + +.button.red { + color: #fff; + background-color: #ff3366; } + .button.red:hover { + color: #fff; + background-color: #ff99b3; } + .button.red:disabled, .button.red.disabled { + color: rgba(255, 255, 255, 0.7); + background-color: rgba(255, 51, 102, 0.7); } + .button.red.outline { + background: none; + color: #ff3366; + border-color: #ff3366; } + .button.red.outline:hover { + color: rgba(255, 51, 102, 0.6); + border-color: rgba(255, 51, 102, 0.5); } + .button.red.outline:disabled, .button.red.outline.disabled { + background: none; + color: rgba(255, 51, 102, 0.7); + border-color: rgba(255, 51, 102, 0.5); } + +.label.custom { + background: #ea48a7; + color: #fff; } + .label.custom.tag, .label.custom.outline { + background: none; + border-color: #ea48a7; + color: #ea48a7; } + +#breadcrumbs-custom-separator li:after { + content: '>'; } + +.demo-gradient { + height: 40px; + margin-bottom: 24px; } + +.demo-gradient-vertical { + background-color: #5faac8; + background-image: linear-gradient(to bottom, #5faac8 0%, #65ccb8 100%); } + +.demo-gradient-vertical-to-opacity { + background: linear-gradient(to bottom, #5faac8 0%, rgba(95, 170, 200, 0) 100%); } + +.demo-gradient-horizontal { + background-color: #5faac8; + background: linear-gradient(to right, #5faac8 0%, #65ccb8 100%); } + +.demo-gradient-horizontal-to-opacity { + background: linear-gradient(to right, #5faac8 0%, rgba(95, 170, 200, 0) 100%); } + +.demo-gradient-radial { + background-image: radial-gradient(circle, #5faac8, #65ccb8); } + +.example-inverted-box { + display: inline-block; + padding: 6px 8px 6px 8px; + line-height: 1; + vertical-align: middle; + background: #d4d4d4; } + +#livetabs { + margin-bottom: 24px; + font-size: 14px; } + +#livetabs ul { + display: flex; } + +#livetabs a { + color: #000; + text-decoration: none; + background: #f4f4f4; + border-radius: 4px; + padding: 4px 12px; + border: 1px solid transparent; } + #livetabs a:hover { + opacity: .7; } + +#livetabs li { + margin-right: 4px; } + +#livetabs li.active a { + background: #fff; + border-color: #eee; + color: rgba(0, 0, 0, 0.5); + cursor: default; } + #livetabs li.active a:hover { + opacity: 1; } + +.togglebox-box { + padding: 24px; + padding-bottom: 16px; + background: #f8f8f8; + margin-bottom: 24px; } + +#navbar-demo { + display: flex; + align-items: center; + background: #f8f8f8; + padding: 24px 20px; + margin-bottom: 24px; } + +#navbar-brand { + margin-right: 24px; } + +#navbar-main ul:after { + content: ''; + display: table; + clear: both; } + +#navbar-main li { + float: left; + margin-right: 20px; } + +#navbar-demo.fixed { + background: rgba(255, 255, 255, 0.98); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.2); } + +#navbar-main li a { + color: #000; + text-decoration: none; + display: block; } + #navbar-main li a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: rgba(0, 0, 0, 0.6); + text-decoration: underline; } + +@media (max-width: 768px) { + #navbar-demo { + flex-direction: column; + text-align: center; } + #navbar-brand { + margin: 0; + margin-bottom: 20px; } + #navbar-main li { + float: none; + margin: 0; + margin-bottom: 20px; } } + +#demo-nav-collapse, +#demo-nav-collapse ul { + margin-left: 0; + list-style: none; } + +#demo-nav-collapse li { + line-height: 32px; } + +#demo-nav-collapse ul { + margin-left: 20px; + font-size: 14px; } + +#demo-nav-collapse a { + color: #000; + text-decoration: none; + display: block; } + #demo-nav-collapse a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: rgba(0, 0, 0, 0.6); + text-decoration: underline; } + +.my-collapse { + margin-bottom: 24px; } + +.my-collapse h4 { + background: #f4f4f4; + padding: 8px 16px; + margin-bottom: 1px; + font-size: 15px; + line-height: 24px; } + +.my-collapse h4 a { + text-decoration: none; + color: #000; + display: block; } + +.my-collapse div { + border: 1px solid rgba(0, 0, 0, 0.1); + padding: 24px 32px 1px; + margin-bottom: 1px; } + +.swatch-box { + text-align: center; } + +.swatch-item { + display: inline-block; + margin: 24px; } + .swatch-item h5 { + font-family: Consolas, Monaco, "Courier New", monospace; + font-weight: bold; + font-size: 14px; + line-height: 24px; + margin-bottom: 0; } + .swatch-item p { + font-family: Consolas, Monaco, "Courier New", monospace; + font-size: 12px; + line-height: 20px; + color: rgba(46, 47, 51, 0.65); } + +.swatch { + display: inline-block; + height: 120px; + width: 120px; + border-radius: 120px; + margin-bottom: 8px; } + +.swatch-bg-headings { + background: #0d0d0e; } + +.swatch-bg-text { + background: #313439; } + +.swatch-bg-link { + background: #007eff; } + +.swatch-bg-link-hover { + background: #ff3366; } + +.swatch-bg-button-primary { + background: #007eff; } + +.swatch-bg-button-secondary { + background: #313439; } + +.swatch-bg-inverted { + background: #fff; } + +.swatch-bg-inverted { + position: relative; + bottom: -8px; + margin-top: -8px; + border: 8px solid #f8f8f8; } diff --git a/themes/coredns/static/css/kube.legenda.css b/themes/coredns/static/css/kube.legenda.css new file mode 100644 index 0000000..5e5288d --- /dev/null +++ b/themes/coredns/static/css/kube.legenda.css @@ -0,0 +1,406 @@ +.autocomplete { + position: absolute; + z-index: 1000; + left: 0; + display: none; + margin: 0; + list-style: none; + background: #fff; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); + max-height: 250px; + overflow: auto; + font-size: 14px; } + .autocomplete a { + padding: 4px 10px; + color: #000; + display: block; + text-decoration: none; } + .autocomplete a:hover { + background: rgba(0, 0, 0, 0.05); } + .autocomplete a.active { + background: #007eff; + color: #fff; } + +.cardform label { + display: block; + text-transform: uppercase; + font-size: 12px; + color: rgba(0, 0, 0, 0.5); } + +.cardform-view select, +.cardform-view textarea, +.cardform-view input { + border: none !important; + background: none; + padding: 0; + cursor: text; + -webkit-appearance: none; } + .cardform-view select:focus, + .cardform-view textarea:focus, + .cardform-view input:focus { + box-shadow: none; + background: none; + outline: none; } + +.cardform-controls { + margin-bottom: 24px; } + +.combobox { + position: relative; } + .combobox input { + padding-right: 32px; + width: 100%; } + .combobox .caret { + position: absolute; + z-index: 2; + top: 0; + right: 0; + height: 100%; + width: 32px; } + .combobox .caret:before { + top: 45%; + left: 12px; } + +.combobox-list { + z-index: 1000; + position: absolute; + left: 0; + margin: 0; + list-style: none; + background: #fff; + font-size: 14px; + width: 100%; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); + max-height: 250px; + font-weight: normal; + overflow: auto; } + .combobox-list li { + padding: 4px 10px; + color: #000; + cursor: pointer; } + .combobox-list li:hover { + background: rgba(0, 0, 0, 0.05); } + .combobox-list li.active { + background: #007eff; + color: #fff; } + +.datepicker { + position: absolute; + background: #fff; + top: 0; + left: 0; + line-height: 24px; + padding: 20px 24px; + border-radius: 3px; + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); } + .datepicker.datepicker-embed { + position: static; + box-shadow: none; + border: 1px solid rgba(0, 0, 0, 0.1); } + +.datepicker-head { + position: relative; + padding-bottom: 8px; } + +.datepicker-controls { + position: absolute; + top: 0; + right: 0; } + +.datepicker-control { + float: left; + width: 24px; + height: 24px; + background: #eee; + border-radius: 3px; + text-align: center; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -khtml-user-select: none; + -ms-user-select: none; + user-select: none; } + +.datepicker-control-next { + margin-left: 4px; } + +.datepicker-month-box { + font-size: 14px; + color: #000; + font-weight: bold; + padding-left: 4px; + height: 24px; } + +.datepicker-select-year { + display: inline-block; + cursor: pointer; + background: #eee; + padding: 0 8px; + position: relative; + border-radius: 3px; + height: 24px; + line-height: 24px; } + .datepicker-select-year .datepicker-select-year-caret { + position: relative; + top: -1px; + display: inline-block; + width: 0; + height: 0; + margin-left: .3em; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; } + .datepicker-select-year select { + z-index: 2; + position: absolute; + top: 0; + left: 0; + opacity: 0; + height: 24px; + -webkit-appearance: menulist-button; + -moz-appearance: menulist-button; + -ms-appearance: menulist-button; + appearance: menulist-button; } + +.datepicker-weekdays { + white-space: nowrap; } + .datepicker-weekdays span { + display: inline-block; + text-align: center; + width: 28px; + height: 28px; + margin: 0 2px; + font-size: 12px; + font-weight: bold; + color: rgba(0, 0, 0, 0.5); } + +.datepicker-row { + white-space: nowrap; } + +.datepicker-cell { + display: inline-block; + text-align: center; + width: 28px; + height: 28px; + margin: 0 2px; + font-size: 12px; } + .datepicker-cell a { + display: block; + color: #000; + text-decoration: none; + border-radius: 40px; } + .datepicker-cell a:hover { + background: #eee; } + .datepicker-cell.datepicker-day-hidden a { + visibility: hidden; } + .datepicker-cell.datepicker-day-weekend a { + color: rgba(0, 0, 0, 0.4); + font-weight: bold; } + .datepicker-cell.datepicker-day-today a { + background: #f23d3d; + color: #fff; } + .datepicker-cell.datepicker-day-last a { + background: none; + color: rgba(0, 0, 0, 0.4); } + .datepicker-cell.datepicker-day-last a:hover { + color: #000; } + .datepicker-cell.datepicker-day-selected a { + background: #3d79f2; + color: #fff; } + .datepicker-cell.datepicker-day-selected a:hover { + color: #fff; } + .datepicker-cell.datepicker-day-disabled a, + .datepicker-cell.datepicker-day-disabled a:hover { + background: none !important; + color: rgba(0, 0, 0, 0.3) !important; + cursor: default; } + +.editable[placeholder]:empty:before { + content: attr(placeholder); + color: rgba(0, 0, 0, 0.4); + font-weight: normal; } + +.editable[placeholder]:empty:focus:before { + content: ""; } + +.livesearch-box { + position: relative; + display: block; + width: 100%; } + .livesearch-box input { + min-width: 120px; } + .livesearch-box .close { + position: absolute; + top: 50%; + margin-top: -6px; + right: 8px; } + +.livesearch-dropdown { + position: absolute; + z-index: 1000; + margin: 0; + list-style: none; + background: #fff; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); + max-height: 250px; + overflow: auto; } + +.loader { + display: inline-block; + margin: auto; + position: relative; + width: 32px; + height: 32px; } + .loader.small { + width: 20px; + height: 20px; } + +button .loader { + margin-bottom: -4px; } + +.loader-spinner { + width: 100%; + height: 100%; + border-radius: 50%; + margin: auto; + position: absolute; + left: 0; + right: 0; + top: 0; + bottom: 0; + margin: auto; + border: 4px solid rgba(0, 0, 0, 0.25); + border-bottom-color: #000; + -webkit-animation: rotate 2s linear 0s infinite; + animation: rotate 2s linear 0s infinite; } + +.notification { + position: fixed; + top: 1rem; + right: 1rem; + padding: .75rem 1rem; + padding-bottom: .5rem; + font-family: Consolas, Monaco, "Courier New", monospace; + font-size: 14px; + line-height: 20px; + background: #e0e1e1; + color: #313439; + font-weight: bold; + min-width: 220px; + max-width: 280px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); } + @media (max-width: 768px) { + .notification { + max-width: 100%; + left: 1rem; } } + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; } + to { + background-position: 0 0; } } + +.progress { + background: #d4d4d4; + height: 12px; } + .progress.absolute { + position: absolute; + top: 0; + left: 0; + width: 100%; } + .progress > div { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent); + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; + font-size: 10px; + line-height: 10px; + color: #fff; + padding: 1px 2px; + height: 100%; + background-color: #007eff; + background-size: 40px 40px; } + .progress > div:empty { + padding: 1px 0; } + +.selector { + position: relative; + display: inline-block; } + +.selector select { + z-index: 2; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + height: 100%; + width: 100%; + opacity: 0; + -webkit-appearance: menulist-button; + -moz-appearance: menulist-button; + -ms-appearance: menulist-button; + appearance: menulist-button; } + +.selector-trigger-box { + cursor: pointer; + position: relative; + display: block; + z-index: 1; + width: 100%; + padding-right: 8px; } + +.upload-box { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + position: relative; + font-size: 12px; + line-height: 20px; + width: 100%; + min-height: 80px; + border: 2px dashed #d4d4d4; + background: #e0e1e1; + cursor: pointer; + overflow: hidden; + text-align: center; } + +.upload-placeholder { + opacity: .6; } + +.upload-hover, +.upload-error { + border-color: rgba(0, 0, 0, 0.2); } + +.upload-hover { + background-color: rgba(0, 126, 255, 0.1); } + +.upload-error { + background-color: rgba(255, 51, 102, 0.1); } + +div.upload-target { + display: flex; } + +ol.upload-target, +ul.upload-target { + list-style: none; + margin-left: 0; } + ol.upload-target li, + ul.upload-target li { + display: flex; } + ol.upload-target .close, + ul.upload-target .close { + top: 2px; } + +.upload-target .close { + order: 1; + background: #d4d4d4; + border-radius: 20px; + margin-left: 4px; + width: 20px; + height: 20px; + line-height: 20px; } diff --git a/themes/coredns/static/css/master.css b/themes/coredns/static/css/master.css new file mode 100644 index 0000000..8570d5d --- /dev/null +++ b/themes/coredns/static/css/master.css @@ -0,0 +1,1135 @@ +body { + font-family: Lato, Arial, sans-serif; } + +h1.title, h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { + font-family: Lato, Arial, sans-serif; } + +button, .button { + font-family: Lato, Arial, sans-serif; } + +h1, h2, h3, h4, h5, h6 { + color: #222; } + +.form-centered { + max-width: 400px; + margin: auto; + margin-bottom: 140px; } + +.form-subscribe { + text-align: center; + border-radius: 4px; + border: 3px dashed rgba(0, 0, 0, 0.1); + padding: 64px 40px; + margin-bottom: 24px; } + .form-subscribe h4 { + margin-bottom: 0; } + .form-subscribe p { + color: rgba(0, 0, 0, 0.5); + margin-bottom: 20px; } + .form-subscribe form { + max-width: 400px; + margin: auto; } + .form-subscribe #form-subscribe-success { + max-width: 500px; + margin: auto; + font-size: 18px; + line-height: 28px; } + .form-subscribe #subscribe-email-validation-error { + margin-bottom: 8px; + font-size: 15px; } + .form-subscribe .form-subscribe-twitter div { + margin: 24px 0; + font-size: 20px; + color: rgba(0, 0, 0, 0.3); } + .form-subscribe .form-subscribe-twitter a { + display: inline-block; + padding-left: 21px; + background: url("/assets/img/common/icon-twitter.png") no-repeat left 4px; } + +#toggle-form-subscribe { + text-align: center; + margin-bottom: 20px; + font-size: 15px; + margin-top: -20px; } + +#nav-toggle-box { + display: flex; + align-items: center; + padding: 8px 16px; } + +#nav-toggle { + margin-left: auto; + color: #000; + text-decoration: none; + padding: 2px 8px; } + +#nav-toggle-brand { + position: relative; + top: -1px; } + +#nav-toggle-brand a, +#nav-toggle-brand span { + color: #000; + font-weight: bold; + text-decoration: none; } + +#top { + display: flex; + align-items: center; + margin-bottom: 24px; + padding: 0 36px; + height: 88px; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); } + #top #top-brand { + margin-right: 52px; } + #top #top-brand span, + #top #top-brand a { + background: none; + text-indent: -9999px; + width: 70px; + line-height: 11px; + background-repeat: no-repeat; } + + #top ul { + display: flex; + align-items: center; + margin: 0; } + #top #top-nav-main { + padding-left: 52px; + border-left: 1px solid rgba(0, 0, 0, 0.15); } + #top #top-nav-main li { + font-size: 16px; + font-weight: 500; + margin-right: 40px; } + #top #top-nav-main span, + #top #top-nav-main a { + display: inline-block; } + #top #top-nav-main a { + color: #000; + text-decoration: none; } + #top #top-nav-main a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: rgba(0, 0, 0, 0.6); + text-decoration: underline; } + #top #top-nav-main b a, + #top #top-nav-main span { + font-weight: 500; + color: rgba(0, 0, 0, 0.4); } + #top #top-nav-main b a { + text-decoration: underline; } + #top #top-nav-main b a:hover { + color: #000; } + #top #top-nav-extra { + margin-left: auto; + font-size: 14px; } + #top #top-nav-extra span, + #top #top-nav-extra a { + color: rgba(0, 0, 0, 0.7); + display: inline-block; + border: 1px solid rgba(0, 0, 0, 0.5); + text-decoration: none; + line-height: 28px; + border-radius: 28px; + padding: 0 20px; } + #top #top-nav-extra a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: #000; + text-decoration: underline; } + #top #top-nav-extra span { + color: rgba(0, 0, 0, 0.4); + border-color: rgba(0, 0, 0, 0.2); } + #top #top-nav-extra li { + padding-right: 5px; } + +#subnav { + margin-top: 24px; + margin-bottom: 24px; + font-size: 15px; } + #subnav ul { + margin: 0; + text-align: center; } + #subnav li { + display: inline-block; } + #subnav li.active a, + #subnav span { + color: rgba(0, 0, 0, 0.4); } + #subnav form, + #subnav em, + #subnav span, + #subnav a { + display: inline-block; + padding: 2px 16px; } + #subnav em { + font-style: normal; } + #subnav a { + color: #8246af; + text-decoration: none; } + #subnav a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: #000; + text-decoration: underline; } + #subnav li:first-child b a { + color: #8246af; + font-weight: normal; + text-decoration: none; } + #subnav li:first-child b a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: #000; + text-decoration: underline; } + #subnav b a { + color: #000; + text-decoration: underline; } + #subnav b a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: rgba(0, 0, 0, 0.6); + text-decoration: underline; } + #subnav .action-button a { + background: rgba(28, 134, 242, 0.05); + font-size: 15px; + margin-left: 16px; + padding: 2px 16px; + border-radius: 3px; + border: 1px solid rgba(28, 134, 242, 0.5); } + #subnav .action-button a:hover { + background: #1c86f2; + border-color: #1c86f2; + color: #fff; + text-decoration: none; } + #subnav form { + margin: 0; } + #subnav form button { + font-size: 15px; + line-height: 24px; + color: #8246af; + height: auto; + padding: 0; + background: none; + box-shadow: none; + vertical-align: baseline; } + #subnav form button:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: #000; + text-decoration: underline; } + +#hero { + padding-top: 48px; + padding-bottom: 56px; + text-align: center; } + #hero h1 { + max-width: 880px; + margin-left: auto; + margin-right: auto; + margin-bottom: 12px; + font-size: 64px; + line-height: 72px; + font-weight: 900; } + #hero p { + max-width: 740px; + margin: auto; + font-size: 21px; + line-height: 32px; + color: rgba(0, 0, 0, 0.5); + margin-top: 28px; + padding-top: 28px; + margin-bottom: 0; + position: relative; } + #hero p a { + color: #000; } + #hero p a:hover { + color: rgba(0, 0, 0, 0.6); } + #hero p:before { + position: absolute; + content: ''; + width: 40px; + height: 3px; + top: 0; + left: 50%; + margin-left: -20px; + background: #ff3366; } + +#intro { + margin-top: 56px; + margin-bottom: 140px; + text-align: center; + position: relative; } + #intro:before { + position: absolute; + content: ''; + width: 40px; + height: 3px; + top: -68px; + left: 50%; + margin-left: -20px; + background: #ff3366; } + #intro h6 { + color: rgba(0, 0, 0, 0.5); + font-weight: normal; } + #intro h2 { + font-weight: 900; } + #intro h2 a { + color: #8246af; + text-decoration: none; } + #intro h2 a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: #000; + text-decoration: underline; } + #intro p { + font-size: 15px; + margin: auto; + padding: 0 20px; } + @media (max-width: 768px) { + #intro .col { + margin-bottom: 48px; } } + +#action-buttons { + margin-bottom: 64px; + text-align: center; } + #action-buttons button, + #action-buttons .button { + margin: 0 4px; } + #action-buttons p { + margin: 0; + margin-top: 20px; + font-size: 13px; + line-height: 20px; + color: rgba(0, 0, 0, 0.5); } + +#contents { + counter-reset: count; + max-width: 400px; + margin: 24px auto 60px auto; + padding: 32px; + background: #fbfbfb; + border: 1px solid rgba(0, 0, 0, 0.08); } + #contents.wide { + max-width: none; + margin-bottom: 24px; } + #contents ol { + margin: 0; } + #contents li { + line-height: 40px; + border-bottom: 1px solid rgba(0, 0, 0, 0.06); + margin-right: 24px; + counter-increment: count; } + #contents li:last-child { + border-bottom: none; } + #contents a { + display: block; + text-decoration: none; + position: relative; + padding-left: 24px; + color: #259d92; } + #contents a:before { + position: absolute; + left: 0; + content: counter(count, decimal-leading-zero); + font-size: 13px; + color: rgba(0, 0, 0, 0.3); } + #contents a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: #000; + text-decoration: underline; } + +#main { + margin: auto; + max-width: 1128px; } + +body.docs #main, +body.grafs-index #main, +body.page-redactor-index #main { + max-width: none; } + +body.grafs-index footer, +body.page-redactor-index footer { + margin-top: 0; } + +body.docs #top { + margin-bottom: 0; } + +body.page-account #hero { + padding: 0; } + body.page-account #hero h1 { + font-size: 32px; + line-height: 32px; + margin-bottom: 48px; } + +.content { + max-width: 840px; + margin: auto; } + +#redactor-intro-box { + max-width: 920px; + margin: auto; + margin-bottom: 48px; } + +#redactor-features { + text-align: center; + margin: 136px auto; + max-width: 1128px; } + +#redactor-features h3 { + font-size: 21px; + margin-top: 0; + margin-bottom: 4px; } + +#redactor-features p { + color: rgba(0, 0, 0, 0.5); } + +#redactor-buying-desc { + max-width: 720px; + margin: auto; + margin-top: 40px; + font-size: 13px; + line-height: 20px; } + +#redactor-buying-desc p { + color: rgba(0, 0, 0, 0.5); } + +#redactor-buy-box { + text-align: center; + margin: 116px auto; + max-width: 1128px; } + +#redactor-cloud { + text-align: center; + margin: 116px auto; + max-width: 1128px; } + #redactor-cloud h2 { + font-size: 48px; + line-height: 56px; + margin-bottom: 36px; + color: rgba(0, 0, 0, 0.15); } + #redactor-cloud ul { + margin: 0; + list-style: none; } + #redactor-cloud li { + list-style: none; + display: inline; + line-height: 44px; + margin: 0 12px; + white-space: nowrap; } + #redactor-cloud li:nth-child(3n) { + font-size: 1.25em; + color: #666; } + #redactor-cloud li:nth-child(4n) { + font-size: 1.5em; + color: #333; } + #redactor-cloud li:nth-child(5n) { + font-size: 1em; + color: #999; } + #redactor-cloud li:nth-child(7n) { + font-size: 2.25em; } + @media (max-width: 768px) { + #redactor-cloud { + display: none; } } + +#redactor-discover { + text-align: center; + background: #f8f8f8; + padding-bottom: 96px; } + #redactor-discover #redactor-discover-box { + max-width: 1128px; + margin: auto; } + #redactor-discover h3 { + font-size: 24px; + line-height: 32px; + text-align: center; + font-weight: 900; + padding: 40px 0; + margin-bottom: 60px; + color: rgba(0, 0, 0, 0.25); + border-bottom: 1px solid rgba(0, 0, 0, 0.05); } + #redactor-discover h4 { + margin-top: 0; } + #redactor-discover h4 a { + font-size: 21px; + color: #000; } + #redactor-discover h4 a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: rgba(0, 0, 0, 0.5); } + #redactor-discover figure { + margin-bottom: 0; } + #redactor-discover .col { + max-width: 340px; } + #redactor-discover p { + font-size: 14px; + line-height: 20px; + color: rgba(0, 0, 0, 0.5); } + @media (max-width: 768px) { + #redactor-discover .col { + max-width: none; } + #redactor-discover p { + padding: 0 24px; } } + +#grafs-matrix-box { + padding: 0 20px; + max-width: 1128px; + margin: auto; + margin-bottom: 80px; } + #grafs-matrix-box .item { + padding-top: 72px; + text-align: center; } + #grafs-matrix-box .item.first { + padding-top: 24px; } + #grafs-matrix-box h5 { + font-size: 17px; + line-height: 24px; + margin-bottom: 8px; } + #grafs-matrix-box p { + max-width: 340px; + margin: auto; + margin-bottom: 32px; + font-size: 13px; + line-height: 20px; + color: rgba(0, 0, 0, 0.7); } + #grafs-matrix-box .row p { + max-width: 280px; + margin-bottom: 40px; } + +#grafs-buy-box { + padding: 0 20px; + padding-bottom: 104px; + max-width: 1128px; + margin: auto; + margin-top: 128px; + text-align: center; + border-bottom: 1px solid rgba(0, 0, 0, 0.07); } + #grafs-buy-box h2 { + font-size: 30px; + line-height: 40px; + font-weight: 900; + margin-bottom: 72px; } + #grafs-buy-box .button { + height: 60px; + padding-top: 20px; + padding-left: 36px; + padding-right: 36px; + font-size: 19px; + font-weight: 500; } + #grafs-buy-box p.desc { + font-size: 13px; + line-height: 20px; + color: rgba(0, 0, 0, 0.6); } + +#grafs-features { + text-align: center; + max-width: 1128px; + margin: 88px auto 104px auto; + padding: 0 20px; } + #grafs-features figure { + margin-bottom: 0; } + #grafs-features h3 { + margin-top: 0; + font-size: 21px; + line-height: 32px; } + #grafs-features p { + font-size: 15px; + color: rgba(0, 0, 0, 0.7); } + +#grafs-discover { + text-align: center; + background: #f8f8f8; + padding-bottom: 96px; } + #grafs-discover #grafs-discover-box { + max-width: 800px; + margin: auto; } + #grafs-discover h3 { + font-size: 24px; + line-height: 32px; + text-align: center; + font-weight: 900; + padding: 40px 0; + margin-bottom: 60px; + color: rgba(0, 0, 0, 0.25); + border-bottom: 1px solid rgba(0, 0, 0, 0.05); } + #grafs-discover h4 { + margin-top: 0; } + #grafs-discover h4 a { + font-size: 21px; + color: #000; } + #grafs-discover h4 a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: rgba(0, 0, 0, 0.5); } + #grafs-discover figure { + margin-bottom: 0; } + #grafs-discover .col { + max-width: 280px; } + #grafs-discover p { + font-size: 14px; + line-height: 20px; + color: rgba(0, 0, 0, 0.5); } + @media (max-width: 768px) { + #grafs-discover .col { + max-width: none; } + #grafs-discover p { + padding: 0 24px; } } + +.grafs-examples-row { + display: flex; + justify-content: center; + flex-wrap: wrap; + margin-bottom: 40px; } + +.grafs-examples-col { + border-radius: 3px; + background: #f8f8f8; + padding: 32px; + padding-bottom: 56px; + width: 300px; + margin: 0 16px; + margin-bottom: 24px; } + .grafs-examples-col figure { + margin-bottom: 0; } + .grafs-examples-col h4 { + font-size: 17px; + line-height: 28px; + margin-top: 0; } + .grafs-examples-col ul { + list-style: none; + margin: 0; } + .grafs-examples-col ul li { + font-size: 15px; + line-height: 36px; } + .grafs-examples-col ul a { + display: block; + color: #8246af; + text-decoration: none; } + .grafs-examples-col ul a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: #000; + text-decoration: underline; } + +#grafs-example-header, +#grafs-example-content { + max-width: 900px; + margin: auto; } + +#grafs-example-header { + margin-top: 72px; + margin-bottom: 44px; + text-align: center; } + #grafs-example-header .tag { + font-size: 13px; + line-height: 24px; + text-transform: uppercase; + color: rgba(0, 0, 0, 0.5); + margin-bottom: 8px; } + #grafs-example-header .tag a { + color: rgba(0, 0, 0, 0.6); } + #grafs-example-header .tag a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: #000; } + #grafs-example-header h1 { + font-size: 48px; + line-height: 52px; + font-weight: 900; } + +#path { + font-size: 15px; + margin-bottom: 12px; } + #path a { + color: #8246af; } + #path a:hover { + color: #000; } + #path span { + color: rgba(0, 0, 0, 0.2); + font-size: 15px; + display: inline-block; + margin: 0 6px; } + #path b { + font-weight: 500; + color: rgba(0, 0, 0, 0.4); } + +#docs-main { + display: flex; } + #docs-main #side { + width: 24%; + padding: 28px 36px; + border-right: 1px solid rgba(0, 0, 0, 0.1); } + #docs-main #side nav li { + font-size: 15px; + line-height: 40px; } + #docs-main #side nav li a { + display: block; + color: #707070; + text-decoration: none; } + #docs-main #side nav li a:hover { + color: #ff3366; + text-decoration: underline; } + #docs-main #side nav span, + #docs-main #side nav li.active a { + color: #ff3366; + font-weight: bold; } + #docs-main #side nav span:hover, + #docs-main #side nav li.active a:hover { + text-decoration: none; } + #docs-main #side nav h6 { + border-top: 1px solid #eee; + padding-top: 16px; + margin-top: 8px; + margin-bottom: 8px; } + #docs-main #area { + width: 76%; + padding: 32px 64px 48px 64px; } + #docs-main #area h1 { + font-size: 36px; + line-height: 40px; + font-weight: 900; + margin-bottom: 28px; } + #docs-main #area h3 { + font-size: 18px; + line-height: 28px; } + #docs-main #area .lead { + font-size: 18px; + line-height: 28px; + margin-bottom: 24px; } + #docs-main #area .doc-head { + position: relative; + margin-top: 24px; + padding-bottom: 8px; + border-bottom: 1px solid #eee; } + #docs-main #area .doc-head span { + position: absolute; + right: 0; + top: 0; + font-weight: normal; + font-size: 13px; + color: rgba(0, 0, 0, 0.4); } + #docs-main #area .doc-head a { + text-decoration: none; + color: #000; + display: block; + font-size: 20px; } + +.chart-example { + position: relative; + margin-top: 44px; + margin-bottom: 40px; } + .chart-example.inverted { + padding: 32px; + background: #191d21; } + .chart-example.inverted .chart-selector a { + color: rgba(255, 255, 255, 0.85); + border-color: rgba(255, 255, 255, 0.3); } + .chart-example.inverted pre { + color: rgba(255, 255, 255, 0.85); + padding: 0; + background: #191d21; } + +.chart-selector { + text-align: center; + font-size: 14px; + margin-bottom: 24px; } + .chart-selector a { + display: inline-block; + background: rgba(46, 196, 182, 0.05); + border: 1px solid rgba(46, 196, 182, 0.25); + border-radius: 40px; + line-height: 28px; + padding: 0 12px; + color: #000; + text-decoration: none; + margin: 0 4px; } + .chart-selector a:hover, + .chart-selector a.active { + text-decoration: none; + background: #2ec4b6; + color: #fff; + border: 1px solid transparent; } + .chart-selector a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; } + +.chart-section-head { + text-align: center; + font-weight: 900; + margin-top: 64px; + margin-bottom: -16px; + font-size: 16px; + line-height: 28px; } + +#posts { + list-style: none; + margin: auto; + margin-top: 48px; + margin-bottom: 128px; + max-width: 680px; + text-align: center; } + +#posts li { + margin-bottom: 40px; } + +#posts h2 { + font-size: 22px; + font-weight: normal; + margin: 0; + line-height: 28px; } + +#posts h2 a { + color: #1eabf2; + text-decoration: none; } + +#posts h2 a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: #000; + text-decoration: underline; } + +#posts time { + font-size: 12px; + color: rgba(0, 0, 0, 0.5); } + +#post-box { + max-width: 740px; + margin: auto; } + +#post { + font-size: 18px; + line-height: 32px; + margin-bottom: 40px; } + +#changelog { + max-width: 820px; + margin: auto; + margin-bottom: 104px; } + #changelog h3 { + margin-bottom: 4px; } + #changelog time { + font-size: 11px; + font-weight: bold; + display: block; + text-transform: uppercase; + margin-bottom: 40px; + color: rgba(0, 0, 0, 0.45); } + #changelog .item { + margin-bottom: 20px; + background: #f8f8f8; + padding: 40px; } + #changelog ul { + margin: 0; + list-style: none; } + #changelog li { + margin-bottom: 16px; + padding-bottom: 16px; + border-bottom: 1px solid #eee; } + #changelog li:last-child { + border-bottom: none; } + #changelog li .label { + margin-right: 4px; } + +#kube-features { + margin-top: 104px; + text-align: center; } + #kube-features h3 { + margin-top: 0; } + #kube-features .row:first-child { + padding-bottom: 32px; + margin-bottom: 64px; + border-bottom: 1px dashed rgba(0, 0, 0, 0.15); } + #kube-features p { + font-size: 15px; + color: rgba(0, 0, 0, 0.75); } + #kube-features .item { + padding: 0 24px; } + +#kube-faq { + max-width: 740px; + margin: auto; + font-size: 17px; + line-height: 28px; + margin-bottom: 104px; + border-top: 1px solid rgba(0, 0, 0, 0.07); } + #kube-faq h2 { + font-size: 24px; + font-weight: 900; + text-align: center; + line-height: 32px; + margin-top: 80px; + margin-bottom: 40px; } + +#components { + text-align: center; } + #components.lists { + text-align: left; } + #components.lists .item { + padding: 24px; } + #components.lists .item:hover { + background: #f8f8f8; } + #components .start { + font-size: 24px; + line-height: 32px; } + #components #search-box { + padding: 24px; + background: #ebf0f6; + margin-bottom: 24px; } + #components .item { + background: #f8f8f8; + padding: 68px 24px 60px 24px; + margin-bottom: 20px; } + #components .item:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + background: #fcfcfc; } + #components figure { + margin-bottom: 0; } + #components h4 { + font-size: 19px; + margin-top: 0; + margin-bottom: 8px; } + #components h4 a { + color: #8246af; + text-decoration: none; } + #components h4 a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: #280071; + text-decoration: underline; } + #components ul { + margin-left: 0; + margin-top: 24px; + list-style: none; } + #components li { + line-height: 32px; + margin-bottom: 4px; } + #components li a { + display: inline-block; + color: #8246af; + line-height: 24px; } + #components li a:hover { + -moz-transition: all linear 0.2s; + transition: all linear 0.2s; + color: #000; + text-decoration: underline; } + #components p { + max-width: 220px; + margin: auto; + font-size: 13px; + line-height: 20px; + color: rgba(0, 0, 0, 0.5); } + #components #docs-search-results p { + max-width: none; + margin-bottom: 16px; } + +.demo-head { + font-size: 24px; + line-height: 32px; + font-weight: 900; + margin-top: 80px; + margin-bottom: 20px; + text-align: center; } + +#price-box { + margin-top: 40px; } + #price-box .item { + text-align: center; + padding: 36px; + margin-bottom: 24px; } + #price-box .item-selected { + position: relative; + top: -28px; + background: #fafaf4; } + #price-box .price-label { + position: absolute; + top: -12px; + left: 50%; + margin-left: -60px; + background: #ff3366; + color: #fff; + font-size: 11px; + text-transform: uppercase; + padding: 0 8px; } + #price-box .price-name { + font-size: 12px; + text-transform: uppercase; + line-height: 24px; + font-weight: 900; } + #price-box .price-amount { + margin: 20px 0 32px 0; + font-size: 34px; } + #price-box ul { + margin-left: 0; + list-style: none; + line-height: 36px; } + #price-box li { + font-size: 14px; + border-bottom: 1px solid rgba(0, 0, 0, 0.07); } + #price-box li:last-child { + border-bottom-color: transparent; } + #price-box footer { + margin-top: 32px; } + #price-box button.stripe-button-el { + height: auto; + min-height: 0; } + +#price-secure-box { + text-align: center; + color: rgba(0, 0, 0, 0.6); } + #price-secure-box .extra { + margin-top: 36px; + font-size: 14px; + line-height: 22px; } + +.not-found { + padding: 40px 0; + text-align: center; + font-style: italic; + color: rgba(0, 0, 0, 0.5); } + +.callout { + background: #f8f8f8; + padding: 40px 48px; } + +.callout-form { + margin-bottom: 40px; } + +.color-black { + color: #000; } + +tr.border-none td { + border: none; } + +#purchases-table td { + padding-top: 24px; + padding-bottom: 24px; } + +#purchases-table tr:first-child td { + padding-top: 16px; } + +#purchases-table tr:last-child td { + border-bottom: none; } + +.purchase-table-license { + margin-top: -16px; + margin-bottom: 8px; } + +.purchase-table-version { + display: block; + margin-top: 8px; + margin-bottom: 8px; + line-height: 16px; + font-size: 11px; } + +#invoice-form, +#invoice-form-old { + margin-bottom: 24px; + padding: 40px; + border: 2px solid #eee; } + +footer { + display: flex; + border-top: 1px solid #eee; + margin-top: 40px; + padding: 0 28px; + padding-top: 24px; + font-size: 13px; + background-color: #5f259f; + color: rgba(255, 255, 255, 0.5); } + footer p { + order: 1; } + footer nav { + order: 2; + margin-left: auto; } + footer nav ul { + display: flex; } + footer nav ul li { + margin-left: 20px; } + footer nav ul li span { + color: rgba(0, 0, 0, 0.3); } + footer nav ul li a { + color: rgba(0, 0, 0, 0.65); + text-decoration: none; } + footer nav ul li a:hover { + color: #000; + text-decoration: underline; } + +@media (max-width: 768px) { + #top { + display: block; + height: auto; + padding-bottom: 24px; } + #top ul { + display: block; } + #top #top-brand { + display: none; } + #top #top-nav-main { + padding: 0; + border: none; } + #top #top-nav-extra { + margin: 0; } + #top #top-nav-main li, + #top #top-nav-extra li { + text-align: center; + width: auto; + margin: 16px 0; + padding: 0; } + #subnav li, + #subnav ul li { + text-align: center; + border: none; + display: block; + margin: 16px 0; } + #hero { + margin-top: 32px; + padding-top: 0; + padding-left: 20px; + padding-right: 20px; } + #hero h1 { + font-size: 40px; + line-height: 48px; } + #hero p { + font-size: 16px; + line-height: 24px; } + #posts, + #post-box, + #main { + padding-left: 20px; + padding-right: 20px; } + #action-buttons .button, + #action-buttons button { + margin: 8px 0; } + footer { + display: block; + text-align: center; } + footer nav ul { + display: block; + margin-bottom: 40px; } + footer nav ul li { + margin: 8px 0; } + #grafs-features ul { + margin-bottom: 24px; } + #grafs-features ul.br { + border: none; } + #grafs-features ul.br li, + #grafs-features ul li { + text-align: center; } + .grafs-call-to-action p { + font-size: 20px; + line-height: 32px; } + #docs-main { + display: block; } + #docs-main #side, + #docs-main #area { + width: 100%; + padding: 20px 0; + border: none; } + .grafs-examples-row { + flex-direction: column; } + .grafs-examples-col { + width: 100%; + margin: 0; + margin-bottom: 20px; } + #price-box .item-selected { + margin-top: 24px; + top: 0; } } diff --git a/themes/coredns/static/font/Lato-Black.woff b/themes/coredns/static/font/Lato-Black.woff new file mode 100644 index 0000000..a0ab25e Binary files /dev/null and b/themes/coredns/static/font/Lato-Black.woff differ diff --git a/themes/coredns/static/font/Lato-Bold.woff b/themes/coredns/static/font/Lato-Bold.woff new file mode 100644 index 0000000..f6d8ebf Binary files /dev/null and b/themes/coredns/static/font/Lato-Bold.woff differ diff --git a/themes/coredns/static/font/Lato-BoldItalic.woff b/themes/coredns/static/font/Lato-BoldItalic.woff new file mode 100644 index 0000000..75077eb Binary files /dev/null and b/themes/coredns/static/font/Lato-BoldItalic.woff differ diff --git a/themes/coredns/static/font/Lato-Italic.woff b/themes/coredns/static/font/Lato-Italic.woff new file mode 100644 index 0000000..33d6186 Binary files /dev/null and b/themes/coredns/static/font/Lato-Italic.woff differ diff --git a/themes/coredns/static/font/Lato-Regular.woff b/themes/coredns/static/font/Lato-Regular.woff new file mode 100644 index 0000000..52074ee Binary files /dev/null and b/themes/coredns/static/font/Lato-Regular.woff differ diff --git a/themes/coredns/static/font/Lato-Semibold.woff b/themes/coredns/static/font/Lato-Semibold.woff new file mode 100644 index 0000000..f8db4f9 Binary files /dev/null and b/themes/coredns/static/font/Lato-Semibold.woff differ diff --git a/themes/coredns/static/img/common/logo.png b/themes/coredns/static/img/common/logo.png new file mode 100644 index 0000000..519c208 Binary files /dev/null and b/themes/coredns/static/img/common/logo.png differ diff --git a/themes/coredns/static/img/common/logx2.png b/themes/coredns/static/img/common/logx2.png new file mode 100644 index 0000000..174cd3f Binary files /dev/null and b/themes/coredns/static/img/common/logx2.png differ diff --git a/themes/coredns/static/img/favicons/logo-384x384.png b/themes/coredns/static/img/favicons/logo-384x384.png new file mode 100644 index 0000000..08cf70e Binary files /dev/null and b/themes/coredns/static/img/favicons/logo-384x384.png differ diff --git a/themes/coredns/static/img/icon-minimalism.png b/themes/coredns/static/img/icon-minimalism.png new file mode 100644 index 0000000..f0961ab Binary files /dev/null and b/themes/coredns/static/img/icon-minimalism.png differ diff --git a/themes/coredns/static/img/icon-typo.png b/themes/coredns/static/img/icon-typo.png new file mode 100644 index 0000000..083b5b4 Binary files /dev/null and b/themes/coredns/static/img/icon-typo.png differ diff --git a/themes/coredns/static/img/kube/brand.png b/themes/coredns/static/img/kube/brand.png new file mode 100644 index 0000000..15ab15e Binary files /dev/null and b/themes/coredns/static/img/kube/brand.png differ diff --git a/themes/coredns/static/img/kube/icon-baseline.png b/themes/coredns/static/img/kube/icon-baseline.png new file mode 100644 index 0000000..e7de5d9 Binary files /dev/null and b/themes/coredns/static/img/kube/icon-baseline.png differ diff --git a/themes/coredns/static/img/kube/icon-minimalism.png b/themes/coredns/static/img/kube/icon-minimalism.png new file mode 100644 index 0000000..f0961ab Binary files /dev/null and b/themes/coredns/static/img/kube/icon-minimalism.png differ diff --git a/themes/coredns/static/img/kube/icon-typo.png b/themes/coredns/static/img/kube/icon-typo.png new file mode 100644 index 0000000..083b5b4 Binary files /dev/null and b/themes/coredns/static/img/kube/icon-typo.png differ diff --git a/themes/coredns/static/img/kube/typography/01.png b/themes/coredns/static/img/kube/typography/01.png new file mode 100644 index 0000000..3d06a7b Binary files /dev/null and b/themes/coredns/static/img/kube/typography/01.png differ diff --git a/themes/coredns/static/img/kube/typography/02.png b/themes/coredns/static/img/kube/typography/02.png new file mode 100644 index 0000000..8077f2b Binary files /dev/null and b/themes/coredns/static/img/kube/typography/02.png differ diff --git a/themes/coredns/static/js/jquery-2.1.4.min.js b/themes/coredns/static/js/jquery-2.1.4.min.js new file mode 100644 index 0000000..6f43554 --- /dev/null +++ b/themes/coredns/static/js/jquery-2.1.4.min.js @@ -0,0 +1,5 @@ +/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ +return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*\s*$/g,ia={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("