pax_global_header00006660000000000000000000000064136363735130014524gustar00rootroot0000000000000052 comment=157669a0e60a9d3487eea857d0bc77ca03885f77 hugo-0.68.3/000077500000000000000000000000001363637351300125645ustar00rootroot00000000000000hugo-0.68.3/.circleci/000077500000000000000000000000001363637351300144175ustar00rootroot00000000000000hugo-0.68.3/.circleci/config.yml000066400000000000000000000023321363637351300164070ustar00rootroot00000000000000defaults: &defaults docker: - image: bepsays/ci-goreleaser:1.14.1-t environment: CGO_ENABLED: "0" version: 2 jobs: build: <<: *defaults steps: - checkout: path: hugo - run: command: | git clone git@github.com:gohugoio/hugoDocs.git cd hugo go mod download sleep 5 go mod verify go test -p 1 ./... - persist_to_workspace: root: . paths: . release: <<: *defaults steps: - attach_workspace: at: /root/project - run: command: | cd hugo git config --global user.email "bjorn.erik.pedersen+hugoreleaser@gmail.com" git config --global user.name "hugoreleaser" go run -tags release main.go release -r ${CIRCLE_BRANCH} workflows: version: 2 release: jobs: - build: filters: branches: only: /release-.*/ - hold: type: approval requires: - build - release: context: org-global requires: - hold hugo-0.68.3/.dockerignore000066400000000000000000000001011363637351300152300ustar00rootroot00000000000000*.md *.log *.txt .git .github .circleci docs examples Dockerfile hugo-0.68.3/.gitattributes000066400000000000000000000002401363637351300154530ustar00rootroot00000000000000# Text files have auto line endings * text=auto # Go source files always have LF line endings *.go text eol=lf # SVG files should not be modified *.svg -text hugo-0.68.3/.github/000077500000000000000000000000001363637351300141245ustar00rootroot00000000000000hugo-0.68.3/.github/ISSUE_TEMPLATE/000077500000000000000000000000001363637351300163075ustar00rootroot00000000000000hugo-0.68.3/.github/ISSUE_TEMPLATE/bug_report.md000066400000000000000000000004771363637351300210110ustar00rootroot00000000000000--- name: 'Bug report' labels: '' assignees: '' about: Create a report to help us improve --- ### What version of Hugo are you using (`hugo version`)?
$ hugo version

### Does this issue reproduce with the latest release? hugo-0.68.3/.github/ISSUE_TEMPLATE/feature_request.md000066400000000000000000000001431363637351300220320ustar00rootroot00000000000000--- name: Proposal about: Suggest an idea for Hugo title: '' labels: 'Proposal' assignees: '' --- hugo-0.68.3/.github/ISSUE_TEMPLATE/support.md000066400000000000000000000005031363637351300203430ustar00rootroot00000000000000--- name: Support (Do not use) about: Please do not use Github for support requests. Visit https://discourse.gohugo.io for support title: '' labels: support assignees: '' --- Issues created with this template will be automatically closed. Please visit https://discourse.gohugo.io for the support you really, really, want!hugo-0.68.3/.github/SUPPORT.md000066400000000000000000000003121363637351300156160ustar00rootroot00000000000000### Asking Support Questions We have an active [discussion forum](https://discourse.gohugo.io) where users and developers can ask questions. Please don't use the GitHub issue tracker to ask questions. hugo-0.68.3/.github/stale.yml000066400000000000000000000021271363637351300157610ustar00rootroot00000000000000# Number of days of inactivity before an issue becomes stale daysUntilStale: 120 # Number of days of inactivity before a stale issue is closed daysUntilClose: 30 # Issues with these labels will never be considered stale exemptLabels: - Keep - Security # Label to use when marking an issue as stale staleLabel: Stale # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > This issue has been automatically marked as stale because it has not had recent activity. The resources of the Hugo team are limited, and so we are asking for your help. If this is a **bug** and you can still reproduce this error on the master branch, please reply with all of the information you have about it in order to keep the issue open. If this is a **feature request**, and you feel that it is still relevant and valuable, please tell us why. This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions. # Comment to post when closing a stale issue. Set to `false` to disable closeComment: false hugo-0.68.3/.github/workflows/000077500000000000000000000000001363637351300161615ustar00rootroot00000000000000hugo-0.68.3/.github/workflows/auto_close_support.yml000066400000000000000000000005211363637351300226330ustar00rootroot00000000000000on: schedule: - cron: 0 5 * * 3 name: Weekly Issue Closure jobs: cycle-weekly-close: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - name: weekly-issue-closure uses: bdougie/close-issues-based-on-label@master env: LABEL: support GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}hugo-0.68.3/.gitignore000066400000000000000000000002751363637351300145600ustar00rootroot00000000000000/hugo docs/public* /.idea hugo.exe *.test *.prof nohup.out cover.out *.swp *.swo .DS_Store *~ vendor/*/ *.bench *.debug coverage*.out dock.sh GoBuilds dist resources/sunset.jpg vendor hugo-0.68.3/.gitmodules000066400000000000000000000000001363637351300147270ustar00rootroot00000000000000hugo-0.68.3/.mailmap000066400000000000000000000002421363637351300142030ustar00rootroot00000000000000spf13 Steve Francia bep Bjørn Erik Pedersen hugo-0.68.3/.travis.yml000066400000000000000000000025311363637351300146760ustar00rootroot00000000000000language: go dist: bionic env: global: - CACHE_NAME=${TRAVIS_ARCH} - GO111MODULE=on - GOPROXY=https://proxy.golang.org - HUGO_BUILD_TAGS=extended git: depth: false go: - "1.13.9" - "1.14.1" - master arch: - amd64 - arm64 os: - linux - osx - windows jobs: allow_failures: - go: master - arch: arm64 fast_finish: true exclude: - os: windows go: master - arch: arm64 os: osx - arch: arm64 os: windows cache: directories: - $HOME/gopath/pkg/mod - $HOME/.cache/go-build - $HOME/Library/Caches/go-build - $HOME/AppData/Local/go-build before_install: - df -h # https://travis-ci.community/t/go-cant-find-gcc-with-go1-11-1-on-windows/293/5 - if [ "$TRAVIS_OS_NAME" = "windows" ]; then choco install mingw -y; export PATH=/c/tools/mingw64/bin:"$PATH"; fi - gem install asciidoctor - type asciidoctor install: - mkdir -p $HOME/src - mv $TRAVIS_BUILD_DIR $HOME/src - export TRAVIS_BUILD_DIR=$HOME/src/hugo - cd $HOME/src/hugo - go get github.com/magefile/mage script: - go mod download - go mod verify - mage -v test - if [ "$TRAVIS_ARCH" = "amd64" ]; then mage -v check; else HUGO_TIMEOUT=30000 mage -v check; fi - mage -v hugo - ./hugo -s docs/ - ./hugo --renderToMemory -s docs/ - df -h hugo-0.68.3/CONTRIBUTING.md000066400000000000000000000203731363637351300150220ustar00rootroot00000000000000# Contributing to Hugo We welcome contributions to Hugo of any kind including documentation, themes, organization, tutorials, blog posts, bug reports, issues, feature requests, feature implementations, pull requests, answering questions on the forum, helping to manage issues, etc. The Hugo community and maintainers are [very active](https://github.com/gohugoio/hugo/pulse/monthly) and helpful, and the project benefits greatly from this activity. We created a [step by step guide](https://gohugo.io/tutorials/how-to-contribute-to-hugo/) if you're unfamiliar with GitHub or contributing to open source projects in general. *Note that this repository only contains the actual source code of Hugo. For **only** documentation-related pull requests / issues please refer to the [hugoDocs](https://github.com/gohugoio/hugoDocs) repository.* *Changes to the codebase **and** related documentation, e.g. for a new feature, should still use a single pull request.* ## Table of Contents * [Asking Support Questions](#asking-support-questions) * [Reporting Issues](#reporting-issues) * [Submitting Patches](#submitting-patches) * [Code Contribution Guidelines](#code-contribution-guidelines) * [Git Commit Message Guidelines](#git-commit-message-guidelines) * [Fetching the Sources From GitHub](#fetching-the-sources-from-github) * [Building Hugo with Your Changes](#building-hugo-with-your-changes) ## Asking Support Questions We have an active [discussion forum](https://discourse.gohugo.io) where users and developers can ask questions. Please don't use the GitHub issue tracker to ask questions. ## Reporting Issues If you believe you have found a defect in Hugo or its documentation, use the GitHub issue tracker to report the problem to the Hugo maintainers. If you're not sure if it's a bug or not, start by asking in the [discussion forum](https://discourse.gohugo.io). When reporting the issue, please provide the version of Hugo in use (`hugo version`) and your operating system. - [Hugo Issues · gohugoio/hugo](https://github.com/gohugoio/hugo/issues) - [Hugo Documentation Issues · gohugoio/hugoDocs](https://github.com/gohugoio/hugoDocs/issues) - [Hugo Website Theme Issues · gohugoio/hugoThemesSite](https://github.com/gohugoio/hugoThemesSite/issues) ## Code Contribution Hugo has become a fully featured static site generator, so any new functionality must: * be useful to many. * fit naturally into _what Hugo does best._ * strive not to break existing sites. * close or update an open [Hugo issue](https://github.com/gohugoio/hugo/issues) If it is of some complexity, the contributor is expected to maintain and support the new future (answer questions on the forum, fix any bugs etc.). It is recommended to open up a discussion on the [Hugo Forum](https://discourse.gohugo.io/) to get feedback on your idea before you begin. If you are submitting a complex feature, create a small design proposal on the [Hugo issue tracker](https://github.com/gohugoio/hugo/issues) before you start. Note that we do not accept new features that require [CGO](https://github.com/golang/go/wiki/cgo). We have one exception to this rule which is LibSASS. **Bug fixes are, of course, always welcome.** ## Submitting Patches The Hugo project welcomes all contributors and contributions regardless of skill or experience level. If you are interested in helping with the project, we will help you with your contribution. ### Code Contribution Guidelines Because we want to create the best possible product for our users and the best contribution experience for our developers, we have a set of guidelines which ensure that all contributions are acceptable. The guidelines are not intended as a filter or barrier to participation. If you are unfamiliar with the contribution process, the Hugo team will help you and teach you how to bring your contribution in accordance with the guidelines. To make the contribution process as seamless as possible, we ask for the following: * Go ahead and fork the project and make your changes. We encourage pull requests to allow for review and discussion of code changes. * When you’re ready to create a pull request, be sure to: * Sign the [CLA](https://cla-assistant.io/gohugoio/hugo). * Have test cases for the new code. If you have questions about how to do this, please ask in your pull request. * Run `go fmt`. * Add documentation if you are adding new features or changing functionality. The docs site lives in `/docs`. * Squash your commits into a single commit. `git rebase -i`. It’s okay to force update your pull request with `git push -f`. * Ensure that `mage check` succeeds. [Travis CI](https://travis-ci.org/gohugoio/hugo) (Windows, Linux and macOS) will fail the build if `mage check` fails. * Follow the **Git Commit Message Guidelines** below. ### Git Commit Message Guidelines This [blog article](http://chris.beams.io/posts/git-commit/) is a good resource for learning how to write good commit messages, the most important part being that each commit message should have a title/subject in imperative mood starting with a capital letter and no trailing period: *"Return error on wrong use of the Paginator"*, **NOT** *"returning some error."* Also, if your commit references one or more GitHub issues, always end your commit message body with *See #1234* or *Fixes #1234*. Replace *1234* with the GitHub issue ID. The last example will close the issue when the commit is merged into *master*. Sometimes it makes sense to prefix the commit message with the package name (or docs folder) all lowercased ending with a colon. That is fine, but the rest of the rules above apply. So it is "tpl: Add emojify template func", not "tpl: add emojify template func.", and "docs: Document emoji", not "doc: document emoji." Please use a short and descriptive branch name, e.g. **NOT** "patch-1". It's very common but creates a naming conflict each time when a submission is pulled for a review. An example: ```text tpl: Add custom index function Add a custom index template function that deviates from the stdlib simply by not returning an "index out of range" error if an array, slice or string index is out of range. Instead, we just return nil values. This should help make the new default function more useful for Hugo users. Fixes #1949 ``` ### Fetching the Sources From GitHub Since Hugo 0.48, Hugo uses the Go Modules support built into Go 1.11 to build. The easiest is to clone Hugo in a directory outside of `GOPATH`, as in the following example: ```bash mkdir $HOME/src cd $HOME/src git clone https://github.com/gohugoio/hugo.git cd hugo go install ``` >Note: Some Go tools may not be fully updated to support Go Modules yet. One example would be LiteIDE. Follow [this workaround](https://github.com/visualfc/liteide/issues/986#issuecomment-428117702) for how to continue to work with Hugo below `GOPATH`. For some convenient build and test targets, you also will want to install Mage: ```bash go get github.com/magefile/mage ``` Now, to make a change to Hugo's source: 1. Create a new branch for your changes (the branch name is arbitrary): ```bash git checkout -b iss1234 ``` 1. After making your changes, commit them to your new branch: ```bash git commit -a -v ``` 1. Fork Hugo in GitHub. 1. Add your fork as a new remote (the remote name, "fork" in this example, is arbitrary): ```bash git remote add fork git://github.com/USERNAME/hugo.git ``` 1. Push the changes to your new remote: ```bash git push --set-upstream fork iss1234 ``` 1. You're now ready to submit a PR based upon the new branch in your forked repository. ### Building Hugo with Your Changes Hugo uses [mage](https://github.com/magefile/mage) to sync vendor dependencies, build Hugo, run the test suite and other things. You must run mage from the Hugo directory. ```bash cd $HOME/go/src/github.com/gohugoio/hugo ``` To build Hugo: ```bash mage hugo ``` To install hugo in `$HOME/go/bin`: ```bash mage install ``` To run the tests: ```bash mage hugoRace mage -v check ``` To list all available commands along with descriptions: ```bash mage -l ``` **Note:** From Hugo 0.43 we have added a build tag, `extended` that adds **SCSS support**. This needs a C compiler installed to build. You can enable this when building by: ```bash HUGO_BUILD_TAGS=extended mage install ```` hugo-0.68.3/Dockerfile000077500000000000000000000020601363637351300145570ustar00rootroot00000000000000# GitHub: https://github.com/gohugoio # Twitter: https://twitter.com/gohugoio # Website: https://gohugo.io/ FROM golang:1.13-alpine AS build # Optionally set HUGO_BUILD_TAGS to "extended" when building like so: # docker build --build-arg HUGO_BUILD_TAGS=extended . ARG HUGO_BUILD_TAGS ARG CGO=1 ENV CGO_ENABLED=${CGO} ENV GOOS=linux ENV GO111MODULE=on WORKDIR /go/src/github.com/gohugoio/hugo COPY . /go/src/github.com/gohugoio/hugo/ # gcc/g++ are required to build SASS libraries for extended version RUN apk update && \ apk add --no-cache gcc g++ musl-dev && \ go get github.com/magefile/mage RUN mage hugo && mage install # --- FROM alpine:3.11 COPY --from=build /go/bin/hugo /usr/bin/hugo # libc6-compat & libstdc++ are required for extended SASS libraries # ca-certificates are required to fetch outside resources (like Twitter oEmbeds) RUN apk update && \ apk add --no-cache ca-certificates libc6-compat libstdc++ git VOLUME /site WORKDIR /site # Expose port for live server EXPOSE 1313 ENTRYPOINT ["hugo"] CMD ["--help"] hugo-0.68.3/LICENSE000066400000000000000000000261351363637351300136000ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. hugo-0.68.3/README.md000066400000000000000000000273741363637351300140600ustar00rootroot00000000000000Hugo A Fast and Flexible Static Site Generator built with love by [bep](https://github.com/bep), [spf13](http://spf13.com/) and [friends](https://github.com/gohugoio/hugo/graphs/contributors) in [Go][]. [Website](https://gohugo.io) | [Forum](https://discourse.gohugo.io) | [Documentation](https://gohugo.io/getting-started/) | [Installation Guide](https://gohugo.io/getting-started/installing/) | [Contribution Guide](CONTRIBUTING.md) | [Twitter](https://twitter.com/gohugoio) [![GoDoc](https://godoc.org/github.com/gohugoio/hugo?status.svg)](https://godoc.org/github.com/gohugoio/hugo) [![Linux and macOS Build Status](https://api.travis-ci.org/gohugoio/hugo.svg?branch=master&label=Windows+and+Linux+and+macOS+build "Windows, Linux and macOS Build Status")](https://travis-ci.org/gohugoio/hugo) [![Go Report Card](https://goreportcard.com/badge/github.com/gohugoio/hugo)](https://goreportcard.com/report/github.com/gohugoio/hugo) ## Overview Hugo is a static HTML and CSS website generator written in [Go][]. It is optimized for speed, ease of use, and configurability. Hugo takes a directory with content and templates and renders them into a full HTML website. Hugo relies on Markdown files with front matter for metadata, and you can run Hugo from any directory. This works well for shared hosts and other systems where you don’t have a privileged account. Hugo renders a typical website of moderate size in a fraction of a second. A good rule of thumb is that each piece of content renders in around 1 millisecond. Hugo is designed to work well for any kind of website including blogs, tumbles, and docs. #### Supported Architectures Currently, we provide pre-built Hugo binaries for Windows, Linux, FreeBSD, NetBSD, DragonFly BSD, Open BSD, macOS (Darwin), and [Android](https://gist.github.com/bep/a0d8a26cf6b4f8bc992729b8e50b480b) for x64, i386 and ARM architectures. Hugo may also be compiled from source wherever the Go compiler tool chain can run, e.g. for other operating systems including Plan 9 and Solaris. **Complete documentation is available at [Hugo Documentation](https://gohugo.io/getting-started/).** ## Choose How to Install If you want to use Hugo as your site generator, simply install the Hugo binaries. The Hugo binaries have no external dependencies. To contribute to the Hugo source code or documentation, you should [fork the Hugo GitHub project](https://github.com/gohugoio/hugo#fork-destination-box) and clone it to your local machine. Finally, you can install the Hugo source code with `go`, build the binaries yourself, and run Hugo that way. Building the binaries is an easy task for an experienced `go` getter. ### Install Hugo as Your Site Generator (Binary Install) Use the [installation instructions in the Hugo documentation](https://gohugo.io/getting-started/installing/). ### Build and Install the Binaries from Source (Advanced Install) #### Prerequisite Tools * [Git](https://git-scm.com/) * [Go (we test it with the last 2 major versions)](https://golang.org/dl/) #### Fetch from GitHub Since Hugo 0.48, Hugo uses the Go Modules support built into Go 1.11 to build. The easiest is to clone Hugo in a directory outside of `GOPATH`, as in the following example: ```bash mkdir $HOME/src cd $HOME/src git clone https://github.com/gohugoio/hugo.git cd hugo go install ``` **If you are a Windows user, substitute the `$HOME` environment variable above with `%USERPROFILE%`.** ## The Hugo Documentation The Hugo documentation now lives in its own repository, see https://github.com/gohugoio/hugoDocs. But we do keep a version of that documentation as a `git subtree` in this repository. To build the sub folder `/docs` as a Hugo site, you need to clone this repo: ```bash git clone git@github.com:gohugoio/hugo.git ``` ## Contributing to Hugo For a complete guide to contributing to Hugo, see the [Contribution Guide](CONTRIBUTING.md). We welcome contributions to Hugo of any kind including documentation, themes, organization, tutorials, blog posts, bug reports, issues, feature requests, feature implementations, pull requests, answering questions on the forum, helping to manage issues, etc. The Hugo community and maintainers are [very active](https://github.com/gohugoio/hugo/pulse/monthly) and helpful, and the project benefits greatly from this activity. ### Asking Support Questions We have an active [discussion forum](https://discourse.gohugo.io) where users and developers can ask questions. Please don't use the GitHub issue tracker to ask questions. ### Reporting Issues If you believe you have found a defect in Hugo or its documentation, use the GitHub issue tracker to report the problem to the Hugo maintainers. If you're not sure if it's a bug or not, start by asking in the [discussion forum](https://discourse.gohugo.io). When reporting the issue, please provide the version of Hugo in use (`hugo version`). ### Submitting Patches The Hugo project welcomes all contributors and contributions regardless of skill or experience level. If you are interested in helping with the project, we will help you with your contribution. Hugo is a very active project with many contributions happening daily. We want to create the best possible product for our users and the best contribution experience for our developers, we have a set of guidelines which ensure that all contributions are acceptable. The guidelines are not intended as a filter or barrier to participation. If you are unfamiliar with the contribution process, the Hugo team will help you and teach you how to bring your contribution in accordance with the guidelines. For a complete guide to contributing code to Hugo, see the [Contribution Guide](CONTRIBUTING.md). [![Analytics](https://ga-beacon.appspot.com/UA-7131036-6/hugo/readme)](https://github.com/igrigorik/ga-beacon) [Go]: https://golang.org/ [Hugo Documentation]: https://gohugo.io/overview/introduction/ ## Dependencies Hugo stands on the shoulder of many great open source libraries, in lexical order: | Dependency | License | | :------------- | :------------- | | [github.com/alecthomas/chroma](https://github.com/alecthomas/chroma) | MIT License | | [github.com/armon/go-radix](https://github.com/armon/go-radix) | MIT License | | [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) | Apache License 2.0 | | [github.com/bep/debounce](https://github.com/bep/debounce) | MIT License | | [github.com/bep/gitmap](https://github.com/bep/gitmap) | MIT License | | [github.com/bep/golibsass](https://github.com/bep/golibsass) | MIT License | | [github.com/bep/tmc](https://github.com/bep/tmc) | MIT License | | [github.com/BurntSushi/locker](https://github.com/BurntSushi/locker) | The Unlicense | | [github.com/BurntSushi/toml](https://github.com/BurntSushi/toml) | MIT License | | [github.com/cpuguy83/go-md2man](https://github.com/cpuguy83/go-md2man) | MIT License | | [github.com/danwakefield/fnmatch](https://github.com/danwakefield/fnmatch) | BSD 2-Clause "Simplified" License | | [github.com/disintegration/gift](https://github.com/disintegration/gift) | MIT License | | [github.com/dustin/go-humanize](https://github.com/dustin/go-humanize) | MIT License | | [github.com/fsnotify/fsnotify](https://github.com/fsnotify/fsnotify) | BSD 3-Clause "New" or "Revised" License | | [github.com/gobwas/glob](https://github.com/gobwas/glob) | MIT License | | [github.com/gorilla/websocket](https://github.com/gorilla/websocket) | BSD 2-Clause "Simplified" License | | [github.com/hashicorp/golang-lru](https://github.com/hashicorp/golang-lru) | Mozilla Public License 2.0 | | [github.com/hashicorp/hcl](https://github.com/hashicorp/hcl) | Mozilla Public License 2.0 | | [github.com/jdkato/prose](https://github.com/jdkato/prose) | MIT License | | [github.com/kr/pretty](https://github.com/kr/pretty) | MIT License | | [github.com/kyokomi/emoji](https://github.com/kyokomi/emoji) | MIT License | | [github.com/magiconair/properties](https://github.com/magiconair/properties) | BSD 2-Clause "Simplified" License | | [github.com/markbates/inflect](https://github.com/markbates/inflect) | MIT License | | [github.com/mattn/go-isatty](https://github.com/mattn/go-isatty) | MIT License | | [github.com/mattn/go-runewidth](https://github.com/mattn/go-runewidth) | MIT License | | [github.com/miekg/mmark](https://github.com/miekg/mmark) | Simplified BSD License | | [github.com/mitchellh/hashstructure](https://github.com/mitchellh/hashstructure) | MIT License | | [github.com/mitchellh/mapstructure](https://github.com/mitchellh/mapstructure) | MIT License | | [github.com/muesli/smartcrop](https://github.com/muesli/smartcrop) | MIT License | | [github.com/nicksnyder/go-i18n](https://github.com/nicksnyder/go-i18n) | MIT License | | [github.com/niklasfasching/go-org](https://github.com/niklasfasching/go-org) | MIT License | | [github.com/olekukonko/tablewriter](https://github.com/olekukonko/tablewriter) | MIT License | | [github.com/pelletier/go-toml](https://github.com/pelletier/go-toml) | MIT License | | [github.com/pkg/errors](https://github.com/pkg/errors) | BSD 2-Clause "Simplified" License | | [github.com/PuerkitoBio/purell](https://github.com/PuerkitoBio/purell) | BSD 3-Clause "New" or "Revised" License | | [github.com/PuerkitoBio/urlesc](https://github.com/PuerkitoBio/urlesc) | BSD 3-Clause "New" or "Revised" License | | [github.com/rogpeppe/go-internal](https://github.com/rogpeppe/go-internal) | BSD 3-Clause "New" or "Revised" License | | [github.com/russross/blackfriday](https://github.com/russross/blackfriday) | Simplified BSD License | | [github.com/rwcarlsen/goexif](https://github.com/rwcarlsen/goexif) | BSD 2-Clause "Simplified" License | | [github.com/spf13/afero](https://github.com/spf13/afero) | Apache License 2.0 | | [github.com/spf13/cast](https://github.com/spf13/cast) | MIT License | | [github.com/spf13/cobra](https://github.com/spf13/cobra) | Apache License 2.0 | | [github.com/spf13/fsync](https://github.com/spf13/fsync) | MIT License | | [github.com/spf13/jwalterweatherman](https://github.com/spf13/jwalterweatherman) | MIT License | | [github.com/spf13/pflag](https://github.com/spf13/pflag) | BSD 3-Clause "New" or "Revised" License | | [github.com/spf13/viper](https://github.com/spf13/viper) | MIT License | | [github.com/tdewolff/minify](https://github.com/tdewolff/minify) | MIT License | | [github.com/tdewolff/parse](https://github.com/tdewolff/parse) | MIT License | | [github.com/yuin/goldmark](https://github.com/yuin/goldmark) | MIT License | | [github.com/yuin/goldmark-highlighting](https://github.com/yuin/goldmark-highlighting) | MIT License | | [go.opencensus.io](https://go.opencensus.io) | Apache License 2.0 | | [go.uber.org/atomic](https://go.uber.org/atomic) | MIT License | | [gocloud.dev](https://gocloud.dev) | Apache License 2.0 | | [golang.org/x/image](https://golang.org/x/image) | BSD 3-Clause "New" or "Revised" License | | [golang.org/x/net](https://golang.org/x/net) | BSD 3-Clause "New" or "Revised" License | | [golang.org/x/oauth2](https://golang.org/x/oauth2) | BSD 3-Clause "New" or "Revised" License | | [golang.org/x/sync](https://golang.org/x/sync) | BSD 3-Clause "New" or "Revised" License | | [golang.org/x/sys](https://golang.org/x/sys) | BSD 3-Clause "New" or "Revised" License | | [golang.org/x/text](https://golang.org/x/text) | BSD 3-Clause "New" or "Revised" License | | [golang.org/x/xerrors](https://golang.org/x/xerrors) | BSD 3-Clause "New" or "Revised" License | | [google.golang.org/api](https://google.golang.org/api) | BSD 3-Clause "New" or "Revised" License | | [google.golang.org/genproto](https://google.golang.org/genproto) | Apache License 2.0 | | [gopkg.in/ini.v1](https://gopkg.in/ini.v1) | Apache License 2.0 | | [gopkg.in/yaml.v2](https://gopkg.in/yaml.v2) | Apache License 2.0 | hugo-0.68.3/bench.sh000077500000000000000000000015331363637351300142040ustar00rootroot00000000000000#!/usr/bin/env bash # allow user to override go executable by running as GOEXE=xxx make ... GOEXE="${GOEXE-go}" # Convenience script to # - For a given branch # - Run benchmark tests for a given package # - Do the same for master # - then compare the two runs with benchcmp benchFilter=".*" if (( $# < 2 )); then echo "USAGE: ./bench.sh (and (regexp, optional))" exit 1 fi if [ $# -eq 3 ]; then benchFilter=$3 fi BRANCH=$1 PACKAGE=$2 git checkout $BRANCH "${GOEXE}" test -test.run=NONE -bench="$benchFilter" -test.benchmem=true ./$PACKAGE > /tmp/bench-$PACKAGE-$BRANCH.txt git checkout master "${GOEXE}" test -test.run=NONE -bench="$benchFilter" -test.benchmem=true ./$PACKAGE > /tmp/bench-$PACKAGE-master.txt benchcmp /tmp/bench-$PACKAGE-master.txt /tmp/bench-$PACKAGE-$BRANCH.txt hugo-0.68.3/benchSite.sh000077500000000000000000000010211363637351300150210ustar00rootroot00000000000000#!/bin/bash # allow user to override go executable by running as GOEXE=xxx make ... GOEXE="${GOEXE-go}" # Send in a regexp mathing the benchmarks you want to run, i.e. './benchSite.sh "YAML"'. # Note the quotes, which will be needed for more complex expressions. # The above will run all variations, but only for front matter YAML. echo "Running with BenchmarkSiteBuilding/${1}" "${GOEXE}" test -run="NONE" -bench="BenchmarkSiteBuilding/${1}" -test.benchmem=true ./hugolib -memprofile mem.prof -count 3 -cpuprofile cpu.prof hugo-0.68.3/benchbep.sh000077500000000000000000000001061363637351300146660ustar00rootroot00000000000000gobench -package=./hugolib -bench="BenchmarkSiteNew/Deep_content_tree"hugo-0.68.3/bepdock.sh000077500000000000000000000001651363637351300145340ustar00rootroot00000000000000docker run --rm --mount type=bind,source="$(pwd)",target=/hugo -w /hugo -i -t bepsays/ci-goreleaser:1.11-2 /bin/bashhugo-0.68.3/bufferpool/000077500000000000000000000000001363637351300147275ustar00rootroot00000000000000hugo-0.68.3/bufferpool/bufpool.go000066400000000000000000000021241363637351300167230ustar00rootroot00000000000000// Copyright 2015 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package bufferpool provides a pool of bytes buffers. package bufferpool import ( "bytes" "sync" ) var bufferPool = &sync.Pool{ New: func() interface{} { return &bytes.Buffer{} }, } // GetBuffer returns a buffer from the pool. func GetBuffer() (buf *bytes.Buffer) { return bufferPool.Get().(*bytes.Buffer) } // PutBuffer returns a buffer to the pool. // The buffer is reset before it is put back into circulation. func PutBuffer(buf *bytes.Buffer) { buf.Reset() bufferPool.Put(buf) } hugo-0.68.3/bufferpool/bufpool_test.go000066400000000000000000000016251363637351300177670ustar00rootroot00000000000000// Copyright 2016-present The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bufferpool import ( "testing" qt "github.com/frankban/quicktest" ) func TestBufferPool(t *testing.T) { c := qt.New(t) buff := GetBuffer() buff.WriteString("do be do be do") c.Assert(buff.String(), qt.Equals, "do be do be do") PutBuffer(buff) c.Assert(buff.Len(), qt.Equals, 0) } hugo-0.68.3/cache/000077500000000000000000000000001363637351300136275ustar00rootroot00000000000000hugo-0.68.3/cache/filecache/000077500000000000000000000000001363637351300155325ustar00rootroot00000000000000hugo-0.68.3/cache/filecache/filecache.go000066400000000000000000000201451363637351300177660ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package filecache import ( "bytes" "errors" "io" "io/ioutil" "os" "path/filepath" "strings" "sync" "time" "github.com/gohugoio/hugo/common/hugio" "github.com/gohugoio/hugo/helpers" "github.com/BurntSushi/locker" "github.com/spf13/afero" ) // ErrFatal can be used to signal an unrecoverable error. var ErrFatal = errors.New("fatal filecache error") const ( filecacheRootDirname = "filecache" ) // Cache caches a set of files in a directory. This is usually a file on // disk, but since this is backed by an Afero file system, it can be anything. type Cache struct { Fs afero.Fs // Max age for items in this cache. Negative duration means forever, // 0 is effectively turning this cache off. maxAge time.Duration // When set, we just remove this entire root directory on expiration. pruneAllRootDir string nlocker *lockTracker } type lockTracker struct { seenMu sync.RWMutex seen map[string]struct{} *locker.Locker } // Lock tracks the ids in use. We use this information to do garbage collection // after a Hugo build. func (l *lockTracker) Lock(id string) { l.seenMu.RLock() if _, seen := l.seen[id]; !seen { l.seenMu.RUnlock() l.seenMu.Lock() l.seen[id] = struct{}{} l.seenMu.Unlock() } else { l.seenMu.RUnlock() } l.Locker.Lock(id) } // ItemInfo contains info about a cached file. type ItemInfo struct { // This is the file's name relative to the cache's filesystem. Name string } // NewCache creates a new file cache with the given filesystem and max age. func NewCache(fs afero.Fs, maxAge time.Duration, pruneAllRootDir string) *Cache { return &Cache{ Fs: fs, nlocker: &lockTracker{Locker: locker.NewLocker(), seen: make(map[string]struct{})}, maxAge: maxAge, pruneAllRootDir: pruneAllRootDir, } } // lockedFile is a file with a lock that is released on Close. type lockedFile struct { afero.File unlock func() } func (l *lockedFile) Close() error { defer l.unlock() return l.File.Close() } // WriteCloser returns a transactional writer into the cache. // It's important that it's closed when done. func (c *Cache) WriteCloser(id string) (ItemInfo, io.WriteCloser, error) { id = cleanID(id) c.nlocker.Lock(id) info := ItemInfo{Name: id} f, err := helpers.OpenFileForWriting(c.Fs, id) if err != nil { c.nlocker.Unlock(id) return info, nil, err } return info, &lockedFile{ File: f, unlock: func() { c.nlocker.Unlock(id) }, }, nil } // ReadOrCreate tries to lookup the file in cache. // If found, it is passed to read and then closed. // If not found a new file is created and passed to create, which should close // it when done. func (c *Cache) ReadOrCreate(id string, read func(info ItemInfo, r io.ReadSeeker) error, create func(info ItemInfo, w io.WriteCloser) error) (info ItemInfo, err error) { id = cleanID(id) c.nlocker.Lock(id) defer c.nlocker.Unlock(id) info = ItemInfo{Name: id} if r := c.getOrRemove(id); r != nil { err = read(info, r) defer r.Close() if err == nil || err == ErrFatal { // See https://github.com/gohugoio/hugo/issues/6401 // To recover from file corruption we handle read errors // as the cache item was not found. // Any file permission issue will also fail in the next step. return } } f, err := helpers.OpenFileForWriting(c.Fs, id) if err != nil { return } err = create(info, f) return } // GetOrCreate tries to get the file with the given id from cache. If not found or expired, create will // be invoked and the result cached. // This method is protected by a named lock using the given id as identifier. func (c *Cache) GetOrCreate(id string, create func() (io.ReadCloser, error)) (ItemInfo, io.ReadCloser, error) { id = cleanID(id) c.nlocker.Lock(id) defer c.nlocker.Unlock(id) info := ItemInfo{Name: id} if r := c.getOrRemove(id); r != nil { return info, r, nil } r, err := create() if err != nil { return info, nil, err } if c.maxAge == 0 { // No caching. return info, hugio.ToReadCloser(r), nil } var buff bytes.Buffer return info, hugio.ToReadCloser(&buff), afero.WriteReader(c.Fs, id, io.TeeReader(r, &buff)) } // GetOrCreateBytes is the same as GetOrCreate, but produces a byte slice. func (c *Cache) GetOrCreateBytes(id string, create func() ([]byte, error)) (ItemInfo, []byte, error) { id = cleanID(id) c.nlocker.Lock(id) defer c.nlocker.Unlock(id) info := ItemInfo{Name: id} if r := c.getOrRemove(id); r != nil { defer r.Close() b, err := ioutil.ReadAll(r) return info, b, err } b, err := create() if err != nil { return info, nil, err } if c.maxAge == 0 { return info, b, nil } if err := afero.WriteReader(c.Fs, id, bytes.NewReader(b)); err != nil { return info, nil, err } return info, b, nil } // GetBytes gets the file content with the given id from the cahce, nil if none found. func (c *Cache) GetBytes(id string) (ItemInfo, []byte, error) { id = cleanID(id) c.nlocker.Lock(id) defer c.nlocker.Unlock(id) info := ItemInfo{Name: id} if r := c.getOrRemove(id); r != nil { defer r.Close() b, err := ioutil.ReadAll(r) return info, b, err } return info, nil, nil } // Get gets the file with the given id from the cahce, nil if none found. func (c *Cache) Get(id string) (ItemInfo, io.ReadCloser, error) { id = cleanID(id) c.nlocker.Lock(id) defer c.nlocker.Unlock(id) info := ItemInfo{Name: id} r := c.getOrRemove(id) return info, r, nil } // getOrRemove gets the file with the given id. If it's expired, it will // be removed. func (c *Cache) getOrRemove(id string) hugio.ReadSeekCloser { if c.maxAge == 0 { // No caching. return nil } if c.maxAge > 0 { fi, err := c.Fs.Stat(id) if err != nil { return nil } if c.isExpired(fi.ModTime()) { c.Fs.Remove(id) return nil } } f, err := c.Fs.Open(id) if err != nil { return nil } return f } func (c *Cache) isExpired(modTime time.Time) bool { if c.maxAge < 0 { return false } return c.maxAge == 0 || time.Since(modTime) > c.maxAge } // For testing func (c *Cache) getString(id string) string { id = cleanID(id) c.nlocker.Lock(id) defer c.nlocker.Unlock(id) f, err := c.Fs.Open(id) if err != nil { return "" } defer f.Close() b, _ := ioutil.ReadAll(f) return string(b) } // Caches is a named set of caches. type Caches map[string]*Cache // Get gets a named cache, nil if none found. func (f Caches) Get(name string) *Cache { return f[strings.ToLower(name)] } // NewCaches creates a new set of file caches from the given // configuration. func NewCaches(p *helpers.PathSpec) (Caches, error) { var dcfg Configs if c, ok := p.Cfg.Get("filecacheConfigs").(Configs); ok { dcfg = c } else { var err error dcfg, err = DecodeConfig(p.Fs.Source, p.Cfg) if err != nil { return nil, err } } fs := p.Fs.Source m := make(Caches) for k, v := range dcfg { var cfs afero.Fs if v.isResourceDir { cfs = p.BaseFs.ResourcesCache } else { cfs = fs } if cfs == nil { // TODO(bep) we still have some places that do not initialize the // full dependencies of a site, e.g. the import Jekyll command. // That command does not need these caches, so let us just continue // for now. continue } baseDir := v.Dir if err := cfs.MkdirAll(baseDir, 0777); err != nil && !os.IsExist(err) { return nil, err } bfs := afero.NewBasePathFs(cfs, baseDir) var pruneAllRootDir string if k == cacheKeyModules { pruneAllRootDir = "pkg" } m[k] = NewCache(bfs, v.MaxAge, pruneAllRootDir) } return m, nil } func cleanID(name string) string { return strings.TrimPrefix(filepath.Clean(name), helpers.FilePathSeparator) } hugo-0.68.3/cache/filecache/filecache_config.go000066400000000000000000000131101363637351300213050ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package filecache import ( "path" "path/filepath" "strings" "time" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/helpers" "github.com/mitchellh/mapstructure" "github.com/pkg/errors" "github.com/spf13/afero" ) const ( cachesConfigKey = "caches" resourcesGenDir = ":resourceDir/_gen" ) var defaultCacheConfig = Config{ MaxAge: -1, // Never expire Dir: ":cacheDir/:project", } const ( cacheKeyGetJSON = "getjson" cacheKeyGetCSV = "getcsv" cacheKeyImages = "images" cacheKeyAssets = "assets" cacheKeyModules = "modules" ) type Configs map[string]Config func (c Configs) CacheDirModules() string { return c[cacheKeyModules].Dir } var defaultCacheConfigs = Configs{ cacheKeyModules: { MaxAge: -1, Dir: ":cacheDir/modules", }, cacheKeyGetJSON: defaultCacheConfig, cacheKeyGetCSV: defaultCacheConfig, cacheKeyImages: { MaxAge: -1, Dir: resourcesGenDir, }, cacheKeyAssets: { MaxAge: -1, Dir: resourcesGenDir, }, } type Config struct { // Max age of cache entries in this cache. Any items older than this will // be removed and not returned from the cache. // a negative value means forever, 0 means cache is disabled. MaxAge time.Duration // The directory where files are stored. Dir string // Will resources/_gen will get its own composite filesystem that // also checks any theme. isResourceDir bool } // GetJSONCache gets the file cache for getJSON. func (f Caches) GetJSONCache() *Cache { return f[cacheKeyGetJSON] } // GetCSVCache gets the file cache for getCSV. func (f Caches) GetCSVCache() *Cache { return f[cacheKeyGetCSV] } // ImageCache gets the file cache for processed images. func (f Caches) ImageCache() *Cache { return f[cacheKeyImages] } // ModulesCache gets the file cache for Hugo Modules. func (f Caches) ModulesCache() *Cache { return f[cacheKeyModules] } // AssetsCache gets the file cache for assets (processed resources, SCSS etc.). func (f Caches) AssetsCache() *Cache { return f[cacheKeyAssets] } func DecodeConfig(fs afero.Fs, cfg config.Provider) (Configs, error) { c := make(Configs) valid := make(map[string]bool) // Add defaults for k, v := range defaultCacheConfigs { c[k] = v valid[k] = true } m := cfg.GetStringMap(cachesConfigKey) _, isOsFs := fs.(*afero.OsFs) for k, v := range m { cc := defaultCacheConfig dc := &mapstructure.DecoderConfig{ Result: &cc, DecodeHook: mapstructure.StringToTimeDurationHookFunc(), WeaklyTypedInput: true, } decoder, err := mapstructure.NewDecoder(dc) if err != nil { return c, err } if err := decoder.Decode(v); err != nil { return nil, err } if cc.Dir == "" { return c, errors.New("must provide cache Dir") } name := strings.ToLower(k) if !valid[name] { return nil, errors.Errorf("%q is not a valid cache name", name) } c[name] = cc } // This is a very old flag in Hugo, but we need to respect it. disabled := cfg.GetBool("ignoreCache") for k, v := range c { dir := filepath.ToSlash(filepath.Clean(v.Dir)) hadSlash := strings.HasPrefix(dir, "/") parts := strings.Split(dir, "/") for i, part := range parts { if strings.HasPrefix(part, ":") { resolved, isResource, err := resolveDirPlaceholder(fs, cfg, part) if err != nil { return c, err } if isResource { v.isResourceDir = true } parts[i] = resolved } } dir = path.Join(parts...) if hadSlash { dir = "/" + dir } v.Dir = filepath.Clean(filepath.FromSlash(dir)) if !v.isResourceDir { if isOsFs && !filepath.IsAbs(v.Dir) { return c, errors.Errorf("%q must resolve to an absolute directory", v.Dir) } // Avoid cache in root, e.g. / (Unix) or c:\ (Windows) if len(strings.TrimPrefix(v.Dir, filepath.VolumeName(v.Dir))) == 1 { return c, errors.Errorf("%q is a root folder and not allowed as cache dir", v.Dir) } } if !strings.HasPrefix(v.Dir, "_gen") { // We do cache eviction (file removes) and since the user can set // his/hers own cache directory, we really want to make sure // we do not delete any files that do not belong to this cache. // We do add the cache name as the root, but this is an extra safe // guard. We skip the files inside /resources/_gen/ because // that would be breaking. v.Dir = filepath.Join(v.Dir, filecacheRootDirname, k) } else { v.Dir = filepath.Join(v.Dir, k) } if disabled { v.MaxAge = 0 } c[k] = v } return c, nil } // Resolves :resourceDir => /myproject/resources etc., :cacheDir => ... func resolveDirPlaceholder(fs afero.Fs, cfg config.Provider, placeholder string) (cacheDir string, isResource bool, err error) { workingDir := cfg.GetString("workingDir") switch strings.ToLower(placeholder) { case ":resourcedir": return "", true, nil case ":cachedir": d, err := helpers.GetCacheDir(fs, cfg) return d, false, err case ":project": return filepath.Base(workingDir), false, nil } return "", false, errors.Errorf("%q is not a valid placeholder (valid values are :cacheDir or :resourceDir)", placeholder) } hugo-0.68.3/cache/filecache/filecache_config_test.go000066400000000000000000000103241363637351300223500ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package filecache import ( "path/filepath" "runtime" "strings" "testing" "time" "github.com/spf13/afero" "github.com/gohugoio/hugo/config" qt "github.com/frankban/quicktest" "github.com/spf13/viper" ) func TestDecodeConfig(t *testing.T) { t.Parallel() c := qt.New(t) configStr := ` resourceDir = "myresources" contentDir = "content" dataDir = "data" i18nDir = "i18n" layoutDir = "layouts" assetDir = "assets" archetypeDir = "archetypes" [caches] [caches.getJSON] maxAge = "10m" dir = "/path/to/c1" [caches.getCSV] maxAge = "11h" dir = "/path/to/c2" [caches.images] dir = "/path/to/c3" ` cfg, err := config.FromConfigString(configStr, "toml") c.Assert(err, qt.IsNil) fs := afero.NewMemMapFs() decoded, err := DecodeConfig(fs, cfg) c.Assert(err, qt.IsNil) c.Assert(len(decoded), qt.Equals, 5) c2 := decoded["getcsv"] c.Assert(c2.MaxAge.String(), qt.Equals, "11h0m0s") c.Assert(c2.Dir, qt.Equals, filepath.FromSlash("/path/to/c2/filecache/getcsv")) c3 := decoded["images"] c.Assert(c3.MaxAge, qt.Equals, time.Duration(-1)) c.Assert(c3.Dir, qt.Equals, filepath.FromSlash("/path/to/c3/filecache/images")) } func TestDecodeConfigIgnoreCache(t *testing.T) { t.Parallel() c := qt.New(t) configStr := ` resourceDir = "myresources" contentDir = "content" dataDir = "data" i18nDir = "i18n" layoutDir = "layouts" assetDir = "assets" archeTypedir = "archetypes" ignoreCache = true [caches] [caches.getJSON] maxAge = 1234 dir = "/path/to/c1" [caches.getCSV] maxAge = 3456 dir = "/path/to/c2" [caches.images] dir = "/path/to/c3" ` cfg, err := config.FromConfigString(configStr, "toml") c.Assert(err, qt.IsNil) fs := afero.NewMemMapFs() decoded, err := DecodeConfig(fs, cfg) c.Assert(err, qt.IsNil) c.Assert(len(decoded), qt.Equals, 5) for _, v := range decoded { c.Assert(v.MaxAge, qt.Equals, time.Duration(0)) } } func TestDecodeConfigDefault(t *testing.T) { c := qt.New(t) cfg := newTestConfig() if runtime.GOOS == "windows" { cfg.Set("resourceDir", "c:\\cache\\resources") cfg.Set("cacheDir", "c:\\cache\\thecache") } else { cfg.Set("resourceDir", "/cache/resources") cfg.Set("cacheDir", "/cache/thecache") } fs := afero.NewMemMapFs() decoded, err := DecodeConfig(fs, cfg) c.Assert(err, qt.IsNil) c.Assert(len(decoded), qt.Equals, 5) imgConfig := decoded[cacheKeyImages] jsonConfig := decoded[cacheKeyGetJSON] if runtime.GOOS == "windows" { c.Assert(imgConfig.Dir, qt.Equals, filepath.FromSlash("_gen/images")) } else { c.Assert(imgConfig.Dir, qt.Equals, "_gen/images") c.Assert(jsonConfig.Dir, qt.Equals, "/cache/thecache/hugoproject/filecache/getjson") } c.Assert(imgConfig.isResourceDir, qt.Equals, true) c.Assert(jsonConfig.isResourceDir, qt.Equals, false) } func TestDecodeConfigInvalidDir(t *testing.T) { t.Parallel() c := qt.New(t) configStr := ` resourceDir = "myresources" contentDir = "content" dataDir = "data" i18nDir = "i18n" layoutDir = "layouts" assetDir = "assets" archeTypedir = "archetypes" [caches] [caches.getJSON] maxAge = "10m" dir = "/" ` if runtime.GOOS == "windows" { configStr = strings.Replace(configStr, "/", "c:\\\\", 1) } cfg, err := config.FromConfigString(configStr, "toml") c.Assert(err, qt.IsNil) fs := afero.NewMemMapFs() _, err = DecodeConfig(fs, cfg) c.Assert(err, qt.Not(qt.IsNil)) } func newTestConfig() *viper.Viper { cfg := viper.New() cfg.Set("workingDir", filepath.FromSlash("/my/cool/hugoproject")) cfg.Set("contentDir", "content") cfg.Set("dataDir", "data") cfg.Set("resourceDir", "resources") cfg.Set("i18nDir", "i18n") cfg.Set("layoutDir", "layouts") cfg.Set("archetypeDir", "archetypes") cfg.Set("assetDir", "assets") return cfg } hugo-0.68.3/cache/filecache/filecache_pruner.go000066400000000000000000000053101363637351300213560ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package filecache import ( "io" "os" "github.com/gohugoio/hugo/hugofs" "github.com/pkg/errors" "github.com/spf13/afero" ) // Prune removes expired and unused items from this cache. // The last one requires a full build so the cache usage can be tracked. // Note that we operate directly on the filesystem here, so this is not // thread safe. func (c Caches) Prune() (int, error) { counter := 0 for k, cache := range c { count, err := cache.Prune(false) counter += count if err != nil { if os.IsNotExist(err) { continue } return counter, errors.Wrapf(err, "failed to prune cache %q", k) } } return counter, nil } // Prune removes expired and unused items from this cache. // If force is set, everything will be removed not considering expiry time. func (c *Cache) Prune(force bool) (int, error) { if c.pruneAllRootDir != "" { return c.pruneRootDir(force) } counter := 0 err := afero.Walk(c.Fs, "", func(name string, info os.FileInfo, err error) error { if info == nil { return nil } name = cleanID(name) if info.IsDir() { f, err := c.Fs.Open(name) if err != nil { // This cache dir may not exist. return nil } defer f.Close() _, err = f.Readdirnames(1) if err == io.EOF { // Empty dir. err = c.Fs.Remove(name) } if err != nil && !os.IsNotExist(err) { return err } return nil } shouldRemove := force || c.isExpired(info.ModTime()) if !shouldRemove && len(c.nlocker.seen) > 0 { // Remove it if it's not been touched/used in the last build. _, seen := c.nlocker.seen[name] shouldRemove = !seen } if shouldRemove { err := c.Fs.Remove(name) if err == nil { counter++ } if err != nil && !os.IsNotExist(err) { return err } } return nil }) return counter, err } func (c *Cache) pruneRootDir(force bool) (int, error) { info, err := c.Fs.Stat(c.pruneAllRootDir) if err != nil { if os.IsNotExist(err) { return 0, nil } return 0, err } if !force && !c.isExpired(info.ModTime()) { return 0, nil } return hugofs.MakeReadableAndRemoveAllModulePkgDir(c.Fs, c.pruneAllRootDir) } hugo-0.68.3/cache/filecache/filecache_pruner_test.go000066400000000000000000000047331363637351300224250ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package filecache import ( "fmt" "testing" "time" "github.com/spf13/afero" qt "github.com/frankban/quicktest" ) func TestPrune(t *testing.T) { t.Parallel() c := qt.New(t) configStr := ` resourceDir = "myresources" contentDir = "content" dataDir = "data" i18nDir = "i18n" layoutDir = "layouts" assetDir = "assets" archeTypedir = "archetypes" [caches] [caches.getjson] maxAge = "200ms" dir = "/cache/c" [caches.getcsv] maxAge = "200ms" dir = "/cache/d" [caches.assets] maxAge = "200ms" dir = ":resourceDir/_gen" [caches.images] maxAge = "200ms" dir = ":resourceDir/_gen" ` for _, name := range []string{cacheKeyGetCSV, cacheKeyGetJSON, cacheKeyAssets, cacheKeyImages} { msg := qt.Commentf("cache: %s", name) p := newPathsSpec(t, afero.NewMemMapFs(), configStr) caches, err := NewCaches(p) c.Assert(err, qt.IsNil) cache := caches[name] for i := 0; i < 10; i++ { id := fmt.Sprintf("i%d", i) cache.GetOrCreateBytes(id, func() ([]byte, error) { return []byte("abc"), nil }) if i == 4 { // This will expire the first 5 time.Sleep(201 * time.Millisecond) } } count, err := caches.Prune() c.Assert(err, qt.IsNil) c.Assert(count, qt.Equals, 5, msg) for i := 0; i < 10; i++ { id := fmt.Sprintf("i%d", i) v := cache.getString(id) if i < 5 { c.Assert(v, qt.Equals, "") } else { c.Assert(v, qt.Equals, "abc") } } caches, err = NewCaches(p) c.Assert(err, qt.IsNil) cache = caches[name] // Touch one and then prune. cache.GetOrCreateBytes("i5", func() ([]byte, error) { return []byte("abc"), nil }) count, err = caches.Prune() c.Assert(err, qt.IsNil) c.Assert(count, qt.Equals, 4) // Now only the i5 should be left. for i := 0; i < 10; i++ { id := fmt.Sprintf("i%d", i) v := cache.getString(id) if i != 5 { c.Assert(v, qt.Equals, "") } else { c.Assert(v, qt.Equals, "abc") } } } } hugo-0.68.3/cache/filecache/filecache_test.go000066400000000000000000000206771363637351300210370ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package filecache import ( "errors" "fmt" "io" "io/ioutil" "os" "path/filepath" "strings" "sync" "testing" "time" "github.com/gohugoio/hugo/langs" "github.com/gohugoio/hugo/modules" "github.com/gohugoio/hugo/common/hugio" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugofs" "github.com/spf13/afero" qt "github.com/frankban/quicktest" ) func TestFileCache(t *testing.T) { t.Parallel() c := qt.New(t) tempWorkingDir, err := ioutil.TempDir("", "hugo_filecache_test_work") c.Assert(err, qt.IsNil) defer os.Remove(tempWorkingDir) tempCacheDir, err := ioutil.TempDir("", "hugo_filecache_test_cache") c.Assert(err, qt.IsNil) defer os.Remove(tempCacheDir) osfs := afero.NewOsFs() for _, test := range []struct { cacheDir string workingDir string }{ // Run with same dirs twice to make sure that works. {tempCacheDir, tempWorkingDir}, {tempCacheDir, tempWorkingDir}, } { configStr := ` workingDir = "WORKING_DIR" resourceDir = "resources" cacheDir = "CACHEDIR" contentDir = "content" dataDir = "data" i18nDir = "i18n" layoutDir = "layouts" assetDir = "assets" archeTypedir = "archetypes" [caches] [caches.getJSON] maxAge = "10h" dir = ":cacheDir/c" ` winPathSep := "\\\\" replacer := strings.NewReplacer("CACHEDIR", test.cacheDir, "WORKING_DIR", test.workingDir) configStr = replacer.Replace(configStr) configStr = strings.Replace(configStr, "\\", winPathSep, -1) p := newPathsSpec(t, osfs, configStr) caches, err := NewCaches(p) c.Assert(err, qt.IsNil) cache := caches.Get("GetJSON") c.Assert(cache, qt.Not(qt.IsNil)) c.Assert(cache.maxAge.String(), qt.Equals, "10h0m0s") bfs, ok := cache.Fs.(*afero.BasePathFs) c.Assert(ok, qt.Equals, true) filename, err := bfs.RealPath("key") c.Assert(err, qt.IsNil) if test.cacheDir != "" { c.Assert(filename, qt.Equals, filepath.Join(test.cacheDir, "c/"+filecacheRootDirname+"/getjson/key")) } else { // Temp dir. c.Assert(filename, qt.Matches, ".*hugo_cache.*"+filecacheRootDirname+".*key") } cache = caches.Get("Images") c.Assert(cache, qt.Not(qt.IsNil)) c.Assert(cache.maxAge, qt.Equals, time.Duration(-1)) bfs, ok = cache.Fs.(*afero.BasePathFs) c.Assert(ok, qt.Equals, true) filename, _ = bfs.RealPath("key") c.Assert(filename, qt.Equals, filepath.FromSlash("_gen/images/key")) rf := func(s string) func() (io.ReadCloser, error) { return func() (io.ReadCloser, error) { return struct { io.ReadSeeker io.Closer }{ strings.NewReader(s), ioutil.NopCloser(nil), }, nil } } bf := func() ([]byte, error) { return []byte("bcd"), nil } for _, ca := range []*Cache{caches.ImageCache(), caches.AssetsCache(), caches.GetJSONCache(), caches.GetCSVCache()} { for i := 0; i < 2; i++ { info, r, err := ca.GetOrCreate("a", rf("abc")) c.Assert(err, qt.IsNil) c.Assert(r, qt.Not(qt.IsNil)) c.Assert(info.Name, qt.Equals, "a") b, _ := ioutil.ReadAll(r) r.Close() c.Assert(string(b), qt.Equals, "abc") info, b, err = ca.GetOrCreateBytes("b", bf) c.Assert(err, qt.IsNil) c.Assert(r, qt.Not(qt.IsNil)) c.Assert(info.Name, qt.Equals, "b") c.Assert(string(b), qt.Equals, "bcd") _, b, err = ca.GetOrCreateBytes("a", bf) c.Assert(err, qt.IsNil) c.Assert(string(b), qt.Equals, "abc") _, r, err = ca.GetOrCreate("a", rf("bcd")) c.Assert(err, qt.IsNil) b, _ = ioutil.ReadAll(r) r.Close() c.Assert(string(b), qt.Equals, "abc") } } c.Assert(caches.Get("getJSON"), qt.Not(qt.IsNil)) info, w, err := caches.ImageCache().WriteCloser("mykey") c.Assert(err, qt.IsNil) c.Assert(info.Name, qt.Equals, "mykey") io.WriteString(w, "Hugo is great!") w.Close() c.Assert(caches.ImageCache().getString("mykey"), qt.Equals, "Hugo is great!") info, r, err := caches.ImageCache().Get("mykey") c.Assert(err, qt.IsNil) c.Assert(r, qt.Not(qt.IsNil)) c.Assert(info.Name, qt.Equals, "mykey") b, _ := ioutil.ReadAll(r) r.Close() c.Assert(string(b), qt.Equals, "Hugo is great!") info, b, err = caches.ImageCache().GetBytes("mykey") c.Assert(err, qt.IsNil) c.Assert(info.Name, qt.Equals, "mykey") c.Assert(string(b), qt.Equals, "Hugo is great!") } } func TestFileCacheConcurrent(t *testing.T) { t.Parallel() c := qt.New(t) configStr := ` resourceDir = "myresources" contentDir = "content" dataDir = "data" i18nDir = "i18n" layoutDir = "layouts" assetDir = "assets" archeTypedir = "archetypes" [caches] [caches.getjson] maxAge = "1s" dir = "/cache/c" ` p := newPathsSpec(t, afero.NewMemMapFs(), configStr) caches, err := NewCaches(p) c.Assert(err, qt.IsNil) const cacheName = "getjson" filenameData := func(i int) (string, string) { data := fmt.Sprintf("data: %d", i) filename := fmt.Sprintf("file%d", i) return filename, data } var wg sync.WaitGroup for i := 0; i < 50; i++ { wg.Add(1) go func(i int) { defer wg.Done() for j := 0; j < 20; j++ { ca := caches.Get(cacheName) c.Assert(ca, qt.Not(qt.IsNil)) filename, data := filenameData(i) _, r, err := ca.GetOrCreate(filename, func() (io.ReadCloser, error) { return hugio.ToReadCloser(strings.NewReader(data)), nil }) c.Assert(err, qt.IsNil) b, _ := ioutil.ReadAll(r) r.Close() c.Assert(string(b), qt.Equals, data) // Trigger some expiration. time.Sleep(50 * time.Millisecond) } }(i) } wg.Wait() } func TestFileCacheReadOrCreateErrorInRead(t *testing.T) { t.Parallel() c := qt.New(t) var result string rf := func(failLevel int) func(info ItemInfo, r io.ReadSeeker) error { return func(info ItemInfo, r io.ReadSeeker) error { if failLevel > 0 { if failLevel > 1 { return ErrFatal } return errors.New("fail") } b, _ := ioutil.ReadAll(r) result = string(b) return nil } } bf := func(s string) func(info ItemInfo, w io.WriteCloser) error { return func(info ItemInfo, w io.WriteCloser) error { defer w.Close() result = s _, err := w.Write([]byte(s)) return err } } cache := NewCache(afero.NewMemMapFs(), 100*time.Hour, "") const id = "a32" _, err := cache.ReadOrCreate(id, rf(0), bf("v1")) c.Assert(err, qt.IsNil) c.Assert(result, qt.Equals, "v1") _, err = cache.ReadOrCreate(id, rf(0), bf("v2")) c.Assert(err, qt.IsNil) c.Assert(result, qt.Equals, "v1") _, err = cache.ReadOrCreate(id, rf(1), bf("v3")) c.Assert(err, qt.IsNil) c.Assert(result, qt.Equals, "v3") _, err = cache.ReadOrCreate(id, rf(2), bf("v3")) c.Assert(err, qt.Equals, ErrFatal) } func TestCleanID(t *testing.T) { c := qt.New(t) c.Assert(cleanID(filepath.FromSlash("/a/b//c.txt")), qt.Equals, filepath.FromSlash("a/b/c.txt")) c.Assert(cleanID(filepath.FromSlash("a/b//c.txt")), qt.Equals, filepath.FromSlash("a/b/c.txt")) } func initConfig(fs afero.Fs, cfg config.Provider) error { if _, err := langs.LoadLanguageSettings(cfg, nil); err != nil { return err } modConfig, err := modules.DecodeConfig(cfg) if err != nil { return err } workingDir := cfg.GetString("workingDir") themesDir := cfg.GetString("themesDir") if !filepath.IsAbs(themesDir) { themesDir = filepath.Join(workingDir, themesDir) } modulesClient := modules.NewClient(modules.ClientConfig{ Fs: fs, WorkingDir: workingDir, ThemesDir: themesDir, ModuleConfig: modConfig, IgnoreVendor: true, }) moduleConfig, err := modulesClient.Collect() if err != nil { return err } if err := modules.ApplyProjectConfigDefaults(cfg, moduleConfig.ActiveModules[len(moduleConfig.ActiveModules)-1]); err != nil { return err } cfg.Set("allModules", moduleConfig.ActiveModules) return nil } func newPathsSpec(t *testing.T, fs afero.Fs, configStr string) *helpers.PathSpec { c := qt.New(t) cfg, err := config.FromConfigString(configStr, "toml") c.Assert(err, qt.IsNil) initConfig(fs, cfg) p, err := helpers.NewPathSpec(hugofs.NewFrom(fs, cfg), cfg, nil) c.Assert(err, qt.IsNil) return p } hugo-0.68.3/cache/namedmemcache/000077500000000000000000000000001363637351300163765ustar00rootroot00000000000000hugo-0.68.3/cache/namedmemcache/named_cache.go000066400000000000000000000040461363637351300211400ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package namedmemcache provides a memory cache with a named lock. This is suitable // for situations where creating the cached resource can be time consuming or otherwise // resource hungry, or in situations where a "once only per key" is a requirement. package namedmemcache import ( "sync" "github.com/BurntSushi/locker" ) // Cache holds the cached values. type Cache struct { nlocker *locker.Locker cache map[string]cacheEntry mu sync.RWMutex } type cacheEntry struct { value interface{} err error } // New creates a new cache. func New() *Cache { return &Cache{ nlocker: locker.NewLocker(), cache: make(map[string]cacheEntry), } } // Clear clears the cache state. func (c *Cache) Clear() { c.mu.Lock() defer c.mu.Unlock() c.cache = make(map[string]cacheEntry) c.nlocker = locker.NewLocker() } // GetOrCreate tries to get the value with the given cache key, if not found // create will be called and cached. // This method is thread safe. It also guarantees that the create func for a given // key is invoced only once for this cache. func (c *Cache) GetOrCreate(key string, create func() (interface{}, error)) (interface{}, error) { c.mu.RLock() entry, found := c.cache[key] c.mu.RUnlock() if found { return entry.value, entry.err } c.nlocker.Lock(key) defer c.nlocker.Unlock(key) // Create it. value, err := create() c.mu.Lock() c.cache[key] = cacheEntry{value: value, err: err} c.mu.Unlock() return value, err } hugo-0.68.3/cache/namedmemcache/named_cache_test.go000066400000000000000000000033051363637351300221740ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package namedmemcache import ( "fmt" "sync" "testing" qt "github.com/frankban/quicktest" ) func TestNamedCache(t *testing.T) { t.Parallel() c := qt.New(t) cache := New() counter := 0 create := func() (interface{}, error) { counter++ return counter, nil } for i := 0; i < 5; i++ { v1, err := cache.GetOrCreate("a1", create) c.Assert(err, qt.IsNil) c.Assert(v1, qt.Equals, 1) v2, err := cache.GetOrCreate("a2", create) c.Assert(err, qt.IsNil) c.Assert(v2, qt.Equals, 2) } cache.Clear() v3, err := cache.GetOrCreate("a2", create) c.Assert(err, qt.IsNil) c.Assert(v3, qt.Equals, 3) } func TestNamedCacheConcurrent(t *testing.T) { t.Parallel() c := qt.New(t) var wg sync.WaitGroup cache := New() create := func(i int) func() (interface{}, error) { return func() (interface{}, error) { return i, nil } } for i := 0; i < 10; i++ { wg.Add(1) go func() { defer wg.Done() for j := 0; j < 100; j++ { id := fmt.Sprintf("id%d", j) v, err := cache.GetOrCreate(id, create(j)) c.Assert(err, qt.IsNil) c.Assert(v, qt.Equals, j) } }() } wg.Wait() } hugo-0.68.3/cache/partitioned_lazy_cache.go000066400000000000000000000050031363637351300206600ustar00rootroot00000000000000// Copyright 2017-present The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cache import ( "sync" ) // Partition represents a cache partition where Load is the callback // for when the partition is needed. type Partition struct { Key string Load func() (map[string]interface{}, error) } // Lazy represents a lazily loaded cache. type Lazy struct { initSync sync.Once initErr error cache map[string]interface{} load func() (map[string]interface{}, error) } // NewLazy creates a lazy cache with the given load func. func NewLazy(load func() (map[string]interface{}, error)) *Lazy { return &Lazy{load: load} } func (l *Lazy) init() error { l.initSync.Do(func() { c, err := l.load() l.cache = c l.initErr = err }) return l.initErr } // Get initializes the cache if not already initialized, then looks up the // given key. func (l *Lazy) Get(key string) (interface{}, bool, error) { l.init() if l.initErr != nil { return nil, false, l.initErr } v, found := l.cache[key] return v, found, nil } // PartitionedLazyCache is a lazily loaded cache paritioned by a supplied string key. type PartitionedLazyCache struct { partitions map[string]*Lazy } // NewPartitionedLazyCache creates a new NewPartitionedLazyCache with the supplied // partitions. func NewPartitionedLazyCache(partitions ...Partition) *PartitionedLazyCache { lazyPartitions := make(map[string]*Lazy, len(partitions)) for _, partition := range partitions { lazyPartitions[partition.Key] = NewLazy(partition.Load) } cache := &PartitionedLazyCache{partitions: lazyPartitions} return cache } // Get initializes the partition if not already done so, then looks up the given // key in the given partition, returns nil if no value found. func (c *PartitionedLazyCache) Get(partition, key string) (interface{}, error) { p, found := c.partitions[partition] if !found { return nil, nil } v, found, err := p.Get(key) if err != nil { return nil, err } if found { return v, nil } return nil, nil } hugo-0.68.3/cache/partitioned_lazy_cache_test.go000066400000000000000000000054731363637351300217320ustar00rootroot00000000000000// Copyright 2017-present The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package cache import ( "errors" "sync" "testing" qt "github.com/frankban/quicktest" ) func TestNewPartitionedLazyCache(t *testing.T) { t.Parallel() c := qt.New(t) p1 := Partition{ Key: "p1", Load: func() (map[string]interface{}, error) { return map[string]interface{}{ "p1_1": "p1v1", "p1_2": "p1v2", "p1_nil": nil, }, nil }, } p2 := Partition{ Key: "p2", Load: func() (map[string]interface{}, error) { return map[string]interface{}{ "p2_1": "p2v1", "p2_2": "p2v2", "p2_3": "p2v3", }, nil }, } cache := NewPartitionedLazyCache(p1, p2) v, err := cache.Get("p1", "p1_1") c.Assert(err, qt.IsNil) c.Assert(v, qt.Equals, "p1v1") v, err = cache.Get("p1", "p2_1") c.Assert(err, qt.IsNil) c.Assert(v, qt.IsNil) v, err = cache.Get("p1", "p1_nil") c.Assert(err, qt.IsNil) c.Assert(v, qt.IsNil) v, err = cache.Get("p2", "p2_3") c.Assert(err, qt.IsNil) c.Assert(v, qt.Equals, "p2v3") v, err = cache.Get("doesnotexist", "p1_1") c.Assert(err, qt.IsNil) c.Assert(v, qt.IsNil) v, err = cache.Get("p1", "doesnotexist") c.Assert(err, qt.IsNil) c.Assert(v, qt.IsNil) errorP := Partition{ Key: "p3", Load: func() (map[string]interface{}, error) { return nil, errors.New("Failed") }, } cache = NewPartitionedLazyCache(errorP) v, err = cache.Get("p1", "doesnotexist") c.Assert(err, qt.IsNil) c.Assert(v, qt.IsNil) _, err = cache.Get("p3", "doesnotexist") c.Assert(err, qt.Not(qt.IsNil)) } func TestConcurrentPartitionedLazyCache(t *testing.T) { t.Parallel() c := qt.New(t) var wg sync.WaitGroup p1 := Partition{ Key: "p1", Load: func() (map[string]interface{}, error) { return map[string]interface{}{ "p1_1": "p1v1", "p1_2": "p1v2", "p1_nil": nil, }, nil }, } p2 := Partition{ Key: "p2", Load: func() (map[string]interface{}, error) { return map[string]interface{}{ "p2_1": "p2v1", "p2_2": "p2v2", "p2_3": "p2v3", }, nil }, } cache := NewPartitionedLazyCache(p1, p2) for i := 0; i < 100; i++ { wg.Add(1) go func() { defer wg.Done() for j := 0; j < 10; j++ { v, err := cache.Get("p1", "p1_1") c.Assert(err, qt.IsNil) c.Assert(v, qt.Equals, "p1v1") } }() } wg.Wait() } hugo-0.68.3/codegen/000077500000000000000000000000001363637351300141705ustar00rootroot00000000000000hugo-0.68.3/codegen/methods.go000066400000000000000000000303361363637351300161670ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // Some functions in this file (see comments) is based on the Go source code, // copyright The Go Authors and governed by a BSD-style license. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package codegen contains helpers for code generation. package codegen import ( "fmt" "go/ast" "go/parser" "go/token" "os" "path" "path/filepath" "reflect" "regexp" "sort" "strings" "sync" ) // Make room for insertions const weightWidth = 1000 // NewInspector creates a new Inspector given a source root. func NewInspector(root string) *Inspector { return &Inspector{ProjectRootDir: root} } // Inspector provides methods to help code generation. It uses a combination // of reflection and source code AST to do the heavy lifting. type Inspector struct { ProjectRootDir string init sync.Once // Determines method order. Go's reflect sorts lexicographically, so // we must parse the source to preserve this order. methodWeight map[string]map[string]int } // MethodsFromTypes create a method set from the include slice, excluding any // method in exclude. func (c *Inspector) MethodsFromTypes(include []reflect.Type, exclude []reflect.Type) Methods { c.parseSource() var methods Methods var excludes = make(map[string]bool) if len(exclude) > 0 { for _, m := range c.MethodsFromTypes(exclude, nil) { excludes[m.Name] = true } } // There may be overlapping interfaces in types. Do a simple check for now. seen := make(map[string]bool) nameAndPackage := func(t reflect.Type) (string, string) { var name, pkg string isPointer := t.Kind() == reflect.Ptr if isPointer { t = t.Elem() } pkgPrefix := "" if pkgPath := t.PkgPath(); pkgPath != "" { pkgPath = strings.TrimSuffix(pkgPath, "/") _, shortPath := path.Split(pkgPath) pkgPrefix = shortPath + "." pkg = pkgPath } name = t.Name() if name == "" { // interface{} name = t.String() } if isPointer { pkgPrefix = "*" + pkgPrefix } name = pkgPrefix + name return name, pkg } for _, t := range include { for i := 0; i < t.NumMethod(); i++ { m := t.Method(i) if excludes[m.Name] || seen[m.Name] { continue } seen[m.Name] = true if m.PkgPath != "" { // Not exported continue } numIn := m.Type.NumIn() ownerName, _ := nameAndPackage(t) method := Method{Owner: t, OwnerName: ownerName, Name: m.Name} for i := 0; i < numIn; i++ { in := m.Type.In(i) name, pkg := nameAndPackage(in) if pkg != "" { method.Imports = append(method.Imports, pkg) } method.In = append(method.In, name) } numOut := m.Type.NumOut() if numOut > 0 { for i := 0; i < numOut; i++ { out := m.Type.Out(i) name, pkg := nameAndPackage(out) if pkg != "" { method.Imports = append(method.Imports, pkg) } method.Out = append(method.Out, name) } } methods = append(methods, method) } } sort.SliceStable(methods, func(i, j int) bool { mi, mj := methods[i], methods[j] wi := c.methodWeight[mi.OwnerName][mi.Name] wj := c.methodWeight[mj.OwnerName][mj.Name] if wi == wj { return mi.Name < mj.Name } return wi < wj }) return methods } func (c *Inspector) parseSource() { c.init.Do(func() { if !strings.Contains(c.ProjectRootDir, "hugo") { panic("dir must be set to the Hugo root") } c.methodWeight = make(map[string]map[string]int) dirExcludes := regexp.MustCompile("docs|examples") fileExcludes := regexp.MustCompile("autogen") var filenames []string filepath.Walk(c.ProjectRootDir, func(path string, info os.FileInfo, err error) error { if info.IsDir() { if dirExcludes.MatchString(info.Name()) { return filepath.SkipDir } } if !strings.HasSuffix(path, ".go") || fileExcludes.MatchString(path) { return nil } filenames = append(filenames, path) return nil }) for _, filename := range filenames { pkg := c.packageFromPath(filename) fset := token.NewFileSet() node, err := parser.ParseFile(fset, filename, nil, parser.ParseComments) if err != nil { panic(err) } ast.Inspect(node, func(n ast.Node) bool { switch t := n.(type) { case *ast.TypeSpec: if t.Name.IsExported() { switch it := t.Type.(type) { case *ast.InterfaceType: iface := pkg + "." + t.Name.Name methodNames := collectMethodsRecursive(pkg, it.Methods.List) weights := make(map[string]int) weight := weightWidth for _, name := range methodNames { weights[name] = weight weight += weightWidth } c.methodWeight[iface] = weights } } } return true }) } // Complement for _, v1 := range c.methodWeight { for k2, w := range v1 { if v, found := c.methodWeight[k2]; found { for k3, v3 := range v { v1[k3] = (v3 / weightWidth) + w } } } } }) } func (c *Inspector) packageFromPath(p string) string { p = filepath.ToSlash(p) base := path.Base(p) if !strings.Contains(base, ".") { return base } return path.Base(strings.TrimSuffix(p, base)) } // Method holds enough information about it to recreate it. type Method struct { // The interface we extracted this method from. Owner reflect.Type // String version of the above, on the form PACKAGE.NAME, e.g. // page.Page OwnerName string // Method name. Name string // Imports needed to satisfy the method signature. Imports []string // Argument types, including any package prefix, e.g. string, int, interface{}, // net.Url In []string // Return types. Out []string } // Declaration creates a method declaration (without any body) for the given receiver. func (m Method) Declaration(receiver string) string { return fmt.Sprintf("func (%s %s) %s%s %s", receiverShort(receiver), receiver, m.Name, m.inStr(), m.outStr()) } // DeclarationNamed creates a method declaration (without any body) for the given receiver // with named return values. func (m Method) DeclarationNamed(receiver string) string { return fmt.Sprintf("func (%s %s) %s%s %s", receiverShort(receiver), receiver, m.Name, m.inStr(), m.outStrNamed()) } // Delegate creates a delegate call string. func (m Method) Delegate(receiver, delegate string) string { ret := "" if len(m.Out) > 0 { ret = "return " } return fmt.Sprintf("%s%s.%s.%s%s", ret, receiverShort(receiver), delegate, m.Name, m.inOutStr()) } func (m Method) String() string { return m.Name + m.inStr() + " " + m.outStr() + "\n" } func (m Method) inOutStr() string { if len(m.In) == 0 { return "()" } args := make([]string, len(m.In)) for i := 0; i < len(args); i++ { args[i] = fmt.Sprintf("arg%d", i) } return "(" + strings.Join(args, ", ") + ")" } func (m Method) inStr() string { if len(m.In) == 0 { return "()" } args := make([]string, len(m.In)) for i := 0; i < len(args); i++ { args[i] = fmt.Sprintf("arg%d %s", i, m.In[i]) } return "(" + strings.Join(args, ", ") + ")" } func (m Method) outStr() string { if len(m.Out) == 0 { return "" } if len(m.Out) == 1 { return m.Out[0] } return "(" + strings.Join(m.Out, ", ") + ")" } func (m Method) outStrNamed() string { if len(m.Out) == 0 { return "" } outs := make([]string, len(m.Out)) for i := 0; i < len(outs); i++ { outs[i] = fmt.Sprintf("o%d %s", i, m.Out[i]) } return "(" + strings.Join(outs, ", ") + ")" } // Methods represents a list of methods for one or more interfaces. // The order matches the defined order in their source file(s). type Methods []Method // Imports returns a sorted list of package imports needed to satisfy the // signatures of all methods. func (m Methods) Imports() []string { var pkgImports []string for _, method := range m { pkgImports = append(pkgImports, method.Imports...) } if len(pkgImports) > 0 { pkgImports = uniqueNonEmptyStrings(pkgImports) sort.Strings(pkgImports) } return pkgImports } // ToMarshalJSON creates a MarshalJSON method for these methods. Any method name // matchin any of the regexps in excludes will be ignored. func (m Methods) ToMarshalJSON(receiver, pkgPath string, excludes ...string) (string, []string) { var sb strings.Builder r := receiverShort(receiver) what := firstToUpper(trimAsterisk(receiver)) pgkName := path.Base(pkgPath) fmt.Fprintf(&sb, "func Marshal%sToJSON(%s %s) ([]byte, error) {\n", what, r, receiver) var methods Methods var excludeRes = make([]*regexp.Regexp, len(excludes)) for i, exclude := range excludes { excludeRes[i] = regexp.MustCompile(exclude) } for _, method := range m { // Exclude methods with arguments and incompatible return values if len(method.In) > 0 || len(method.Out) == 0 || len(method.Out) > 2 { continue } if len(method.Out) == 2 { if method.Out[1] != "error" { continue } } for _, re := range excludeRes { if re.MatchString(method.Name) { continue } } methods = append(methods, method) } for _, method := range methods { varn := varName(method.Name) if len(method.Out) == 1 { fmt.Fprintf(&sb, "\t%s := %s.%s()\n", varn, r, method.Name) } else { fmt.Fprintf(&sb, "\t%s, err := %s.%s()\n", varn, r, method.Name) fmt.Fprint(&sb, "\tif err != nil {\n\t\treturn nil, err\n\t}\n") } } fmt.Fprint(&sb, "\n\ts := struct {\n") for _, method := range methods { fmt.Fprintf(&sb, "\t\t%s %s\n", method.Name, typeName(method.Out[0], pgkName)) } fmt.Fprint(&sb, "\n\t}{\n") for _, method := range methods { varn := varName(method.Name) fmt.Fprintf(&sb, "\t\t%s: %s,\n", method.Name, varn) } fmt.Fprint(&sb, "\n\t}\n\n") fmt.Fprint(&sb, "\treturn json.Marshal(&s)\n}") pkgImports := append(methods.Imports(), "encoding/json") if pkgPath != "" { // Exclude self for i, pkgImp := range pkgImports { if pkgImp == pkgPath { pkgImports = append(pkgImports[:i], pkgImports[i+1:]...) } } } return sb.String(), pkgImports } func collectMethodsRecursive(pkg string, f []*ast.Field) []string { var methodNames []string for _, m := range f { if m.Names != nil { methodNames = append(methodNames, m.Names[0].Name) continue } if ident, ok := m.Type.(*ast.Ident); ok && ident.Obj != nil { // Embedded interface methodNames = append( methodNames, collectMethodsRecursive( pkg, ident.Obj.Decl.(*ast.TypeSpec).Type.(*ast.InterfaceType).Methods.List)...) } else { // Embedded, but in a different file/package. Return the // package.Name and deal with that later. name := packageName(m.Type) if !strings.Contains(name, ".") { // Assume current package name = pkg + "." + name } methodNames = append(methodNames, name) } } return methodNames } func firstToLower(name string) string { return strings.ToLower(name[:1]) + name[1:] } func firstToUpper(name string) string { return strings.ToUpper(name[:1]) + name[1:] } func packageName(e ast.Expr) string { switch tp := e.(type) { case *ast.Ident: return tp.Name case *ast.SelectorExpr: return fmt.Sprintf("%s.%s", packageName(tp.X), packageName(tp.Sel)) } return "" } func receiverShort(receiver string) string { return strings.ToLower(trimAsterisk(receiver))[:1] } func trimAsterisk(name string) string { return strings.TrimPrefix(name, "*") } func typeName(name, pkg string) string { return strings.TrimPrefix(name, pkg+".") } func uniqueNonEmptyStrings(s []string) []string { var unique []string set := map[string]interface{}{} for _, val := range s { if val == "" { continue } if _, ok := set[val]; !ok { unique = append(unique, val) set[val] = val } } return unique } func varName(name string) string { name = firstToLower(name) // Adjust some reserved keywords, see https://golang.org/ref/spec#Keywords switch name { case "type": name = "typ" case "package": name = "pkg" // Not reserved, but syntax highlighters has it as a keyword. case "len": name = "length" } return name } hugo-0.68.3/codegen/methods2_test.go000066400000000000000000000013221363637351300173010ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package codegen type IEmbed interface { MethodEmbed3(s string) string MethodEmbed1() string MethodEmbed2() } hugo-0.68.3/codegen/methods_test.go000066400000000000000000000050651363637351300172270ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package codegen import ( "fmt" "net" "os" "reflect" "testing" qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/common/herrors" ) func TestMethods(t *testing.T) { var ( zeroIE = reflect.TypeOf((*IEmbed)(nil)).Elem() zeroIEOnly = reflect.TypeOf((*IEOnly)(nil)).Elem() zeroI = reflect.TypeOf((*I)(nil)).Elem() ) dir, _ := os.Getwd() insp := NewInspector(dir) t.Run("MethodsFromTypes", func(t *testing.T) { c := qt.New(t) methods := insp.MethodsFromTypes([]reflect.Type{zeroI}, nil) methodsStr := fmt.Sprint(methods) c.Assert(methodsStr, qt.Contains, "Method1(arg0 herrors.ErrorContext)") c.Assert(methodsStr, qt.Contains, "Method7() interface {}") c.Assert(methodsStr, qt.Contains, "Method0() string\n Method4() string") c.Assert(methodsStr, qt.Contains, "MethodEmbed3(arg0 string) string\n MethodEmbed1() string") c.Assert(methods.Imports(), qt.Contains, "github.com/gohugoio/hugo/common/herrors") }) t.Run("EmbedOnly", func(t *testing.T) { c := qt.New(t) methods := insp.MethodsFromTypes([]reflect.Type{zeroIEOnly}, nil) methodsStr := fmt.Sprint(methods) c.Assert(methodsStr, qt.Contains, "MethodEmbed3(arg0 string) string") }) t.Run("ToMarshalJSON", func(t *testing.T) { c := qt.New(t) m, pkg := insp.MethodsFromTypes( []reflect.Type{zeroI}, []reflect.Type{zeroIE}).ToMarshalJSON("*page", "page") c.Assert(m, qt.Contains, "method6 := p.Method6()") c.Assert(m, qt.Contains, "Method0: method0,") c.Assert(m, qt.Contains, "return json.Marshal(&s)") c.Assert(pkg, qt.Contains, "github.com/gohugoio/hugo/common/herrors") c.Assert(pkg, qt.Contains, "encoding/json") fmt.Println(pkg) }) } type I interface { IEmbed Method0() string Method4() string Method1(myerr herrors.ErrorContext) Method3(myint int, mystring string) Method5() (string, error) Method6() *net.IP Method7() interface{} Method8() herrors.ErrorContext method2() method9() os.FileInfo } type IEOnly interface { IEmbed } hugo-0.68.3/commands/000077500000000000000000000000001363637351300143655ustar00rootroot00000000000000hugo-0.68.3/commands/check.go000066400000000000000000000016221363637351300157720ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build !darwin package commands import ( "github.com/spf13/cobra" ) var _ cmder = (*checkCmd)(nil) type checkCmd struct { *baseCmd } func newCheckCmd() *checkCmd { return &checkCmd{baseCmd: &baseCmd{cmd: &cobra.Command{ Use: "check", Short: "Contains some verification checks", }, }} } hugo-0.68.3/commands/check_darwin.go000066400000000000000000000016721363637351300173430ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "github.com/spf13/cobra" ) var _ cmder = (*checkCmd)(nil) type checkCmd struct { *baseCmd } func newCheckCmd() *checkCmd { cc := &checkCmd{baseCmd: &baseCmd{cmd: &cobra.Command{ Use: "check", Short: "Contains some verification checks", }, }} cc.cmd.AddCommand(newLimitCmd().getCommand()) return cc } hugo-0.68.3/commands/commandeer.go000066400000000000000000000225251363637351300170340ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "bytes" "errors" "sync" hconfig "github.com/gohugoio/hugo/config" "golang.org/x/sync/semaphore" "io/ioutil" "github.com/gohugoio/hugo/common/herrors" "github.com/gohugoio/hugo/common/hugo" jww "github.com/spf13/jwalterweatherman" "os" "path/filepath" "regexp" "time" "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/config" "github.com/spf13/cobra" "github.com/gohugoio/hugo/hugolib" "github.com/spf13/afero" "github.com/bep/debounce" "github.com/gohugoio/hugo/common/types" "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/langs" ) type commandeerHugoState struct { *deps.DepsCfg hugoSites *hugolib.HugoSites fsCreate sync.Once created chan struct{} } type commandeer struct { *commandeerHugoState logger *loggers.Logger serverConfig *config.Server // Currently only set when in "fast render mode". But it seems to // be fast enough that we could maybe just add it for all server modes. changeDetector *fileChangeDetector // We need to reuse this on server rebuilds. destinationFs afero.Fs h *hugoBuilderCommon ftch flagsToConfigHandler visitedURLs *types.EvictingStringQueue cfgInit func(c *commandeer) error // We watch these for changes. configFiles []string // Used in cases where we get flooded with events in server mode. debounce func(f func()) serverPorts []int languagesConfigured bool languages langs.Languages doLiveReload bool fastRenderMode bool showErrorInBrowser bool wasError bool configured bool paused bool fullRebuildSem *semaphore.Weighted // Any error from the last build. buildErr error } func newCommandeerHugoState() *commandeerHugoState { return &commandeerHugoState{ created: make(chan struct{}), } } func (c *commandeerHugoState) hugo() *hugolib.HugoSites { <-c.created return c.hugoSites } func (c *commandeer) errCount() int { return int(c.logger.ErrorCounter.Count()) } func (c *commandeer) getErrorWithContext() interface{} { errCount := c.errCount() if errCount == 0 { return nil } m := make(map[string]interface{}) m["Error"] = errors.New(removeErrorPrefixFromLog(c.logger.Errors())) m["Version"] = hugo.BuildVersionString() fe := herrors.UnwrapErrorWithFileContext(c.buildErr) if fe != nil { m["File"] = fe } if c.h.verbose { var b bytes.Buffer herrors.FprintStackTraceFromErr(&b, c.buildErr) m["StackTrace"] = b.String() } return m } func (c *commandeer) Set(key string, value interface{}) { if c.configured { panic("commandeer cannot be changed") } c.Cfg.Set(key, value) } func (c *commandeer) initFs(fs *hugofs.Fs) error { c.destinationFs = fs.Destination c.DepsCfg.Fs = fs return nil } func newCommandeer(mustHaveConfigFile, running bool, h *hugoBuilderCommon, f flagsToConfigHandler, cfgInit func(c *commandeer) error, subCmdVs ...*cobra.Command) (*commandeer, error) { var rebuildDebouncer func(f func()) if running { // The time value used is tested with mass content replacements in a fairly big Hugo site. // It is better to wait for some seconds in those cases rather than get flooded // with rebuilds. rebuildDebouncer = debounce.New(4 * time.Second) } out := ioutil.Discard if !h.quiet { out = os.Stdout } c := &commandeer{ h: h, ftch: f, commandeerHugoState: newCommandeerHugoState(), cfgInit: cfgInit, visitedURLs: types.NewEvictingStringQueue(10), debounce: rebuildDebouncer, fullRebuildSem: semaphore.NewWeighted(1), // This will be replaced later, but we need something to log to before the configuration is read. logger: loggers.NewLogger(jww.LevelError, jww.LevelError, out, ioutil.Discard, running), } return c, c.loadConfig(mustHaveConfigFile, running) } type fileChangeDetector struct { sync.Mutex current map[string]string prev map[string]string irrelevantRe *regexp.Regexp } func (f *fileChangeDetector) OnFileClose(name, md5sum string) { f.Lock() defer f.Unlock() f.current[name] = md5sum } func (f *fileChangeDetector) changed() []string { if f == nil { return nil } f.Lock() defer f.Unlock() var c []string for k, v := range f.current { vv, found := f.prev[k] if !found || v != vv { c = append(c, k) } } return f.filterIrrelevant(c) } func (f *fileChangeDetector) filterIrrelevant(in []string) []string { var filtered []string for _, v := range in { if !f.irrelevantRe.MatchString(v) { filtered = append(filtered, v) } } return filtered } func (f *fileChangeDetector) PrepareNew() { if f == nil { return } f.Lock() defer f.Unlock() if f.current == nil { f.current = make(map[string]string) f.prev = make(map[string]string) return } f.prev = make(map[string]string) for k, v := range f.current { f.prev[k] = v } f.current = make(map[string]string) } func (c *commandeer) loadConfig(mustHaveConfigFile, running bool) error { if c.DepsCfg == nil { c.DepsCfg = &deps.DepsCfg{} } if c.logger != nil { // Truncate the error log if this is a reload. c.logger.Reset() } cfg := c.DepsCfg c.configured = false cfg.Running = running var dir string if c.h.source != "" { dir, _ = filepath.Abs(c.h.source) } else { dir, _ = os.Getwd() } var sourceFs afero.Fs = hugofs.Os if c.DepsCfg.Fs != nil { sourceFs = c.DepsCfg.Fs.Source } environment := c.h.getEnvironment(running) doWithConfig := func(cfg config.Provider) error { if c.ftch != nil { c.ftch.flagsToConfig(cfg) } cfg.Set("workingDir", dir) cfg.Set("environment", environment) return nil } cfgSetAndInit := func(cfg config.Provider) error { c.Cfg = cfg if c.cfgInit == nil { return nil } err := c.cfgInit(c) return err } configPath := c.h.source if configPath == "" { configPath = dir } config, configFiles, err := hugolib.LoadConfig( hugolib.ConfigSourceDescriptor{ Fs: sourceFs, Logger: c.logger, Path: configPath, WorkingDir: dir, Filename: c.h.cfgFile, AbsConfigDir: c.h.getConfigDir(dir), Environ: os.Environ(), Environment: environment}, cfgSetAndInit, doWithConfig) if err != nil && mustHaveConfigFile { return err } else if mustHaveConfigFile && len(configFiles) == 0 { return hugolib.ErrNoConfigFile } c.configFiles = configFiles if l, ok := c.Cfg.Get("languagesSorted").(langs.Languages); ok { c.languagesConfigured = true c.languages = l } // Set some commonly used flags c.doLiveReload = running && !c.Cfg.GetBool("disableLiveReload") c.fastRenderMode = c.doLiveReload && !c.Cfg.GetBool("disableFastRender") c.showErrorInBrowser = c.doLiveReload && !c.Cfg.GetBool("disableBrowserError") // This is potentially double work, but we need to do this one more time now // that all the languages have been configured. if c.cfgInit != nil { if err := c.cfgInit(c); err != nil { return err } } logger, err := c.createLogger(config, running) if err != nil { return err } cfg.Logger = logger c.logger = logger c.serverConfig = hconfig.DecodeServer(cfg.Cfg) createMemFs := config.GetBool("renderToMemory") if createMemFs { // Rendering to memoryFS, publish to Root regardless of publishDir. config.Set("publishDir", "/") } c.fsCreate.Do(func() { fs := hugofs.NewFrom(sourceFs, config) if c.destinationFs != nil { // Need to reuse the destination on server rebuilds. fs.Destination = c.destinationFs } else if createMemFs { // Hugo writes the output to memory instead of the disk. fs.Destination = new(afero.MemMapFs) } if c.fastRenderMode { // For now, fast render mode only. It should, however, be fast enough // for the full variant, too. changeDetector := &fileChangeDetector{ // We use this detector to decide to do a Hot reload of a single path or not. // We need to filter out source maps and possibly some other to be able // to make that decision. irrelevantRe: regexp.MustCompile(`\.map$`), } changeDetector.PrepareNew() fs.Destination = hugofs.NewHashingFs(fs.Destination, changeDetector) c.changeDetector = changeDetector } if c.Cfg.GetBool("logPathWarnings") { fs.Destination = hugofs.NewCreateCountingFs(fs.Destination) } // To debug hard-to-find path issues. //fs.Destination = hugofs.NewStacktracerFs(fs.Destination, `fr/fr`) err = c.initFs(fs) if err != nil { close(c.created) return } var h *hugolib.HugoSites h, err = hugolib.NewHugoSites(*c.DepsCfg) c.hugoSites = h close(c.created) }) if err != nil { return err } cacheDir, err := helpers.GetCacheDir(sourceFs, config) if err != nil { return err } config.Set("cacheDir", cacheDir) cfg.Logger.INFO.Println("Using config file:", config.ConfigFileUsed()) return nil } hugo-0.68.3/commands/commands.go000066400000000000000000000243571363637351300165300ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "fmt" "os" "time" "github.com/gohugoio/hugo/hugolib/paths" "github.com/gohugoio/hugo/common/hugo" "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/helpers" "github.com/spf13/cobra" ) type commandsBuilder struct { hugoBuilderCommon commands []cmder } func newCommandsBuilder() *commandsBuilder { return &commandsBuilder{} } func (b *commandsBuilder) addCommands(commands ...cmder) *commandsBuilder { b.commands = append(b.commands, commands...) return b } func (b *commandsBuilder) addAll() *commandsBuilder { b.addCommands( b.newServerCmd(), newVersionCmd(), newEnvCmd(), b.newConfigCmd(), newCheckCmd(), b.newDeployCmd(), b.newConvertCmd(), b.newNewCmd(), b.newListCmd(), newImportCmd(), newGenCmd(), createReleaser(), b.newModCmd(), ) return b } func (b *commandsBuilder) build() *hugoCmd { h := b.newHugoCmd() addCommands(h.getCommand(), b.commands...) return h } func addCommands(root *cobra.Command, commands ...cmder) { for _, command := range commands { cmd := command.getCommand() if cmd == nil { continue } root.AddCommand(cmd) } } type baseCmd struct { cmd *cobra.Command } var _ commandsBuilderGetter = (*baseBuilderCmd)(nil) // Used in tests. type commandsBuilderGetter interface { getCommandsBuilder() *commandsBuilder } type baseBuilderCmd struct { *baseCmd *commandsBuilder } func (b *baseBuilderCmd) getCommandsBuilder() *commandsBuilder { return b.commandsBuilder } func (c *baseCmd) getCommand() *cobra.Command { return c.cmd } func newBaseCmd(cmd *cobra.Command) *baseCmd { return &baseCmd{cmd: cmd} } func (b *commandsBuilder) newBuilderCmd(cmd *cobra.Command) *baseBuilderCmd { bcmd := &baseBuilderCmd{commandsBuilder: b, baseCmd: &baseCmd{cmd: cmd}} bcmd.hugoBuilderCommon.handleFlags(cmd) return bcmd } func (b *commandsBuilder) newBuilderBasicCmd(cmd *cobra.Command) *baseBuilderCmd { bcmd := &baseBuilderCmd{commandsBuilder: b, baseCmd: &baseCmd{cmd: cmd}} bcmd.hugoBuilderCommon.handleCommonBuilderFlags(cmd) return bcmd } func (c *baseCmd) flagsToConfig(cfg config.Provider) { initializeFlags(c.cmd, cfg) } type hugoCmd struct { *baseBuilderCmd // Need to get the sites once built. c *commandeer } var _ cmder = (*nilCommand)(nil) type nilCommand struct { } func (c *nilCommand) getCommand() *cobra.Command { return nil } func (c *nilCommand) flagsToConfig(cfg config.Provider) { } func (b *commandsBuilder) newHugoCmd() *hugoCmd { cc := &hugoCmd{} cc.baseBuilderCmd = b.newBuilderCmd(&cobra.Command{ Use: "hugo", Short: "hugo builds your site", Long: `hugo is the main command, used to build your Hugo site. Hugo is a Fast and Flexible Static Site Generator built with love by spf13 and friends in Go. Complete documentation is available at http://gohugo.io/.`, RunE: func(cmd *cobra.Command, args []string) error { defer cc.timeTrack(time.Now(), "Total") cfgInit := func(c *commandeer) error { if cc.buildWatch { c.Set("disableLiveReload", true) } return nil } c, err := initializeConfig(true, cc.buildWatch, &cc.hugoBuilderCommon, cc, cfgInit) if err != nil { return err } cc.c = c return c.build() }, }) cc.cmd.PersistentFlags().StringVar(&cc.cfgFile, "config", "", "config file (default is path/config.yaml|json|toml)") cc.cmd.PersistentFlags().StringVar(&cc.cfgDir, "configDir", "config", "config dir") cc.cmd.PersistentFlags().BoolVar(&cc.quiet, "quiet", false, "build in quiet mode") // Set bash-completion _ = cc.cmd.PersistentFlags().SetAnnotation("config", cobra.BashCompFilenameExt, config.ValidConfigFileExtensions) cc.cmd.PersistentFlags().BoolVarP(&cc.verbose, "verbose", "v", false, "verbose output") cc.cmd.PersistentFlags().BoolVarP(&cc.debug, "debug", "", false, "debug output") cc.cmd.PersistentFlags().BoolVar(&cc.logging, "log", false, "enable Logging") cc.cmd.PersistentFlags().StringVar(&cc.logFile, "logFile", "", "log File path (if set, logging enabled automatically)") cc.cmd.PersistentFlags().BoolVar(&cc.verboseLog, "verboseLog", false, "verbose logging") cc.cmd.Flags().BoolVarP(&cc.buildWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed") cc.cmd.Flags().Bool("renderToMemory", false, "render to memory (only useful for benchmark testing)") // Set bash-completion _ = cc.cmd.PersistentFlags().SetAnnotation("logFile", cobra.BashCompFilenameExt, []string{}) cc.cmd.SetGlobalNormalizationFunc(helpers.NormalizeHugoFlags) cc.cmd.SilenceUsage = true return cc } type hugoBuilderCommon struct { source string baseURL string environment string buildWatch bool gc bool // Profile flags (for debugging of performance problems) cpuprofile string memprofile string mutexprofile string traceprofile string // TODO(bep) var vs string logging bool verbose bool verboseLog bool debug bool quiet bool cfgFile string cfgDir string logFile string } func (cc *hugoBuilderCommon) timeTrack(start time.Time, name string) { if cc.quiet { return } elapsed := time.Since(start) fmt.Printf("%s in %v ms\n", name, int(1000*elapsed.Seconds())) } func (cc *hugoBuilderCommon) getConfigDir(baseDir string) string { if cc.cfgDir != "" { return paths.AbsPathify(baseDir, cc.cfgDir) } if v, found := os.LookupEnv("HUGO_CONFIGDIR"); found { return paths.AbsPathify(baseDir, v) } return paths.AbsPathify(baseDir, "config") } func (cc *hugoBuilderCommon) getEnvironment(isServer bool) string { if cc.environment != "" { return cc.environment } if v, found := os.LookupEnv("HUGO_ENVIRONMENT"); found { return v } // Used by Netlify and Forestry if v, found := os.LookupEnv("HUGO_ENV"); found { return v } if isServer { return hugo.EnvironmentDevelopment } return hugo.EnvironmentProduction } func (cc *hugoBuilderCommon) handleCommonBuilderFlags(cmd *cobra.Command) { cmd.PersistentFlags().StringVarP(&cc.source, "source", "s", "", "filesystem path to read files relative from") cmd.PersistentFlags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{}) cmd.PersistentFlags().StringVarP(&cc.environment, "environment", "e", "", "build environment") cmd.PersistentFlags().StringP("themesDir", "", "", "filesystem path to themes directory") cmd.PersistentFlags().BoolP("ignoreVendor", "", false, "ignores any _vendor directory") } func (cc *hugoBuilderCommon) handleFlags(cmd *cobra.Command) { cc.handleCommonBuilderFlags(cmd) cmd.Flags().Bool("cleanDestinationDir", false, "remove files from destination not found in static directories") cmd.Flags().BoolP("buildDrafts", "D", false, "include content marked as draft") cmd.Flags().BoolP("buildFuture", "F", false, "include content with publishdate in the future") cmd.Flags().BoolP("buildExpired", "E", false, "include expired content") cmd.Flags().StringP("contentDir", "c", "", "filesystem path to content directory") cmd.Flags().StringP("layoutDir", "l", "", "filesystem path to layout directory") cmd.Flags().StringP("cacheDir", "", "", "filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/") cmd.Flags().BoolP("ignoreCache", "", false, "ignores the cache directory") cmd.Flags().StringP("destination", "d", "", "filesystem path to write files to") cmd.Flags().StringSliceP("theme", "t", []string{}, "themes to use (located in /themes/THEMENAME/)") cmd.Flags().StringVarP(&cc.baseURL, "baseURL", "b", "", "hostname (and path) to the root, e.g. http://spf13.com/") cmd.Flags().Bool("enableGitInfo", false, "add Git revision, date and author info to the pages") cmd.Flags().BoolVar(&cc.gc, "gc", false, "enable to run some cleanup tasks (remove unused cache files) after the build") cmd.Flags().Bool("templateMetrics", false, "display metrics about template executions") cmd.Flags().Bool("templateMetricsHints", false, "calculate some improvement hints when combined with --templateMetrics") cmd.Flags().BoolP("forceSyncStatic", "", false, "copy all files when static is changed.") cmd.Flags().BoolP("noTimes", "", false, "don't sync modification time of files") cmd.Flags().BoolP("noChmod", "", false, "don't sync permission mode of files") cmd.Flags().BoolP("i18n-warnings", "", false, "print missing translations") cmd.Flags().BoolP("path-warnings", "", false, "print warnings on duplicate target paths etc.") cmd.Flags().StringVarP(&cc.cpuprofile, "profile-cpu", "", "", "write cpu profile to `file`") cmd.Flags().StringVarP(&cc.memprofile, "profile-mem", "", "", "write memory profile to `file`") cmd.Flags().StringVarP(&cc.mutexprofile, "profile-mutex", "", "", "write Mutex profile to `file`") cmd.Flags().StringVarP(&cc.traceprofile, "trace", "", "", "write trace to `file` (not useful in general)") // Hide these for now. cmd.Flags().MarkHidden("profile-cpu") cmd.Flags().MarkHidden("profile-mem") cmd.Flags().MarkHidden("profile-mutex") cmd.Flags().StringSlice("disableKinds", []string{}, "disable different kind of pages (home, RSS etc.)") cmd.Flags().Bool("minify", false, "minify any supported output format (HTML, XML etc.)") // Set bash-completion. // Each flag must first be defined before using the SetAnnotation() call. _ = cmd.Flags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{}) _ = cmd.Flags().SetAnnotation("cacheDir", cobra.BashCompSubdirsInDir, []string{}) _ = cmd.Flags().SetAnnotation("destination", cobra.BashCompSubdirsInDir, []string{}) _ = cmd.Flags().SetAnnotation("theme", cobra.BashCompSubdirsInDir, []string{"themes"}) } func checkErr(logger *loggers.Logger, err error, s ...string) { if err == nil { return } if len(s) == 0 { logger.CRITICAL.Println(err) return } for _, message := range s { logger.ERROR.Println(message) } logger.ERROR.Println(err) } hugo-0.68.3/commands/commands_test.go000066400000000000000000000270541363637351300175640ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "fmt" "io/ioutil" "os" "path/filepath" "testing" "github.com/gohugoio/hugo/htesting" "github.com/spf13/afero" "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/common/types" "github.com/spf13/cobra" "github.com/spf13/viper" qt "github.com/frankban/quicktest" ) func TestExecute(t *testing.T) { c := qt.New(t) createSite := func(c *qt.C) (string, func()) { dir, clean, err := createSimpleTestSite(t, testSiteConfig{}) c.Assert(err, qt.IsNil) return dir, clean } c.Run("hugo", func(c *qt.C) { dir, clean := createSite(c) defer clean() resp := Execute([]string{"-s=" + dir}) c.Assert(resp.Err, qt.IsNil) result := resp.Result c.Assert(len(result.Sites) == 1, qt.Equals, true) c.Assert(len(result.Sites[0].RegularPages()) == 1, qt.Equals, true) c.Assert(result.Sites[0].Info.Params()["myparam"], qt.Equals, "paramproduction") }) c.Run("hugo, set environment", func(c *qt.C) { dir, clean := createSite(c) defer clean() resp := Execute([]string{"-s=" + dir, "-e=staging"}) c.Assert(resp.Err, qt.IsNil) result := resp.Result c.Assert(result.Sites[0].Info.Params()["myparam"], qt.Equals, "paramstaging") }) c.Run("convert toJSON", func(c *qt.C) { dir, clean := createSite(c) output := filepath.Join(dir, "myjson") defer clean() resp := Execute([]string{"convert", "toJSON", "-s=" + dir, "-e=staging", "-o=" + output}) c.Assert(resp.Err, qt.IsNil) converted := readFileFrom(c, filepath.Join(output, "content", "p1.md")) c.Assert(converted, qt.Equals, "{\n \"title\": \"P1\",\n \"weight\": 1\n}\n\nContent\n\n", qt.Commentf(converted)) }) c.Run("config, set environment", func(c *qt.C) { dir, clean := createSite(c) defer clean() out, err := captureStdout(func() error { resp := Execute([]string{"config", "-s=" + dir, "-e=staging"}) return resp.Err }) c.Assert(err, qt.IsNil) c.Assert(out, qt.Contains, "params = map[myparam:paramstaging]", qt.Commentf(out)) }) c.Run("deploy, environment set", func(c *qt.C) { dir, clean := createSite(c) defer clean() resp := Execute([]string{"deploy", "-s=" + dir, "-e=staging", "--target=mydeployment", "--dryRun"}) c.Assert(resp.Err, qt.Not(qt.IsNil)) c.Assert(resp.Err.Error(), qt.Contains, `no provider registered for "hugocloud"`) }) c.Run("list", func(c *qt.C) { dir, clean := createSite(c) defer clean() out, err := captureStdout(func() error { resp := Execute([]string{"list", "all", "-s=" + dir, "-e=staging"}) return resp.Err }) c.Assert(err, qt.IsNil) c.Assert(out, qt.Contains, "p1.md") }) c.Run("new theme", func(c *qt.C) { dir, clean := createSite(c) defer clean() themesDir := filepath.Join(dir, "mythemes") resp := Execute([]string{"new", "theme", "mytheme", "-s=" + dir, "-e=staging", "--themesDir=" + themesDir}) c.Assert(resp.Err, qt.IsNil) themeTOML := readFileFrom(c, filepath.Join(themesDir, "mytheme", "theme.toml")) c.Assert(themeTOML, qt.Contains, "name = \"Mytheme\"") }) c.Run("new site", func(c *qt.C) { dir, clean := createSite(c) defer clean() siteDir := filepath.Join(dir, "mysite") resp := Execute([]string{"new", "site", siteDir, "-e=staging"}) c.Assert(resp.Err, qt.IsNil) config := readFileFrom(c, filepath.Join(siteDir, "config.toml")) c.Assert(config, qt.Contains, "baseURL = \"http://example.org/\"") checkNewSiteInited(c, siteDir) }) } func checkNewSiteInited(c *qt.C, basepath string) { paths := []string{ filepath.Join(basepath, "layouts"), filepath.Join(basepath, "content"), filepath.Join(basepath, "archetypes"), filepath.Join(basepath, "static"), filepath.Join(basepath, "data"), filepath.Join(basepath, "config.toml"), } for _, path := range paths { _, err := os.Stat(path) c.Assert(err, qt.IsNil) } } func readFileFrom(c *qt.C, filename string) string { c.Helper() filename = filepath.Clean(filename) b, err := afero.ReadFile(hugofs.Os, filename) c.Assert(err, qt.IsNil) return string(b) } func TestCommandsPersistentFlags(t *testing.T) { c := qt.New(t) noOpRunE := func(cmd *cobra.Command, args []string) error { return nil } tests := []struct { args []string check func(command []cmder) }{{[]string{"server", "--config=myconfig.toml", "--configDir=myconfigdir", "--contentDir=mycontent", "--disableKinds=page,home", "--environment=testing", "--configDir=myconfigdir", "--layoutDir=mylayouts", "--theme=mytheme", "--gc", "--themesDir=mythemes", "--cleanDestinationDir", "--navigateToChanged", "--disableLiveReload", "--noHTTPCache", "--i18n-warnings", "--destination=/tmp/mydestination", "-b=https://example.com/b/", "--port=1366", "--renderToDisk", "--source=mysource", "--path-warnings", }, func(commands []cmder) { var sc *serverCmd for _, command := range commands { if b, ok := command.(commandsBuilderGetter); ok { v := b.getCommandsBuilder().hugoBuilderCommon c.Assert(v.cfgFile, qt.Equals, "myconfig.toml") c.Assert(v.cfgDir, qt.Equals, "myconfigdir") c.Assert(v.source, qt.Equals, "mysource") c.Assert(v.baseURL, qt.Equals, "https://example.com/b/") } if srvCmd, ok := command.(*serverCmd); ok { sc = srvCmd } } c.Assert(sc, qt.Not(qt.IsNil)) c.Assert(sc.navigateToChanged, qt.Equals, true) c.Assert(sc.disableLiveReload, qt.Equals, true) c.Assert(sc.noHTTPCache, qt.Equals, true) c.Assert(sc.renderToDisk, qt.Equals, true) c.Assert(sc.serverPort, qt.Equals, 1366) c.Assert(sc.environment, qt.Equals, "testing") cfg := viper.New() sc.flagsToConfig(cfg) c.Assert(cfg.GetString("publishDir"), qt.Equals, "/tmp/mydestination") c.Assert(cfg.GetString("contentDir"), qt.Equals, "mycontent") c.Assert(cfg.GetString("layoutDir"), qt.Equals, "mylayouts") c.Assert(cfg.GetStringSlice("theme"), qt.DeepEquals, []string{"mytheme"}) c.Assert(cfg.GetString("themesDir"), qt.Equals, "mythemes") c.Assert(cfg.GetString("baseURL"), qt.Equals, "https://example.com/b/") c.Assert(cfg.Get("disableKinds"), qt.DeepEquals, []string{"page", "home"}) c.Assert(cfg.GetBool("gc"), qt.Equals, true) // The flag is named path-warnings c.Assert(cfg.GetBool("logPathWarnings"), qt.Equals, true) // The flag is named i18n-warnings c.Assert(cfg.GetBool("logI18nWarnings"), qt.Equals, true) }}} for _, test := range tests { b := newCommandsBuilder() root := b.addAll().build() for _, c := range b.commands { if c.getCommand() == nil { continue } // We are only intereseted in the flag handling here. c.getCommand().RunE = noOpRunE } rootCmd := root.getCommand() rootCmd.SetArgs(test.args) c.Assert(rootCmd.Execute(), qt.IsNil) test.check(b.commands) } } func TestCommandsExecute(t *testing.T) { c := qt.New(t) dir, clean, err := createSimpleTestSite(t, testSiteConfig{}) c.Assert(err, qt.IsNil) dirOut, clean2, err := htesting.CreateTempDir(hugofs.Os, "hugo-cli-out") c.Assert(err, qt.IsNil) defer clean() defer clean2() sourceFlag := fmt.Sprintf("-s=%s", dir) tests := []struct { commands []string flags []string expectErrToContain string }{ // TODO(bep) permission issue on my OSX? "operation not permitted" {[]string{"check", "ulimit"}, nil, false}, {[]string{"env"}, nil, ""}, {[]string{"version"}, nil, ""}, // no args = hugo build {nil, []string{sourceFlag}, ""}, {nil, []string{sourceFlag, "--renderToMemory"}, ""}, {[]string{"config"}, []string{sourceFlag}, ""}, {[]string{"convert", "toTOML"}, []string{sourceFlag, "-o=" + filepath.Join(dirOut, "toml")}, ""}, {[]string{"convert", "toYAML"}, []string{sourceFlag, "-o=" + filepath.Join(dirOut, "yaml")}, ""}, {[]string{"convert", "toJSON"}, []string{sourceFlag, "-o=" + filepath.Join(dirOut, "json")}, ""}, {[]string{"gen", "autocomplete"}, []string{"--completionfile=" + filepath.Join(dirOut, "autocomplete.txt")}, ""}, {[]string{"gen", "chromastyles"}, []string{"--style=manni"}, ""}, {[]string{"gen", "doc"}, []string{"--dir=" + filepath.Join(dirOut, "doc")}, ""}, {[]string{"gen", "man"}, []string{"--dir=" + filepath.Join(dirOut, "man")}, ""}, {[]string{"list", "drafts"}, []string{sourceFlag}, ""}, {[]string{"list", "expired"}, []string{sourceFlag}, ""}, {[]string{"list", "future"}, []string{sourceFlag}, ""}, {[]string{"new", "new-page.md"}, []string{sourceFlag}, ""}, {[]string{"new", "site", filepath.Join(dirOut, "new-site")}, nil, ""}, {[]string{"unknowncommand"}, nil, "unknown command"}, // TODO(bep) cli refactor fix https://github.com/gohugoio/hugo/issues/4450 //{[]string{"new", "theme", filepath.Join(dirOut, "new-theme")}, nil,false}, } for _, test := range tests { b := newCommandsBuilder().addAll().build() hugoCmd := b.getCommand() test.flags = append(test.flags, "--quiet") hugoCmd.SetArgs(append(test.commands, test.flags...)) // TODO(bep) capture output and add some simple asserts // TODO(bep) misspelled subcommands does not return an error. We should investigate this // but before that, check for "Error: unknown command". _, err := hugoCmd.ExecuteC() if test.expectErrToContain != "" { c.Assert(err, qt.Not(qt.IsNil)) c.Assert(err.Error(), qt.Contains, test.expectErrToContain) } else { c.Assert(err, qt.IsNil) } // Assert that we have not left any development debug artifacts in // the code. if b.c != nil { _, ok := b.c.destinationFs.(types.DevMarker) c.Assert(ok, qt.Equals, false) } } } type testSiteConfig struct { configTOML string contentDir string } func createSimpleTestSite(t *testing.T, cfg testSiteConfig) (string, func(), error) { d, clean, e := htesting.CreateTempDir(hugofs.Os, "hugo-cli") if e != nil { return "", nil, e } cfgStr := ` baseURL = "https://example.org" title = "Hugo Commands" ` contentDir := "content" if cfg.configTOML != "" { cfgStr = cfg.configTOML } if cfg.contentDir != "" { contentDir = cfg.contentDir } os.MkdirAll(filepath.Join(d, "public"), 0777) // Just the basic. These are for CLI tests, not site testing. writeFile(t, filepath.Join(d, "config.toml"), cfgStr) writeFile(t, filepath.Join(d, "config", "staging", "params.toml"), `myparam="paramstaging"`) writeFile(t, filepath.Join(d, "config", "staging", "deployment.toml"), ` [[targets]] name = "mydeployment" URL = "hugocloud://hugotestbucket" `) writeFile(t, filepath.Join(d, "config", "testing", "params.toml"), `myparam="paramtesting"`) writeFile(t, filepath.Join(d, "config", "production", "params.toml"), `myparam="paramproduction"`) writeFile(t, filepath.Join(d, contentDir, "p1.md"), ` --- title: "P1" weight: 1 --- Content `) writeFile(t, filepath.Join(d, "layouts", "_default", "single.html"), ` Single: {{ .Title }} `) writeFile(t, filepath.Join(d, "layouts", "_default", "list.html"), ` List: {{ .Title }} Environment: {{ hugo.Environment }} `) return d, clean, nil } func writeFile(t *testing.T, filename, content string) { must(t, os.MkdirAll(filepath.Dir(filename), os.FileMode(0755))) must(t, ioutil.WriteFile(filename, []byte(content), os.FileMode(0755))) } func must(t *testing.T, err error) { if err != nil { t.Fatal(err) } } hugo-0.68.3/commands/config.go000066400000000000000000000066351363637351300161730ustar00rootroot00000000000000// Copyright 2015 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License.Print the version number of Hug package commands import ( "encoding/json" "fmt" "os" "reflect" "regexp" "sort" "strings" "github.com/gohugoio/hugo/parser" "github.com/gohugoio/hugo/parser/metadecoders" "github.com/gohugoio/hugo/modules" "github.com/spf13/cobra" "github.com/spf13/viper" ) var _ cmder = (*configCmd)(nil) type configCmd struct { *baseBuilderCmd } func (b *commandsBuilder) newConfigCmd() *configCmd { cc := &configCmd{} cmd := &cobra.Command{ Use: "config", Short: "Print the site configuration", Long: `Print the site configuration, both default and custom settings.`, RunE: cc.printConfig, } printMountsCmd := &cobra.Command{ Use: "mounts", Short: "Print the configured file mounts", RunE: cc.printMounts, } cmd.AddCommand(printMountsCmd) cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd) return cc } func (c *configCmd) printMounts(cmd *cobra.Command, args []string) error { cfg, err := initializeConfig(true, false, &c.hugoBuilderCommon, c, nil) if err != nil { return err } allModules := cfg.Cfg.Get("allmodules").(modules.Modules) for _, m := range allModules { if err := parser.InterfaceToConfig(&modMounts{m: m}, metadecoders.JSON, os.Stdout); err != nil { return err } } return nil } func (c *configCmd) printConfig(cmd *cobra.Command, args []string) error { cfg, err := initializeConfig(true, false, &c.hugoBuilderCommon, c, nil) if err != nil { return err } allSettings := cfg.Cfg.(*viper.Viper).AllSettings() // We need to clean up this, but we store objects in the config that // isn't really interesting to the end user, so filter these. ignoreKeysRe := regexp.MustCompile("client|sorted|filecacheconfigs|allmodules|multilingual") separator := ": " if len(cfg.configFiles) > 0 && strings.HasSuffix(cfg.configFiles[0], ".toml") { separator = " = " } var keys []string for k := range allSettings { if ignoreKeysRe.MatchString(k) { continue } keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { kv := reflect.ValueOf(allSettings[k]) if kv.Kind() == reflect.String { fmt.Printf("%s%s\"%+v\"\n", k, separator, allSettings[k]) } else { fmt.Printf("%s%s%+v\n", k, separator, allSettings[k]) } } return nil } type modMounts struct { m modules.Module } type modMount struct { Source string `json:"source"` Target string `json:"target"` Lang string `json:"lang,omitempty"` } func (m *modMounts) MarshalJSON() ([]byte, error) { var mounts []modMount for _, mount := range m.m.Mounts() { mounts = append(mounts, modMount{ Source: mount.Source, Target: mount.Target, Lang: mount.Lang, }) } return json.Marshal(&struct { Path string `json:"path"` Dir string `json:"dir"` Mounts []modMount `json:"mounts"` }{ Path: m.m.Path(), Dir: m.m.Dir(), Mounts: mounts, }) } hugo-0.68.3/commands/convert.go000066400000000000000000000124441363637351300164010ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "bytes" "fmt" "strings" "time" "github.com/gohugoio/hugo/parser/pageparser" "github.com/gohugoio/hugo/resources/page" "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/parser" "github.com/gohugoio/hugo/parser/metadecoders" "github.com/pkg/errors" "github.com/gohugoio/hugo/hugolib" "path/filepath" "github.com/spf13/cobra" ) var ( _ cmder = (*convertCmd)(nil) ) type convertCmd struct { outputDir string unsafe bool *baseBuilderCmd } func (b *commandsBuilder) newConvertCmd() *convertCmd { cc := &convertCmd{} cmd := &cobra.Command{ Use: "convert", Short: "Convert your content to different formats", Long: `Convert your content (e.g. front matter) to different formats. See convert's subcommands toJSON, toTOML and toYAML for more information.`, RunE: nil, } cmd.AddCommand( &cobra.Command{ Use: "toJSON", Short: "Convert front matter to JSON", Long: `toJSON converts all front matter in the content directory to use JSON for the front matter.`, RunE: func(cmd *cobra.Command, args []string) error { return cc.convertContents(metadecoders.JSON) }, }, &cobra.Command{ Use: "toTOML", Short: "Convert front matter to TOML", Long: `toTOML converts all front matter in the content directory to use TOML for the front matter.`, RunE: func(cmd *cobra.Command, args []string) error { return cc.convertContents(metadecoders.TOML) }, }, &cobra.Command{ Use: "toYAML", Short: "Convert front matter to YAML", Long: `toYAML converts all front matter in the content directory to use YAML for the front matter.`, RunE: func(cmd *cobra.Command, args []string) error { return cc.convertContents(metadecoders.YAML) }, }, ) cmd.PersistentFlags().StringVarP(&cc.outputDir, "output", "o", "", "filesystem path to write files to") cmd.PersistentFlags().BoolVar(&cc.unsafe, "unsafe", false, "enable less safe operations, please backup first") cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd) return cc } func (cc *convertCmd) convertContents(format metadecoders.Format) error { if cc.outputDir == "" && !cc.unsafe { return newUserError("Unsafe operation not allowed, use --unsafe or set a different output path") } c, err := initializeConfig(true, false, &cc.hugoBuilderCommon, cc, nil) if err != nil { return err } c.Cfg.Set("buildDrafts", true) h, err := hugolib.NewHugoSites(*c.DepsCfg) if err != nil { return err } if err := h.Build(hugolib.BuildCfg{SkipRender: true}); err != nil { return err } site := h.Sites[0] site.Log.FEEDBACK.Println("processing", len(site.AllPages()), "content files") for _, p := range site.AllPages() { if err := cc.convertAndSavePage(p, site, format); err != nil { return err } } return nil } func (cc *convertCmd) convertAndSavePage(p page.Page, site *hugolib.Site, targetFormat metadecoders.Format) error { // The resources are not in .Site.AllPages. for _, r := range p.Resources().ByType("page") { if err := cc.convertAndSavePage(r.(page.Page), site, targetFormat); err != nil { return err } } if p.File().IsZero() { // No content file. return nil } errMsg := fmt.Errorf("Error processing file %q", p.Path()) site.Log.INFO.Println("Attempting to convert", p.File().Filename()) f := p.File() file, err := f.FileInfo().Meta().Open() if err != nil { site.Log.ERROR.Println(errMsg) file.Close() return nil } pf, err := pageparser.ParseFrontMatterAndContent(file) if err != nil { site.Log.ERROR.Println(errMsg) file.Close() return err } file.Close() // better handling of dates in formats that don't have support for them if pf.FrontMatterFormat == metadecoders.JSON || pf.FrontMatterFormat == metadecoders.YAML || pf.FrontMatterFormat == metadecoders.TOML { for k, v := range pf.FrontMatter { switch vv := v.(type) { case time.Time: pf.FrontMatter[k] = vv.Format(time.RFC3339) } } } var newContent bytes.Buffer err = parser.InterfaceToFrontMatter(pf.FrontMatter, targetFormat, &newContent) if err != nil { site.Log.ERROR.Println(errMsg) return err } newContent.Write(pf.Content) newFilename := p.File().Filename() if cc.outputDir != "" { contentDir := strings.TrimSuffix(newFilename, p.Path()) contentDir = filepath.Base(contentDir) newFilename = filepath.Join(cc.outputDir, contentDir, p.Path()) } fs := hugofs.Os if err := helpers.WriteToDisk(newFilename, &newContent, fs); err != nil { return errors.Wrapf(err, "Failed to save file %q:", newFilename) } return nil } type parsedFile struct { frontMatterFormat metadecoders.Format frontMatterSource []byte frontMatter map[string]interface{} // Everything after Front Matter content []byte } hugo-0.68.3/commands/deploy.go000066400000000000000000000051341363637351300162130ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "context" "github.com/gohugoio/hugo/deploy" "github.com/spf13/cobra" ) var _ cmder = (*deployCmd)(nil) // deployCmd supports deploying sites to Cloud providers. type deployCmd struct { *baseBuilderCmd } // TODO: In addition to the "deploy" command, consider adding a "--deploy" // flag for the default command; this would build the site and then deploy it. // It's not obvious how to do this; would all of the deploy-specific flags // have to exist at the top level as well? // TODO: The output files change every time "hugo" is executed, it looks // like because of map order randomization. This means that you can // run "hugo && hugo deploy" again and again and upload new stuff every time. Is // this intended? func (b *commandsBuilder) newDeployCmd() *deployCmd { cc := &deployCmd{} cmd := &cobra.Command{ Use: "deploy", Short: "Deploy your site to a Cloud provider.", Long: `Deploy your site to a Cloud provider. See https://gohugo.io/hosting-and-deployment/hugo-deploy/ for detailed documentation. `, RunE: func(cmd *cobra.Command, args []string) error { cfgInit := func(c *commandeer) error { return nil } comm, err := initializeConfig(true, false, &cc.hugoBuilderCommon, cc, cfgInit) if err != nil { return err } deployer, err := deploy.New(comm.Cfg, comm.hugo().PathSpec.PublishFs) if err != nil { return err } return deployer.Deploy(context.Background()) }, } cmd.Flags().String("target", "", "target deployment from deployments section in config file; defaults to the first one") cmd.Flags().Bool("confirm", false, "ask for confirmation before making changes to the target") cmd.Flags().Bool("dryRun", false, "dry run") cmd.Flags().Bool("force", false, "force upload of all files") cmd.Flags().Bool("invalidateCDN", true, "invalidate the CDN cache listed in the deployment target") cmd.Flags().Int("maxDeletes", 256, "maximum # of files to delete, or -1 to disable") cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd) return cc } hugo-0.68.3/commands/env.go000066400000000000000000000024131363637351300155040ustar00rootroot00000000000000// Copyright 2016 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "runtime" "github.com/spf13/cobra" jww "github.com/spf13/jwalterweatherman" ) var _ cmder = (*envCmd)(nil) type envCmd struct { *baseCmd } func newEnvCmd() *envCmd { return &envCmd{baseCmd: newBaseCmd(&cobra.Command{ Use: "env", Short: "Print Hugo version and environment info", Long: `Print Hugo version and environment info. This is useful in Hugo bug reports.`, RunE: func(cmd *cobra.Command, args []string) error { printHugoVersion() jww.FEEDBACK.Printf("GOOS=%q\n", runtime.GOOS) jww.FEEDBACK.Printf("GOARCH=%q\n", runtime.GOARCH) jww.FEEDBACK.Printf("GOVERSION=%q\n", runtime.Version()) return nil }, }), } } hugo-0.68.3/commands/gen.go000066400000000000000000000021201363637351300154600ustar00rootroot00000000000000// Copyright 2015 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "github.com/spf13/cobra" ) var _ cmder = (*genCmd)(nil) type genCmd struct { *baseCmd } func newGenCmd() *genCmd { cc := &genCmd{} cc.baseCmd = newBaseCmd(&cobra.Command{ Use: "gen", Short: "A collection of several useful generators.", }) cc.cmd.AddCommand( newGenautocompleteCmd().getCommand(), newGenDocCmd().getCommand(), newGenManCmd().getCommand(), createGenDocsHelper().getCommand(), createGenChromaStyles().getCommand()) return cc } hugo-0.68.3/commands/genautocomplete.go000066400000000000000000000045751363637351300201220ustar00rootroot00000000000000// Copyright 2015 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "github.com/spf13/cobra" jww "github.com/spf13/jwalterweatherman" ) var _ cmder = (*genautocompleteCmd)(nil) type genautocompleteCmd struct { autocompleteTarget string // bash for now (zsh and others will come) autocompleteType string *baseCmd } func newGenautocompleteCmd() *genautocompleteCmd { cc := &genautocompleteCmd{} cc.baseCmd = newBaseCmd(&cobra.Command{ Use: "autocomplete", Short: "Generate shell autocompletion script for Hugo", Long: `Generates a shell autocompletion script for Hugo. NOTE: The current version supports Bash only. This should work for *nix systems with Bash installed. By default, the file is written directly to /etc/bash_completion.d for convenience, and the command may need superuser rights, e.g.: $ sudo hugo gen autocomplete Add ` + "`--completionfile=/path/to/file`" + ` flag to set alternative file-path and name. Logout and in again to reload the completion scripts, or just source them in directly: $ . /etc/bash_completion`, RunE: func(cmd *cobra.Command, args []string) error { if cc.autocompleteType != "bash" { return newUserError("Only Bash is supported for now") } err := cmd.Root().GenBashCompletionFile(cc.autocompleteTarget) if err != nil { return err } jww.FEEDBACK.Println("Bash completion file for Hugo saved to", cc.autocompleteTarget) return nil }, }) cc.cmd.PersistentFlags().StringVarP(&cc.autocompleteTarget, "completionfile", "", "/etc/bash_completion.d/hugo.sh", "autocompletion file") cc.cmd.PersistentFlags().StringVarP(&cc.autocompleteType, "type", "", "bash", "autocompletion type (currently only bash supported)") // For bash-completion cc.cmd.PersistentFlags().SetAnnotation("completionfile", cobra.BashCompFilenameExt, []string{}) return cc } hugo-0.68.3/commands/genchromastyles.go000066400000000000000000000045121363637351300201250ustar00rootroot00000000000000// Copyright 2017-present The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "os" "github.com/alecthomas/chroma" "github.com/alecthomas/chroma/formatters/html" "github.com/alecthomas/chroma/styles" "github.com/spf13/cobra" ) var ( _ cmder = (*genChromaStyles)(nil) ) type genChromaStyles struct { style string highlightStyle string linesStyle string *baseCmd } // TODO(bep) highlight func createGenChromaStyles() *genChromaStyles { g := &genChromaStyles{ baseCmd: newBaseCmd(&cobra.Command{ Use: "chromastyles", Short: "Generate CSS stylesheet for the Chroma code highlighter", Long: `Generate CSS stylesheet for the Chroma code highlighter for a given style. This stylesheet is needed if pygmentsUseClasses is enabled in config. See https://help.farbox.com/pygments.html for preview of available styles`, }), } g.cmd.RunE = func(cmd *cobra.Command, args []string) error { return g.generate() } g.cmd.PersistentFlags().StringVar(&g.style, "style", "friendly", "highlighter style (see https://help.farbox.com/pygments.html)") g.cmd.PersistentFlags().StringVar(&g.highlightStyle, "highlightStyle", "bg:#ffffcc", "style used for highlighting lines (see https://github.com/alecthomas/chroma)") g.cmd.PersistentFlags().StringVar(&g.linesStyle, "linesStyle", "", "style used for line numbers (see https://github.com/alecthomas/chroma)") return g } func (g *genChromaStyles) generate() error { builder := styles.Get(g.style).Builder() if g.highlightStyle != "" { builder.Add(chroma.LineHighlight, g.highlightStyle) } if g.linesStyle != "" { builder.Add(chroma.LineNumbers, g.linesStyle) } style, err := builder.Build() if err != nil { return err } formatter := html.New(html.WithClasses(true)) formatter.WriteCSS(os.Stdout, style) return nil } hugo-0.68.3/commands/gendoc.go000066400000000000000000000054641363637351300161640ustar00rootroot00000000000000// Copyright 2016 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "fmt" "path" "path/filepath" "strings" "time" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugofs" "github.com/spf13/cobra" "github.com/spf13/cobra/doc" jww "github.com/spf13/jwalterweatherman" ) var _ cmder = (*genDocCmd)(nil) type genDocCmd struct { gendocdir string *baseCmd } func newGenDocCmd() *genDocCmd { const gendocFrontmatterTemplate = `--- date: %s title: "%s" slug: %s url: %s --- ` cc := &genDocCmd{} cc.baseCmd = newBaseCmd(&cobra.Command{ Use: "doc", Short: "Generate Markdown documentation for the Hugo CLI.", Long: `Generate Markdown documentation for the Hugo CLI. This command is, mostly, used to create up-to-date documentation of Hugo's command-line interface for http://gohugo.io/. It creates one Markdown file per command with front matter suitable for rendering in Hugo.`, RunE: func(cmd *cobra.Command, args []string) error { if !strings.HasSuffix(cc.gendocdir, helpers.FilePathSeparator) { cc.gendocdir += helpers.FilePathSeparator } if found, _ := helpers.Exists(cc.gendocdir, hugofs.Os); !found { jww.FEEDBACK.Println("Directory", cc.gendocdir, "does not exist, creating...") if err := hugofs.Os.MkdirAll(cc.gendocdir, 0777); err != nil { return err } } now := time.Now().Format("2006-01-02") prepender := func(filename string) string { name := filepath.Base(filename) base := strings.TrimSuffix(name, path.Ext(name)) url := "/commands/" + strings.ToLower(base) + "/" return fmt.Sprintf(gendocFrontmatterTemplate, now, strings.Replace(base, "_", " ", -1), base, url) } linkHandler := func(name string) string { base := strings.TrimSuffix(name, path.Ext(name)) return "/commands/" + strings.ToLower(base) + "/" } jww.FEEDBACK.Println("Generating Hugo command-line documentation in", cc.gendocdir, "...") doc.GenMarkdownTreeCustom(cmd.Root(), cc.gendocdir, prepender, linkHandler) jww.FEEDBACK.Println("Done.") return nil }, }) cc.cmd.PersistentFlags().StringVar(&cc.gendocdir, "dir", "/tmp/hugodoc/", "the directory to write the doc.") // For bash-completion cc.cmd.PersistentFlags().SetAnnotation("dir", cobra.BashCompSubdirsInDir, []string{}) return cc } hugo-0.68.3/commands/gendocshelper.go000066400000000000000000000031721363637351300175410ustar00rootroot00000000000000// Copyright 2017-present The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "encoding/json" "fmt" "os" "path/filepath" "github.com/gohugoio/hugo/docshelper" "github.com/spf13/cobra" ) var ( _ cmder = (*genDocsHelper)(nil) ) type genDocsHelper struct { target string *baseCmd } func createGenDocsHelper() *genDocsHelper { g := &genDocsHelper{ baseCmd: newBaseCmd(&cobra.Command{ Use: "docshelper", Short: "Generate some data files for the Hugo docs.", Hidden: true, }), } g.cmd.RunE = func(cmd *cobra.Command, args []string) error { return g.generate() } g.cmd.PersistentFlags().StringVarP(&g.target, "dir", "", "docs/data", "data dir") return g } func (g *genDocsHelper) generate() error { fmt.Println("Generate docs data to", g.target) targetFile := filepath.Join(g.target, "docs.json") f, err := os.Create(targetFile) if err != nil { return err } defer f.Close() enc := json.NewEncoder(f) enc.SetIndent("", " ") if err := enc.Encode(docshelper.GetDocProvider()); err != nil { return err } fmt.Println("Done!") return nil } hugo-0.68.3/commands/genman.go000066400000000000000000000044371363637351300161710ustar00rootroot00000000000000// Copyright 2016 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "fmt" "strings" "github.com/gohugoio/hugo/common/hugo" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugofs" "github.com/spf13/cobra" "github.com/spf13/cobra/doc" jww "github.com/spf13/jwalterweatherman" ) var _ cmder = (*genManCmd)(nil) type genManCmd struct { genmandir string *baseCmd } func newGenManCmd() *genManCmd { cc := &genManCmd{} cc.baseCmd = newBaseCmd(&cobra.Command{ Use: "man", Short: "Generate man pages for the Hugo CLI", Long: `This command automatically generates up-to-date man pages of Hugo's command-line interface. By default, it creates the man page files in the "man" directory under the current directory.`, RunE: func(cmd *cobra.Command, args []string) error { header := &doc.GenManHeader{ Section: "1", Manual: "Hugo Manual", Source: fmt.Sprintf("Hugo %s", hugo.CurrentVersion), } if !strings.HasSuffix(cc.genmandir, helpers.FilePathSeparator) { cc.genmandir += helpers.FilePathSeparator } if found, _ := helpers.Exists(cc.genmandir, hugofs.Os); !found { jww.FEEDBACK.Println("Directory", cc.genmandir, "does not exist, creating...") if err := hugofs.Os.MkdirAll(cc.genmandir, 0777); err != nil { return err } } cmd.Root().DisableAutoGenTag = true jww.FEEDBACK.Println("Generating Hugo man pages in", cc.genmandir, "...") doc.GenManTree(cmd.Root(), header, cc.genmandir) jww.FEEDBACK.Println("Done.") return nil }, }) cc.cmd.PersistentFlags().StringVar(&cc.genmandir, "dir", "man/", "the directory to write the man pages.") // For bash-completion cc.cmd.PersistentFlags().SetAnnotation("dir", cobra.BashCompSubdirsInDir, []string{}) return cc } hugo-0.68.3/commands/helpers.go000066400000000000000000000042051363637351300163570ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package commands defines and implements command-line commands and flags // used by Hugo. Commands and flags are implemented using Cobra. package commands import ( "fmt" "regexp" "github.com/gohugoio/hugo/config" "github.com/spf13/cobra" ) const ( ansiEsc = "\u001B" clearLine = "\r\033[K" hideCursor = ansiEsc + "[?25l" showCursor = ansiEsc + "[?25h" ) type flagsToConfigHandler interface { flagsToConfig(cfg config.Provider) } type cmder interface { flagsToConfigHandler getCommand() *cobra.Command } // commandError is an error used to signal different error situations in command handling. type commandError struct { s string userError bool } func (c commandError) Error() string { return c.s } func (c commandError) isUserError() bool { return c.userError } func newUserError(a ...interface{}) commandError { return commandError{s: fmt.Sprintln(a...), userError: true} } func newSystemError(a ...interface{}) commandError { return commandError{s: fmt.Sprintln(a...), userError: false} } func newSystemErrorF(format string, a ...interface{}) commandError { return commandError{s: fmt.Sprintf(format, a...), userError: false} } // Catch some of the obvious user errors from Cobra. // We don't want to show the usage message for every error. // The below may be to generic. Time will show. var userErrorRegexp = regexp.MustCompile("argument|flag|shorthand") func isUserError(err error) bool { if cErr, ok := err.(commandError); ok && cErr.isUserError() { return true } return userErrorRegexp.MatchString(err.Error()) } hugo-0.68.3/commands/hugo.go000066400000000000000000000677101363637351300156710ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package commands defines and implements command-line commands and flags // used by Hugo. Commands and flags are implemented using Cobra. package commands import ( "context" "fmt" "io/ioutil" "os/signal" "runtime/pprof" "runtime/trace" "sync/atomic" "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/resources/page" "github.com/pkg/errors" "github.com/gohugoio/hugo/common/herrors" "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/common/terminal" "syscall" "github.com/gohugoio/hugo/hugolib/filesystems" "golang.org/x/sync/errgroup" "os" "path/filepath" "runtime" "strings" "time" "github.com/gohugoio/hugo/config" flag "github.com/spf13/pflag" "github.com/fsnotify/fsnotify" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugolib" "github.com/gohugoio/hugo/livereload" "github.com/gohugoio/hugo/watcher" "github.com/spf13/afero" "github.com/spf13/cobra" "github.com/spf13/fsync" jww "github.com/spf13/jwalterweatherman" ) // The Response value from Execute. type Response struct { // The build Result will only be set in the hugo build command. Result *hugolib.HugoSites // Err is set when the command failed to execute. Err error // The command that was executed. Cmd *cobra.Command } // IsUserError returns true is the Response error is a user error rather than a // system error. func (r Response) IsUserError() bool { return r.Err != nil && isUserError(r.Err) } // Execute adds all child commands to the root command HugoCmd and sets flags appropriately. // The args are usually filled with os.Args[1:]. func Execute(args []string) Response { hugoCmd := newCommandsBuilder().addAll().build() cmd := hugoCmd.getCommand() cmd.SetArgs(args) c, err := cmd.ExecuteC() var resp Response if c == cmd && hugoCmd.c != nil { // Root command executed resp.Result = hugoCmd.c.hugo() } if err == nil { errCount := int(loggers.GlobalErrorCounter.Count()) if errCount > 0 { err = fmt.Errorf("logged %d errors", errCount) } else if resp.Result != nil { errCount = resp.Result.NumLogErrors() if errCount > 0 { err = fmt.Errorf("logged %d errors", errCount) } } } resp.Err = err resp.Cmd = c return resp } // InitializeConfig initializes a config file with sensible default configuration flags. func initializeConfig(mustHaveConfigFile, running bool, h *hugoBuilderCommon, f flagsToConfigHandler, cfgInit func(c *commandeer) error) (*commandeer, error) { c, err := newCommandeer(mustHaveConfigFile, running, h, f, cfgInit) if err != nil { return nil, err } return c, nil } func (c *commandeer) createLogger(cfg config.Provider, running bool) (*loggers.Logger, error) { var ( logHandle = ioutil.Discard logThreshold = jww.LevelWarn logFile = cfg.GetString("logFile") outHandle = ioutil.Discard stdoutThreshold = jww.LevelWarn ) if !c.h.quiet { outHandle = os.Stdout } if c.h.verboseLog || c.h.logging || (c.h.logFile != "") { var err error if logFile != "" { logHandle, err = os.OpenFile(logFile, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666) if err != nil { return nil, newSystemError("Failed to open log file:", logFile, err) } } else { logHandle, err = ioutil.TempFile("", "hugo") if err != nil { return nil, newSystemError(err) } } } else if !c.h.quiet && cfg.GetBool("verbose") { stdoutThreshold = jww.LevelInfo } if cfg.GetBool("debug") { stdoutThreshold = jww.LevelDebug } if c.h.verboseLog { logThreshold = jww.LevelInfo if cfg.GetBool("debug") { logThreshold = jww.LevelDebug } } loggers.InitGlobalLogger(stdoutThreshold, logThreshold, outHandle, logHandle) helpers.InitLoggers() return loggers.NewLogger(stdoutThreshold, logThreshold, outHandle, logHandle, running), nil } func initializeFlags(cmd *cobra.Command, cfg config.Provider) { persFlagKeys := []string{ "debug", "verbose", "logFile", // Moved from vars } flagKeys := []string{ "cleanDestinationDir", "buildDrafts", "buildFuture", "buildExpired", "uglyURLs", "canonifyURLs", "enableRobotsTXT", "enableGitInfo", "pluralizeListTitles", "preserveTaxonomyNames", "ignoreCache", "forceSyncStatic", "noTimes", "noChmod", "ignoreVendor", "templateMetrics", "templateMetricsHints", // Moved from vars. "baseURL", "buildWatch", "cacheDir", "cfgFile", "confirm", "contentDir", "debug", "destination", "disableKinds", "dryRun", "force", "gc", "i18n-warnings", "invalidateCDN", "layoutDir", "logFile", "maxDeletes", "quiet", "renderToMemory", "source", "target", "theme", "themesDir", "verbose", "verboseLog", "duplicateTargetPaths", } for _, key := range persFlagKeys { setValueFromFlag(cmd.PersistentFlags(), key, cfg, "", false) } for _, key := range flagKeys { setValueFromFlag(cmd.Flags(), key, cfg, "", false) } setValueFromFlag(cmd.Flags(), "minify", cfg, "minifyOutput", true) // Set some "config aliases" setValueFromFlag(cmd.Flags(), "destination", cfg, "publishDir", false) setValueFromFlag(cmd.Flags(), "i18n-warnings", cfg, "logI18nWarnings", false) setValueFromFlag(cmd.Flags(), "path-warnings", cfg, "logPathWarnings", false) } func setValueFromFlag(flags *flag.FlagSet, key string, cfg config.Provider, targetKey string, force bool) { key = strings.TrimSpace(key) if (force && flags.Lookup(key) != nil) || flags.Changed(key) { f := flags.Lookup(key) configKey := key if targetKey != "" { configKey = targetKey } // Gotta love this API. switch f.Value.Type() { case "bool": bv, _ := flags.GetBool(key) cfg.Set(configKey, bv) case "string": cfg.Set(configKey, f.Value.String()) case "stringSlice": bv, _ := flags.GetStringSlice(key) cfg.Set(configKey, bv) case "int": iv, _ := flags.GetInt(key) cfg.Set(configKey, iv) default: panic(fmt.Sprintf("update switch with %s", f.Value.Type())) } } } func isTerminal() bool { return terminal.IsTerminal(os.Stdout) } func ifTerminal(s string) string { if !isTerminal() { return "" } return s } func (c *commandeer) fullBuild() error { var ( g errgroup.Group langCount map[string]uint64 ) if !c.h.quiet { fmt.Print(ifTerminal(hideCursor) + "Building sites … ") if isTerminal() { defer func() { fmt.Print(showCursor + clearLine) }() } } copyStaticFunc := func() error { cnt, err := c.copyStatic() if err != nil { return errors.Wrap(err, "Error copying static files") } langCount = cnt return nil } buildSitesFunc := func() error { if err := c.buildSites(); err != nil { return errors.Wrap(err, "Error building site") } return nil } // Do not copy static files and build sites in parallel if cleanDestinationDir is enabled. // This flag deletes all static resources in /public folder that are missing in /static, // and it does so at the end of copyStatic() call. if c.Cfg.GetBool("cleanDestinationDir") { if err := copyStaticFunc(); err != nil { return err } if err := buildSitesFunc(); err != nil { return err } } else { g.Go(copyStaticFunc) g.Go(buildSitesFunc) if err := g.Wait(); err != nil { return err } } for _, s := range c.hugo().Sites { s.ProcessingStats.Static = langCount[s.Language().Lang] } if c.h.gc { count, err := c.hugo().GC() if err != nil { return err } for _, s := range c.hugo().Sites { // We have no way of knowing what site the garbage belonged to. s.ProcessingStats.Cleaned = uint64(count) } } return nil } func (c *commandeer) initCPUProfile() (func(), error) { if c.h.cpuprofile == "" { return nil, nil } f, err := os.Create(c.h.cpuprofile) if err != nil { return nil, errors.Wrap(err, "failed to create CPU profile") } if err := pprof.StartCPUProfile(f); err != nil { return nil, errors.Wrap(err, "failed to start CPU profile") } return func() { pprof.StopCPUProfile() f.Close() }, nil } func (c *commandeer) initMemProfile() { if c.h.memprofile == "" { return } f, err := os.Create(c.h.memprofile) if err != nil { c.logger.ERROR.Println("could not create memory profile: ", err) } defer f.Close() runtime.GC() // get up-to-date statistics if err := pprof.WriteHeapProfile(f); err != nil { c.logger.ERROR.Println("could not write memory profile: ", err) } } func (c *commandeer) initTraceProfile() (func(), error) { if c.h.traceprofile == "" { return nil, nil } f, err := os.Create(c.h.traceprofile) if err != nil { return nil, errors.Wrap(err, "failed to create trace file") } if err := trace.Start(f); err != nil { return nil, errors.Wrap(err, "failed to start trace") } return func() { trace.Stop() f.Close() }, nil } func (c *commandeer) initMutexProfile() (func(), error) { if c.h.mutexprofile == "" { return nil, nil } f, err := os.Create(c.h.mutexprofile) if err != nil { return nil, err } runtime.SetMutexProfileFraction(1) return func() { pprof.Lookup("mutex").WriteTo(f, 0) f.Close() }, nil } func (c *commandeer) initProfiling() (func(), error) { stopCPUProf, err := c.initCPUProfile() if err != nil { return nil, err } stopMutexProf, err := c.initMutexProfile() if err != nil { return nil, err } stopTraceProf, err := c.initTraceProfile() if err != nil { return nil, err } return func() { c.initMemProfile() if stopCPUProf != nil { stopCPUProf() } if stopMutexProf != nil { stopMutexProf() } if stopTraceProf != nil { stopTraceProf() } }, nil } func (c *commandeer) build() error { stopProfiling, err := c.initProfiling() if err != nil { return err } defer func() { if stopProfiling != nil { stopProfiling() } }() if err := c.fullBuild(); err != nil { return err } // TODO(bep) Feedback? if !c.h.quiet { fmt.Println() c.hugo().PrintProcessingStats(os.Stdout) fmt.Println() if createCounter, ok := c.destinationFs.(hugofs.DuplicatesReporter); ok { dupes := createCounter.ReportDuplicates() if dupes != "" { c.logger.WARN.Println("Duplicate target paths:", dupes) } } } if c.h.buildWatch { watchDirs, err := c.getDirList() if err != nil { return err } baseWatchDir := c.Cfg.GetString("workingDir") rootWatchDirs := getRootWatchDirsStr(baseWatchDir, watchDirs) c.logger.FEEDBACK.Printf("Watching for changes in %s%s{%s}\n", baseWatchDir, helpers.FilePathSeparator, rootWatchDirs) c.logger.FEEDBACK.Println("Press Ctrl+C to stop") watcher, err := c.newWatcher(watchDirs...) checkErr(c.Logger, err) defer watcher.Close() var sigs = make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) <-sigs } return nil } func (c *commandeer) serverBuild() error { defer c.timeTrack(time.Now(), "Built") stopProfiling, err := c.initProfiling() if err != nil { return err } defer func() { if stopProfiling != nil { stopProfiling() } }() if err := c.fullBuild(); err != nil { return err } // TODO(bep) Feedback? if !c.h.quiet { fmt.Println() c.hugo().PrintProcessingStats(os.Stdout) fmt.Println() } return nil } func (c *commandeer) copyStatic() (map[string]uint64, error) { m, err := c.doWithPublishDirs(c.copyStaticTo) if err == nil || os.IsNotExist(err) { return m, nil } return m, err } func (c *commandeer) doWithPublishDirs(f func(sourceFs *filesystems.SourceFilesystem) (uint64, error)) (map[string]uint64, error) { langCount := make(map[string]uint64) staticFilesystems := c.hugo().BaseFs.SourceFilesystems.Static if len(staticFilesystems) == 0 { c.logger.INFO.Println("No static directories found to sync") return langCount, nil } for lang, fs := range staticFilesystems { cnt, err := f(fs) if err != nil { return langCount, err } if lang == "" { // Not multihost for _, l := range c.languages { langCount[l.Lang] = cnt } } else { langCount[lang] = cnt } } return langCount, nil } type countingStatFs struct { afero.Fs statCounter uint64 } func (fs *countingStatFs) Stat(name string) (os.FileInfo, error) { f, err := fs.Fs.Stat(name) if err == nil { if !f.IsDir() { atomic.AddUint64(&fs.statCounter, 1) } } return f, err } func chmodFilter(dst, src os.FileInfo) bool { // Hugo publishes data from multiple sources, potentially // with overlapping directory structures. We cannot sync permissions // for directories as that would mean that we might end up with write-protected // directories inside /public. // One example of this would be syncing from the Go Module cache, // which have 0555 directories. return src.IsDir() } func (c *commandeer) copyStaticTo(sourceFs *filesystems.SourceFilesystem) (uint64, error) { publishDir := c.hugo().PathSpec.PublishDir // If root, remove the second '/' if publishDir == "//" { publishDir = helpers.FilePathSeparator } if sourceFs.PublishFolder != "" { publishDir = filepath.Join(publishDir, sourceFs.PublishFolder) } fs := &countingStatFs{Fs: sourceFs.Fs} syncer := fsync.NewSyncer() syncer.NoTimes = c.Cfg.GetBool("noTimes") syncer.NoChmod = c.Cfg.GetBool("noChmod") syncer.ChmodFilter = chmodFilter syncer.SrcFs = fs syncer.DestFs = c.Fs.Destination // Now that we are using a unionFs for the static directories // We can effectively clean the publishDir on initial sync syncer.Delete = c.Cfg.GetBool("cleanDestinationDir") if syncer.Delete { c.logger.INFO.Println("removing all files from destination that don't exist in static dirs") syncer.DeleteFilter = func(f os.FileInfo) bool { return f.IsDir() && strings.HasPrefix(f.Name(), ".") } } c.logger.INFO.Println("syncing static files to", publishDir) // because we are using a baseFs (to get the union right). // set sync src to root err := syncer.Sync(publishDir, helpers.FilePathSeparator) if err != nil { return 0, err } // Sync runs Stat 3 times for every source file (which sounds much) numFiles := fs.statCounter / 3 return numFiles, err } func (c *commandeer) firstPathSpec() *helpers.PathSpec { return c.hugo().Sites[0].PathSpec } func (c *commandeer) timeTrack(start time.Time, name string) { elapsed := time.Since(start) c.logger.FEEDBACK.Printf("%s in %v ms", name, int(1000*elapsed.Seconds())) } // getDirList provides NewWatcher() with a list of directories to watch for changes. func (c *commandeer) getDirList() ([]string, error) { var filenames []string walkFn := func(path string, fi hugofs.FileMetaInfo, err error) error { if err != nil { c.logger.ERROR.Println("walker: ", err) return nil } if fi.IsDir() { if fi.Name() == ".git" || fi.Name() == "node_modules" || fi.Name() == "bower_components" { return filepath.SkipDir } filenames = append(filenames, fi.Meta().Filename()) } return nil } watchFiles := c.hugo().PathSpec.BaseFs.WatchDirs() for _, fi := range watchFiles { if !fi.IsDir() { filenames = append(filenames, fi.Meta().Filename()) continue } w := hugofs.NewWalkway(hugofs.WalkwayConfig{Logger: c.logger, Info: fi, WalkFn: walkFn}) if err := w.Walk(); err != nil { c.logger.ERROR.Println("walker: ", err) } } filenames = helpers.UniqueStringsSorted(filenames) return filenames, nil } func (c *commandeer) buildSites() (err error) { return c.hugo().Build(hugolib.BuildCfg{}) } func (c *commandeer) handleBuildErr(err error, msg string) { c.buildErr = err c.logger.ERROR.Print(msg + ":\n\n") c.logger.ERROR.Println(helpers.FirstUpper(err.Error())) if !c.h.quiet && c.h.verbose { herrors.PrintStackTraceFromErr(err) } } func (c *commandeer) rebuildSites(events []fsnotify.Event) error { defer c.timeTrack(time.Now(), "Total") c.buildErr = nil visited := c.visitedURLs.PeekAllSet() if c.fastRenderMode { // Make sure we always render the home pages for _, l := range c.languages { langPath := c.hugo().PathSpec.GetLangSubDir(l.Lang) if langPath != "" { langPath = langPath + "/" } home := c.hugo().PathSpec.PrependBasePath("/"+langPath, false) visited[home] = true } } return c.hugo().Build(hugolib.BuildCfg{RecentlyVisited: visited, ErrRecovery: c.wasError}, events...) } func (c *commandeer) partialReRender(urls ...string) error { defer func() { c.wasError = false }() c.buildErr = nil visited := make(map[string]bool) for _, url := range urls { visited[url] = true } return c.hugo().Build(hugolib.BuildCfg{RecentlyVisited: visited, PartialReRender: true, ErrRecovery: c.wasError}) } func (c *commandeer) fullRebuild(changeType string) { if changeType == configChangeGoMod { // go.mod may be changed during the build itself, and // we really want to prevent superfluous builds. if !c.fullRebuildSem.TryAcquire(1) { return } c.fullRebuildSem.Release(1) } c.fullRebuildSem.Acquire(context.Background(), 1) go func() { defer c.fullRebuildSem.Release(1) c.printChangeDetected(changeType) defer func() { // Allow any file system events to arrive back. // This will block any rebuild on config changes for the // duration of the sleep. time.Sleep(2 * time.Second) }() defer c.timeTrack(time.Now(), "Rebuilt") c.commandeerHugoState = newCommandeerHugoState() err := c.loadConfig(true, true) if err != nil { // Set the processing on pause until the state is recovered. c.paused = true c.handleBuildErr(err, "Failed to reload config") } else { c.paused = false } if !c.paused { _, err := c.copyStatic() if err != nil { c.logger.ERROR.Println(err) return } err = c.buildSites() if err != nil { c.logger.ERROR.Println(err) } else if !c.h.buildWatch && !c.Cfg.GetBool("disableLiveReload") { livereload.ForceRefresh() } } }() } // newWatcher creates a new watcher to watch filesystem events. func (c *commandeer) newWatcher(dirList ...string) (*watcher.Batcher, error) { if runtime.GOOS == "darwin" { tweakLimit() } staticSyncer, err := newStaticSyncer(c) if err != nil { return nil, err } watcher, err := watcher.New(1 * time.Second) if err != nil { return nil, err } for _, d := range dirList { if d != "" { _ = watcher.Add(d) } } // Identifies changes to config (config.toml) files. configSet := make(map[string]bool) c.logger.FEEDBACK.Println("Watching for config changes in", strings.Join(c.configFiles, ", ")) for _, configFile := range c.configFiles { watcher.Add(configFile) configSet[configFile] = true } go func() { for { select { case evs := <-watcher.Events: c.handleEvents(watcher, staticSyncer, evs, configSet) if c.showErrorInBrowser && c.errCount() > 0 { // Need to reload browser to show the error livereload.ForceRefresh() } case err := <-watcher.Errors: if err != nil { c.logger.ERROR.Println("Error while watching:", err) } } } }() return watcher, nil } func (c *commandeer) printChangeDetected(typ string) { msg := "\nChange" if typ != "" { msg += " of " + typ } msg += " detected, rebuilding site." c.logger.FEEDBACK.Println(msg) const layout = "2006-01-02 15:04:05.000 -0700" c.logger.FEEDBACK.Println(time.Now().Format(layout)) } const ( configChangeConfig = "config file" configChangeGoMod = "go.mod file" ) func (c *commandeer) handleEvents(watcher *watcher.Batcher, staticSyncer *staticSyncer, evs []fsnotify.Event, configSet map[string]bool) { defer func() { c.wasError = false }() var isHandled bool for _, ev := range evs { isConfig := configSet[ev.Name] configChangeType := configChangeConfig if isConfig { if strings.Contains(ev.Name, "go.mod") { configChangeType = configChangeGoMod } } if !isConfig { // It may be one of the /config folders dirname := filepath.Dir(ev.Name) if dirname != "." && configSet[dirname] { isConfig = true } } if isConfig { isHandled = true if ev.Op&fsnotify.Chmod == fsnotify.Chmod { continue } if ev.Op&fsnotify.Remove == fsnotify.Remove || ev.Op&fsnotify.Rename == fsnotify.Rename { for _, configFile := range c.configFiles { counter := 0 for watcher.Add(configFile) != nil { counter++ if counter >= 100 { break } time.Sleep(100 * time.Millisecond) } } } // Config file(s) changed. Need full rebuild. c.fullRebuild(configChangeType) return } } if isHandled { return } if c.paused { // Wait for the server to get into a consistent state before // we continue with processing. return } if len(evs) > 50 { // This is probably a mass edit of the content dir. // Schedule a full rebuild for when it slows down. c.debounce(func() { c.fullRebuild("") }) return } c.logger.INFO.Println("Received System Events:", evs) staticEvents := []fsnotify.Event{} dynamicEvents := []fsnotify.Event{} // Special handling for symbolic links inside /content. filtered := []fsnotify.Event{} for _, ev := range evs { // Check the most specific first, i.e. files. contentMapped := c.hugo().ContentChanges.GetSymbolicLinkMappings(ev.Name) if len(contentMapped) > 0 { for _, mapped := range contentMapped { filtered = append(filtered, fsnotify.Event{Name: mapped, Op: ev.Op}) } continue } // Check for any symbolic directory mapping. dir, name := filepath.Split(ev.Name) contentMapped = c.hugo().ContentChanges.GetSymbolicLinkMappings(dir) if len(contentMapped) == 0 { filtered = append(filtered, ev) continue } for _, mapped := range contentMapped { mappedFilename := filepath.Join(mapped, name) filtered = append(filtered, fsnotify.Event{Name: mappedFilename, Op: ev.Op}) } } evs = filtered for _, ev := range evs { ext := filepath.Ext(ev.Name) baseName := filepath.Base(ev.Name) istemp := strings.HasSuffix(ext, "~") || (ext == ".swp") || // vim (ext == ".swx") || // vim (ext == ".tmp") || // generic temp file (ext == ".DS_Store") || // OSX Thumbnail baseName == "4913" || // vim strings.HasPrefix(ext, ".goutputstream") || // gnome strings.HasSuffix(ext, "jb_old___") || // intelliJ strings.HasSuffix(ext, "jb_tmp___") || // intelliJ strings.HasSuffix(ext, "jb_bak___") || // intelliJ strings.HasPrefix(ext, ".sb-") || // byword strings.HasPrefix(baseName, ".#") || // emacs strings.HasPrefix(baseName, "#") // emacs if istemp { continue } if c.hugo().Deps.SourceSpec.IgnoreFile(ev.Name) { continue } // Sometimes during rm -rf operations a '"": REMOVE' is triggered. Just ignore these if ev.Name == "" { continue } // Write and rename operations are often followed by CHMOD. // There may be valid use cases for rebuilding the site on CHMOD, // but that will require more complex logic than this simple conditional. // On OS X this seems to be related to Spotlight, see: // https://github.com/go-fsnotify/fsnotify/issues/15 // A workaround is to put your site(s) on the Spotlight exception list, // but that may be a little mysterious for most end users. // So, for now, we skip reload on CHMOD. // We do have to check for WRITE though. On slower laptops a Chmod // could be aggregated with other important events, and we still want // to rebuild on those if ev.Op&(fsnotify.Chmod|fsnotify.Write|fsnotify.Create) == fsnotify.Chmod { continue } walkAdder := func(path string, f hugofs.FileMetaInfo, err error) error { if f.IsDir() { c.logger.FEEDBACK.Println("adding created directory to watchlist", path) if err := watcher.Add(path); err != nil { return err } } else if !staticSyncer.isStatic(path) { // Hugo's rebuilding logic is entirely file based. When you drop a new folder into // /content on OSX, the above logic will handle future watching of those files, // but the initial CREATE is lost. dynamicEvents = append(dynamicEvents, fsnotify.Event{Name: path, Op: fsnotify.Create}) } return nil } // recursively add new directories to watch list // When mkdir -p is used, only the top directory triggers an event (at least on OSX) if ev.Op&fsnotify.Create == fsnotify.Create { if s, err := c.Fs.Source.Stat(ev.Name); err == nil && s.Mode().IsDir() { _ = helpers.SymbolicWalk(c.Fs.Source, ev.Name, walkAdder) } } if staticSyncer.isStatic(ev.Name) { staticEvents = append(staticEvents, ev) } else { dynamicEvents = append(dynamicEvents, ev) } } if len(staticEvents) > 0 { c.printChangeDetected("Static files") if c.Cfg.GetBool("forceSyncStatic") { c.logger.FEEDBACK.Printf("Syncing all static files\n") _, err := c.copyStatic() if err != nil { c.logger.ERROR.Println("Error copying static files to publish dir:", err) return } } else { if err := staticSyncer.syncsStaticEvents(staticEvents); err != nil { c.logger.ERROR.Println("Error syncing static files to publish dir:", err) return } } if !c.h.buildWatch && !c.Cfg.GetBool("disableLiveReload") { // Will block forever trying to write to a channel that nobody is reading if livereload isn't initialized // force refresh when more than one file if !c.wasError && len(staticEvents) == 1 { ev := staticEvents[0] path := c.hugo().BaseFs.SourceFilesystems.MakeStaticPathRelative(ev.Name) path = c.firstPathSpec().RelURL(helpers.ToSlashTrimLeading(path), false) livereload.RefreshPath(path) } else { livereload.ForceRefresh() } } } if len(dynamicEvents) > 0 { partitionedEvents := partitionDynamicEvents( c.firstPathSpec().BaseFs.SourceFilesystems, dynamicEvents) doLiveReload := !c.h.buildWatch && !c.Cfg.GetBool("disableLiveReload") onePageName := pickOneWriteOrCreatePath(partitionedEvents.ContentEvents) c.printChangeDetected("") c.changeDetector.PrepareNew() if err := c.rebuildSites(dynamicEvents); err != nil { c.handleBuildErr(err, "Rebuild failed") } if doLiveReload { if len(partitionedEvents.ContentEvents) == 0 && len(partitionedEvents.AssetEvents) > 0 { if c.wasError { livereload.ForceRefresh() return } changed := c.changeDetector.changed() if c.changeDetector != nil && len(changed) == 0 { // Nothing has changed. return } else if len(changed) == 1 { pathToRefresh := c.firstPathSpec().RelURL(helpers.ToSlashTrimLeading(changed[0]), false) livereload.RefreshPath(pathToRefresh) } else { livereload.ForceRefresh() } } if len(partitionedEvents.ContentEvents) > 0 { navigate := c.Cfg.GetBool("navigateToChanged") // We have fetched the same page above, but it may have // changed. var p page.Page if navigate { if onePageName != "" { p = c.hugo().GetContentPage(onePageName) } } if p != nil { livereload.NavigateToPathForPort(p.RelPermalink(), p.Site().ServerPort()) } else { livereload.ForceRefresh() } } } } } // dynamicEvents contains events that is considered dynamic, as in "not static". // Both of these categories will trigger a new build, but the asset events // does not fit into the "navigate to changed" logic. type dynamicEvents struct { ContentEvents []fsnotify.Event AssetEvents []fsnotify.Event } func partitionDynamicEvents(sourceFs *filesystems.SourceFilesystems, events []fsnotify.Event) (de dynamicEvents) { for _, e := range events { if sourceFs.IsAsset(e.Name) { de.AssetEvents = append(de.AssetEvents, e) } else { de.ContentEvents = append(de.ContentEvents, e) } } return } func pickOneWriteOrCreatePath(events []fsnotify.Event) string { name := "" // Some editors (for example notepad.exe on Windows) triggers a change // both for directory and file. So we pick the longest path, which should // be the file itself. for _, ev := range events { if (ev.Op&fsnotify.Write == fsnotify.Write || ev.Op&fsnotify.Create == fsnotify.Create) && len(ev.Name) > len(name) { name = ev.Name } } return name } hugo-0.68.3/commands/hugo_test.go000066400000000000000000000023361363637351300167210ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "testing" qt "github.com/frankban/quicktest" ) // Issue #5662 func TestHugoWithContentDirOverride(t *testing.T) { c := qt.New(t) hugoCmd := newCommandsBuilder().addAll().build() cmd := hugoCmd.getCommand() contentDir := "contentOverride" cfgStr := ` baseURL = "https://example.org" title = "Hugo Commands" contentDir = "thisdoesnotexist" ` dir, clean, err := createSimpleTestSite(t, testSiteConfig{configTOML: cfgStr, contentDir: contentDir}) c.Assert(err, qt.IsNil) defer clean() cmd.SetArgs([]string{"-s=" + dir, "-c=" + contentDir}) _, err = cmd.ExecuteC() c.Assert(err, qt.IsNil) } hugo-0.68.3/commands/hugo_windows.go000066400000000000000000000016671363637351300174420ustar00rootroot00000000000000// Copyright 2015 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import "github.com/spf13/cobra" func init() { // This message to show to Windows users if Hugo is opened from explorer.exe cobra.MousetrapHelpText = ` Hugo is a command-line tool for generating static website. You need to open cmd.exe and run Hugo from there. Visit https://gohugo.io/ for more information.` } hugo-0.68.3/commands/import_jekyll.go000066400000000000000000000366451363637351300176160ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "bytes" "errors" "fmt" "io/ioutil" "os" "path/filepath" "regexp" "strconv" "strings" "time" "unicode" "github.com/gohugoio/hugo/parser/pageparser" "github.com/gohugoio/hugo/common/hugio" "github.com/gohugoio/hugo/parser/metadecoders" "github.com/gohugoio/hugo/common/maps" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/hugolib" "github.com/gohugoio/hugo/parser" "github.com/spf13/afero" "github.com/spf13/cobra" jww "github.com/spf13/jwalterweatherman" ) var _ cmder = (*importCmd)(nil) type importCmd struct { *baseCmd } func newImportCmd() *importCmd { cc := &importCmd{} cc.baseCmd = newBaseCmd(&cobra.Command{ Use: "import", Short: "Import your site from others.", Long: `Import your site from other web site generators like Jekyll. Import requires a subcommand, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`.", RunE: nil, }) importJekyllCmd := &cobra.Command{ Use: "jekyll", Short: "hugo import from Jekyll", Long: `hugo import from Jekyll. Import from Jekyll requires two paths, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`.", RunE: cc.importFromJekyll, } importJekyllCmd.Flags().Bool("force", false, "allow import into non-empty target directory") cc.cmd.AddCommand(importJekyllCmd) return cc } func (i *importCmd) importFromJekyll(cmd *cobra.Command, args []string) error { if len(args) < 2 { return newUserError(`import from jekyll requires two paths, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`.") } jekyllRoot, err := filepath.Abs(filepath.Clean(args[0])) if err != nil { return newUserError("path error:", args[0]) } targetDir, err := filepath.Abs(filepath.Clean(args[1])) if err != nil { return newUserError("path error:", args[1]) } jww.INFO.Println("Import Jekyll from:", jekyllRoot, "to:", targetDir) if strings.HasPrefix(filepath.Dir(targetDir), jekyllRoot) { return newUserError("abort: target path should not be inside the Jekyll root") } forceImport, _ := cmd.Flags().GetBool("force") fs := afero.NewOsFs() jekyllPostDirs, hasAnyPost := i.getJekyllDirInfo(fs, jekyllRoot) if !hasAnyPost { return errors.New("abort: jekyll root contains neither posts nor drafts") } err = i.createSiteFromJekyll(jekyllRoot, targetDir, jekyllPostDirs, forceImport) if err != nil { return newUserError(err) } jww.FEEDBACK.Println("Importing...") fileCount := 0 callback := func(path string, fi hugofs.FileMetaInfo, err error) error { if err != nil { return err } if fi.IsDir() { return nil } relPath, err := filepath.Rel(jekyllRoot, path) if err != nil { return newUserError("get rel path error:", path) } relPath = filepath.ToSlash(relPath) draft := false switch { case strings.Contains(relPath, "_posts/"): relPath = filepath.Join("content/post", strings.Replace(relPath, "_posts/", "", -1)) case strings.Contains(relPath, "_drafts/"): relPath = filepath.Join("content/draft", strings.Replace(relPath, "_drafts/", "", -1)) draft = true default: return nil } fileCount++ return convertJekyllPost(path, relPath, targetDir, draft) } for jekyllPostDir, hasAnyPostInDir := range jekyllPostDirs { if hasAnyPostInDir { if err = helpers.SymbolicWalk(hugofs.Os, filepath.Join(jekyllRoot, jekyllPostDir), callback); err != nil { return err } } } jww.FEEDBACK.Println("Congratulations!", fileCount, "post(s) imported!") jww.FEEDBACK.Println("Now, start Hugo by yourself:\n" + "$ git clone https://github.com/spf13/herring-cove.git " + args[1] + "/themes/herring-cove") jww.FEEDBACK.Println("$ cd " + args[1] + "\n$ hugo server --theme=herring-cove") return nil } func (i *importCmd) getJekyllDirInfo(fs afero.Fs, jekyllRoot string) (map[string]bool, bool) { postDirs := make(map[string]bool) hasAnyPost := false if entries, err := ioutil.ReadDir(jekyllRoot); err == nil { for _, entry := range entries { if entry.IsDir() { subDir := filepath.Join(jekyllRoot, entry.Name()) if isPostDir, hasAnyPostInDir := i.retrieveJekyllPostDir(fs, subDir); isPostDir { postDirs[entry.Name()] = hasAnyPostInDir if hasAnyPostInDir { hasAnyPost = true } } } } } return postDirs, hasAnyPost } func (i *importCmd) retrieveJekyllPostDir(fs afero.Fs, dir string) (bool, bool) { if strings.HasSuffix(dir, "_posts") || strings.HasSuffix(dir, "_drafts") { isEmpty, _ := helpers.IsEmpty(dir, fs) return true, !isEmpty } if entries, err := ioutil.ReadDir(dir); err == nil { for _, entry := range entries { if entry.IsDir() { subDir := filepath.Join(dir, entry.Name()) if isPostDir, hasAnyPost := i.retrieveJekyllPostDir(fs, subDir); isPostDir { return isPostDir, hasAnyPost } } } } return false, true } func (i *importCmd) createSiteFromJekyll(jekyllRoot, targetDir string, jekyllPostDirs map[string]bool, force bool) error { s, err := hugolib.NewSiteDefaultLang() if err != nil { return err } fs := s.Fs.Source if exists, _ := helpers.Exists(targetDir, fs); exists { if isDir, _ := helpers.IsDir(targetDir, fs); !isDir { return errors.New("target path \"" + targetDir + "\" exists but is not a directory") } isEmpty, _ := helpers.IsEmpty(targetDir, fs) if !isEmpty && !force { return errors.New("target path \"" + targetDir + "\" exists and is not empty") } } jekyllConfig := i.loadJekyllConfig(fs, jekyllRoot) mkdir(targetDir, "layouts") mkdir(targetDir, "content") mkdir(targetDir, "archetypes") mkdir(targetDir, "static") mkdir(targetDir, "data") mkdir(targetDir, "themes") i.createConfigFromJekyll(fs, targetDir, "yaml", jekyllConfig) i.copyJekyllFilesAndFolders(jekyllRoot, filepath.Join(targetDir, "static"), jekyllPostDirs) return nil } func (i *importCmd) loadJekyllConfig(fs afero.Fs, jekyllRoot string) map[string]interface{} { path := filepath.Join(jekyllRoot, "_config.yml") exists, err := helpers.Exists(path, fs) if err != nil || !exists { jww.WARN.Println("_config.yaml not found: Is the specified Jekyll root correct?") return nil } f, err := fs.Open(path) if err != nil { return nil } defer f.Close() b, err := ioutil.ReadAll(f) if err != nil { return nil } c, err := metadecoders.Default.UnmarshalToMap(b, metadecoders.YAML) if err != nil { return nil } return c } func (i *importCmd) createConfigFromJekyll(fs afero.Fs, inpath string, kind metadecoders.Format, jekyllConfig map[string]interface{}) (err error) { title := "My New Hugo Site" baseURL := "http://example.org/" for key, value := range jekyllConfig { lowerKey := strings.ToLower(key) switch lowerKey { case "title": if str, ok := value.(string); ok { title = str } case "url": if str, ok := value.(string); ok { baseURL = str } } } in := map[string]interface{}{ "baseURL": baseURL, "title": title, "languageCode": "en-us", "disablePathToLower": true, } var buf bytes.Buffer err = parser.InterfaceToConfig(in, kind, &buf) if err != nil { return err } return helpers.WriteToDisk(filepath.Join(inpath, "config."+string(kind)), &buf, fs) } func (i *importCmd) copyJekyllFilesAndFolders(jekyllRoot, dest string, jekyllPostDirs map[string]bool) (err error) { fs := hugofs.Os fi, err := fs.Stat(jekyllRoot) if err != nil { return err } if !fi.IsDir() { return errors.New(jekyllRoot + " is not a directory") } err = os.MkdirAll(dest, fi.Mode()) if err != nil { return err } entries, err := ioutil.ReadDir(jekyllRoot) if err != nil { return err } for _, entry := range entries { sfp := filepath.Join(jekyllRoot, entry.Name()) dfp := filepath.Join(dest, entry.Name()) if entry.IsDir() { if entry.Name()[0] != '_' && entry.Name()[0] != '.' { if _, ok := jekyllPostDirs[entry.Name()]; !ok { err = hugio.CopyDir(fs, sfp, dfp, nil) if err != nil { jww.ERROR.Println(err) } } } } else { lowerEntryName := strings.ToLower(entry.Name()) exceptSuffix := []string{".md", ".markdown", ".html", ".htm", ".xml", ".textile", "rakefile", "gemfile", ".lock"} isExcept := false for _, suffix := range exceptSuffix { if strings.HasSuffix(lowerEntryName, suffix) { isExcept = true break } } if !isExcept && entry.Name()[0] != '.' && entry.Name()[0] != '_' { err = hugio.CopyFile(fs, sfp, dfp) if err != nil { jww.ERROR.Println(err) } } } } return nil } func parseJekyllFilename(filename string) (time.Time, string, error) { re := regexp.MustCompile(`(\d+-\d+-\d+)-(.+)\..*`) r := re.FindAllStringSubmatch(filename, -1) if len(r) == 0 { return time.Now(), "", errors.New("filename not match") } postDate, err := time.Parse("2006-1-2", r[0][1]) if err != nil { return time.Now(), "", err } postName := r[0][2] return postDate, postName, nil } func convertJekyllPost(path, relPath, targetDir string, draft bool) error { jww.TRACE.Println("Converting", path) filename := filepath.Base(path) postDate, postName, err := parseJekyllFilename(filename) if err != nil { jww.WARN.Printf("Failed to parse filename '%s': %s. Skipping.", filename, err) return nil } jww.TRACE.Println(filename, postDate, postName) targetFile := filepath.Join(targetDir, relPath) targetParentDir := filepath.Dir(targetFile) os.MkdirAll(targetParentDir, 0777) contentBytes, err := ioutil.ReadFile(path) if err != nil { jww.ERROR.Println("Read file error:", path) return err } pf, err := pageparser.ParseFrontMatterAndContent(bytes.NewReader(contentBytes)) if err != nil { jww.ERROR.Println("Parse file error:", path) return err } newmetadata, err := convertJekyllMetaData(pf.FrontMatter, postName, postDate, draft) if err != nil { jww.ERROR.Println("Convert metadata error:", path) return err } content, err := convertJekyllContent(newmetadata, string(pf.Content)) if err != nil { jww.ERROR.Println("Converting Jekyll error:", path) return err } fs := hugofs.Os if err := helpers.WriteToDisk(targetFile, strings.NewReader(content), fs); err != nil { return fmt.Errorf("failed to save file %q: %s", filename, err) } return nil } func convertJekyllMetaData(m interface{}, postName string, postDate time.Time, draft bool) (interface{}, error) { metadata, err := maps.ToStringMapE(m) if err != nil { return nil, err } if draft { metadata["draft"] = true } for key, value := range metadata { lowerKey := strings.ToLower(key) switch lowerKey { case "layout": delete(metadata, key) case "permalink": if str, ok := value.(string); ok { metadata["url"] = str } delete(metadata, key) case "category": if str, ok := value.(string); ok { metadata["categories"] = []string{str} } delete(metadata, key) case "excerpt_separator": if key != lowerKey { delete(metadata, key) metadata[lowerKey] = value } case "date": if str, ok := value.(string); ok { re := regexp.MustCompile(`(\d+):(\d+):(\d+)`) r := re.FindAllStringSubmatch(str, -1) if len(r) > 0 { hour, _ := strconv.Atoi(r[0][1]) minute, _ := strconv.Atoi(r[0][2]) second, _ := strconv.Atoi(r[0][3]) postDate = time.Date(postDate.Year(), postDate.Month(), postDate.Day(), hour, minute, second, 0, time.UTC) } } delete(metadata, key) } } metadata["date"] = postDate.Format(time.RFC3339) return metadata, nil } func convertJekyllContent(m interface{}, content string) (string, error) { metadata, _ := maps.ToStringMapE(m) lines := strings.Split(content, "\n") var resultLines []string for _, line := range lines { resultLines = append(resultLines, strings.Trim(line, "\r\n")) } content = strings.Join(resultLines, "\n") excerptSep := "" if value, ok := metadata["excerpt_separator"]; ok { if str, strOk := value.(string); strOk { content = strings.Replace(content, strings.TrimSpace(str), excerptSep, -1) } } replaceList := []struct { re *regexp.Regexp replace string }{ {regexp.MustCompile("(?i)"), ""}, {regexp.MustCompile(`\{%\s*raw\s*%\}\s*(.*?)\s*\{%\s*endraw\s*%\}`), "$1"}, {regexp.MustCompile(`{%\s*endhighlight\s*%}`), "{{< / highlight >}}"}, } for _, replace := range replaceList { content = replace.re.ReplaceAllString(content, replace.replace) } replaceListFunc := []struct { re *regexp.Regexp replace func(string) string }{ // Octopress image tag: http://octopress.org/docs/plugins/image-tag/ {regexp.MustCompile(`{%\s+img\s*(.*?)\s*%}`), replaceImageTag}, {regexp.MustCompile(`{%\s*highlight\s*(.*?)\s*%}`), replaceHighlightTag}, } for _, replace := range replaceListFunc { content = replace.re.ReplaceAllStringFunc(content, replace.replace) } var buf bytes.Buffer if len(metadata) != 0 { err := parser.InterfaceToFrontMatter(m, metadecoders.YAML, &buf) if err != nil { return "", err } } buf.WriteString(content) return buf.String(), nil } func replaceHighlightTag(match string) string { r := regexp.MustCompile(`{%\s*highlight\s*(.*?)\s*%}`) parts := r.FindStringSubmatch(match) lastQuote := rune(0) f := func(c rune) bool { switch { case c == lastQuote: lastQuote = rune(0) return false case lastQuote != rune(0): return false case unicode.In(c, unicode.Quotation_Mark): lastQuote = c return false default: return unicode.IsSpace(c) } } // splitting string by space but considering quoted section items := strings.FieldsFunc(parts[1], f) result := bytes.NewBufferString("{{< highlight ") result.WriteString(items[0]) // language options := items[1:] for i, opt := range options { opt = strings.Replace(opt, "\"", "", -1) if opt == "linenos" { opt = "linenos=table" } if i == 0 { opt = " \"" + opt } if i < len(options)-1 { opt += "," } else if i == len(options)-1 { opt += "\"" } result.WriteString(opt) } result.WriteString(" >}}") return result.String() } func replaceImageTag(match string) string { r := regexp.MustCompile(`{%\s+img\s*(\p{L}*)\s+([\S]*/[\S]+)\s+(\d*)\s*(\d*)\s*(.*?)\s*%}`) result := bytes.NewBufferString("{{< figure ") parts := r.FindStringSubmatch(match) // Index 0 is the entire string, ignore replaceOptionalPart(result, "class", parts[1]) replaceOptionalPart(result, "src", parts[2]) replaceOptionalPart(result, "width", parts[3]) replaceOptionalPart(result, "height", parts[4]) // title + alt part := parts[5] if len(part) > 0 { splits := strings.Split(part, "'") lenSplits := len(splits) if lenSplits == 1 { replaceOptionalPart(result, "title", splits[0]) } else if lenSplits == 3 { replaceOptionalPart(result, "title", splits[1]) } else if lenSplits == 5 { replaceOptionalPart(result, "title", splits[1]) replaceOptionalPart(result, "alt", splits[3]) } } result.WriteString(">}}") return result.String() } func replaceOptionalPart(buffer *bytes.Buffer, partName string, part string) { if len(part) > 0 { buffer.WriteString(partName + "=\"" + part + "\" ") } } hugo-0.68.3/commands/import_jekyll_test.go000066400000000000000000000140631363637351300206430ustar00rootroot00000000000000// Copyright 2015 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "encoding/json" "testing" "time" qt "github.com/frankban/quicktest" ) func TestParseJekyllFilename(t *testing.T) { c := qt.New(t) filenameArray := []string{ "2015-01-02-test.md", "2012-03-15-中文.markup", } expectResult := []struct { postDate time.Time postName string }{ {time.Date(2015, time.January, 2, 0, 0, 0, 0, time.UTC), "test"}, {time.Date(2012, time.March, 15, 0, 0, 0, 0, time.UTC), "中文"}, } for i, filename := range filenameArray { postDate, postName, err := parseJekyllFilename(filename) c.Assert(err, qt.IsNil) c.Assert(expectResult[i].postDate.Format("2006-01-02"), qt.Equals, postDate.Format("2006-01-02")) c.Assert(expectResult[i].postName, qt.Equals, postName) } } func TestConvertJekyllMetadata(t *testing.T) { c := qt.New(t) testDataList := []struct { metadata interface{} postName string postDate time.Time draft bool expect string }{ {map[interface{}]interface{}{}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false, `{"date":"2015-10-01T00:00:00Z"}`}, {map[interface{}]interface{}{}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), true, `{"date":"2015-10-01T00:00:00Z","draft":true}`}, {map[interface{}]interface{}{"Permalink": "/permalink.html", "layout": "post"}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false, `{"date":"2015-10-01T00:00:00Z","url":"/permalink.html"}`}, {map[interface{}]interface{}{"permalink": "/permalink.html"}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false, `{"date":"2015-10-01T00:00:00Z","url":"/permalink.html"}`}, {map[interface{}]interface{}{"category": nil, "permalink": 123}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false, `{"date":"2015-10-01T00:00:00Z"}`}, {map[interface{}]interface{}{"Excerpt_Separator": "sep"}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false, `{"date":"2015-10-01T00:00:00Z","excerpt_separator":"sep"}`}, {map[interface{}]interface{}{"category": "book", "layout": "post", "Others": "Goods", "Date": "2015-10-01 12:13:11"}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false, `{"Others":"Goods","categories":["book"],"date":"2015-10-01T12:13:11Z"}`}, } for _, data := range testDataList { result, err := convertJekyllMetaData(data.metadata, data.postName, data.postDate, data.draft) c.Assert(err, qt.IsNil) jsonResult, err := json.Marshal(result) c.Assert(err, qt.IsNil) c.Assert(string(jsonResult), qt.Equals, data.expect) } } func TestConvertJekyllContent(t *testing.T) { c := qt.New(t) testDataList := []struct { metadata interface{} content string expect string }{ {map[interface{}]interface{}{}, "Test content\r\n\npart2 content", "Test content\n\npart2 content"}, {map[interface{}]interface{}{}, "Test content\n\npart2 content", "Test content\n\npart2 content"}, {map[interface{}]interface{}{"excerpt_separator": ""}, "Test content\n\npart2 content", "---\nexcerpt_separator: \n---\nTest content\n\npart2 content"}, {map[interface{}]interface{}{}, "{% raw %}text{% endraw %}", "text"}, {map[interface{}]interface{}{}, "{%raw%} text2 {%endraw %}", "text2"}, {map[interface{}]interface{}{}, "{% highlight go %}\nvar s int\n{% endhighlight %}", "{{< highlight go >}}\nvar s int\n{{< / highlight >}}"}, {map[interface{}]interface{}{}, "{% highlight go linenos hl_lines=\"1 2\" %}\nvar s string\nvar i int\n{% endhighlight %}", "{{< highlight go \"linenos=table,hl_lines=1 2\" >}}\nvar s string\nvar i int\n{{< / highlight >}}"}, // Octopress image tag {map[interface{}]interface{}{}, "{% img http://placekitten.com/890/280 %}", "{{< figure src=\"http://placekitten.com/890/280\" >}}"}, {map[interface{}]interface{}{}, "{% img left http://placekitten.com/320/250 Place Kitten #2 %}", "{{< figure class=\"left\" src=\"http://placekitten.com/320/250\" title=\"Place Kitten #2\" >}}"}, {map[interface{}]interface{}{}, "{% img right http://placekitten.com/300/500 150 250 'Place Kitten #3' %}", "{{< figure class=\"right\" src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #3\" >}}"}, {map[interface{}]interface{}{}, "{% img right http://placekitten.com/300/500 150 250 'Place Kitten #4' 'An image of a very cute kitten' %}", "{{< figure class=\"right\" src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}"}, {map[interface{}]interface{}{}, "{% img http://placekitten.com/300/500 150 250 'Place Kitten #4' 'An image of a very cute kitten' %}", "{{< figure src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}"}, {map[interface{}]interface{}{}, "{% img right /placekitten/300/500 'Place Kitten #4' 'An image of a very cute kitten' %}", "{{< figure class=\"right\" src=\"/placekitten/300/500\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}"}, {map[interface{}]interface{}{"category": "book", "layout": "post", "Date": "2015-10-01 12:13:11"}, "somecontent", "---\nDate: \"2015-10-01 12:13:11\"\ncategory: book\nlayout: post\n---\nsomecontent"}, } for _, data := range testDataList { result, err := convertJekyllContent(data.metadata, data.content) c.Assert(result, qt.Equals, data.expect) c.Assert(err, qt.IsNil) } } hugo-0.68.3/commands/limit_darwin.go000066400000000000000000000044731363637351300174060ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "syscall" "github.com/spf13/cobra" jww "github.com/spf13/jwalterweatherman" ) var _ cmder = (*limitCmd)(nil) type limitCmd struct { *baseCmd } func newLimitCmd() *limitCmd { ccmd := &cobra.Command{ Use: "ulimit", Short: "Check system ulimit settings", Long: `Hugo will inspect the current ulimit settings on the system. This is primarily to ensure that Hugo can watch enough files on some OSs`, RunE: func(cmd *cobra.Command, args []string) error { var rLimit syscall.Rlimit err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) if err != nil { return newSystemError("Error Getting rlimit ", err) } jww.FEEDBACK.Println("Current rLimit:", rLimit) if rLimit.Cur >= newRlimit { return nil } jww.FEEDBACK.Println("Attempting to increase limit") rLimit.Cur = newRlimit err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) if err != nil { return newSystemError("Error Setting rLimit ", err) } err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) if err != nil { return newSystemError("Error Getting rLimit ", err) } jww.FEEDBACK.Println("rLimit after change:", rLimit) return nil }, } return &limitCmd{baseCmd: newBaseCmd(ccmd)} } const newRlimit = 10240 func tweakLimit() { var rLimit syscall.Rlimit err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) if err != nil { jww.WARN.Println("Unable to get rlimit:", err) return } if rLimit.Cur < newRlimit { rLimit.Cur = newRlimit err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) if err != nil { // This may not succeed, see https://github.com/golang/go/issues/30401 jww.INFO.Println("Unable to increase number of open files limit:", err) } } } hugo-0.68.3/commands/limit_others.go000066400000000000000000000012561363637351300174220ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build !darwin package commands func tweakLimit() { // nothing to do } hugo-0.68.3/commands/list.go000066400000000000000000000124311363637351300156700ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "encoding/csv" "os" "strconv" "strings" "time" "github.com/gohugoio/hugo/hugolib" "github.com/gohugoio/hugo/resources/resource" "github.com/spf13/cobra" jww "github.com/spf13/jwalterweatherman" ) var _ cmder = (*listCmd)(nil) type listCmd struct { *baseBuilderCmd } func (lc *listCmd) buildSites(config map[string]interface{}) (*hugolib.HugoSites, error) { cfgInit := func(c *commandeer) error { for key, value := range config { c.Set(key, value) } return nil } c, err := initializeConfig(true, false, &lc.hugoBuilderCommon, lc, cfgInit) if err != nil { return nil, err } sites, err := hugolib.NewHugoSites(*c.DepsCfg) if err != nil { return nil, newSystemError("Error creating sites", err) } if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil { return nil, newSystemError("Error Processing Source Content", err) } return sites, nil } func (b *commandsBuilder) newListCmd() *listCmd { cc := &listCmd{} cmd := &cobra.Command{ Use: "list", Short: "Listing out various types of content", Long: `Listing out various types of content. List requires a subcommand, e.g. ` + "`hugo list drafts`.", RunE: nil, } cmd.AddCommand( &cobra.Command{ Use: "drafts", Short: "List all drafts", Long: `List all of the drafts in your content directory.`, RunE: func(cmd *cobra.Command, args []string) error { sites, err := cc.buildSites(map[string]interface{}{"buildDrafts": true}) if err != nil { return newSystemError("Error building sites", err) } for _, p := range sites.Pages() { if p.Draft() { jww.FEEDBACK.Println(strings.TrimPrefix(p.File().Filename(), sites.WorkingDir+string(os.PathSeparator))) } } return nil }, }, &cobra.Command{ Use: "future", Short: "List all posts dated in the future", Long: `List all of the posts in your content directory which will be posted in the future.`, RunE: func(cmd *cobra.Command, args []string) error { sites, err := cc.buildSites(map[string]interface{}{"buildFuture": true}) if err != nil { return newSystemError("Error building sites", err) } writer := csv.NewWriter(os.Stdout) defer writer.Flush() for _, p := range sites.Pages() { if resource.IsFuture(p) { err := writer.Write([]string{ strings.TrimPrefix(p.File().Filename(), sites.WorkingDir+string(os.PathSeparator)), p.PublishDate().Format(time.RFC3339), }) if err != nil { return newSystemError("Error writing future posts to stdout", err) } } } return nil }, }, &cobra.Command{ Use: "expired", Short: "List all posts already expired", Long: `List all of the posts in your content directory which has already expired.`, RunE: func(cmd *cobra.Command, args []string) error { sites, err := cc.buildSites(map[string]interface{}{"buildExpired": true}) if err != nil { return newSystemError("Error building sites", err) } writer := csv.NewWriter(os.Stdout) defer writer.Flush() for _, p := range sites.Pages() { if resource.IsExpired(p) { err := writer.Write([]string{ strings.TrimPrefix(p.File().Filename(), sites.WorkingDir+string(os.PathSeparator)), p.ExpiryDate().Format(time.RFC3339), }) if err != nil { return newSystemError("Error writing expired posts to stdout", err) } } } return nil }, }, &cobra.Command{ Use: "all", Short: "List all posts", Long: `List all of the posts in your content directory, include drafts, future and expired pages.`, RunE: func(cmd *cobra.Command, args []string) error { sites, err := cc.buildSites(map[string]interface{}{ "buildExpired": true, "buildDrafts": true, "buildFuture": true, }) if err != nil { return newSystemError("Error building sites", err) } writer := csv.NewWriter(os.Stdout) defer writer.Flush() writer.Write([]string{ "path", "slug", "title", "date", "expiryDate", "publishDate", "draft", "permalink", }) for _, p := range sites.Pages() { if !p.IsPage() { continue } err := writer.Write([]string{ strings.TrimPrefix(p.File().Filename(), sites.WorkingDir+string(os.PathSeparator)), p.Slug(), p.Title(), p.Date().Format(time.RFC3339), p.ExpiryDate().Format(time.RFC3339), p.PublishDate().Format(time.RFC3339), strconv.FormatBool(p.Draft()), p.Permalink(), }) if err != nil { return newSystemError("Error writing posts to stdout", err) } } return nil }, }, ) cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd) return cc } hugo-0.68.3/commands/list_test.go000066400000000000000000000024171363637351300167320ustar00rootroot00000000000000package commands import ( "bytes" "encoding/csv" "io" "os" "path/filepath" "strings" "testing" qt "github.com/frankban/quicktest" ) func captureStdout(f func() error) (string, error) { old := os.Stdout r, w, _ := os.Pipe() os.Stdout = w err := f() w.Close() os.Stdout = old var buf bytes.Buffer io.Copy(&buf, r) return buf.String(), err } func TestListAll(t *testing.T) { c := qt.New(t) dir, clean, err := createSimpleTestSite(t, testSiteConfig{}) defer clean() c.Assert(err, qt.IsNil) hugoCmd := newCommandsBuilder().addAll().build() cmd := hugoCmd.getCommand() defer func() { os.RemoveAll(dir) }() cmd.SetArgs([]string{"-s=" + dir, "list", "all"}) out, err := captureStdout(func() error { _, err := cmd.ExecuteC() return err }) c.Assert(err, qt.IsNil) r := csv.NewReader(strings.NewReader(out)) header, err := r.Read() c.Assert(err, qt.IsNil) c.Assert(header, qt.DeepEquals, []string{ "path", "slug", "title", "date", "expiryDate", "publishDate", "draft", "permalink", }) record, err := r.Read() c.Assert(err, qt.IsNil) c.Assert(record, qt.DeepEquals, []string{ filepath.Join("content", "p1.md"), "", "P1", "0001-01-01T00:00:00Z", "0001-01-01T00:00:00Z", "0001-01-01T00:00:00Z", "false", "https://example.org/p1/", }) } hugo-0.68.3/commands/mod.go000066400000000000000000000172431363637351300155020ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "errors" "fmt" "os" "path/filepath" "regexp" "github.com/gohugoio/hugo/modules" "github.com/spf13/cobra" ) var _ cmder = (*modCmd)(nil) type modCmd struct { *baseBuilderCmd } func (c *modCmd) newVerifyCmd() *cobra.Command { var clean bool verifyCmd := &cobra.Command{ Use: "verify", Short: "Verify dependencies.", Long: `Verify checks that the dependencies of the current module, which are stored in a local downloaded source cache, have not been modified since being downloaded. `, RunE: func(cmd *cobra.Command, args []string) error { return c.withModsClient(true, func(c *modules.Client) error { return c.Verify(clean) }) }, } verifyCmd.Flags().BoolVarP(&clean, "clean", "", false, "delete module cache for dependencies that fail verification") return verifyCmd } var moduleNotFoundRe = regexp.MustCompile("module.*not found") func (c *modCmd) newCleanCmd() *cobra.Command { var pattern string var all bool cmd := &cobra.Command{ Use: "clean", Short: "Delete the Hugo Module cache for the current project.", Long: `Delete the Hugo Module cache for the current project. Note that after you run this command, all of your dependencies will be re-downloaded next time you run "hugo". Also note that if you configure a positive maxAge for the "modules" file cache, it will also be cleaned as part of "hugo --gc". `, RunE: func(cmd *cobra.Command, args []string) error { if all { com, err := c.initConfig(false) if err != nil && !moduleNotFoundRe.MatchString(err.Error()) { return err } _, err = com.hugo().FileCaches.ModulesCache().Prune(true) return err } return c.withModsClient(true, func(c *modules.Client) error { return c.Clean(pattern) }) }, } cmd.Flags().StringVarP(&pattern, "pattern", "", "", `pattern matching module paths to clean (all if not set), e.g. "**hugo*"`) cmd.Flags().BoolVarP(&all, "all", "", false, "clean entire module cache") return cmd } func (b *commandsBuilder) newModCmd() *modCmd { c := &modCmd{} const commonUsage = ` Note that Hugo will always start out by resolving the components defined in the site configuration, provided by a _vendor directory (if no --ignoreVendor flag provided), Go Modules, or a folder inside the themes directory, in that order. See https://gohugo.io/hugo-modules/ for more information. ` cmd := &cobra.Command{ Use: "mod", Short: "Various Hugo Modules helpers.", Long: `Various helpers to help manage the modules in your project's dependency graph. Most operations here requires a Go version installed on your system (>= Go 1.12) and the relevant VCS client (typically Git). This is not needed if you only operate on modules inside /themes or if you have vendored them via "hugo mod vendor". ` + commonUsage, RunE: nil, } cmd.AddCommand( &cobra.Command{ Use: "get", DisableFlagParsing: true, Short: "Resolves dependencies in your current Hugo Project.", Long: ` Resolves dependencies in your current Hugo Project. Some examples: Install the latest version possible for a given module: hugo mod get github.com/gohugoio/testshortcodes Install a specific version: hugo mod get github.com/gohugoio/testshortcodes@v0.3.0 Install the latest versions of all module dependencies: hugo mod get -u hugo mod get -u ./... (recursive) Run "go help get" for more information. All flags available for "go get" is also relevant here. ` + commonUsage, RunE: func(cmd *cobra.Command, args []string) error { // We currently just pass on the flags we get to Go and // need to do the flag handling manually. if len(args) == 1 && args[0] == "-h" { return cmd.Help() } var lastArg string if len(args) != 0 { lastArg = args[len(args)-1] } if lastArg == "./..." { args = args[:len(args)-1] // Do a recursive update. dirname, err := os.Getwd() if err != nil { return err } // Sanity check. We do recursive walking and want to avoid // accidents. if len(dirname) < 5 { return errors.New("must not be run from the file system root") } filepath.Walk(dirname, func(path string, info os.FileInfo, err error) error { if info.IsDir() { return nil } if info.Name() == "go.mod" { // Found a module. dir := filepath.Dir(path) fmt.Println("Update module in", dir) c.source = dir err := c.withModsClient(false, func(c *modules.Client) error { if len(args) == 1 && args[0] == "-h" { return cmd.Help() } return c.Get(args...) }) if err != nil { return err } } return nil }) return nil } return c.withModsClient(false, func(c *modules.Client) error { return c.Get(args...) }) }, }, &cobra.Command{ Use: "graph", Short: "Print a module dependency graph.", Long: `Print a module dependency graph with information about module status (disabled, vendored). Note that for vendored modules, that is the version listed and not the one from go.mod. `, RunE: func(cmd *cobra.Command, args []string) error { return c.withModsClient(true, func(c *modules.Client) error { return c.Graph(os.Stdout) }) }, }, &cobra.Command{ Use: "init", Short: "Initialize this project as a Hugo Module.", Long: `Initialize this project as a Hugo Module. It will try to guess the module path, but you may help by passing it as an argument, e.g: hugo mod init github.com/gohugoio/testshortcodes Note that Hugo Modules supports multi-module projects, so you can initialize a Hugo Module inside a subfolder on GitHub, as one example. `, RunE: func(cmd *cobra.Command, args []string) error { var path string if len(args) >= 1 { path = args[0] } return c.withModsClient(false, func(c *modules.Client) error { return c.Init(path) }) }, }, &cobra.Command{ Use: "vendor", Short: "Vendor all module dependencies into the _vendor directory.", Long: `Vendor all module dependencies into the _vendor directory. If a module is vendored, that is where Hugo will look for it's dependencies. `, RunE: func(cmd *cobra.Command, args []string) error { return c.withModsClient(true, func(c *modules.Client) error { return c.Vendor() }) }, }, c.newVerifyCmd(), &cobra.Command{ Use: "tidy", Short: "Remove unused entries in go.mod and go.sum.", RunE: func(cmd *cobra.Command, args []string) error { return c.withModsClient(true, func(c *modules.Client) error { return c.Tidy() }) }, }, c.newCleanCmd(), ) c.baseBuilderCmd = b.newBuilderCmd(cmd) return c } func (c *modCmd) withModsClient(failOnMissingConfig bool, f func(*modules.Client) error) error { com, err := c.initConfig(failOnMissingConfig) if err != nil { return err } return f(com.hugo().ModulesClient) } func (c *modCmd) initConfig(failOnNoConfig bool) (*commandeer, error) { com, err := initializeConfig(failOnNoConfig, false, &c.hugoBuilderCommon, c, nil) if err != nil { return nil, err } return com, nil } hugo-0.68.3/commands/new.go000066400000000000000000000067011363637351300155110ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "bytes" "os" "path/filepath" "strings" "github.com/gohugoio/hugo/create" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugolib" "github.com/spf13/afero" "github.com/spf13/cobra" jww "github.com/spf13/jwalterweatherman" ) var _ cmder = (*newCmd)(nil) type newCmd struct { contentEditor string contentType string *baseBuilderCmd } func (b *commandsBuilder) newNewCmd() *newCmd { cmd := &cobra.Command{ Use: "new [path]", Short: "Create new content for your site", Long: `Create a new content file and automatically set the date and title. It will guess which kind of file to create based on the path provided. You can also specify the kind with ` + "`-k KIND`" + `. If archetypes are provided in your theme or site, they will be used. Ensure you run this within the root directory of your site.`, } cc := &newCmd{baseBuilderCmd: b.newBuilderCmd(cmd)} cmd.Flags().StringVarP(&cc.contentType, "kind", "k", "", "content type to create") cmd.Flags().StringVar(&cc.contentEditor, "editor", "", "edit new content with this editor, if provided") cmd.AddCommand(b.newNewSiteCmd().getCommand()) cmd.AddCommand(b.newNewThemeCmd().getCommand()) cmd.RunE = cc.newContent return cc } func (n *newCmd) newContent(cmd *cobra.Command, args []string) error { cfgInit := func(c *commandeer) error { if cmd.Flags().Changed("editor") { c.Set("newContentEditor", n.contentEditor) } return nil } c, err := initializeConfig(true, false, &n.hugoBuilderCommon, n, cfgInit) if err != nil { return err } if len(args) < 1 { return newUserError("path needs to be provided") } createPath := args[0] var kind string createPath, kind = newContentPathSection(c.hugo(), createPath) if n.contentType != "" { kind = n.contentType } return create.NewContent(c.hugo(), kind, createPath) } func mkdir(x ...string) { p := filepath.Join(x...) err := os.MkdirAll(p, 0777) // before umask if err != nil { jww.FATAL.Fatalln(err) } } func touchFile(fs afero.Fs, x ...string) { inpath := filepath.Join(x...) mkdir(filepath.Dir(inpath)) err := helpers.WriteToDisk(inpath, bytes.NewReader([]byte{}), fs) if err != nil { jww.FATAL.Fatalln(err) } } func newContentPathSection(h *hugolib.HugoSites, path string) (string, string) { // Forward slashes is used in all examples. Convert if needed. // Issue #1133 createpath := filepath.FromSlash(path) if h != nil { for _, dir := range h.BaseFs.Content.Dirs { createpath = strings.TrimPrefix(createpath, dir.Meta().Filename()) } } var section string // assume the first directory is the section (kind) if strings.Contains(createpath[1:], helpers.FilePathSeparator) { parts := strings.Split(strings.TrimPrefix(createpath, helpers.FilePathSeparator), helpers.FilePathSeparator) if len(parts) > 0 { section = parts[0] } } return createpath, section } hugo-0.68.3/commands/new_content_test.go000066400000000000000000000016621363637351300203030ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "path/filepath" "testing" qt "github.com/frankban/quicktest" ) // Issue #1133 func TestNewContentPathSectionWithForwardSlashes(t *testing.T) { c := qt.New(t) p, s := newContentPathSection(nil, "/post/new.md") c.Assert(p, qt.Equals, filepath.FromSlash("/post/new.md")) c.Assert(s, qt.Equals, "post") } hugo-0.68.3/commands/new_site.go000066400000000000000000000112571363637351300165370ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "bytes" "errors" "path/filepath" "strings" "github.com/gohugoio/hugo/parser/metadecoders" _errors "github.com/pkg/errors" "github.com/gohugoio/hugo/create" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/parser" "github.com/spf13/cobra" jww "github.com/spf13/jwalterweatherman" "github.com/spf13/viper" ) var _ cmder = (*newSiteCmd)(nil) type newSiteCmd struct { configFormat string *baseBuilderCmd } func (b *commandsBuilder) newNewSiteCmd() *newSiteCmd { cc := &newSiteCmd{} cmd := &cobra.Command{ Use: "site [path]", Short: "Create a new site (skeleton)", Long: `Create a new site in the provided directory. The new site will have the correct structure, but no content or theme yet. Use ` + "`hugo new [contentPath]`" + ` to create new content.`, RunE: cc.newSite, } cmd.Flags().StringVarP(&cc.configFormat, "format", "f", "toml", "config & frontmatter format") cmd.Flags().Bool("force", false, "init inside non-empty directory") cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd) return cc } func (n *newSiteCmd) doNewSite(fs *hugofs.Fs, basepath string, force bool) error { archeTypePath := filepath.Join(basepath, "archetypes") dirs := []string{ filepath.Join(basepath, "layouts"), filepath.Join(basepath, "content"), archeTypePath, filepath.Join(basepath, "static"), filepath.Join(basepath, "data"), filepath.Join(basepath, "themes"), } if exists, _ := helpers.Exists(basepath, fs.Source); exists { if isDir, _ := helpers.IsDir(basepath, fs.Source); !isDir { return errors.New(basepath + " already exists but not a directory") } isEmpty, _ := helpers.IsEmpty(basepath, fs.Source) switch { case !isEmpty && !force: return errors.New(basepath + " already exists and is not empty. See --force.") case !isEmpty && force: all := append(dirs, filepath.Join(basepath, "config."+n.configFormat)) for _, path := range all { if exists, _ := helpers.Exists(path, fs.Source); exists { return errors.New(path + " already exists") } } } } for _, dir := range dirs { if err := fs.Source.MkdirAll(dir, 0777); err != nil { return _errors.Wrap(err, "Failed to create dir") } } createConfig(fs, basepath, n.configFormat) // Create a default archetype file. helpers.SafeWriteToDisk(filepath.Join(archeTypePath, "default.md"), strings.NewReader(create.ArchetypeTemplateTemplate), fs.Source) jww.FEEDBACK.Printf("Congratulations! Your new Hugo site is created in %s.\n\n", basepath) jww.FEEDBACK.Println(nextStepsText()) return nil } // newSite creates a new Hugo site and initializes a structured Hugo directory. func (n *newSiteCmd) newSite(cmd *cobra.Command, args []string) error { if len(args) < 1 { return newUserError("path needs to be provided") } createpath, err := filepath.Abs(filepath.Clean(args[0])) if err != nil { return newUserError(err) } forceNew, _ := cmd.Flags().GetBool("force") return n.doNewSite(hugofs.NewDefault(viper.New()), createpath, forceNew) } func createConfig(fs *hugofs.Fs, inpath string, kind string) (err error) { in := map[string]string{ "baseURL": "http://example.org/", "title": "My New Hugo Site", "languageCode": "en-us", } var buf bytes.Buffer err = parser.InterfaceToConfig(in, metadecoders.FormatFromString(kind), &buf) if err != nil { return err } return helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), &buf, fs.Source) } func nextStepsText() string { var nextStepsText bytes.Buffer nextStepsText.WriteString(`Just a few more steps and you're ready to go: 1. Download a theme into the same-named folder. Choose a theme from https://themes.gohugo.io/ or create your own with the "hugo new theme " command. 2. Perhaps you want to add some content. You can add single files with "hugo new `) nextStepsText.WriteString(filepath.Join("", ".")) nextStepsText.WriteString(`". 3. Start the built-in live server via "hugo server". Visit https://gohugo.io/ for quickstart guide and full documentation.`) return nextStepsText.String() } hugo-0.68.3/commands/new_theme.go000066400000000000000000000124221363637351300166700ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "bytes" "errors" "path/filepath" "strings" "time" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugofs" "github.com/spf13/cobra" jww "github.com/spf13/jwalterweatherman" ) var _ cmder = (*newThemeCmd)(nil) type newThemeCmd struct { *baseBuilderCmd } func (b *commandsBuilder) newNewThemeCmd() *newThemeCmd { cc := &newThemeCmd{} cmd := &cobra.Command{ Use: "theme [name]", Short: "Create a new theme", Long: `Create a new theme (skeleton) called [name] in the current directory. New theme is a skeleton. Please add content to the touched files. Add your name to the copyright line in the license and adjust the theme.toml file as you see fit.`, RunE: cc.newTheme, } cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd) return cc } // newTheme creates a new Hugo theme template func (n *newThemeCmd) newTheme(cmd *cobra.Command, args []string) error { c, err := initializeConfig(false, false, &n.hugoBuilderCommon, n, nil) if err != nil { return err } if len(args) < 1 { return newUserError("theme name needs to be provided") } createpath := c.hugo().PathSpec.AbsPathify(filepath.Join(c.Cfg.GetString("themesDir"), args[0])) jww.FEEDBACK.Println("Creating theme at", createpath) cfg := c.DepsCfg if x, _ := helpers.Exists(createpath, cfg.Fs.Source); x { return errors.New(createpath + " already exists") } mkdir(createpath, "layouts", "_default") mkdir(createpath, "layouts", "partials") touchFile(cfg.Fs.Source, createpath, "layouts", "index.html") touchFile(cfg.Fs.Source, createpath, "layouts", "404.html") touchFile(cfg.Fs.Source, createpath, "layouts", "_default", "list.html") touchFile(cfg.Fs.Source, createpath, "layouts", "_default", "single.html") baseofDefault := []byte(` {{- partial "head.html" . -}} {{- partial "header.html" . -}}
{{- block "main" . }}{{- end }}
{{- partial "footer.html" . -}} `) err = helpers.WriteToDisk(filepath.Join(createpath, "layouts", "_default", "baseof.html"), bytes.NewReader(baseofDefault), cfg.Fs.Source) if err != nil { return err } touchFile(cfg.Fs.Source, createpath, "layouts", "partials", "head.html") touchFile(cfg.Fs.Source, createpath, "layouts", "partials", "header.html") touchFile(cfg.Fs.Source, createpath, "layouts", "partials", "footer.html") mkdir(createpath, "archetypes") archDefault := []byte("+++\n+++\n") err = helpers.WriteToDisk(filepath.Join(createpath, "archetypes", "default.md"), bytes.NewReader(archDefault), cfg.Fs.Source) if err != nil { return err } mkdir(createpath, "static", "js") mkdir(createpath, "static", "css") by := []byte(`The MIT License (MIT) Copyright (c) ` + time.Now().Format("2006") + ` YOUR_NAME_HERE 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. `) err = helpers.WriteToDisk(filepath.Join(createpath, "LICENSE"), bytes.NewReader(by), cfg.Fs.Source) if err != nil { return err } n.createThemeMD(cfg.Fs, createpath) return nil } func (n *newThemeCmd) createThemeMD(fs *hugofs.Fs, inpath string) (err error) { by := []byte(`# theme.toml template for a Hugo theme # See https://github.com/gohugoio/hugoThemes#themetoml for an example name = "` + strings.Title(helpers.MakeTitle(filepath.Base(inpath))) + `" license = "MIT" licenselink = "https://github.com/yourname/yourtheme/blob/master/LICENSE" description = "" homepage = "http://example.com/" tags = [] features = [] min_version = "0.41" [author] name = "" homepage = "" # If porting an existing theme [original] name = "" homepage = "" repo = "" `) err = helpers.WriteToDisk(filepath.Join(inpath, "theme.toml"), bytes.NewReader(by), fs.Source) if err != nil { return } return nil } hugo-0.68.3/commands/release.go000066400000000000000000000037701363637351300163430ustar00rootroot00000000000000// +build release // Copyright 2017-present The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "errors" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/releaser" "github.com/spf13/cobra" ) var _ cmder = (*releaseCommandeer)(nil) type releaseCommandeer struct { cmd *cobra.Command version string skipPublish bool try bool } func createReleaser() cmder { // Note: This is a command only meant for internal use and must be run // via "go run -tags release main.go release" on the actual code base that is in the release. r := &releaseCommandeer{ cmd: &cobra.Command{ Use: "release", Short: "Release a new version of Hugo.", Hidden: true, }, } r.cmd.RunE = func(cmd *cobra.Command, args []string) error { return r.release() } r.cmd.PersistentFlags().StringVarP(&r.version, "rel", "r", "", "new release version, i.e. 0.25.1") r.cmd.PersistentFlags().BoolVarP(&r.skipPublish, "skip-publish", "", false, "skip all publishing pipes of the release") r.cmd.PersistentFlags().BoolVarP(&r.try, "try", "", false, "simulate a release, i.e. no changes") return r } func (c *releaseCommandeer) getCommand() *cobra.Command { return c.cmd } func (c *releaseCommandeer) flagsToConfig(cfg config.Provider) { } func (r *releaseCommandeer) release() error { if r.version == "" { return errors.New("must set the --rel flag to the relevant version number") } return releaser.New(r.version, r.skipPublish, r.try).Run() } hugo-0.68.3/commands/release_noop.go000066400000000000000000000012751363637351300173740ustar00rootroot00000000000000// +build !release // Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands func createReleaser() cmder { return &nilCommand{} } hugo-0.68.3/commands/server.go000066400000000000000000000350051363637351300162250ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "bytes" "fmt" "io" "net" "net/http" "net/url" "os" "os/signal" "path/filepath" "regexp" "runtime" "strconv" "strings" "sync" "syscall" "time" "github.com/pkg/errors" "github.com/gohugoio/hugo/livereload" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/helpers" "github.com/spf13/afero" "github.com/spf13/cobra" jww "github.com/spf13/jwalterweatherman" ) type serverCmd struct { // Can be used to stop the server. Useful in tests stop <-chan bool disableLiveReload bool navigateToChanged bool renderToDisk bool serverAppend bool serverInterface string serverPort int liveReloadPort int serverWatch bool noHTTPCache bool disableFastRender bool disableBrowserError bool *baseBuilderCmd } func (b *commandsBuilder) newServerCmd() *serverCmd { return b.newServerCmdSignaled(nil) } func (b *commandsBuilder) newServerCmdSignaled(stop <-chan bool) *serverCmd { cc := &serverCmd{stop: stop} cc.baseBuilderCmd = b.newBuilderCmd(&cobra.Command{ Use: "server", Aliases: []string{"serve"}, Short: "A high performance webserver", Long: `Hugo provides its own webserver which builds and serves the site. While hugo server is high performance, it is a webserver with limited options. Many run it in production, but the standard behavior is for people to use it in development and use a more full featured server such as Nginx or Caddy. 'hugo server' will avoid writing the rendered and served content to disk, preferring to store it in memory. By default hugo will also watch your files for any changes you make and automatically rebuild the site. It will then live reload any open browser pages and push the latest content to them. As most Hugo sites are built in a fraction of a second, you will be able to save and see your changes nearly instantly.`, RunE: cc.server, }) cc.cmd.Flags().IntVarP(&cc.serverPort, "port", "p", 1313, "port on which the server will listen") cc.cmd.Flags().IntVar(&cc.liveReloadPort, "liveReloadPort", -1, "port for live reloading (i.e. 443 in HTTPS proxy situations)") cc.cmd.Flags().StringVarP(&cc.serverInterface, "bind", "", "127.0.0.1", "interface to which the server will bind") cc.cmd.Flags().BoolVarP(&cc.serverWatch, "watch", "w", true, "watch filesystem for changes and recreate as needed") cc.cmd.Flags().BoolVar(&cc.noHTTPCache, "noHTTPCache", false, "prevent HTTP caching") cc.cmd.Flags().BoolVarP(&cc.serverAppend, "appendPort", "", true, "append port to baseURL") cc.cmd.Flags().BoolVar(&cc.disableLiveReload, "disableLiveReload", false, "watch without enabling live browser reload on rebuild") cc.cmd.Flags().BoolVar(&cc.navigateToChanged, "navigateToChanged", false, "navigate to changed content file on live browser reload") cc.cmd.Flags().BoolVar(&cc.renderToDisk, "renderToDisk", false, "render to Destination path (default is render to memory & serve from there)") cc.cmd.Flags().BoolVar(&cc.disableFastRender, "disableFastRender", false, "enables full re-renders on changes") cc.cmd.Flags().BoolVar(&cc.disableBrowserError, "disableBrowserError", false, "do not show build errors in the browser") cc.cmd.Flags().String("memstats", "", "log memory usage to this file") cc.cmd.Flags().String("meminterval", "100ms", "interval to poll memory usage (requires --memstats), valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".") return cc } type filesOnlyFs struct { fs http.FileSystem } type noDirFile struct { http.File } func (fs filesOnlyFs) Open(name string) (http.File, error) { f, err := fs.fs.Open(name) if err != nil { return nil, err } return noDirFile{f}, nil } func (f noDirFile) Readdir(count int) ([]os.FileInfo, error) { return nil, nil } var serverPorts []int func (sc *serverCmd) server(cmd *cobra.Command, args []string) error { // If a Destination is provided via flag write to disk destination, _ := cmd.Flags().GetString("destination") if destination != "" { sc.renderToDisk = true } var serverCfgInit sync.Once cfgInit := func(c *commandeer) error { c.Set("renderToMemory", !sc.renderToDisk) if cmd.Flags().Changed("navigateToChanged") { c.Set("navigateToChanged", sc.navigateToChanged) } if cmd.Flags().Changed("disableLiveReload") { c.Set("disableLiveReload", sc.disableLiveReload) } if cmd.Flags().Changed("disableFastRender") { c.Set("disableFastRender", sc.disableFastRender) } if cmd.Flags().Changed("disableBrowserError") { c.Set("disableBrowserError", sc.disableBrowserError) } if sc.serverWatch { c.Set("watch", true) } // TODO(bep) yes, we should fix. if !c.languagesConfigured { return nil } var err error // We can only do this once. serverCfgInit.Do(func() { serverPorts = make([]int, 1) if c.languages.IsMultihost() { if !sc.serverAppend { err = newSystemError("--appendPort=false not supported when in multihost mode") } serverPorts = make([]int, len(c.languages)) } currentServerPort := sc.serverPort for i := 0; i < len(serverPorts); i++ { l, err := net.Listen("tcp", net.JoinHostPort(sc.serverInterface, strconv.Itoa(currentServerPort))) if err == nil { l.Close() serverPorts[i] = currentServerPort } else { if i == 0 && sc.cmd.Flags().Changed("port") { // port set explicitly by user -- he/she probably meant it! err = newSystemErrorF("Server startup failed: %s", err) } c.logger.FEEDBACK.Println("port", sc.serverPort, "already in use, attempting to use an available port") sp, err := helpers.FindAvailablePort() if err != nil { err = newSystemError("Unable to find alternative port to use:", err) } serverPorts[i] = sp.Port } currentServerPort = serverPorts[i] + 1 } }) c.serverPorts = serverPorts c.Set("port", sc.serverPort) if sc.liveReloadPort != -1 { c.Set("liveReloadPort", sc.liveReloadPort) } else { c.Set("liveReloadPort", serverPorts[0]) } isMultiHost := c.languages.IsMultihost() for i, language := range c.languages { var serverPort int if isMultiHost { serverPort = serverPorts[i] } else { serverPort = serverPorts[0] } baseURL, err := sc.fixURL(language, sc.baseURL, serverPort) if err != nil { return nil } if isMultiHost { language.Set("baseURL", baseURL) } if i == 0 { c.Set("baseURL", baseURL) } } return err } if err := memStats(); err != nil { jww.WARN.Println("memstats error:", err) } c, err := initializeConfig(true, true, &sc.hugoBuilderCommon, sc, cfgInit) if err != nil { return err } if err := c.serverBuild(); err != nil { return err } for _, s := range c.hugo().Sites { s.RegisterMediaTypes() } // Watch runs its own server as part of the routine if sc.serverWatch { watchDirs, err := c.getDirList() if err != nil { return err } watchGroups := helpers.ExtractAndGroupRootPaths(watchDirs) for _, group := range watchGroups { jww.FEEDBACK.Printf("Watching for changes in %s\n", group) } watcher, err := c.newWatcher(watchDirs...) if err != nil { return err } defer watcher.Close() } return c.serve(sc) } func getRootWatchDirsStr(baseDir string, watchDirs []string) string { relWatchDirs := make([]string, len(watchDirs)) for i, dir := range watchDirs { relWatchDirs[i], _ = helpers.GetRelativePath(dir, baseDir) } return strings.Join(helpers.UniqueStringsSorted(helpers.ExtractRootPaths(relWatchDirs)), ",") } type fileServer struct { baseURLs []string roots []string errorTemplate func(err interface{}) (io.Reader, error) c *commandeer s *serverCmd } func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, error) { baseURL := f.baseURLs[i] root := f.roots[i] port := f.c.serverPorts[i] publishDir := f.c.Cfg.GetString("publishDir") if root != "" { publishDir = filepath.Join(publishDir, root) } absPublishDir := f.c.hugo().PathSpec.AbsPathify(publishDir) jww.FEEDBACK.Printf("Environment: %q", f.c.hugo().Deps.Site.Hugo().Environment) if i == 0 { if f.s.renderToDisk { jww.FEEDBACK.Println("Serving pages from " + absPublishDir) } else { jww.FEEDBACK.Println("Serving pages from memory") } } httpFs := afero.NewHttpFs(f.c.destinationFs) fs := filesOnlyFs{httpFs.Dir(absPublishDir)} if i == 0 && f.c.fastRenderMode { jww.FEEDBACK.Println("Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender") } // We're only interested in the path u, err := url.Parse(baseURL) if err != nil { return nil, "", "", errors.Wrap(err, "Invalid baseURL") } decorate := func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if f.c.showErrorInBrowser { // First check the error state err := f.c.getErrorWithContext() if err != nil { f.c.wasError = true w.WriteHeader(500) r, err := f.errorTemplate(err) if err != nil { f.c.logger.ERROR.Println(err) } port = 1313 if !f.c.paused { port = f.c.Cfg.GetInt("liveReloadPort") } fmt.Fprint(w, injectLiveReloadScript(r, port)) return } } if f.s.noHTTPCache { w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0") w.Header().Set("Pragma", "no-cache") } for _, header := range f.c.serverConfig.Match(r.RequestURI) { w.Header().Set(header.Key, header.Value) } if f.c.fastRenderMode && f.c.buildErr == nil { p := r.RequestURI if strings.HasSuffix(p, "/") || strings.HasSuffix(p, "html") || strings.HasSuffix(p, "htm") { if !f.c.visitedURLs.Contains(p) { // If not already on stack, re-render that single page. if err := f.c.partialReRender(p); err != nil { f.c.handleBuildErr(err, fmt.Sprintf("Failed to render %q", p)) if f.c.showErrorInBrowser { http.Redirect(w, r, p, http.StatusMovedPermanently) return } } } f.c.visitedURLs.Add(p) } } h.ServeHTTP(w, r) }) } fileserver := decorate(http.FileServer(fs)) mu := http.NewServeMux() if u.Path == "" || u.Path == "/" { mu.Handle("/", fileserver) } else { mu.Handle(u.Path, http.StripPrefix(u.Path, fileserver)) } endpoint := net.JoinHostPort(f.s.serverInterface, strconv.Itoa(port)) return mu, u.String(), endpoint, nil } var logErrorRe = regexp.MustCompile(`(?s)ERROR \d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} `) func removeErrorPrefixFromLog(content string) string { return logErrorRe.ReplaceAllLiteralString(content, "") } func (c *commandeer) serve(s *serverCmd) error { isMultiHost := c.hugo().IsMultihost() var ( baseURLs []string roots []string ) if isMultiHost { for _, s := range c.hugo().Sites { baseURLs = append(baseURLs, s.BaseURL.String()) roots = append(roots, s.Language().Lang) } } else { s := c.hugo().Sites[0] baseURLs = []string{s.BaseURL.String()} roots = []string{""} } templ, err := c.hugo().TextTmpl().Parse("__default_server_error", buildErrorTemplate) if err != nil { return err } srv := &fileServer{ baseURLs: baseURLs, roots: roots, c: c, s: s, errorTemplate: func(ctx interface{}) (io.Reader, error) { b := &bytes.Buffer{} err := c.hugo().Tmpl().Execute(templ, b, ctx) return b, err }, } doLiveReload := !c.Cfg.GetBool("disableLiveReload") if doLiveReload { livereload.Initialize() } var sigs = make(chan os.Signal, 1) signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) for i := range baseURLs { mu, serverURL, endpoint, err := srv.createEndpoint(i) if doLiveReload { mu.HandleFunc("/livereload.js", livereload.ServeJS) mu.HandleFunc("/livereload", livereload.Handler) } jww.FEEDBACK.Printf("Web Server is available at %s (bind address %s)\n", serverURL, s.serverInterface) go func() { err = http.ListenAndServe(endpoint, mu) if err != nil { c.logger.ERROR.Printf("Error: %s\n", err.Error()) os.Exit(1) } }() } jww.FEEDBACK.Println("Press Ctrl+C to stop") if s.stop != nil { select { case <-sigs: case <-s.stop: } } else { <-sigs } return nil } // fixURL massages the baseURL into a form needed for serving // all pages correctly. func (sc *serverCmd) fixURL(cfg config.Provider, s string, port int) (string, error) { useLocalhost := false if s == "" { s = cfg.GetString("baseURL") useLocalhost = true } if !strings.HasSuffix(s, "/") { s = s + "/" } // do an initial parse of the input string u, err := url.Parse(s) if err != nil { return "", err } // if no Host is defined, then assume that no schema or double-slash were // present in the url. Add a double-slash and make a best effort attempt. if u.Host == "" && s != "/" { s = "//" + s u, err = url.Parse(s) if err != nil { return "", err } } if useLocalhost { if u.Scheme == "https" { u.Scheme = "http" } u.Host = "localhost" } if sc.serverAppend { if strings.Contains(u.Host, ":") { u.Host, _, err = net.SplitHostPort(u.Host) if err != nil { return "", errors.Wrap(err, "Failed to split baseURL hostpost") } } u.Host += fmt.Sprintf(":%d", port) } return u.String(), nil } func memStats() error { b := newCommandsBuilder() sc := b.newServerCmd().getCommand() memstats := sc.Flags().Lookup("memstats").Value.String() if memstats != "" { interval, err := time.ParseDuration(sc.Flags().Lookup("meminterval").Value.String()) if err != nil { interval, _ = time.ParseDuration("100ms") } fileMemStats, err := os.Create(memstats) if err != nil { return err } fileMemStats.WriteString("# Time\tHeapSys\tHeapAlloc\tHeapIdle\tHeapReleased\n") go func() { var stats runtime.MemStats start := time.Now().UnixNano() for { runtime.ReadMemStats(&stats) if fileMemStats != nil { fileMemStats.WriteString(fmt.Sprintf("%d\t%d\t%d\t%d\t%d\n", (time.Now().UnixNano()-start)/1000000, stats.HeapSys, stats.HeapAlloc, stats.HeapIdle, stats.HeapReleased)) time.Sleep(interval) } else { break } } }() } return nil } hugo-0.68.3/commands/server_errors.go000066400000000000000000000046101363637351300176170ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "bytes" "io" "github.com/gohugoio/hugo/transform" "github.com/gohugoio/hugo/transform/livereloadinject" ) var buildErrorTemplate = ` Hugo Server: Error
{{ highlight .Error "apl" "linenos=false,noclasses=true,style=paraiso-dark" }} {{ with .File }} {{ $params := printf "noclasses=true,style=paraiso-dark,linenos=table,hl_lines=%d,linenostart=%d" (add .LinesPos 1) (sub .Position.LineNumber .LinesPos) }} {{ $lexer := .ChromaLexer | default "go-html-template" }} {{ highlight (delimit .Lines "\n") $lexer $params }} {{ end }} {{ with .StackTrace }} {{ highlight . "apl" "noclasses=true,style=paraiso-dark" }} {{ end }}

{{ .Version }}

Reload Page
` func injectLiveReloadScript(src io.Reader, port int) string { var b bytes.Buffer chain := transform.Chain{livereloadinject.New(port)} chain.Apply(&b, src) return b.String() } hugo-0.68.3/commands/server_test.go000066400000000000000000000101721363637351300172620ustar00rootroot00000000000000// Copyright 2015 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "fmt" "net/http" "os" "runtime" "strings" "testing" "time" "github.com/gohugoio/hugo/helpers" qt "github.com/frankban/quicktest" "github.com/spf13/viper" ) func TestServer(t *testing.T) { if isWindowsCI() { // TODO(bep) not sure why server tests have started to fail on the Windows CI server. t.Skip("Skip server test on appveyor") } c := qt.New(t) dir, clean, err := createSimpleTestSite(t, testSiteConfig{}) defer clean() c.Assert(err, qt.IsNil) // Let us hope that this port is available on all systems ... port := 1331 defer func() { os.RemoveAll(dir) }() stop := make(chan bool) b := newCommandsBuilder() scmd := b.newServerCmdSignaled(stop) cmd := scmd.getCommand() cmd.SetArgs([]string{"-s=" + dir, fmt.Sprintf("-p=%d", port)}) go func() { _, err = cmd.ExecuteC() c.Assert(err, qt.IsNil) }() // There is no way to know exactly when the server is ready for connections. // We could improve by something like https://golang.org/pkg/net/http/httptest/#Server // But for now, let us sleep and pray! time.Sleep(2 * time.Second) resp, err := http.Get("http://localhost:1331/") c.Assert(err, qt.IsNil) defer resp.Body.Close() homeContent := helpers.ReaderToString(resp.Body) c.Assert(homeContent, qt.Contains, "List: Hugo Commands") c.Assert(homeContent, qt.Contains, "Environment: development") // Stop the server. stop <- true } func TestFixURL(t *testing.T) { type data struct { TestName string CLIBaseURL string CfgBaseURL string AppendPort bool Port int Result string } tests := []data{ {"Basic http localhost", "", "http://foo.com", true, 1313, "http://localhost:1313/"}, {"Basic https production, http localhost", "", "https://foo.com", true, 1313, "http://localhost:1313/"}, {"Basic subdir", "", "http://foo.com/bar", true, 1313, "http://localhost:1313/bar/"}, {"Basic production", "http://foo.com", "http://foo.com", false, 80, "http://foo.com/"}, {"Production subdir", "http://foo.com/bar", "http://foo.com/bar", false, 80, "http://foo.com/bar/"}, {"No http", "", "foo.com", true, 1313, "//localhost:1313/"}, {"Override configured port", "", "foo.com:2020", true, 1313, "//localhost:1313/"}, {"No http production", "foo.com", "foo.com", false, 80, "//foo.com/"}, {"No http production with port", "foo.com", "foo.com", true, 2020, "//foo.com:2020/"}, {"No config", "", "", true, 1313, "//localhost:1313/"}, } for _, test := range tests { t.Run(test.TestName, func(t *testing.T) { b := newCommandsBuilder() s := b.newServerCmd() v := viper.New() baseURL := test.CLIBaseURL v.Set("baseURL", test.CfgBaseURL) s.serverAppend = test.AppendPort s.serverPort = test.Port result, err := s.fixURL(v, baseURL, s.serverPort) if err != nil { t.Errorf("Unexpected error %s", err) } if result != test.Result { t.Errorf("Expected %q, got %q", test.Result, result) } }) } } func TestRemoveErrorPrefixFromLog(t *testing.T) { c := qt.New(t) content := `ERROR 2018/10/07 13:11:12 Error while rendering "home": template: _default/baseof.html:4:3: executing "main" at : error calling partial: template: partials/logo.html:5:84: executing "partials/logo.html" at <$resized.AHeight>: can't evaluate field AHeight in type *resource.Image ERROR 2018/10/07 13:11:12 Rebuild failed: logged 1 error(s) ` withoutError := removeErrorPrefixFromLog(content) c.Assert(strings.Contains(withoutError, "ERROR"), qt.Equals, false) } func isWindowsCI() bool { return runtime.GOOS == "windows" && os.Getenv("CI") != "" } hugo-0.68.3/commands/static_syncer.go000066400000000000000000000106601363637351300175710ustar00rootroot00000000000000// Copyright 2017 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "os" "path/filepath" "github.com/gohugoio/hugo/hugolib/filesystems" "github.com/fsnotify/fsnotify" "github.com/gohugoio/hugo/helpers" "github.com/spf13/fsync" ) type staticSyncer struct { c *commandeer } func newStaticSyncer(c *commandeer) (*staticSyncer, error) { return &staticSyncer{c: c}, nil } func (s *staticSyncer) isStatic(filename string) bool { return s.c.hugo().BaseFs.SourceFilesystems.IsStatic(filename) } func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error { c := s.c syncFn := func(sourceFs *filesystems.SourceFilesystem) (uint64, error) { publishDir := c.hugo().PathSpec.PublishDir // If root, remove the second '/' if publishDir == "//" { publishDir = helpers.FilePathSeparator } if sourceFs.PublishFolder != "" { publishDir = filepath.Join(publishDir, sourceFs.PublishFolder) } syncer := fsync.NewSyncer() syncer.NoTimes = c.Cfg.GetBool("noTimes") syncer.NoChmod = c.Cfg.GetBool("noChmod") syncer.ChmodFilter = chmodFilter syncer.SrcFs = sourceFs.Fs syncer.DestFs = c.Fs.Destination // prevent spamming the log on changes logger := helpers.NewDistinctFeedbackLogger() for _, ev := range staticEvents { // Due to our approach of layering both directories and the content's rendered output // into one we can't accurately remove a file not in one of the source directories. // If a file is in the local static dir and also in the theme static dir and we remove // it from one of those locations we expect it to still exist in the destination // // If Hugo generates a file (from the content dir) over a static file // the content generated file should take precedence. // // Because we are now watching and handling individual events it is possible that a static // event that occupies the same path as a content generated file will take precedence // until a regeneration of the content takes places. // // Hugo assumes that these cases are very rare and will permit this bad behavior // The alternative is to track every single file and which pipeline rendered it // and then to handle conflict resolution on every event. fromPath := ev.Name relPath := sourceFs.MakePathRelative(fromPath) if relPath == "" { // Not member of this virtual host. continue } // Remove || rename is harder and will require an assumption. // Hugo takes the following approach: // If the static file exists in any of the static source directories after this event // Hugo will re-sync it. // If it does not exist in all of the static directories Hugo will remove it. // // This assumes that Hugo has not generated content on top of a static file and then removed // the source of that static file. In this case Hugo will incorrectly remove that file // from the published directory. if ev.Op&fsnotify.Rename == fsnotify.Rename || ev.Op&fsnotify.Remove == fsnotify.Remove { if _, err := sourceFs.Fs.Stat(relPath); os.IsNotExist(err) { // If file doesn't exist in any static dir, remove it toRemove := filepath.Join(publishDir, relPath) logger.Println("File no longer exists in static dir, removing", toRemove) _ = c.Fs.Destination.RemoveAll(toRemove) } else if err == nil { // If file still exists, sync it logger.Println("Syncing", relPath, "to", publishDir) if err := syncer.Sync(filepath.Join(publishDir, relPath), relPath); err != nil { c.logger.ERROR.Println(err) } } else { c.logger.ERROR.Println(err) } continue } // For all other event operations Hugo will sync static. logger.Println("Syncing", relPath, "to", publishDir) if err := syncer.Sync(filepath.Join(publishDir, relPath), relPath); err != nil { c.logger.ERROR.Println(err) } } return 0, nil } _, err := c.doWithPublishDirs(syncFn) return err } hugo-0.68.3/commands/version.go000066400000000000000000000023011363637351300163750ustar00rootroot00000000000000// Copyright 2015 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package commands import ( "github.com/gohugoio/hugo/common/hugo" "github.com/spf13/cobra" jww "github.com/spf13/jwalterweatherman" ) var _ cmder = (*versionCmd)(nil) type versionCmd struct { *baseCmd } func newVersionCmd() *versionCmd { return &versionCmd{ newBaseCmd(&cobra.Command{ Use: "version", Short: "Print the version number of Hugo", Long: `All software has versions. This is Hugo's.`, RunE: func(cmd *cobra.Command, args []string) error { printHugoVersion() return nil }, }), } } func printHugoVersion() { jww.FEEDBACK.Println(hugo.BuildVersionString()) } hugo-0.68.3/common/000077500000000000000000000000001363637351300140545ustar00rootroot00000000000000hugo-0.68.3/common/collections/000077500000000000000000000000001363637351300163725ustar00rootroot00000000000000hugo-0.68.3/common/collections/append.go000066400000000000000000000056521363637351300202000ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package collections import ( "fmt" "reflect" ) // Append appends from to a slice to and returns the resulting slice. // If length of from is one and the only element is a slice of same type as to, // it will be appended. func Append(to interface{}, from ...interface{}) (interface{}, error) { tov, toIsNil := indirect(reflect.ValueOf(to)) toIsNil = toIsNil || to == nil var tot reflect.Type if !toIsNil { if tov.Kind() != reflect.Slice { return nil, fmt.Errorf("expected a slice, got %T", to) } tot = tov.Type().Elem() toIsNil = tov.Len() == 0 if len(from) == 1 { fromv := reflect.ValueOf(from[0]) if fromv.Kind() == reflect.Slice { if toIsNil { // If we get nil []string, we just return the []string return from[0], nil } fromt := reflect.TypeOf(from[0]).Elem() // If we get []string []string, we append the from slice to to if tot == fromt { return reflect.AppendSlice(tov, fromv).Interface(), nil } else if !fromt.AssignableTo(tot) { // Fall back to a []interface{} slice. return appendToInterfaceSliceFromValues(tov, fromv) } } } } if toIsNil { return Slice(from...), nil } for _, f := range from { fv := reflect.ValueOf(f) if !fv.Type().AssignableTo(tot) { // Fall back to a []interface{} slice. tov, _ := indirect(reflect.ValueOf(to)) return appendToInterfaceSlice(tov, from...) } tov = reflect.Append(tov, fv) } return tov.Interface(), nil } func appendToInterfaceSliceFromValues(slice1, slice2 reflect.Value) ([]interface{}, error) { var tos []interface{} for _, slice := range []reflect.Value{slice1, slice2} { for i := 0; i < slice.Len(); i++ { tos = append(tos, slice.Index(i).Interface()) } } return tos, nil } func appendToInterfaceSlice(tov reflect.Value, from ...interface{}) ([]interface{}, error) { var tos []interface{} for i := 0; i < tov.Len(); i++ { tos = append(tos, tov.Index(i).Interface()) } tos = append(tos, from...) return tos, nil } // indirect is borrowed from the Go stdlib: 'text/template/exec.go' // TODO(bep) consolidate func indirect(v reflect.Value) (rv reflect.Value, isNil bool) { for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() { if v.IsNil() { return v, true } if v.Kind() == reflect.Interface && v.NumMethod() > 0 { break } } return v, false } hugo-0.68.3/common/collections/append_test.go000066400000000000000000000050501363637351300212270ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package collections import ( "html/template" "testing" qt "github.com/frankban/quicktest" ) func TestAppend(t *testing.T) { t.Parallel() c := qt.New(t) for _, test := range []struct { start interface{} addend []interface{} expected interface{} }{ {[]string{"a", "b"}, []interface{}{"c"}, []string{"a", "b", "c"}}, {[]string{"a", "b"}, []interface{}{"c", "d", "e"}, []string{"a", "b", "c", "d", "e"}}, {[]string{"a", "b"}, []interface{}{[]string{"c", "d", "e"}}, []string{"a", "b", "c", "d", "e"}}, {[]string{"a"}, []interface{}{"b", template.HTML("c")}, []interface{}{"a", "b", template.HTML("c")}}, {nil, []interface{}{"a", "b"}, []string{"a", "b"}}, {nil, []interface{}{nil}, []interface{}{nil}}, {[]interface{}{}, []interface{}{[]string{"c", "d", "e"}}, []string{"c", "d", "e"}}, {tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}}, []interface{}{&tstSlicer{"c"}}, tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}, &tstSlicer{"c"}}}, {&tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}}, []interface{}{&tstSlicer{"c"}}, tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}, &tstSlicer{"c"}}}, {testSlicerInterfaces{&tstSlicerIn1{"a"}, &tstSlicerIn1{"b"}}, []interface{}{&tstSlicerIn1{"c"}}, testSlicerInterfaces{&tstSlicerIn1{"a"}, &tstSlicerIn1{"b"}, &tstSlicerIn1{"c"}}}, //https://github.com/gohugoio/hugo/issues/5361 {[]string{"a", "b"}, []interface{}{tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}}}, []interface{}{"a", "b", &tstSlicer{"a"}, &tstSlicer{"b"}}}, {[]string{"a", "b"}, []interface{}{&tstSlicer{"a"}}, []interface{}{"a", "b", &tstSlicer{"a"}}}, // Errors {"", []interface{}{[]string{"a", "b"}}, false}, // No string concatenation. {"ab", []interface{}{"c"}, false}, } { result, err := Append(test.start, test.addend...) if b, ok := test.expected.(bool); ok && !b { c.Assert(err, qt.Not(qt.IsNil)) continue } c.Assert(err, qt.IsNil) c.Assert(result, qt.DeepEquals, test.expected) } } hugo-0.68.3/common/collections/collections.go000066400000000000000000000015631363637351300212440ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package collections contains common Hugo functionality related to collection // handling. package collections // Grouper defines a very generic way to group items by a given key. type Grouper interface { Group(key interface{}, items interface{}) (interface{}, error) } hugo-0.68.3/common/collections/slice.go000066400000000000000000000033401363637351300200200ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package collections import ( "reflect" ) // Slicer defines a very generic way to create a typed slice. This is used // in collections.Slice template func to get types such as Pages, PageGroups etc. // instead of the less useful []interface{}. type Slicer interface { Slice(items interface{}) (interface{}, error) } // Slice returns a slice of all passed arguments. func Slice(args ...interface{}) interface{} { if len(args) == 0 { return args } first := args[0] firstType := reflect.TypeOf(first) if firstType == nil { return args } if g, ok := first.(Slicer); ok { v, err := g.Slice(args) if err == nil { return v } // If Slice fails, the items are not of the same type and // []interface{} is the best we can do. return args } if len(args) > 1 { // This can be a mix of types. for i := 1; i < len(args); i++ { if firstType != reflect.TypeOf(args[i]) { // []interface{} is the best we can do return args } } } slice := reflect.MakeSlice(reflect.SliceOf(firstType), len(args), len(args)) for i, arg := range args { slice.Index(i).Set(reflect.ValueOf(arg)) } return slice.Interface() } hugo-0.68.3/common/collections/slice_test.go000066400000000000000000000061101363637351300210550ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package collections import ( "errors" "testing" qt "github.com/frankban/quicktest" ) var _ Slicer = (*tstSlicer)(nil) var _ Slicer = (*tstSlicerIn1)(nil) var _ Slicer = (*tstSlicerIn2)(nil) var _ testSlicerInterface = (*tstSlicerIn1)(nil) var _ testSlicerInterface = (*tstSlicerIn1)(nil) type testSlicerInterface interface { Name() string } type testSlicerInterfaces []testSlicerInterface type tstSlicerIn1 struct { TheName string } type tstSlicerIn2 struct { TheName string } type tstSlicer struct { TheName string } func (p *tstSlicerIn1) Slice(in interface{}) (interface{}, error) { items := in.([]interface{}) result := make(testSlicerInterfaces, len(items)) for i, v := range items { switch vv := v.(type) { case testSlicerInterface: result[i] = vv default: return nil, errors.New("invalid type") } } return result, nil } func (p *tstSlicerIn2) Slice(in interface{}) (interface{}, error) { items := in.([]interface{}) result := make(testSlicerInterfaces, len(items)) for i, v := range items { switch vv := v.(type) { case testSlicerInterface: result[i] = vv default: return nil, errors.New("invalid type") } } return result, nil } func (p *tstSlicerIn1) Name() string { return p.TheName } func (p *tstSlicerIn2) Name() string { return p.TheName } func (p *tstSlicer) Slice(in interface{}) (interface{}, error) { items := in.([]interface{}) result := make(tstSlicers, len(items)) for i, v := range items { switch vv := v.(type) { case *tstSlicer: result[i] = vv default: return nil, errors.New("invalid type") } } return result, nil } type tstSlicers []*tstSlicer func TestSlice(t *testing.T) { t.Parallel() c := qt.New(t) for i, test := range []struct { args []interface{} expected interface{} }{ {[]interface{}{"a", "b"}, []string{"a", "b"}}, {[]interface{}{&tstSlicer{"a"}, &tstSlicer{"b"}}, tstSlicers{&tstSlicer{"a"}, &tstSlicer{"b"}}}, {[]interface{}{&tstSlicer{"a"}, "b"}, []interface{}{&tstSlicer{"a"}, "b"}}, {[]interface{}{}, []interface{}{}}, {[]interface{}{nil}, []interface{}{nil}}, {[]interface{}{5, "b"}, []interface{}{5, "b"}}, {[]interface{}{&tstSlicerIn1{"a"}, &tstSlicerIn2{"b"}}, testSlicerInterfaces{&tstSlicerIn1{"a"}, &tstSlicerIn2{"b"}}}, {[]interface{}{&tstSlicerIn1{"a"}, &tstSlicer{"b"}}, []interface{}{&tstSlicerIn1{"a"}, &tstSlicer{"b"}}}, } { errMsg := qt.Commentf("[%d] %v", i, test.args) result := Slice(test.args...) c.Assert(test.expected, qt.DeepEquals, result, errMsg) } } hugo-0.68.3/common/herrors/000077500000000000000000000000001363637351300155405ustar00rootroot00000000000000hugo-0.68.3/common/herrors/error_locator.go000066400000000000000000000140521363637351300207450ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package errors contains common Hugo errors and error related utilities. package herrors import ( "io" "io/ioutil" "path/filepath" "strings" "github.com/gohugoio/hugo/common/text" "github.com/spf13/afero" ) // LineMatcher contains the elements used to match an error to a line type LineMatcher struct { Position text.Position Error error LineNumber int Offset int Line string } // LineMatcherFn is used to match a line with an error. type LineMatcherFn func(m LineMatcher) bool // SimpleLineMatcher simply matches by line number. var SimpleLineMatcher = func(m LineMatcher) bool { return m.Position.LineNumber == m.LineNumber } var _ text.Positioner = ErrorContext{} // ErrorContext contains contextual information about an error. This will // typically be the lines surrounding some problem in a file. type ErrorContext struct { // If a match will contain the matched line and up to 2 lines before and after. // Will be empty if no match. Lines []string // The position of the error in the Lines above. 0 based. LinesPos int position text.Position // The lexer to use for syntax highlighting. // https://gohugo.io/content-management/syntax-highlighting/#list-of-chroma-highlighting-languages ChromaLexer string } // Position returns the text position of this error. func (e ErrorContext) Position() text.Position { return e.position } var _ causer = (*ErrorWithFileContext)(nil) // ErrorWithFileContext is an error with some additional file context related // to that error. type ErrorWithFileContext struct { cause error ErrorContext } func (e *ErrorWithFileContext) Error() string { pos := e.Position() if pos.IsValid() { return pos.String() + ": " + e.cause.Error() } return e.cause.Error() } func (e *ErrorWithFileContext) Cause() error { return e.cause } // WithFileContextForFile will try to add a file context with lines matching the given matcher. // If no match could be found, the original error is returned with false as the second return value. func WithFileContextForFile(e error, realFilename, filename string, fs afero.Fs, matcher LineMatcherFn) (error, bool) { f, err := fs.Open(filename) if err != nil { return e, false } defer f.Close() return WithFileContext(e, realFilename, f, matcher) } // WithFileContextForFile will try to add a file context with lines matching the given matcher. // If no match could be found, the original error is returned with false as the second return value. func WithFileContext(e error, realFilename string, r io.Reader, matcher LineMatcherFn) (error, bool) { if e == nil { panic("error missing") } le := UnwrapFileError(e) if le == nil { var ok bool if le, ok = ToFileError("", e).(FileError); !ok { return e, false } } var errCtx ErrorContext posle := le.Position() if posle.Offset != -1 { errCtx = locateError(r, le, func(m LineMatcher) bool { if posle.Offset >= m.Offset && posle.Offset < m.Offset+len(m.Line) { lno := posle.LineNumber - m.Position.LineNumber + m.LineNumber m.Position = text.Position{LineNumber: lno} } return matcher(m) }) } else { errCtx = locateError(r, le, matcher) } pos := &errCtx.position if pos.LineNumber == -1 { return e, false } pos.Filename = realFilename if le.Type() != "" { errCtx.ChromaLexer = chromaLexerFromType(le.Type()) } else { errCtx.ChromaLexer = chromaLexerFromFilename(realFilename) } return &ErrorWithFileContext{cause: e, ErrorContext: errCtx}, true } // UnwrapErrorWithFileContext tries to unwrap an ErrorWithFileContext from err. // It returns nil if this is not possible. func UnwrapErrorWithFileContext(err error) *ErrorWithFileContext { for err != nil { switch v := err.(type) { case *ErrorWithFileContext: return v case causer: err = v.Cause() default: return nil } } return nil } func chromaLexerFromType(fileType string) string { switch fileType { case "html", "htm": return "go-html-template" } return fileType } func extNoDelimiter(filename string) string { return strings.TrimPrefix(filepath.Ext(filename), ".") } func chromaLexerFromFilename(filename string) string { if strings.Contains(filename, "layouts") { return "go-html-template" } ext := extNoDelimiter(filename) return chromaLexerFromType(ext) } func locateErrorInString(src string, matcher LineMatcherFn) ErrorContext { return locateError(strings.NewReader(src), &fileError{}, matcher) } func locateError(r io.Reader, le FileError, matches LineMatcherFn) ErrorContext { if le == nil { panic("must provide an error") } errCtx := ErrorContext{position: text.Position{LineNumber: -1, ColumnNumber: 1, Offset: -1}, LinesPos: -1} b, err := ioutil.ReadAll(r) if err != nil { return errCtx } pos := &errCtx.position lepos := le.Position() lines := strings.Split(string(b), "\n") if lepos.ColumnNumber >= 0 { pos.ColumnNumber = lepos.ColumnNumber } lineNo := 0 posBytes := 0 for li, line := range lines { lineNo = li + 1 m := LineMatcher{ Position: le.Position(), Error: le, LineNumber: lineNo, Offset: posBytes, Line: line, } if errCtx.LinesPos == -1 && matches(m) { pos.LineNumber = lineNo break } posBytes += len(line) } if pos.LineNumber != -1 { low := pos.LineNumber - 3 if low < 0 { low = 0 } if pos.LineNumber > 2 { errCtx.LinesPos = 2 } else { errCtx.LinesPos = pos.LineNumber - 1 } high := pos.LineNumber + 2 if high > len(lines) { high = len(lines) } errCtx.Lines = lines[low:high] } return errCtx } hugo-0.68.3/common/herrors/error_locator_test.go000066400000000000000000000064221363637351300220060ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package errors contains common Hugo errors and error related utilities. package herrors import ( "strings" "testing" qt "github.com/frankban/quicktest" ) func TestErrorLocator(t *testing.T) { c := qt.New(t) lineMatcher := func(m LineMatcher) bool { return strings.Contains(m.Line, "THEONE") } lines := `LINE 1 LINE 2 LINE 3 LINE 4 This is THEONE LINE 6 LINE 7 LINE 8 ` location := locateErrorInString(lines, lineMatcher) c.Assert(location.Lines, qt.DeepEquals, []string{"LINE 3", "LINE 4", "This is THEONE", "LINE 6", "LINE 7"}) pos := location.Position() c.Assert(pos.LineNumber, qt.Equals, 5) c.Assert(location.LinesPos, qt.Equals, 2) c.Assert(locateErrorInString(`This is THEONE`, lineMatcher).Lines, qt.DeepEquals, []string{"This is THEONE"}) location = locateErrorInString(`L1 This is THEONE L2 `, lineMatcher) c.Assert(location.Position().LineNumber, qt.Equals, 2) c.Assert(location.LinesPos, qt.Equals, 1) c.Assert(location.Lines, qt.DeepEquals, []string{"L1", "This is THEONE", "L2", ""}) location = locateErrorInString(`This is THEONE L2 `, lineMatcher) c.Assert(location.LinesPos, qt.Equals, 0) c.Assert(location.Lines, qt.DeepEquals, []string{"This is THEONE", "L2", ""}) location = locateErrorInString(`L1 This THEONE `, lineMatcher) c.Assert(location.Lines, qt.DeepEquals, []string{"L1", "This THEONE", ""}) c.Assert(location.LinesPos, qt.Equals, 1) location = locateErrorInString(`L1 L2 This THEONE `, lineMatcher) c.Assert(location.Lines, qt.DeepEquals, []string{"L1", "L2", "This THEONE", ""}) c.Assert(location.LinesPos, qt.Equals, 2) location = locateErrorInString("NO MATCH", lineMatcher) c.Assert(location.Position().LineNumber, qt.Equals, -1) c.Assert(location.LinesPos, qt.Equals, -1) c.Assert(len(location.Lines), qt.Equals, 0) lineMatcher = func(m LineMatcher) bool { return m.LineNumber == 6 } location = locateErrorInString(`A B C D E F G H I J`, lineMatcher) c.Assert(location.Lines, qt.DeepEquals, []string{"D", "E", "F", "G", "H"}) c.Assert(location.Position().LineNumber, qt.Equals, 6) c.Assert(location.LinesPos, qt.Equals, 2) // Test match EOF lineMatcher = func(m LineMatcher) bool { return m.LineNumber == 4 } location = locateErrorInString(`A B C `, lineMatcher) c.Assert(location.Lines, qt.DeepEquals, []string{"B", "C", ""}) c.Assert(location.Position().LineNumber, qt.Equals, 4) c.Assert(location.LinesPos, qt.Equals, 2) offsetMatcher := func(m LineMatcher) bool { return m.Offset == 1 } location = locateErrorInString(`A B C D E`, offsetMatcher) c.Assert(location.Lines, qt.DeepEquals, []string{"A", "B", "C", "D"}) c.Assert(location.Position().LineNumber, qt.Equals, 2) c.Assert(location.LinesPos, qt.Equals, 1) } hugo-0.68.3/common/herrors/errors.go000066400000000000000000000051731363637351300174110ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package herrors contains common Hugo errors and error related utilities. package herrors import ( "bytes" "errors" "fmt" "io" "os" "runtime" "runtime/debug" "strconv" _errors "github.com/pkg/errors" ) // As defined in https://godoc.org/github.com/pkg/errors type causer interface { Cause() error } type stackTracer interface { StackTrace() _errors.StackTrace } // PrintStackTraceFromErr prints the error's stack trace to stdoud. func PrintStackTraceFromErr(err error) { FprintStackTraceFromErr(os.Stdout, err) } // FprintStackTraceFromErr prints the error's stack trace to w. func FprintStackTraceFromErr(w io.Writer, err error) { if err, ok := err.(stackTracer); ok { for _, f := range err.StackTrace() { fmt.Fprintf(w, "%+s:%d\n", f, f) } } } // PrintStackTrace prints the current stacktrace to w. func PrintStackTrace(w io.Writer) { buf := make([]byte, 1<<16) runtime.Stack(buf, true) fmt.Fprintf(w, "%s", buf) } // ErrorSender is a, typically, non-blocking error handler. type ErrorSender interface { SendError(err error) } // Recover is a helper function that can be used to capture panics. // Put this at the top of a method/function that crashes in a template: // defer herrors.Recover() func Recover(args ...interface{}) { if r := recover(); r != nil { fmt.Println("ERR:", r) args = append(args, "stacktrace from panic: \n"+string(debug.Stack()), "\n") fmt.Println(args...) } } // Get the current goroutine id. Used only for debugging. func GetGID() uint64 { b := make([]byte, 64) b = b[:runtime.Stack(b, false)] b = bytes.TrimPrefix(b, []byte("goroutine ")) b = b[:bytes.IndexByte(b, ' ')] n, _ := strconv.ParseUint(string(b), 10, 64) return n } // ErrFeatureNotAvailable denotes that a feature is unavailable. // // We will, at least to begin with, make some Hugo features (SCSS with libsass) optional, // and this error is used to signal those situations. var ErrFeatureNotAvailable = errors.New("this feature is not available in your current Hugo version, see https://goo.gl/YMrWcn for more information") hugo-0.68.3/common/herrors/file_error.go000066400000000000000000000064311363637351300202230ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitatio ns under the License. package herrors import ( "encoding/json" "github.com/gohugoio/hugo/common/text" "github.com/pkg/errors" ) var ( _ causer = (*fileError)(nil) ) // FileError represents an error when handling a file: Parsing a config file, // execute a template etc. type FileError interface { error text.Positioner // A string identifying the type of file, e.g. JSON, TOML, markdown etc. Type() string } var _ FileError = (*fileError)(nil) type fileError struct { position text.Position fileType string cause error } // Position returns the text position of this error. func (e fileError) Position() text.Position { return e.position } func (e *fileError) Type() string { return e.fileType } func (e *fileError) Error() string { if e.cause == nil { return "" } return e.cause.Error() } func (f *fileError) Cause() error { return f.cause } // NewFileError creates a new FileError. func NewFileError(fileType string, offset, lineNumber, columnNumber int, err error) FileError { pos := text.Position{Offset: offset, LineNumber: lineNumber, ColumnNumber: columnNumber} return &fileError{cause: err, fileType: fileType, position: pos} } // UnwrapFileError tries to unwrap a FileError from err. // It returns nil if this is not possible. func UnwrapFileError(err error) FileError { for err != nil { switch v := err.(type) { case FileError: return v case causer: err = v.Cause() default: return nil } } return nil } // ToFileErrorWithOffset will return a new FileError with a line number // with the given offset from the original. func ToFileErrorWithOffset(fe FileError, offset int) FileError { pos := fe.Position() return ToFileErrorWithLineNumber(fe, pos.LineNumber+offset) } // ToFileErrorWithOffset will return a new FileError with the given line number. func ToFileErrorWithLineNumber(fe FileError, lineNumber int) FileError { pos := fe.Position() pos.LineNumber = lineNumber return &fileError{cause: fe, fileType: fe.Type(), position: pos} } // ToFileError will convert the given error to an error supporting // the FileError interface. func ToFileError(fileType string, err error) FileError { for _, handle := range lineNumberExtractors { lno, col := handle(err) offset, typ := extractOffsetAndType(err) if fileType == "" { fileType = typ } if lno > 0 || offset != -1 { return NewFileError(fileType, offset, lno, col, err) } } // Fall back to the pointing to line number 1. return NewFileError(fileType, -1, 1, 1, err) } func extractOffsetAndType(e error) (int, string) { e = errors.Cause(e) switch v := e.(type) { case *json.UnmarshalTypeError: return int(v.Offset), "json" case *json.SyntaxError: return int(v.Offset), "json" default: return -1, "" } } hugo-0.68.3/common/herrors/file_error_test.go000066400000000000000000000036411363637351300212620ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package herrors import ( "testing" "github.com/pkg/errors" qt "github.com/frankban/quicktest" ) func TestToLineNumberError(t *testing.T) { t.Parallel() c := qt.New(t) for i, test := range []struct { in error offset int lineNumber int columnNumber int }{ {errors.New("no line number for you"), 0, 1, 1}, {errors.New(`template: _default/single.html:4:15: executing "_default/single.html" at <.Titles>: can't evaluate field Titles in type *hugolib.PageOutput`), 0, 4, 15}, {errors.New("parse failed: template: _default/bundle-resource-meta.html:11: unexpected in operand"), 0, 11, 1}, {errors.New(`failed:: template: _default/bundle-resource-meta.html:2:7: executing "main" at <.Titles>`), 0, 2, 7}, {errors.New("error in front matter: Near line 32 (last key parsed 'title')"), 0, 32, 1}, {errors.New(`failed to load translations: (6, 7): was expecting token =, but got "g" instead`), 0, 6, 7}, } { got := ToFileError("template", test.in) errMsg := qt.Commentf("[%d][%T]", i, got) le, ok := got.(FileError) c.Assert(ok, qt.Equals, true) c.Assert(ok, qt.Equals, true, errMsg) pos := le.Position() c.Assert(pos.LineNumber, qt.Equals, test.lineNumber, errMsg) c.Assert(pos.ColumnNumber, qt.Equals, test.columnNumber, errMsg) c.Assert(errors.Cause(got), qt.Not(qt.IsNil)) } } hugo-0.68.3/common/herrors/line_number_extractors.go000066400000000000000000000032251363637351300226460ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitatio ns under the License. package herrors import ( "regexp" "strconv" ) var lineNumberExtractors = []lineNumberExtractor{ // Template/shortcode parse errors newLineNumberErrHandlerFromRegexp(".*:(\\d+):(\\d*):"), newLineNumberErrHandlerFromRegexp(".*:(\\d+):"), // TOML parse errors newLineNumberErrHandlerFromRegexp(".*Near line (\\d+)(\\s.*)"), // YAML parse errors newLineNumberErrHandlerFromRegexp("line (\\d+):"), // i18n bundle errors newLineNumberErrHandlerFromRegexp("\\((\\d+),\\s(\\d*)"), } type lineNumberExtractor func(e error) (int, int) func newLineNumberErrHandlerFromRegexp(expression string) lineNumberExtractor { re := regexp.MustCompile(expression) return extractLineNo(re) } func extractLineNo(re *regexp.Regexp) lineNumberExtractor { return func(e error) (int, int) { if e == nil { panic("no error") } col := 1 s := e.Error() m := re.FindStringSubmatch(s) if len(m) >= 2 { lno, _ := strconv.Atoi(m[1]) if len(m) > 2 { col, _ = strconv.Atoi(m[2]) } if col <= 0 { col = 1 } return lno, col } return -1, col } } hugo-0.68.3/common/hreflect/000077500000000000000000000000001363637351300156505ustar00rootroot00000000000000hugo-0.68.3/common/hreflect/helpers.go000066400000000000000000000054551363637351300176520ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // Some functions in this file (see comments) is based on the Go source code, // copyright The Go Authors and governed by a BSD-style license. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package hreflect contains reflect helpers. package hreflect import ( "reflect" "github.com/gohugoio/hugo/common/types" ) // IsTruthful returns whether in represents a truthful value. // See IsTruthfulValue func IsTruthful(in interface{}) bool { switch v := in.(type) { case reflect.Value: return IsTruthfulValue(v) default: return IsTruthfulValue(reflect.ValueOf(in)) } } var zeroType = reflect.TypeOf((*types.Zeroer)(nil)).Elem() // IsTruthfulValue returns whether the given value has a meaningful truth value. // This is based on template.IsTrue in Go's stdlib, but also considers // IsZero and any interface value will be unwrapped before it's considered // for truthfulness. // // Based on: // https://github.com/golang/go/blob/178a2c42254166cffed1b25fb1d3c7a5727cada6/src/text/template/exec.go#L306 func IsTruthfulValue(val reflect.Value) (truth bool) { val = indirectInterface(val) if !val.IsValid() { // Something like var x interface{}, never set. It's a form of nil. return } if val.Type().Implements(zeroType) { return !val.Interface().(types.Zeroer).IsZero() } switch val.Kind() { case reflect.Array, reflect.Map, reflect.Slice, reflect.String: truth = val.Len() > 0 case reflect.Bool: truth = val.Bool() case reflect.Complex64, reflect.Complex128: truth = val.Complex() != 0 case reflect.Chan, reflect.Func, reflect.Ptr, reflect.Interface: truth = !val.IsNil() case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: truth = val.Int() != 0 case reflect.Float32, reflect.Float64: truth = val.Float() != 0 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: truth = val.Uint() != 0 case reflect.Struct: truth = true // Struct values are always true. default: return } return } // Based on: https://github.com/golang/go/blob/178a2c42254166cffed1b25fb1d3c7a5727cada6/src/text/template/exec.go#L931 func indirectInterface(v reflect.Value) reflect.Value { if v.Kind() != reflect.Interface { return v } if v.IsNil() { return reflect.Value{} } return v.Elem() } hugo-0.68.3/common/hreflect/helpers_test.go000066400000000000000000000021611363637351300207000ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package hreflect import ( "reflect" "testing" "time" qt "github.com/frankban/quicktest" ) func TestIsTruthful(t *testing.T) { c := qt.New(t) c.Assert(IsTruthful(true), qt.Equals, true) c.Assert(IsTruthful(false), qt.Equals, false) c.Assert(IsTruthful(time.Now()), qt.Equals, true) c.Assert(IsTruthful(time.Time{}), qt.Equals, false) } func BenchmarkIsTruthFul(b *testing.B) { v := reflect.ValueOf("Hugo") b.ResetTimer() for i := 0; i < b.N; i++ { if !IsTruthfulValue(v) { b.Fatal("not truthful") } } } hugo-0.68.3/common/hugio/000077500000000000000000000000001363637351300151675ustar00rootroot00000000000000hugo-0.68.3/common/hugio/copy.go000066400000000000000000000036541363637351300165000ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package hugio import ( "io" "io/ioutil" "os" "path/filepath" "github.com/pkg/errors" "github.com/spf13/afero" ) // CopyFile copies a file. func CopyFile(fs afero.Fs, from, to string) error { sf, err := os.Open(from) if err != nil { return err } defer sf.Close() df, err := os.Create(to) if err != nil { return err } defer df.Close() _, err = io.Copy(df, sf) if err == nil { si, err := os.Stat(from) if err != nil { err = os.Chmod(to, si.Mode()) if err != nil { return err } } } return nil } // CopyDir copies a directory. func CopyDir(fs afero.Fs, from, to string, shouldCopy func(filename string) bool) error { fi, err := os.Stat(from) if err != nil { return err } if !fi.IsDir() { return errors.Errorf("%q is not a directory", from) } err = fs.MkdirAll(to, 0777) // before umask if err != nil { return err } entries, _ := ioutil.ReadDir(from) for _, entry := range entries { fromFilename := filepath.Join(from, entry.Name()) toFilename := filepath.Join(to, entry.Name()) if entry.IsDir() { if shouldCopy != nil && !shouldCopy(fromFilename) { continue } if err := CopyDir(fs, fromFilename, toFilename, shouldCopy); err != nil { return err } } else { if err := CopyFile(fs, fromFilename, toFilename); err != nil { return err } } } return nil } hugo-0.68.3/common/hugio/readers.go000066400000000000000000000032611363637351300171450ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package hugio import ( "io" "strings" ) // ReadSeeker wraps io.Reader and io.Seeker. type ReadSeeker interface { io.Reader io.Seeker } // ReadSeekCloser is implemented by afero.File. We use this as the common type for // content in Resource objects, even for strings. type ReadSeekCloser interface { ReadSeeker io.Closer } // ReadSeekerNoOpCloser implements ReadSeekCloser by doing nothing in Close. // TODO(bep) rename this and simila to ReadSeekerNopCloser, naming used in stdlib, which kind of makes sense. type ReadSeekerNoOpCloser struct { ReadSeeker } // Close does nothing. func (r ReadSeekerNoOpCloser) Close() error { return nil } // NewReadSeekerNoOpCloser creates a new ReadSeekerNoOpCloser with the given ReadSeeker. func NewReadSeekerNoOpCloser(r ReadSeeker) ReadSeekerNoOpCloser { return ReadSeekerNoOpCloser{r} } // NewReadSeekerNoOpCloserFromString uses strings.NewReader to create a new ReadSeekerNoOpCloser // from the given string. func NewReadSeekerNoOpCloserFromString(content string) ReadSeekerNoOpCloser { return ReadSeekerNoOpCloser{strings.NewReader(content)} } hugo-0.68.3/common/hugio/writers.go000066400000000000000000000036221363637351300172200ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package hugio import ( "io" "io/ioutil" ) type multiWriteCloser struct { io.Writer closers []io.WriteCloser } func (m multiWriteCloser) Close() error { var err error for _, c := range m.closers { if closeErr := c.Close(); err != nil { err = closeErr } } return err } // NewMultiWriteCloser creates a new io.WriteCloser that duplicates its writes to all the // provided writers. func NewMultiWriteCloser(writeClosers ...io.WriteCloser) io.WriteCloser { writers := make([]io.Writer, len(writeClosers)) for i, w := range writeClosers { writers[i] = w } return multiWriteCloser{Writer: io.MultiWriter(writers...), closers: writeClosers} } // ToWriteCloser creates an io.WriteCloser from the given io.Writer. // If it's not already, one will be created with a Close method that does nothing. func ToWriteCloser(w io.Writer) io.WriteCloser { if rw, ok := w.(io.WriteCloser); ok { return rw } return struct { io.Writer io.Closer }{ w, ioutil.NopCloser(nil), } } // ToReadCloser creates an io.ReadCloser from the given io.Reader. // If it's not already, one will be created with a Close method that does nothing. func ToReadCloser(r io.Reader) io.ReadCloser { if rc, ok := r.(io.ReadCloser); ok { return rc } return struct { io.Reader io.Closer }{ r, ioutil.NopCloser(nil), } } hugo-0.68.3/common/hugo/000077500000000000000000000000001363637351300150165ustar00rootroot00000000000000hugo-0.68.3/common/hugo/hugo.go000066400000000000000000000036551363637351300163200ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package hugo import ( "fmt" "html/template" ) const ( EnvironmentDevelopment = "development" EnvironmentProduction = "production" ) var ( // commitHash contains the current Git revision. Use make to build to make // sure this gets set. commitHash string // buildDate contains the date of the current build. buildDate string ) // Info contains information about the current Hugo environment type Info struct { CommitHash string BuildDate string // The build environment. // Defaults are "production" (hugo) and "development" (hugo server). // This can also be set by the user. // It can be any string, but it will be all lower case. Environment string } // Version returns the current version as a comparable version string. func (i Info) Version() VersionString { return CurrentVersion.Version() } // Generator a Hugo meta generator HTML tag. func (i Info) Generator() template.HTML { return template.HTML(fmt.Sprintf(``, CurrentVersion.String())) } func (i Info) IsProduction() bool { return i.Environment == EnvironmentProduction } // NewInfo creates a new Hugo Info object. func NewInfo(environment string) Info { if environment == "" { environment = EnvironmentProduction } return Info{ CommitHash: commitHash, BuildDate: buildDate, Environment: environment, } } hugo-0.68.3/common/hugo/hugo_test.go000066400000000000000000000024771363637351300173600ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package hugo import ( "fmt" "testing" qt "github.com/frankban/quicktest" ) func TestHugoInfo(t *testing.T) { c := qt.New(t) hugoInfo := NewInfo("") c.Assert(hugoInfo.Version(), qt.Equals, CurrentVersion.Version()) c.Assert(fmt.Sprintf("%T", VersionString("")), qt.Equals, fmt.Sprintf("%T", hugoInfo.Version())) c.Assert(hugoInfo.CommitHash, qt.Equals, commitHash) c.Assert(hugoInfo.BuildDate, qt.Equals, buildDate) c.Assert(hugoInfo.Environment, qt.Equals, "production") c.Assert(string(hugoInfo.Generator()), qt.Contains, fmt.Sprintf("Hugo %s", hugoInfo.Version())) c.Assert(hugoInfo.IsProduction(), qt.Equals, true) devHugoInfo := NewInfo("development") c.Assert(devHugoInfo.IsProduction(), qt.Equals, false) } hugo-0.68.3/common/hugo/vars_extended.go000066400000000000000000000012311363637351300201750ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build extended package hugo var IsExtended = true hugo-0.68.3/common/hugo/vars_regular.go000066400000000000000000000012331363637351300200400ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build !extended package hugo var IsExtended = false hugo-0.68.3/common/hugo/version.go000066400000000000000000000137031363637351300170360ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package hugo import ( "fmt" "io" "runtime" "strings" "github.com/gohugoio/hugo/compare" "github.com/spf13/cast" ) // Version represents the Hugo build version. type Version struct { // Major and minor version. Number float32 // Increment this for bug releases PatchLevel int // HugoVersionSuffix is the suffix used in the Hugo version string. // It will be blank for release versions. Suffix string } var ( _ compare.Eqer = (*VersionString)(nil) _ compare.Comparer = (*VersionString)(nil) ) func (v Version) String() string { return version(v.Number, v.PatchLevel, v.Suffix) } // Version returns the Hugo version. func (v Version) Version() VersionString { return VersionString(v.String()) } // VersionString represents a Hugo version string. type VersionString string func (h VersionString) String() string { return string(h) } // Compare implements the compare.Comparer interface. func (h VersionString) Compare(other interface{}) int { v := MustParseVersion(h.String()) return compareVersionsWithSuffix(v.Number, v.PatchLevel, v.Suffix, other) } // Eq implements the compare.Eqer interface. func (h VersionString) Eq(other interface{}) bool { s, err := cast.ToStringE(other) if err != nil { return false } return s == h.String() } var versionSuffixes = []string{"-test", "-DEV"} // ParseVersion parses a version string. func ParseVersion(s string) (Version, error) { var vv Version for _, suffix := range versionSuffixes { if strings.HasSuffix(s, suffix) { vv.Suffix = suffix s = strings.TrimSuffix(s, suffix) } } v, p := parseVersion(s) vv.Number = v vv.PatchLevel = p return vv, nil } // MustParseVersion parses a version string // and panics if any error occurs. func MustParseVersion(s string) Version { vv, err := ParseVersion(s) if err != nil { panic(err) } return vv } // ReleaseVersion represents the release version. func (v Version) ReleaseVersion() Version { v.Suffix = "" return v } // Next returns the next Hugo release version. func (v Version) Next() Version { return Version{Number: v.Number + 0.01} } // Prev returns the previous Hugo release version. func (v Version) Prev() Version { return Version{Number: v.Number - 0.01} } // NextPatchLevel returns the next patch/bugfix Hugo version. // This will be a patch increment on the previous Hugo version. func (v Version) NextPatchLevel(level int) Version { return Version{Number: v.Number - 0.01, PatchLevel: level} } // BuildVersionString creates a version string. This is what you see when // running "hugo version". func BuildVersionString() string { program := "Hugo Static Site Generator" version := "v" + CurrentVersion.String() if commitHash != "" { version += "-" + strings.ToUpper(commitHash) } if IsExtended { version += "/extended" } osArch := runtime.GOOS + "/" + runtime.GOARCH date := buildDate if date == "" { date = "unknown" } return fmt.Sprintf("%s %s %s BuildDate: %s", program, version, osArch, date) } func version(version float32, patchVersion int, suffix string) string { if patchVersion > 0 || version > 0.53 { return fmt.Sprintf("%.2f.%d%s", version, patchVersion, suffix) } return fmt.Sprintf("%.2f%s", version, suffix) } // CompareVersion compares the given version string or number against the // running Hugo version. // It returns -1 if the given version is less than, 0 if equal and 1 if greater than // the running version. func CompareVersion(version interface{}) int { return compareVersionsWithSuffix(CurrentVersion.Number, CurrentVersion.PatchLevel, CurrentVersion.Suffix, version) } func compareVersions(inVersion float32, inPatchVersion int, in interface{}) int { return compareVersionsWithSuffix(inVersion, inPatchVersion, "", in) } func compareVersionsWithSuffix(inVersion float32, inPatchVersion int, suffix string, in interface{}) int { var c int switch d := in.(type) { case float64: c = compareFloatVersions(inVersion, float32(d)) case float32: c = compareFloatVersions(inVersion, d) case int: c = compareFloatVersions(inVersion, float32(d)) case int32: c = compareFloatVersions(inVersion, float32(d)) case int64: c = compareFloatVersions(inVersion, float32(d)) default: s, err := cast.ToStringE(in) if err != nil { return -1 } v, err := ParseVersion(s) if err != nil { return -1 } if v.Number == inVersion && v.PatchLevel == inPatchVersion { return strings.Compare(suffix, v.Suffix) } if v.Number < inVersion || (v.Number == inVersion && v.PatchLevel < inPatchVersion) { return -1 } return 1 } if c == 0 && suffix != "" { return 1 } return c } func parseVersion(s string) (float32, int) { var ( v float32 p int ) if strings.Count(s, ".") == 2 { li := strings.LastIndex(s, ".") p = cast.ToInt(s[li+1:]) s = s[:li] } v = float32(cast.ToFloat64(s)) return v, p } func compareFloatVersions(version float32, v float32) int { if v == version { return 0 } if v < version { return -1 } return 1 } func GoMinorVersion() int { return goMinorVersion(runtime.Version()) } func goMinorVersion(version string) int { if strings.HasPrefix(version, "devel") { return 9999 // magic } var major, minor int var trailing string n, err := fmt.Sscanf(version, "go%d.%d%s", &major, &minor, &trailing) if n == 2 && err == io.EOF { // Means there were no trailing characters (i.e., not an alpha/beta) err = nil } if err != nil { return 0 } return minor } hugo-0.68.3/common/hugo/version_current.go000066400000000000000000000014331363637351300205750ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package hugo // CurrentVersion represents the current build version. // This should be the only one. var CurrentVersion = Version{ Number: 0.68, PatchLevel: 3, Suffix: "", } hugo-0.68.3/common/hugo/version_test.go000066400000000000000000000071021363637351300200710ustar00rootroot00000000000000// Copyright 2015 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package hugo import ( "testing" qt "github.com/frankban/quicktest" ) func TestHugoVersion(t *testing.T) { c := qt.New(t) c.Assert(version(0.15, 0, "-DEV"), qt.Equals, "0.15-DEV") c.Assert(version(0.15, 2, "-DEV"), qt.Equals, "0.15.2-DEV") v := Version{Number: 0.21, PatchLevel: 0, Suffix: "-DEV"} c.Assert(v.ReleaseVersion().String(), qt.Equals, "0.21") c.Assert(v.String(), qt.Equals, "0.21-DEV") c.Assert(v.Next().String(), qt.Equals, "0.22") nextVersionString := v.Next().Version() c.Assert(nextVersionString.String(), qt.Equals, "0.22") c.Assert(nextVersionString.Eq("0.22"), qt.Equals, true) c.Assert(nextVersionString.Eq("0.21"), qt.Equals, false) c.Assert(nextVersionString.Eq(nextVersionString), qt.Equals, true) c.Assert(v.NextPatchLevel(3).String(), qt.Equals, "0.20.3") // We started to use full semver versions even for main // releases in v0.54.0 v = Version{Number: 0.53, PatchLevel: 0} c.Assert(v.String(), qt.Equals, "0.53") c.Assert(v.Next().String(), qt.Equals, "0.54.0") c.Assert(v.Next().Next().String(), qt.Equals, "0.55.0") v = Version{Number: 0.54, PatchLevel: 0, Suffix: "-DEV"} c.Assert(v.String(), qt.Equals, "0.54.0-DEV") } func TestCompareVersions(t *testing.T) { c := qt.New(t) c.Assert(compareVersions(0.20, 0, 0.20), qt.Equals, 0) c.Assert(compareVersions(0.20, 0, float32(0.20)), qt.Equals, 0) c.Assert(compareVersions(0.20, 0, float64(0.20)), qt.Equals, 0) c.Assert(compareVersions(0.19, 1, 0.20), qt.Equals, 1) c.Assert(compareVersions(0.19, 3, "0.20.2"), qt.Equals, 1) c.Assert(compareVersions(0.19, 1, 0.01), qt.Equals, -1) c.Assert(compareVersions(0, 1, 3), qt.Equals, 1) c.Assert(compareVersions(0, 1, int32(3)), qt.Equals, 1) c.Assert(compareVersions(0, 1, int64(3)), qt.Equals, 1) c.Assert(compareVersions(0.20, 0, "0.20"), qt.Equals, 0) c.Assert(compareVersions(0.20, 1, "0.20.1"), qt.Equals, 0) c.Assert(compareVersions(0.20, 1, "0.20"), qt.Equals, -1) c.Assert(compareVersions(0.20, 0, "0.20.1"), qt.Equals, 1) c.Assert(compareVersions(0.20, 1, "0.20.2"), qt.Equals, 1) c.Assert(compareVersions(0.21, 1, "0.22.1"), qt.Equals, 1) c.Assert(compareVersions(0.22, 0, "0.22-DEV"), qt.Equals, -1) c.Assert(compareVersions(0.22, 0, "0.22.1-DEV"), qt.Equals, 1) c.Assert(compareVersionsWithSuffix(0.22, 0, "-DEV", "0.22"), qt.Equals, 1) c.Assert(compareVersionsWithSuffix(0.22, 1, "-DEV", "0.22"), qt.Equals, -1) c.Assert(compareVersionsWithSuffix(0.22, 1, "-DEV", "0.22.1-DEV"), qt.Equals, 0) } func TestParseHugoVersion(t *testing.T) { c := qt.New(t) c.Assert(MustParseVersion("0.25").String(), qt.Equals, "0.25") c.Assert(MustParseVersion("0.25.2").String(), qt.Equals, "0.25.2") c.Assert(MustParseVersion("0.25-test").String(), qt.Equals, "0.25-test") c.Assert(MustParseVersion("0.25-DEV").String(), qt.Equals, "0.25-DEV") } func TestGoMinorVersion(t *testing.T) { c := qt.New(t) c.Assert(goMinorVersion("go1.12.5"), qt.Equals, 12) c.Assert(goMinorVersion("go1.14rc1"), qt.Equals, 14) c.Assert(GoMinorVersion() >= 11, qt.Equals, true) } hugo-0.68.3/common/loggers/000077500000000000000000000000001363637351300155165ustar00rootroot00000000000000hugo-0.68.3/common/loggers/loggers.go000066400000000000000000000131631363637351300175130ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package loggers import ( "bytes" "fmt" "io" "io/ioutil" "log" "os" "regexp" "runtime" "time" "github.com/gohugoio/hugo/common/terminal" jww "github.com/spf13/jwalterweatherman" ) var ( // Counts ERROR logs to the global jww logger. GlobalErrorCounter *jww.Counter ) func init() { GlobalErrorCounter = &jww.Counter{} jww.SetLogListeners(jww.LogCounter(GlobalErrorCounter, jww.LevelError)) } // Logger wraps a *loggers.Logger and some other related logging state. type Logger struct { *jww.Notepad // The writer that represents stdout. // Will be ioutil.Discard when in quiet mode. Out io.Writer ErrorCounter *jww.Counter WarnCounter *jww.Counter // This is only set in server mode. errors *bytes.Buffer } // PrintTimerIfDelayed prints a time statement to the FEEDBACK logger // if considerable time is spent. func (l *Logger) PrintTimerIfDelayed(start time.Time, name string) { elapsed := time.Since(start) milli := int(1000 * elapsed.Seconds()) if milli < 500 { return } l.FEEDBACK.Printf("%s in %v ms", name, milli) } func (l *Logger) PrintTimer(start time.Time, name string) { elapsed := time.Since(start) milli := int(1000 * elapsed.Seconds()) l.FEEDBACK.Printf("%s in %v ms", name, milli) } func (l *Logger) Errors() string { if l.errors == nil { return "" } return ansiColorRe.ReplaceAllString(l.errors.String(), "") } // Reset resets the logger's internal state. func (l *Logger) Reset() { l.ErrorCounter.Reset() if l.errors != nil { l.errors.Reset() } } // NewLogger creates a new Logger for the given thresholds func NewLogger(stdoutThreshold, logThreshold jww.Threshold, outHandle, logHandle io.Writer, saveErrors bool) *Logger { return newLogger(stdoutThreshold, logThreshold, outHandle, logHandle, saveErrors) } // NewDebugLogger is a convenience function to create a debug logger. func NewDebugLogger() *Logger { return newBasicLogger(jww.LevelDebug) } // NewWarningLogger is a convenience function to create a warning logger. func NewWarningLogger() *Logger { return newBasicLogger(jww.LevelWarn) } // NewErrorLogger is a convenience function to create an error logger. func NewErrorLogger() *Logger { return newBasicLogger(jww.LevelError) } var ( ansiColorRe = regexp.MustCompile("(?s)\\033\\[\\d*(;\\d*)*m") errorRe = regexp.MustCompile("^(ERROR|FATAL|WARN)") ) type ansiCleaner struct { w io.Writer } func (a ansiCleaner) Write(p []byte) (n int, err error) { return a.w.Write(ansiColorRe.ReplaceAll(p, []byte(""))) } type labelColorizer struct { w io.Writer } func (a labelColorizer) Write(p []byte) (n int, err error) { replaced := errorRe.ReplaceAllStringFunc(string(p), func(m string) string { switch m { case "ERROR", "FATAL": return terminal.Error(m) case "WARN": return terminal.Warning(m) default: return m } }) // io.MultiWriter will abort if we return a bigger write count than input // bytes, so we lie a little. _, err = a.w.Write([]byte(replaced)) return len(p), err } // InitGlobalLogger initializes the global logger, used in some rare cases. func InitGlobalLogger(stdoutThreshold, logThreshold jww.Threshold, outHandle, logHandle io.Writer) { outHandle, logHandle = getLogWriters(outHandle, logHandle) jww.SetStdoutOutput(outHandle) jww.SetLogOutput(logHandle) jww.SetLogThreshold(logThreshold) jww.SetStdoutThreshold(stdoutThreshold) } func getLogWriters(outHandle, logHandle io.Writer) (io.Writer, io.Writer) { isTerm := terminal.IsTerminal(os.Stdout) if logHandle != ioutil.Discard && isTerm { // Remove any Ansi coloring from log output logHandle = ansiCleaner{w: logHandle} } if isTerm { outHandle = labelColorizer{w: outHandle} } return outHandle, logHandle } type fatalLogWriter int func (s fatalLogWriter) Write(p []byte) (n int, err error) { trace := make([]byte, 1500) runtime.Stack(trace, true) fmt.Printf("\n===========\n\n%s\n", trace) os.Exit(-1) return 0, nil } var fatalLogListener = func(t jww.Threshold) io.Writer { if t != jww.LevelError { // Only interested in ERROR return nil } return new(fatalLogWriter) } func newLogger(stdoutThreshold, logThreshold jww.Threshold, outHandle, logHandle io.Writer, saveErrors bool) *Logger { errorCounter := &jww.Counter{} warnCounter := &jww.Counter{} outHandle, logHandle = getLogWriters(outHandle, logHandle) listeners := []jww.LogListener{jww.LogCounter(errorCounter, jww.LevelError), jww.LogCounter(warnCounter, jww.LevelWarn)} var errorBuff *bytes.Buffer if saveErrors { errorBuff = new(bytes.Buffer) errorCapture := func(t jww.Threshold) io.Writer { if t != jww.LevelError { // Only interested in ERROR return nil } return errorBuff } listeners = append(listeners, errorCapture) } return &Logger{ Notepad: jww.NewNotepad(stdoutThreshold, logThreshold, outHandle, logHandle, "", log.Ldate|log.Ltime, listeners...), Out: outHandle, ErrorCounter: errorCounter, WarnCounter: warnCounter, errors: errorBuff, } } func newBasicLogger(t jww.Threshold) *Logger { return newLogger(t, jww.LevelError, os.Stdout, ioutil.Discard, false) } hugo-0.68.3/common/loggers/loggers_test.go000066400000000000000000000016151363637351300205510ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package loggers import ( "testing" qt "github.com/frankban/quicktest" ) func TestLogger(t *testing.T) { c := qt.New(t) l := NewWarningLogger() l.ERROR.Println("One error") l.ERROR.Println("Two error") l.WARN.Println("A warning") c.Assert(l.ErrorCounter.Count(), qt.Equals, uint64(2)) } hugo-0.68.3/common/maps/000077500000000000000000000000001363637351300150145ustar00rootroot00000000000000hugo-0.68.3/common/maps/maps.go000066400000000000000000000062471363637351300163140ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package maps import ( "strings" "github.com/gobwas/glob" "github.com/spf13/cast" ) // ToLower makes all the keys in the given map lower cased and will do so // recursively. // Notes: // * This will modify the map given. // * Any nested map[interface{}]interface{} will be converted to Params. func ToLower(m Params) { for k, v := range m { var retyped bool switch v.(type) { case map[interface{}]interface{}: var p Params = cast.ToStringMap(v) v = p ToLower(p) retyped = true case map[string]interface{}: var p Params = v.(map[string]interface{}) v = p ToLower(p) retyped = true } lKey := strings.ToLower(k) if retyped || k != lKey { delete(m, k) m[lKey] = v } } } func ToStringMapE(in interface{}) (map[string]interface{}, error) { switch in.(type) { case Params: return in.(Params), nil default: return cast.ToStringMapE(in) } } func ToStringMap(in interface{}) map[string]interface{} { m, _ := ToStringMapE(in) return m } type keyRename struct { pattern glob.Glob newKey string } // KeyRenamer supports renaming of keys in a map. type KeyRenamer struct { renames []keyRename } // NewKeyRenamer creates a new KeyRenamer given a list of pattern and new key // value pairs. func NewKeyRenamer(patternKeys ...string) (KeyRenamer, error) { var renames []keyRename for i := 0; i < len(patternKeys); i += 2 { g, err := glob.Compile(strings.ToLower(patternKeys[i]), '/') if err != nil { return KeyRenamer{}, err } renames = append(renames, keyRename{pattern: g, newKey: patternKeys[i+1]}) } return KeyRenamer{renames: renames}, nil } func (r KeyRenamer) getNewKey(keyPath string) string { for _, matcher := range r.renames { if matcher.pattern.Match(keyPath) { return matcher.newKey } } return "" } // Rename renames the keys in the given map according // to the patterns in the current KeyRenamer. func (r KeyRenamer) Rename(m map[string]interface{}) { r.renamePath("", m) } func (KeyRenamer) keyPath(k1, k2 string) string { k1, k2 = strings.ToLower(k1), strings.ToLower(k2) if k1 == "" { return k2 } else { return k1 + "/" + k2 } } func (r KeyRenamer) renamePath(parentKeyPath string, m map[string]interface{}) { for key, val := range m { keyPath := r.keyPath(parentKeyPath, key) switch val.(type) { case map[interface{}]interface{}: val = cast.ToStringMap(val) r.renamePath(keyPath, val.(map[string]interface{})) case map[string]interface{}: r.renamePath(keyPath, val.(map[string]interface{})) } newKey := r.getNewKey(keyPath) if newKey != "" { delete(m, key) m[newKey] = val } } } hugo-0.68.3/common/maps/maps_get.go000066400000000000000000000017451363637351300171510ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package maps import ( "github.com/spf13/cast" ) // GetString tries to get a value with key from map m and convert it to a string. // It will return an empty string if not found or if it cannot be convertd to a string. func GetString(m map[string]interface{}, key string) string { if m == nil { return "" } v, found := m[key] if !found { return "" } return cast.ToString(v) } hugo-0.68.3/common/maps/maps_test.go000066400000000000000000000047341363637351300173520ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package maps import ( "fmt" "reflect" "testing" qt "github.com/frankban/quicktest" ) func TestToLower(t *testing.T) { tests := []struct { input map[string]interface{} expected map[string]interface{} }{ { map[string]interface{}{ "abC": 32, }, Params{ "abc": 32, }, }, { map[string]interface{}{ "abC": 32, "deF": map[interface{}]interface{}{ 23: "A value", 24: map[string]interface{}{ "AbCDe": "A value", "eFgHi": "Another value", }, }, "gHi": map[string]interface{}{ "J": 25, }, }, Params{ "abc": 32, "def": Params{ "23": "A value", "24": Params{ "abcde": "A value", "efghi": "Another value", }, }, "ghi": Params{ "j": 25, }, }, }, } for i, test := range tests { t.Run(fmt.Sprint(i), func(t *testing.T) { // ToLower modifies input. ToLower(test.input) if !reflect.DeepEqual(test.expected, test.input) { t.Errorf("[%d] Expected\n%#v, got\n%#v\n", i, test.expected, test.input) } }) } } func TestRenameKeys(t *testing.T) { c := qt.New(t) m := map[string]interface{}{ "a": 32, "ren1": "m1", "ren2": "m1_2", "sub": map[string]interface{}{ "subsub": map[string]interface{}{ "REN1": "m2", "ren2": "m2_2", }, }, "no": map[string]interface{}{ "ren1": "m2", "ren2": "m2_2", }, } expected := map[string]interface{}{ "a": 32, "new1": "m1", "new2": "m1_2", "sub": map[string]interface{}{ "subsub": map[string]interface{}{ "new1": "m2", "ren2": "m2_2", }, }, "no": map[string]interface{}{ "ren1": "m2", "ren2": "m2_2", }, } renamer, err := NewKeyRenamer( "{ren1,sub/*/ren1}", "new1", "{Ren2,sub/ren2}", "new2", ) c.Assert(err, qt.IsNil) renamer.Rename(m) if !reflect.DeepEqual(expected, m) { t.Errorf("Expected\n%#v, got\n%#v\n", expected, m) } } hugo-0.68.3/common/maps/params.go000066400000000000000000000053771363637351300166420ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package maps import ( "strings" "github.com/spf13/cast" ) // Params is a map where all keys are lower case. type Params map[string]interface{} // Get does a lower case and nested search in this map. // It will return nil if none found. func (p Params) Get(indices ...string) interface{} { v, _, _ := getNested(p, indices) return v } func getNested(m map[string]interface{}, indices []string) (interface{}, string, map[string]interface{}) { if len(indices) == 0 { return nil, "", nil } first := indices[0] v, found := m[strings.ToLower(cast.ToString(first))] if !found { return nil, "", nil } if len(indices) == 1 { return v, first, m } switch m2 := v.(type) { case Params: return getNested(m2, indices[1:]) case map[string]interface{}: return getNested(m2, indices[1:]) default: return nil, "", nil } } // GetNestedParam gets the first match of the keyStr in the candidates given. // It will first try the exact match and then try to find it as a nested map value, // using the given separator, e.g. "mymap.name". // It assumes that all the maps given have lower cased keys. func GetNestedParam(keyStr, separator string, candidates ...Params) (interface{}, error) { keyStr = strings.ToLower(keyStr) // Try exact match first for _, m := range candidates { if v, ok := m[keyStr]; ok { return v, nil } } keySegments := strings.Split(keyStr, separator) for _, m := range candidates { if v := m.Get(keySegments...); v != nil { return v, nil } } return nil, nil } func GetNestedParamFn(keyStr, separator string, lookupFn func(key string) interface{}) (interface{}, string, map[string]interface{}, error) { keySegments := strings.Split(strings.ToLower(keyStr), separator) if len(keySegments) == 0 { return nil, "", nil, nil } first := lookupFn(keySegments[0]) if first == nil { return nil, "", nil, nil } if len(keySegments) == 1 { return first, keySegments[0], nil, nil } switch m := first.(type) { case map[string]interface{}: v, key, owner := getNested(m, keySegments[1:]) return v, key, owner, nil case Params: v, key, owner := getNested(m, keySegments[1:]) return v, key, owner, nil } return nil, "", nil, nil } hugo-0.68.3/common/maps/params_test.go000066400000000000000000000027321363637351300176710ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package maps import ( "testing" qt "github.com/frankban/quicktest" ) func TestGetNestedParam(t *testing.T) { m := map[string]interface{}{ "string": "value", "first": 1, "with_underscore": 2, "nested": map[string]interface{}{ "color": "blue", "nestednested": map[string]interface{}{ "color": "green", }, }, } c := qt.New(t) must := func(keyStr, separator string, candidates ...Params) interface{} { v, err := GetNestedParam(keyStr, separator, candidates...) c.Assert(err, qt.IsNil) return v } c.Assert(must("first", "_", m), qt.Equals, 1) c.Assert(must("First", "_", m), qt.Equals, 1) c.Assert(must("with_underscore", "_", m), qt.Equals, 2) c.Assert(must("nested_color", "_", m), qt.Equals, "blue") c.Assert(must("nested.nestednested.color", ".", m), qt.Equals, "green") c.Assert(must("string.name", ".", m), qt.IsNil) } hugo-0.68.3/common/maps/scratch.go000066400000000000000000000073371363637351300170040ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package maps import ( "reflect" "sort" "sync" "github.com/gohugoio/hugo/common/collections" "github.com/gohugoio/hugo/common/math" ) // Scratch is a writable context used for stateful operations in Page/Node rendering. type Scratch struct { values map[string]interface{} mu sync.RWMutex } // Scratcher provides a scratching service. type Scratcher interface { Scratch() *Scratch } type scratcher struct { s *Scratch } func (s scratcher) Scratch() *Scratch { return s.s } // NewScratcher creates a new Scratcher. func NewScratcher() Scratcher { return scratcher{s: NewScratch()} } // Add will, for single values, add (using the + operator) the addend to the existing addend (if found). // Supports numeric values and strings. // // If the first add for a key is an array or slice, then the next value(s) will be appended. func (c *Scratch) Add(key string, newAddend interface{}) (string, error) { var newVal interface{} c.mu.RLock() existingAddend, found := c.values[key] c.mu.RUnlock() if found { var err error addendV := reflect.TypeOf(existingAddend) if addendV.Kind() == reflect.Slice || addendV.Kind() == reflect.Array { newVal, err = collections.Append(existingAddend, newAddend) if err != nil { return "", err } } else { newVal, err = math.DoArithmetic(existingAddend, newAddend, '+') if err != nil { return "", err } } } else { newVal = newAddend } c.mu.Lock() c.values[key] = newVal c.mu.Unlock() return "", nil // have to return something to make it work with the Go templates } // Set stores a value with the given key in the Node context. // This value can later be retrieved with Get. func (c *Scratch) Set(key string, value interface{}) string { c.mu.Lock() c.values[key] = value c.mu.Unlock() return "" } // Delete deletes the given key. func (c *Scratch) Delete(key string) string { c.mu.Lock() delete(c.values, key) c.mu.Unlock() return "" } // Get returns a value previously set by Add or Set. func (c *Scratch) Get(key string) interface{} { c.mu.RLock() val := c.values[key] c.mu.RUnlock() return val } // SetInMap stores a value to a map with the given key in the Node context. // This map can later be retrieved with GetSortedMapValues. func (c *Scratch) SetInMap(key string, mapKey string, value interface{}) string { c.mu.Lock() _, found := c.values[key] if !found { c.values[key] = make(map[string]interface{}) } c.values[key].(map[string]interface{})[mapKey] = value c.mu.Unlock() return "" } // GetSortedMapValues returns a sorted map previously filled with SetInMap. func (c *Scratch) GetSortedMapValues(key string) interface{} { c.mu.RLock() if c.values[key] == nil { c.mu.RUnlock() return nil } unsortedMap := c.values[key].(map[string]interface{}) c.mu.RUnlock() var keys []string for mapKey := range unsortedMap { keys = append(keys, mapKey) } sort.Strings(keys) sortedArray := make([]interface{}, len(unsortedMap)) for i, mapKey := range keys { sortedArray[i] = unsortedMap[mapKey] } return sortedArray } // NewScratch returns a new instance Scratch. func NewScratch() *Scratch { return &Scratch{values: make(map[string]interface{})} } hugo-0.68.3/common/maps/scratch_test.go000066400000000000000000000113271363637351300200350ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package maps import ( "reflect" "sync" "testing" qt "github.com/frankban/quicktest" ) func TestScratchAdd(t *testing.T) { t.Parallel() c := qt.New(t) scratch := NewScratch() scratch.Add("int1", 10) scratch.Add("int1", 20) scratch.Add("int2", 20) c.Assert(scratch.Get("int1"), qt.Equals, int64(30)) c.Assert(scratch.Get("int2"), qt.Equals, 20) scratch.Add("float1", float64(10.5)) scratch.Add("float1", float64(20.1)) c.Assert(scratch.Get("float1"), qt.Equals, float64(30.6)) scratch.Add("string1", "Hello ") scratch.Add("string1", "big ") scratch.Add("string1", "World!") c.Assert(scratch.Get("string1"), qt.Equals, "Hello big World!") scratch.Add("scratch", scratch) _, err := scratch.Add("scratch", scratch) if err == nil { t.Errorf("Expected error from invalid arithmetic") } } func TestScratchAddSlice(t *testing.T) { t.Parallel() c := qt.New(t) scratch := NewScratch() _, err := scratch.Add("intSlice", []int{1, 2}) c.Assert(err, qt.IsNil) _, err = scratch.Add("intSlice", 3) c.Assert(err, qt.IsNil) sl := scratch.Get("intSlice") expected := []int{1, 2, 3} if !reflect.DeepEqual(expected, sl) { t.Errorf("Slice difference, go %q expected %q", sl, expected) } _, err = scratch.Add("intSlice", []int{4, 5}) c.Assert(err, qt.IsNil) sl = scratch.Get("intSlice") expected = []int{1, 2, 3, 4, 5} if !reflect.DeepEqual(expected, sl) { t.Errorf("Slice difference, go %q expected %q", sl, expected) } } // https://github.com/gohugoio/hugo/issues/5275 func TestScratchAddTypedSliceToInterfaceSlice(t *testing.T) { t.Parallel() c := qt.New(t) scratch := NewScratch() scratch.Set("slice", []interface{}{}) _, err := scratch.Add("slice", []int{1, 2}) c.Assert(err, qt.IsNil) c.Assert(scratch.Get("slice"), qt.DeepEquals, []int{1, 2}) } // https://github.com/gohugoio/hugo/issues/5361 func TestScratchAddDifferentTypedSliceToInterfaceSlice(t *testing.T) { t.Parallel() c := qt.New(t) scratch := NewScratch() scratch.Set("slice", []string{"foo"}) _, err := scratch.Add("slice", []int{1, 2}) c.Assert(err, qt.IsNil) c.Assert(scratch.Get("slice"), qt.DeepEquals, []interface{}{"foo", 1, 2}) } func TestScratchSet(t *testing.T) { t.Parallel() c := qt.New(t) scratch := NewScratch() scratch.Set("key", "val") c.Assert(scratch.Get("key"), qt.Equals, "val") } func TestScratchDelete(t *testing.T) { t.Parallel() c := qt.New(t) scratch := NewScratch() scratch.Set("key", "val") scratch.Delete("key") scratch.Add("key", "Lucy Parsons") c.Assert(scratch.Get("key"), qt.Equals, "Lucy Parsons") } // Issue #2005 func TestScratchInParallel(t *testing.T) { var wg sync.WaitGroup scratch := NewScratch() key := "counter" scratch.Set(key, int64(1)) for i := 1; i <= 10; i++ { wg.Add(1) go func(j int) { for k := 0; k < 10; k++ { newVal := int64(k + j) _, err := scratch.Add(key, newVal) if err != nil { t.Errorf("Got err %s", err) } scratch.Set(key, newVal) val := scratch.Get(key) if counter, ok := val.(int64); ok { if counter < 1 { t.Errorf("Got %d", counter) } } else { t.Errorf("Got %T", val) } } wg.Done() }(i) } wg.Wait() } func TestScratchGet(t *testing.T) { t.Parallel() scratch := NewScratch() nothing := scratch.Get("nothing") if nothing != nil { t.Errorf("Should not return anything, but got %v", nothing) } } func TestScratchSetInMap(t *testing.T) { t.Parallel() c := qt.New(t) scratch := NewScratch() scratch.SetInMap("key", "lux", "Lux") scratch.SetInMap("key", "abc", "Abc") scratch.SetInMap("key", "zyx", "Zyx") scratch.SetInMap("key", "abc", "Abc (updated)") scratch.SetInMap("key", "def", "Def") c.Assert(scratch.GetSortedMapValues("key"), qt.DeepEquals, []interface{}{0: "Abc (updated)", 1: "Def", 2: "Lux", 3: "Zyx"}) } func TestScratchGetSortedMapValues(t *testing.T) { t.Parallel() scratch := NewScratch() nothing := scratch.GetSortedMapValues("nothing") if nothing != nil { t.Errorf("Should not return anything, but got %v", nothing) } } func BenchmarkScratchGet(b *testing.B) { scratch := NewScratch() scratch.Add("A", 1) b.ResetTimer() for i := 0; i < b.N; i++ { scratch.Get("A") } } hugo-0.68.3/common/math/000077500000000000000000000000001363637351300150055ustar00rootroot00000000000000hugo-0.68.3/common/math/math.go000066400000000000000000000073511363637351300162730ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package math import ( "errors" "reflect" ) // DoArithmetic performs arithmetic operations (+,-,*,/) using reflection to // determine the type of the two terms. func DoArithmetic(a, b interface{}, op rune) (interface{}, error) { av := reflect.ValueOf(a) bv := reflect.ValueOf(b) var ai, bi int64 var af, bf float64 var au, bu uint64 switch av.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: ai = av.Int() switch bv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: bi = bv.Int() case reflect.Float32, reflect.Float64: af = float64(ai) // may overflow ai = 0 bf = bv.Float() case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: bu = bv.Uint() if ai >= 0 { au = uint64(ai) ai = 0 } else { bi = int64(bu) // may overflow bu = 0 } default: return nil, errors.New("can't apply the operator to the values") } case reflect.Float32, reflect.Float64: af = av.Float() switch bv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: bf = float64(bv.Int()) // may overflow case reflect.Float32, reflect.Float64: bf = bv.Float() case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: bf = float64(bv.Uint()) // may overflow default: return nil, errors.New("can't apply the operator to the values") } case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: au = av.Uint() switch bv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: bi = bv.Int() if bi >= 0 { bu = uint64(bi) bi = 0 } else { ai = int64(au) // may overflow au = 0 } case reflect.Float32, reflect.Float64: af = float64(au) // may overflow au = 0 bf = bv.Float() case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: bu = bv.Uint() default: return nil, errors.New("can't apply the operator to the values") } case reflect.String: as := av.String() if bv.Kind() == reflect.String && op == '+' { bs := bv.String() return as + bs, nil } return nil, errors.New("can't apply the operator to the values") default: return nil, errors.New("can't apply the operator to the values") } switch op { case '+': if ai != 0 || bi != 0 { return ai + bi, nil } else if af != 0 || bf != 0 { return af + bf, nil } else if au != 0 || bu != 0 { return au + bu, nil } return 0, nil case '-': if ai != 0 || bi != 0 { return ai - bi, nil } else if af != 0 || bf != 0 { return af - bf, nil } else if au != 0 || bu != 0 { return au - bu, nil } return 0, nil case '*': if ai != 0 || bi != 0 { return ai * bi, nil } else if af != 0 || bf != 0 { return af * bf, nil } else if au != 0 || bu != 0 { return au * bu, nil } return 0, nil case '/': if bi != 0 { return ai / bi, nil } else if bf != 0 { return af / bf, nil } else if bu != 0 { return au / bu, nil } return nil, errors.New("can't divide the value by 0") default: return nil, errors.New("there is no such an operation") } } hugo-0.68.3/common/math/math_test.go000066400000000000000000000057061363637351300173340ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package math import ( "testing" qt "github.com/frankban/quicktest" ) func TestDoArithmetic(t *testing.T) { t.Parallel() c := qt.New(t) for _, test := range []struct { a interface{} b interface{} op rune expect interface{} }{ {3, 2, '+', int64(5)}, {3, 2, '-', int64(1)}, {3, 2, '*', int64(6)}, {3, 2, '/', int64(1)}, {3.0, 2, '+', float64(5)}, {3.0, 2, '-', float64(1)}, {3.0, 2, '*', float64(6)}, {3.0, 2, '/', float64(1.5)}, {3, 2.0, '+', float64(5)}, {3, 2.0, '-', float64(1)}, {3, 2.0, '*', float64(6)}, {3, 2.0, '/', float64(1.5)}, {3.0, 2.0, '+', float64(5)}, {3.0, 2.0, '-', float64(1)}, {3.0, 2.0, '*', float64(6)}, {3.0, 2.0, '/', float64(1.5)}, {uint(3), uint(2), '+', uint64(5)}, {uint(3), uint(2), '-', uint64(1)}, {uint(3), uint(2), '*', uint64(6)}, {uint(3), uint(2), '/', uint64(1)}, {uint(3), 2, '+', uint64(5)}, {uint(3), 2, '-', uint64(1)}, {uint(3), 2, '*', uint64(6)}, {uint(3), 2, '/', uint64(1)}, {3, uint(2), '+', uint64(5)}, {3, uint(2), '-', uint64(1)}, {3, uint(2), '*', uint64(6)}, {3, uint(2), '/', uint64(1)}, {uint(3), -2, '+', int64(1)}, {uint(3), -2, '-', int64(5)}, {uint(3), -2, '*', int64(-6)}, {uint(3), -2, '/', int64(-1)}, {-3, uint(2), '+', int64(-1)}, {-3, uint(2), '-', int64(-5)}, {-3, uint(2), '*', int64(-6)}, {-3, uint(2), '/', int64(-1)}, {uint(3), 2.0, '+', float64(5)}, {uint(3), 2.0, '-', float64(1)}, {uint(3), 2.0, '*', float64(6)}, {uint(3), 2.0, '/', float64(1.5)}, {3.0, uint(2), '+', float64(5)}, {3.0, uint(2), '-', float64(1)}, {3.0, uint(2), '*', float64(6)}, {3.0, uint(2), '/', float64(1.5)}, {0, 0, '+', 0}, {0, 0, '-', 0}, {0, 0, '*', 0}, {"foo", "bar", '+', "foobar"}, {3, 0, '/', false}, {3.0, 0, '/', false}, {3, 0.0, '/', false}, {uint(3), uint(0), '/', false}, {3, uint(0), '/', false}, {-3, uint(0), '/', false}, {uint(3), 0, '/', false}, {3.0, uint(0), '/', false}, {uint(3), 0.0, '/', false}, {3, "foo", '+', false}, {3.0, "foo", '+', false}, {uint(3), "foo", '+', false}, {"foo", 3, '+', false}, {"foo", "bar", '-', false}, {3, 2, '%', false}, } { result, err := DoArithmetic(test.a, test.b, test.op) if b, ok := test.expect.(bool); ok && !b { c.Assert(err, qt.Not(qt.IsNil)) continue } c.Assert(err, qt.IsNil) c.Assert(test.expect, qt.Equals, result) } } hugo-0.68.3/common/para/000077500000000000000000000000001363637351300147775ustar00rootroot00000000000000hugo-0.68.3/common/para/para.go000066400000000000000000000034421363637351300162540ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package para implements parallel execution helpers. package para import ( "context" "golang.org/x/sync/errgroup" ) // Workers configures a task executor with the most number of tasks to be executed in parallel. type Workers struct { sem chan struct{} } // Runner wraps the lifecycle methods of a new task set. // // Run wil block until a worker is available or the context is cancelled, // and then run the given func in a new goroutine. // Wait will wait for all the running goroutines to finish. type Runner interface { Run(func() error) Wait() error } type errGroupRunner struct { *errgroup.Group w *Workers ctx context.Context } func (g *errGroupRunner) Run(fn func() error) { select { case g.w.sem <- struct{}{}: case <-g.ctx.Done(): return } g.Go(func() error { err := fn() <-g.w.sem return err }) } // New creates a new Workers with the given number of workers. func New(numWorkers int) *Workers { return &Workers{ sem: make(chan struct{}, numWorkers), } } // Start starts a new Runner. func (w *Workers) Start(ctx context.Context) (Runner, context.Context) { g, ctx := errgroup.WithContext(ctx) return &errGroupRunner{ Group: g, ctx: ctx, w: w, }, ctx } hugo-0.68.3/common/para/para_test.go000066400000000000000000000036221363637351300173130ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package para import ( "context" "runtime" "sort" "sync" "sync/atomic" "testing" "time" qt "github.com/frankban/quicktest" ) func TestPara(t *testing.T) { if runtime.NumCPU() < 4 { t.Skipf("skip para test, CPU count is %d", runtime.NumCPU()) } c := qt.New(t) c.Run("Order", func(c *qt.C) { n := 500 ints := make([]int, n) for i := 0; i < n; i++ { ints[i] = i } p := New(4) r, _ := p.Start(context.Background()) var result []int var mu sync.Mutex for i := 0; i < n; i++ { i := i r.Run(func() error { mu.Lock() defer mu.Unlock() result = append(result, i) return nil }) } c.Assert(r.Wait(), qt.IsNil) c.Assert(result, qt.HasLen, len(ints)) c.Assert(sort.IntsAreSorted(result), qt.Equals, false, qt.Commentf("Para does not seem to be parallel")) sort.Ints(result) c.Assert(result, qt.DeepEquals, ints) }) c.Run("Time", func(c *qt.C) { const n = 100 p := New(5) r, _ := p.Start(context.Background()) start := time.Now() var counter int64 for i := 0; i < n; i++ { r.Run(func() error { atomic.AddInt64(&counter, 1) time.Sleep(1 * time.Millisecond) return nil }) } c.Assert(r.Wait(), qt.IsNil) c.Assert(counter, qt.Equals, int64(n)) c.Assert(time.Since(start) < n/2*time.Millisecond, qt.Equals, true) }) } hugo-0.68.3/common/terminal/000077500000000000000000000000001363637351300156675ustar00rootroot00000000000000hugo-0.68.3/common/terminal/colors.go000066400000000000000000000035671363637351300175320ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package terminal contains helper for the terminal, such as coloring output. package terminal import ( "fmt" "os" "runtime" "strings" isatty "github.com/mattn/go-isatty" ) const ( errorColor = "\033[1;31m%s\033[0m" warningColor = "\033[0;33m%s\033[0m" noticeColor = "\033[1;36m%s\033[0m" ) // IsTerminal return true if the file descriptor is terminal and the TERM // environment variable isn't a dumb one. func IsTerminal(f *os.File) bool { if runtime.GOOS == "windows" { return false } fd := f.Fd() return os.Getenv("TERM") != "dumb" && (isatty.IsTerminal(fd) || isatty.IsCygwinTerminal(fd)) } // Notice colorizes the string in a noticeable color. func Notice(s string) string { return colorize(s, noticeColor) } // Error colorizes the string in a colour that grabs attention. func Error(s string) string { return colorize(s, errorColor) } // Warning colorizes the string in a colour that warns. func Warning(s string) string { return colorize(s, warningColor) } // colorize s in color. func colorize(s, color string) string { s = fmt.Sprintf(color, doublePercent(s)) return singlePercent(s) } func doublePercent(str string) string { return strings.Replace(str, "%", "%%", -1) } func singlePercent(str string) string { return strings.Replace(str, "%%", "%", -1) } hugo-0.68.3/common/text/000077500000000000000000000000001363637351300150405ustar00rootroot00000000000000hugo-0.68.3/common/text/position.go000066400000000000000000000050111363637351300172300ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package text import ( "fmt" "os" "strings" "github.com/gohugoio/hugo/common/terminal" ) // Positioner represents a thing that knows its position in a text file or stream, // typically an error. type Positioner interface { Position() Position } // Position holds a source position in a text file or stream. type Position struct { Filename string // filename, if any Offset int // byte offset, starting at 0. It's set to -1 if not provided. LineNumber int // line number, starting at 1 ColumnNumber int // column number, starting at 1 (character count per line) } func (pos Position) String() string { if pos.Filename == "" { pos.Filename = "" } return positionStringFormatfunc(pos) } // IsValid returns true if line number is > 0. func (pos Position) IsValid() bool { return pos.LineNumber > 0 } var positionStringFormatfunc func(p Position) string func createPositionStringFormatter(formatStr string) func(p Position) string { if formatStr == "" { formatStr = "\":file::line::col\"" } var identifiers = []string{":file", ":line", ":col"} var identifiersFound []string for i := range formatStr { for _, id := range identifiers { if strings.HasPrefix(formatStr[i:], id) { identifiersFound = append(identifiersFound, id) } } } replacer := strings.NewReplacer(":file", "%s", ":line", "%d", ":col", "%d") format := replacer.Replace(formatStr) f := func(pos Position) string { args := make([]interface{}, len(identifiersFound)) for i, id := range identifiersFound { switch id { case ":file": args[i] = pos.Filename case ":line": args[i] = pos.LineNumber case ":col": args[i] = pos.ColumnNumber } } msg := fmt.Sprintf(format, args...) if terminal.IsTerminal(os.Stdout) { return terminal.Notice(msg) } return msg } return f } func init() { positionStringFormatfunc = createPositionStringFormatter(os.Getenv("HUGO_FILE_LOG_FORMAT")) } hugo-0.68.3/common/text/position_test.go000066400000000000000000000023631363637351300202760ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package text import ( "testing" qt "github.com/frankban/quicktest" ) func TestPositionStringFormatter(t *testing.T) { c := qt.New(t) pos := Position{Filename: "/my/file.txt", LineNumber: 12, ColumnNumber: 13, Offset: 14} c.Assert(createPositionStringFormatter(":file|:col|:line")(pos), qt.Equals, "/my/file.txt|13|12") c.Assert(createPositionStringFormatter(":col|:file|:line")(pos), qt.Equals, "13|/my/file.txt|12") c.Assert(createPositionStringFormatter("好::col")(pos), qt.Equals, "好:13") c.Assert(createPositionStringFormatter("")(pos), qt.Equals, "\"/my/file.txt:12:13\"") c.Assert(pos.String(), qt.Equals, "\"/my/file.txt:12:13\"") } hugo-0.68.3/common/text/transform.go000066400000000000000000000025321363637351300174040ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package text import ( "sync" "unicode" "golang.org/x/text/runes" "golang.org/x/text/transform" "golang.org/x/text/unicode/norm" ) var accentTransformerPool = &sync.Pool{ New: func() interface{} { return transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC) }, } // RemoveAccents removes all accents from b. func RemoveAccents(b []byte) []byte { t := accentTransformerPool.Get().(transform.Transformer) b, _, _ = transform.Bytes(t, b) t.Reset() accentTransformerPool.Put(t) return b } // RemoveAccentsString removes all accents from s. func RemoveAccentsString(s string) string { t := accentTransformerPool.Get().(transform.Transformer) s, _, _ = transform.String(t, s) t.Reset() accentTransformerPool.Put(t) return s } hugo-0.68.3/common/text/transform_test.go000066400000000000000000000017101363637351300204400ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package text import ( "testing" qt "github.com/frankban/quicktest" ) func TestRemoveAccents(t *testing.T) { c := qt.New(t) c.Assert(string(RemoveAccents([]byte("Resumé"))), qt.Equals, "Resume") c.Assert(string(RemoveAccents([]byte("Hugo Rocks!"))), qt.Equals, "Hugo Rocks!") c.Assert(string(RemoveAccentsString("Resumé")), qt.Equals, "Resume") } hugo-0.68.3/common/types/000077500000000000000000000000001363637351300152205ustar00rootroot00000000000000hugo-0.68.3/common/types/convert.go000066400000000000000000000033201363637351300172250ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package types import ( "html/template" "github.com/spf13/cast" ) // ToStringSlicePreserveString converts v to a string slice. // If v is a string, it will be wrapped in a string slice. func ToStringSlicePreserveString(v interface{}) []string { if v == nil { return nil } if sds, ok := v.(string); ok { return []string{sds} } return cast.ToStringSlice(v) } // TypeToString converts v to a string if it's a valid string type. // Note that this will not try to convert numeric values etc., // use ToString for that. func TypeToString(v interface{}) (string, bool) { switch s := v.(type) { case string: return s, true case template.HTML: return string(s), true case template.CSS: return string(s), true case template.HTMLAttr: return string(s), true case template.JS: return string(s), true case template.JSStr: return string(s), true case template.URL: return string(s), true case template.Srcset: return string(s), true } return "", false } // ToString converts v to a string. func ToString(v interface{}) string { if s, ok := TypeToString(v); ok { return s } return cast.ToString(v) } hugo-0.68.3/common/types/convert_test.go000066400000000000000000000017361363637351300202750ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package types import ( "testing" qt "github.com/frankban/quicktest" ) func TestToStringSlicePreserveString(t *testing.T) { c := qt.New(t) c.Assert(ToStringSlicePreserveString("Hugo"), qt.DeepEquals, []string{"Hugo"}) c.Assert(ToStringSlicePreserveString([]interface{}{"A", "B"}), qt.DeepEquals, []string{"A", "B"}) c.Assert(ToStringSlicePreserveString(nil), qt.IsNil) } hugo-0.68.3/common/types/evictingqueue.go000066400000000000000000000050741363637351300204320ustar00rootroot00000000000000// Copyright 2017-present The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package types contains types shared between packages in Hugo. package types import ( "sync" ) // EvictingStringQueue is a queue which automatically evicts elements from the head of // the queue when attempting to add new elements onto the queue and it is full. // This queue orders elements LIFO (last-in-first-out). It throws away duplicates. // Note: This queue currently does not contain any remove (poll etc.) methods. type EvictingStringQueue struct { size int vals []string set map[string]bool mu sync.Mutex } // NewEvictingStringQueue creates a new queue with the given size. func NewEvictingStringQueue(size int) *EvictingStringQueue { return &EvictingStringQueue{size: size, set: make(map[string]bool)} } // Add adds a new string to the tail of the queue if it's not already there. func (q *EvictingStringQueue) Add(v string) { q.mu.Lock() if q.set[v] { q.mu.Unlock() return } if len(q.set) == q.size { // Full delete(q.set, q.vals[0]) q.vals = append(q.vals[:0], q.vals[1:]...) } q.set[v] = true q.vals = append(q.vals, v) q.mu.Unlock() } // Contains returns whether the queue contains v. func (q *EvictingStringQueue) Contains(v string) bool { q.mu.Lock() defer q.mu.Unlock() return q.set[v] } // Peek looks at the last element added to the queue. func (q *EvictingStringQueue) Peek() string { q.mu.Lock() l := len(q.vals) if l == 0 { q.mu.Unlock() return "" } elem := q.vals[l-1] q.mu.Unlock() return elem } // PeekAll looks at all the elements in the queue, with the newest first. func (q *EvictingStringQueue) PeekAll() []string { q.mu.Lock() vals := make([]string, len(q.vals)) copy(vals, q.vals) q.mu.Unlock() for i, j := 0, len(vals)-1; i < j; i, j = i+1, j-1 { vals[i], vals[j] = vals[j], vals[i] } return vals } // PeekAllSet returns PeekAll as a set. func (q *EvictingStringQueue) PeekAllSet() map[string]bool { all := q.PeekAll() set := make(map[string]bool) for _, v := range all { set[v] = true } return set } hugo-0.68.3/common/types/evictingqueue_test.go000066400000000000000000000035231363637351300214660ustar00rootroot00000000000000// Copyright 2017-present The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package types import ( "sync" "testing" qt "github.com/frankban/quicktest" ) func TestEvictingStringQueue(t *testing.T) { c := qt.New(t) queue := NewEvictingStringQueue(3) c.Assert(queue.Peek(), qt.Equals, "") queue.Add("a") queue.Add("b") queue.Add("a") c.Assert(queue.Peek(), qt.Equals, "b") queue.Add("b") c.Assert(queue.Peek(), qt.Equals, "b") queue.Add("a") queue.Add("b") c.Assert(queue.Contains("a"), qt.Equals, true) c.Assert(queue.Contains("foo"), qt.Equals, false) c.Assert(queue.PeekAll(), qt.DeepEquals, []string{"b", "a"}) c.Assert(queue.Peek(), qt.Equals, "b") queue.Add("c") queue.Add("d") // Overflowed, a should now be removed. c.Assert(queue.PeekAll(), qt.DeepEquals, []string{"d", "c", "b"}) c.Assert(len(queue.PeekAllSet()), qt.Equals, 3) c.Assert(queue.PeekAllSet()["c"], qt.Equals, true) } func TestEvictingStringQueueConcurrent(t *testing.T) { var wg sync.WaitGroup val := "someval" queue := NewEvictingStringQueue(3) for j := 0; j < 100; j++ { wg.Add(1) go func() { defer wg.Done() queue.Add(val) v := queue.Peek() if v != val { t.Error("wrong val") } vals := queue.PeekAll() if len(vals) != 1 || vals[0] != val { t.Error("wrong val") } }() } wg.Wait() } hugo-0.68.3/common/types/types.go000066400000000000000000000042131363637351300167130ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package types contains types shared between packages in Hugo. package types import ( "fmt" "reflect" "github.com/spf13/cast" ) // RLocker represents the read locks in sync.RWMutex. type RLocker interface { RLock() RUnlock() } // KeyValueStr is a string tuple. type KeyValueStr struct { Key string Value string } // KeyValues holds an key and a slice of values. type KeyValues struct { Key interface{} Values []interface{} } // KeyString returns the key as a string, an empty string if conversion fails. func (k KeyValues) KeyString() string { return cast.ToString(k.Key) } func (k KeyValues) String() string { return fmt.Sprintf("%v: %v", k.Key, k.Values) } // NewKeyValuesStrings takes a given key and slice of values and returns a new // KeyValues struct. func NewKeyValuesStrings(key string, values ...string) KeyValues { iv := make([]interface{}, len(values)) for i := 0; i < len(values); i++ { iv[i] = values[i] } return KeyValues{Key: key, Values: iv} } // Zeroer, as implemented by time.Time, will be used by the truth template // funcs in Hugo (if, with, not, and, or). type Zeroer interface { IsZero() bool } // IsNil reports whether v is nil. func IsNil(v interface{}) bool { if v == nil { return true } value := reflect.ValueOf(v) switch value.Kind() { case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: return value.IsNil() } return false } // DevMarker is a marker interface for types that should only be used during // development. type DevMarker interface { DevOnly() } hugo-0.68.3/common/types/types_test.go000066400000000000000000000016041363637351300177530ustar00rootroot00000000000000// Copyright 2017-present The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package types import ( "testing" qt "github.com/frankban/quicktest" ) func TestKeyValues(t *testing.T) { c := qt.New(t) kv := NewKeyValuesStrings("key", "a1", "a2") c.Assert(kv.KeyString(), qt.Equals, "key") c.Assert(kv.Values, qt.DeepEquals, []interface{}{"a1", "a2"}) } hugo-0.68.3/common/urls/000077500000000000000000000000001363637351300150415ustar00rootroot00000000000000hugo-0.68.3/common/urls/ref.go000066400000000000000000000016231363637351300161460ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package urls // RefLinker is implemented by those who support reference linking. // args must contain a path, but can also point to the target // language or output format. type RefLinker interface { Ref(args map[string]interface{}) (string, error) RelRef(args map[string]interface{}) (string, error) } hugo-0.68.3/compare/000077500000000000000000000000001363637351300142125ustar00rootroot00000000000000hugo-0.68.3/compare/compare.go000066400000000000000000000024341363637351300161720ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package compare // Eqer can be used to determine if this value is equal to the other. // The semantics of equals is that the two value are interchangeable // in the Hugo templates. type Eqer interface { Eq(other interface{}) bool } // ProbablyEqer is an equal check that may return false positives, but never // a false negative. type ProbablyEqer interface { ProbablyEq(other interface{}) bool } // Comparer can be used to compare two values. // This will be used when using the le, ge etc. operators in the templates. // Compare returns -1 if the given version is less than, 0 if equal and 1 if greater than // the running version. type Comparer interface { Compare(other interface{}) int } hugo-0.68.3/compare/compare_strings.go000066400000000000000000000042371363637351300177460ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package compare import ( "strings" "unicode" "unicode/utf8" ) // Strings returns an integer comparing two strings lexicographically. func Strings(s, t string) int { c := compareFold(s, t) if c == 0 { // "B" and "b" would be the same so we need a tiebreaker. return strings.Compare(s, t) } return c } // This function is derived from strings.EqualFold in Go's stdlib. // https://github.com/golang/go/blob/ad4a58e31501bce5de2aad90a620eaecdc1eecb8/src/strings/strings.go#L893 func compareFold(s, t string) int { for s != "" && t != "" { var sr, tr rune if s[0] < utf8.RuneSelf { sr, s = rune(s[0]), s[1:] } else { r, size := utf8.DecodeRuneInString(s) sr, s = r, s[size:] } if t[0] < utf8.RuneSelf { tr, t = rune(t[0]), t[1:] } else { r, size := utf8.DecodeRuneInString(t) tr, t = r, t[size:] } if tr == sr { continue } c := 1 if tr < sr { tr, sr = sr, tr c = -c } // ASCII only. if tr < utf8.RuneSelf { if sr >= 'A' && sr <= 'Z' { if tr <= 'Z' { // Same case. return -c } diff := tr - (sr + 'a' - 'A') if diff == 0 { continue } if diff < 0 { return c } if diff > 0 { return -c } } } // Unicode. r := unicode.SimpleFold(sr) for r != sr && r < tr { r = unicode.SimpleFold(r) } if r == tr { continue } return -c } if s == "" && t == "" { return 0 } if s == "" { return -1 } return 1 } // LessStrings returns whether s is less than t lexicographically. func LessStrings(s, t string) bool { return Strings(s, t) < 0 } hugo-0.68.3/compare/compare_strings_test.go000066400000000000000000000027351363637351300210060ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package compare import ( "sort" "strings" "testing" qt "github.com/frankban/quicktest" ) func TestCompare(t *testing.T) { c := qt.New(t) for _, test := range []struct { a string b string }{ {"a", "a"}, {"A", "a"}, {"Ab", "Ac"}, {"az", "Za"}, {"C", "D"}, {"B", "a"}, {"C", ""}, {"", ""}, {"αβδC", "ΑΒΔD"}, {"αβδC", "ΑΒΔ"}, {"αβδ", "ΑΒΔD"}, {"αβδ", "ΑΒΔ"}, {"β", "δ"}, {"好", strings.ToLower("好")}, } { expect := strings.Compare(strings.ToLower(test.a), strings.ToLower(test.b)) got := compareFold(test.a, test.b) c.Assert(got, qt.Equals, expect) } } func TestLexicographicSort(t *testing.T) { c := qt.New(t) s := []string{"b", "Bz", "ba", "A", "Ba", "ba"} sort.Slice(s, func(i, j int) bool { return LessStrings(s[i], s[j]) }) c.Assert(s, qt.DeepEquals, []string{"A", "b", "Ba", "ba", "ba", "Bz"}) } hugo-0.68.3/config/000077500000000000000000000000001363637351300140315ustar00rootroot00000000000000hugo-0.68.3/config/commonConfig.go000066400000000000000000000062321363637351300170010ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "sort" "strings" "sync" "github.com/gohugoio/hugo/common/types" "github.com/gobwas/glob" "github.com/gohugoio/hugo/common/herrors" "github.com/mitchellh/mapstructure" "github.com/spf13/cast" jww "github.com/spf13/jwalterweatherman" ) var DefaultBuild = Build{ UseResourceCacheWhen: "fallback", } // Build holds some build related condfiguration. type Build struct { UseResourceCacheWhen string // never, fallback, always. Default is fallback } func (b Build) UseResourceCache(err error) bool { if b.UseResourceCacheWhen == "never" { return false } if b.UseResourceCacheWhen == "fallback" { return err == herrors.ErrFeatureNotAvailable } return true } func DecodeBuild(cfg Provider) Build { m := cfg.GetStringMap("build") b := DefaultBuild if m == nil { return b } err := mapstructure.WeakDecode(m, &b) if err != nil { return DefaultBuild } b.UseResourceCacheWhen = strings.ToLower(b.UseResourceCacheWhen) when := b.UseResourceCacheWhen if when != "never" && when != "always" && when != "fallback" { b.UseResourceCacheWhen = "fallback" } return b } // Sitemap configures the sitemap to be generated. type Sitemap struct { ChangeFreq string Priority float64 Filename string } func DecodeSitemap(prototype Sitemap, input map[string]interface{}) Sitemap { for key, value := range input { switch key { case "changefreq": prototype.ChangeFreq = cast.ToString(value) case "priority": prototype.Priority = cast.ToFloat64(value) case "filename": prototype.Filename = cast.ToString(value) default: jww.WARN.Printf("Unknown Sitemap field: %s\n", key) } } return prototype } // Config for the dev server. type Server struct { Headers []Headers compiledInit sync.Once compiled []glob.Glob } func (s *Server) Match(pattern string) []types.KeyValueStr { s.compiledInit.Do(func() { for _, h := range s.Headers { s.compiled = append(s.compiled, glob.MustCompile(h.For)) } }) if s.compiled == nil { return nil } var matches []types.KeyValueStr for i, g := range s.compiled { if g.Match(pattern) { h := s.Headers[i] for k, v := range h.Values { matches = append(matches, types.KeyValueStr{Key: k, Value: cast.ToString(v)}) } } } sort.Slice(matches, func(i, j int) bool { return matches[i].Key < matches[j].Key }) return matches } type Headers struct { For string Values map[string]interface{} } func DecodeServer(cfg Provider) *Server { m := cfg.GetStringMap("server") s := &Server{} if m == nil { return s } _ = mapstructure.WeakDecode(m, s) return s } hugo-0.68.3/config/commonConfig_test.go000066400000000000000000000044241363637351300200410ustar00rootroot00000000000000// Copyright 2020 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "errors" "testing" "github.com/gohugoio/hugo/common/herrors" "github.com/gohugoio/hugo/common/types" qt "github.com/frankban/quicktest" "github.com/spf13/viper" ) func TestBuild(t *testing.T) { c := qt.New(t) v := viper.New() v.Set("build", map[string]interface{}{ "useResourceCacheWhen": "always", }) b := DecodeBuild(v) c.Assert(b.UseResourceCacheWhen, qt.Equals, "always") v.Set("build", map[string]interface{}{ "useResourceCacheWhen": "foo", }) b = DecodeBuild(v) c.Assert(b.UseResourceCacheWhen, qt.Equals, "fallback") c.Assert(b.UseResourceCache(herrors.ErrFeatureNotAvailable), qt.Equals, true) c.Assert(b.UseResourceCache(errors.New("err")), qt.Equals, false) b.UseResourceCacheWhen = "always" c.Assert(b.UseResourceCache(herrors.ErrFeatureNotAvailable), qt.Equals, true) c.Assert(b.UseResourceCache(errors.New("err")), qt.Equals, true) c.Assert(b.UseResourceCache(nil), qt.Equals, true) b.UseResourceCacheWhen = "never" c.Assert(b.UseResourceCache(herrors.ErrFeatureNotAvailable), qt.Equals, false) c.Assert(b.UseResourceCache(errors.New("err")), qt.Equals, false) c.Assert(b.UseResourceCache(nil), qt.Equals, false) } func TestServer(t *testing.T) { c := qt.New(t) cfg, err := FromConfigString(`[[server.headers]] for = "/*.jpg" [server.headers.values] X-Frame-Options = "DENY" X-XSS-Protection = "1; mode=block" X-Content-Type-Options = "nosniff" `, "toml") c.Assert(err, qt.IsNil) s := DecodeServer(cfg) c.Assert(s.Match("/foo.jpg"), qt.DeepEquals, []types.KeyValueStr{ {Key: "X-Content-Type-Options", Value: "nosniff"}, {Key: "X-Frame-Options", Value: "DENY"}, {Key: "X-XSS-Protection", Value: "1; mode=block"}}) } hugo-0.68.3/config/configLoader.go000066400000000000000000000061051363637351300167560ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "path/filepath" "strings" "github.com/gohugoio/hugo/common/maps" "github.com/gohugoio/hugo/parser/metadecoders" "github.com/spf13/afero" "github.com/spf13/viper" ) var ( ValidConfigFileExtensions = []string{"toml", "yaml", "yml", "json"} validConfigFileExtensionsMap map[string]bool = make(map[string]bool) ) func init() { for _, ext := range ValidConfigFileExtensions { validConfigFileExtensionsMap[ext] = true } } // IsValidConfigFilename returns whether filename is one of the supported // config formats in Hugo. func IsValidConfigFilename(filename string) bool { ext := strings.ToLower(strings.TrimPrefix(filepath.Ext(filename), ".")) return validConfigFileExtensionsMap[ext] } // FromConfigString creates a config from the given YAML, JSON or TOML config. This is useful in tests. func FromConfigString(config, configType string) (Provider, error) { v := newViper() m, err := readConfig(metadecoders.FormatFromString(configType), []byte(config)) if err != nil { return nil, err } v.MergeConfigMap(m) return v, nil } // FromFile loads the configuration from the given filename. func FromFile(fs afero.Fs, filename string) (Provider, error) { m, err := loadConfigFromFile(fs, filename) if err != nil { return nil, err } v := newViper() err = v.MergeConfigMap(m) if err != nil { return nil, err } return v, nil } // FromFileToMap is the same as FromFile, but it returns the config values // as a simple map. func FromFileToMap(fs afero.Fs, filename string) (map[string]interface{}, error) { return loadConfigFromFile(fs, filename) } func readConfig(format metadecoders.Format, data []byte) (map[string]interface{}, error) { m, err := metadecoders.Default.UnmarshalToMap(data, format) if err != nil { return nil, err } RenameKeys(m) return m, nil } func loadConfigFromFile(fs afero.Fs, filename string) (map[string]interface{}, error) { m, err := metadecoders.Default.UnmarshalFileToMap(fs, filename) if err != nil { return nil, err } RenameKeys(m) return m, nil } var keyAliases maps.KeyRenamer func init() { var err error keyAliases, err = maps.NewKeyRenamer( // Before 0.53 we used singular for "menu". "{menu,languages/*/menu}", "menus", ) if err != nil { panic(err) } } // RenameKeys renames config keys in m recursively according to a global Hugo // alias definition. func RenameKeys(m map[string]interface{}) { keyAliases.Rename(m) } func newViper() *viper.Viper { v := viper.New() return v } hugo-0.68.3/config/configLoader_test.go000066400000000000000000000021251363637351300200130ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "strings" "testing" qt "github.com/frankban/quicktest" ) func TestIsValidConfigFileName(t *testing.T) { c := qt.New(t) for _, ext := range ValidConfigFileExtensions { filename := "config." + ext c.Assert(IsValidConfigFilename(filename), qt.Equals, true) c.Assert(IsValidConfigFilename(strings.ToUpper(filename)), qt.Equals, true) } c.Assert(IsValidConfigFilename(""), qt.Equals, false) c.Assert(IsValidConfigFilename("config.toml.swp"), qt.Equals, false) } hugo-0.68.3/config/configProvider.go000066400000000000000000000034211363637351300173400ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "github.com/gohugoio/hugo/common/types" ) // Provider provides the configuration settings for Hugo. type Provider interface { GetString(key string) string GetInt(key string) int GetBool(key string) bool GetStringMap(key string) map[string]interface{} GetStringMapString(key string) map[string]string GetStringSlice(key string) []string Get(key string) interface{} Set(key string, value interface{}) IsSet(key string) bool } // GetStringSlicePreserveString returns a string slice from the given config and key. // It differs from the GetStringSlice method in that if the config value is a string, // we do not attempt to split it into fields. func GetStringSlicePreserveString(cfg Provider, key string) []string { sd := cfg.Get(key) return types.ToStringSlicePreserveString(sd) } // SetBaseTestDefaults provides some common config defaults used in tests. func SetBaseTestDefaults(cfg Provider) { cfg.Set("resourceDir", "resources") cfg.Set("contentDir", "content") cfg.Set("dataDir", "data") cfg.Set("i18nDir", "i18n") cfg.Set("layoutDir", "layouts") cfg.Set("assetDir", "assets") cfg.Set("archetypeDir", "archetypes") cfg.Set("publishDir", "public") } hugo-0.68.3/config/configProvider_test.go000066400000000000000000000021561363637351300204030ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "testing" qt "github.com/frankban/quicktest" "github.com/spf13/viper" ) func TestGetStringSlicePreserveString(t *testing.T) { c := qt.New(t) cfg := viper.New() s := "This is a string" sSlice := []string{"This", "is", "a", "slice"} cfg.Set("s1", s) cfg.Set("s2", sSlice) c.Assert(GetStringSlicePreserveString(cfg, "s1"), qt.DeepEquals, []string{s}) c.Assert(GetStringSlicePreserveString(cfg, "s2"), qt.DeepEquals, sSlice) c.Assert(GetStringSlicePreserveString(cfg, "s3"), qt.IsNil) } hugo-0.68.3/config/env.go000066400000000000000000000032441363637351300151530ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "os" "runtime" "strconv" "strings" ) // GetNumWorkerMultiplier returns the base value used to calculate the number // of workers to use for Hugo's parallel execution. // It returns the value in HUGO_NUMWORKERMULTIPLIER OS env variable if set to a // positive integer, else the number of logical CPUs. func GetNumWorkerMultiplier() int { if gmp := os.Getenv("HUGO_NUMWORKERMULTIPLIER"); gmp != "" { if p, err := strconv.Atoi(gmp); err == nil && p > 0 { return p } } return runtime.NumCPU() } // SetEnvVars sets vars on the form key=value in the oldVars slice. func SetEnvVars(oldVars *[]string, keyValues ...string) { for i := 0; i < len(keyValues); i += 2 { setEnvVar(oldVars, keyValues[i], keyValues[i+1]) } } func SplitEnvVar(v string) (string, string) { parts := strings.Split(v, "=") return parts[0], parts[1] } func setEnvVar(vars *[]string, key, value string) { for i := range *vars { if strings.HasPrefix((*vars)[i], key+"=") { (*vars)[i] = key + "=" + value return } } // New var. *vars = append(*vars, key+"="+value) } hugo-0.68.3/config/env_test.go000066400000000000000000000020431363637351300162060ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package config import ( "testing" qt "github.com/frankban/quicktest" ) func TestSetEnvVars(t *testing.T) { t.Parallel() c := qt.New(t) vars := []string{"FOO=bar", "HUGO=cool", "BAR=foo"} SetEnvVars(&vars, "HUGO", "rocking!", "NEW", "bar") c.Assert(vars, qt.DeepEquals, []string{"FOO=bar", "HUGO=rocking!", "BAR=foo", "NEW=bar"}) key, val := SplitEnvVar("HUGO=rocks") c.Assert(key, qt.Equals, "HUGO") c.Assert(val, qt.Equals, "rocks") } hugo-0.68.3/config/privacy/000077500000000000000000000000001363637351300155065ustar00rootroot00000000000000hugo-0.68.3/config/privacy/privacyConfig.go000066400000000000000000000066631363637351300206530ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package privacy import ( "github.com/gohugoio/hugo/config" "github.com/mitchellh/mapstructure" ) const privacyConfigKey = "privacy" // Service is the common values for a service in a policy definition. type Service struct { Disable bool } // Config is a privacy configuration for all the relevant services in Hugo. type Config struct { Disqus Disqus GoogleAnalytics GoogleAnalytics Instagram Instagram Twitter Twitter Vimeo Vimeo YouTube YouTube } // Disqus holds the privacy configuration settings related to the Disqus template. type Disqus struct { Service `mapstructure:",squash"` } // GoogleAnalytics holds the privacy configuration settings related to the Google Analytics template. type GoogleAnalytics struct { Service `mapstructure:",squash"` // Enabling this will disable the use of Cookies and use Session Storage to Store the GA Client ID. UseSessionStorage bool // Enabling this will make the GA templates respect the // "Do Not Track" HTTP header. See https://www.paulfurley.com/google-analytics-dnt/. RespectDoNotTrack bool // Enabling this will make it so the users' IP addresses are anonymized within Google Analytics. AnonymizeIP bool } // Instagram holds the privacy configuration settings related to the Instagram shortcode. type Instagram struct { Service `mapstructure:",squash"` // If simple mode is enabled, a static and no-JS version of the Instagram // image card will be built. Simple bool } // Twitter holds the privacy configuration settingsrelated to the Twitter shortcode. type Twitter struct { Service `mapstructure:",squash"` // When set to true, the Tweet and its embedded page on your site are not used // for purposes that include personalized suggestions and personalized ads. EnableDNT bool // If simple mode is enabled, a static and no-JS version of the Tweet will be built. Simple bool } // Vimeo holds the privacy configuration settingsrelated to the Vimeo shortcode. type Vimeo struct { Service `mapstructure:",squash"` // If simple mode is enabled, only a thumbnail is fetched from i.vimeocdn.com and // shown with a play button overlaid. If a user clicks the button, he/she will // be taken to the video page on vimeo.com in a new browser tab. Simple bool } // YouTube holds the privacy configuration settingsrelated to the YouTube shortcode. type YouTube struct { Service `mapstructure:",squash"` // When you turn on privacy-enhanced mode, // YouTube won’t store information about visitors on your website // unless the user plays the embedded video. PrivacyEnhanced bool } // DecodeConfig creates a privacy Config from a given Hugo configuration. func DecodeConfig(cfg config.Provider) (pc Config, err error) { if !cfg.IsSet(privacyConfigKey) { return } m := cfg.GetStringMap(privacyConfigKey) err = mapstructure.WeakDecode(m, &pc) return } hugo-0.68.3/config/privacy/privacyConfig_test.go000066400000000000000000000046071363637351300217060ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package privacy import ( "testing" qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/config" "github.com/spf13/viper" ) func TestDecodeConfigFromTOML(t *testing.T) { c := qt.New(t) tomlConfig := ` someOtherValue = "foo" [privacy] [privacy.disqus] disable = true [privacy.googleAnalytics] disable = true respectDoNotTrack = true anonymizeIP = true useSessionStorage = true [privacy.instagram] disable = true simple = true [privacy.twitter] disable = true enableDNT = true simple = true [privacy.vimeo] disable = true simple = true [privacy.youtube] disable = true privacyEnhanced = true simple = true ` cfg, err := config.FromConfigString(tomlConfig, "toml") c.Assert(err, qt.IsNil) pc, err := DecodeConfig(cfg) c.Assert(err, qt.IsNil) c.Assert(pc, qt.Not(qt.IsNil)) got := []bool{ pc.Disqus.Disable, pc.GoogleAnalytics.Disable, pc.GoogleAnalytics.RespectDoNotTrack, pc.GoogleAnalytics.AnonymizeIP, pc.GoogleAnalytics.UseSessionStorage, pc.Instagram.Disable, pc.Instagram.Simple, pc.Twitter.Disable, pc.Twitter.EnableDNT, pc.Twitter.Simple, pc.Vimeo.Disable, pc.Vimeo.Simple, pc.YouTube.PrivacyEnhanced, pc.YouTube.Disable, } c.Assert(got, qt.All(qt.Equals), true) } func TestDecodeConfigFromTOMLCaseInsensitive(t *testing.T) { c := qt.New(t) tomlConfig := ` someOtherValue = "foo" [Privacy] [Privacy.YouTube] PrivacyENhanced = true ` cfg, err := config.FromConfigString(tomlConfig, "toml") c.Assert(err, qt.IsNil) pc, err := DecodeConfig(cfg) c.Assert(err, qt.IsNil) c.Assert(pc, qt.Not(qt.IsNil)) c.Assert(pc.YouTube.PrivacyEnhanced, qt.Equals, true) } func TestDecodeConfigDefault(t *testing.T) { c := qt.New(t) pc, err := DecodeConfig(viper.New()) c.Assert(err, qt.IsNil) c.Assert(pc, qt.Not(qt.IsNil)) c.Assert(pc.YouTube.PrivacyEnhanced, qt.Equals, false) } hugo-0.68.3/config/services/000077500000000000000000000000001363637351300156545ustar00rootroot00000000000000hugo-0.68.3/config/services/servicesConfig.go000066400000000000000000000054371363637351300211650ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package services import ( "github.com/gohugoio/hugo/config" "github.com/mitchellh/mapstructure" ) const ( servicesConfigKey = "services" disqusShortnameKey = "disqusshortname" googleAnalyticsKey = "googleanalytics" rssLimitKey = "rssLimit" ) // Config is a privacy configuration for all the relevant services in Hugo. type Config struct { Disqus Disqus GoogleAnalytics GoogleAnalytics Instagram Instagram Twitter Twitter RSS RSS } // Disqus holds the functional configuration settings related to the Disqus template. type Disqus struct { // A Shortname is the unique identifier assigned to a Disqus site. Shortname string } // GoogleAnalytics holds the functional configuration settings related to the Google Analytics template. type GoogleAnalytics struct { // The GA tracking ID. ID string } // Instagram holds the functional configuration settings related to the Instagram shortcodes. type Instagram struct { // The Simple variant of the Instagram is decorated with Bootstrap 4 card classes. // This means that if you use Bootstrap 4 or want to provide your own CSS, you want // to disable the inline CSS provided by Hugo. DisableInlineCSS bool } // Twitter holds the functional configuration settings related to the Twitter shortcodes. type Twitter struct { // The Simple variant of Twitter is decorated with a basic set of inline styles. // This means that if you want to provide your own CSS, you want // to disable the inline CSS provided by Hugo. DisableInlineCSS bool } // RSS holds the functional configuration settings related to the RSS feeds. type RSS struct { // Limit the number of pages. Limit int } // DecodeConfig creates a services Config from a given Hugo configuration. func DecodeConfig(cfg config.Provider) (c Config, err error) { m := cfg.GetStringMap(servicesConfigKey) err = mapstructure.WeakDecode(m, &c) // Keep backwards compatibility. if c.GoogleAnalytics.ID == "" { // Try the global config c.GoogleAnalytics.ID = cfg.GetString(googleAnalyticsKey) } if c.Disqus.Shortname == "" { c.Disqus.Shortname = cfg.GetString(disqusShortnameKey) } if c.RSS.Limit == 0 { c.RSS.Limit = cfg.GetInt(rssLimitKey) } return } hugo-0.68.3/config/services/servicesConfig_test.go000066400000000000000000000034251363637351300222170ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package services import ( "testing" qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/config" "github.com/spf13/viper" ) func TestDecodeConfigFromTOML(t *testing.T) { c := qt.New(t) tomlConfig := ` someOtherValue = "foo" [services] [services.disqus] shortname = "DS" [services.googleAnalytics] id = "ga_id" [services.instagram] disableInlineCSS = true [services.twitter] disableInlineCSS = true ` cfg, err := config.FromConfigString(tomlConfig, "toml") c.Assert(err, qt.IsNil) config, err := DecodeConfig(cfg) c.Assert(err, qt.IsNil) c.Assert(config, qt.Not(qt.IsNil)) c.Assert(config.Disqus.Shortname, qt.Equals, "DS") c.Assert(config.GoogleAnalytics.ID, qt.Equals, "ga_id") c.Assert(config.Instagram.DisableInlineCSS, qt.Equals, true) } // Support old root-level GA settings etc. func TestUseSettingsFromRootIfSet(t *testing.T) { c := qt.New(t) cfg := viper.New() cfg.Set("disqusShortname", "root_short") cfg.Set("googleAnalytics", "ga_root") config, err := DecodeConfig(cfg) c.Assert(err, qt.IsNil) c.Assert(config, qt.Not(qt.IsNil)) c.Assert(config.Disqus.Shortname, qt.Equals, "root_short") c.Assert(config.GoogleAnalytics.ID, qt.Equals, "ga_root") } hugo-0.68.3/create/000077500000000000000000000000001363637351300140275ustar00rootroot00000000000000hugo-0.68.3/create/content.go000066400000000000000000000177541363637351300160460ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package create provides functions to create new content. package create import ( "bytes" "github.com/pkg/errors" "io" "os" "os/exec" "path/filepath" "strings" "github.com/gohugoio/hugo/hugofs/files" "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugolib" "github.com/spf13/afero" jww "github.com/spf13/jwalterweatherman" ) // NewContent creates a new content file in the content directory based upon the // given kind, which is used to lookup an archetype. func NewContent( sites *hugolib.HugoSites, kind, targetPath string) error { targetPath = filepath.Clean(targetPath) ext := helpers.Ext(targetPath) ps := sites.PathSpec archetypeFs := ps.BaseFs.SourceFilesystems.Archetypes.Fs sourceFs := ps.Fs.Source jww.INFO.Printf("attempting to create %q of %q of ext %q", targetPath, kind, ext) archetypeFilename, isDir := findArchetype(ps, kind, ext) contentPath, s := resolveContentPath(sites, sourceFs, targetPath) if isDir { langFs, err := hugofs.NewLanguageFs(sites.LanguageSet(), archetypeFs) if err != nil { return err } cm, err := mapArcheTypeDir(ps, langFs, archetypeFilename) if err != nil { return err } if cm.siteUsed { if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil { return err } } name := filepath.Base(targetPath) return newContentFromDir(archetypeFilename, sites, sourceFs, cm, name, contentPath) } // Building the sites can be expensive, so only do it if really needed. siteUsed := false if archetypeFilename != "" { var err error siteUsed, err = usesSiteVar(archetypeFs, archetypeFilename) if err != nil { return err } } if siteUsed { if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil { return err } } content, err := executeArcheTypeAsTemplate(s, "", kind, targetPath, archetypeFilename) if err != nil { return err } if err := helpers.SafeWriteToDisk(contentPath, bytes.NewReader(content), s.Fs.Source); err != nil { return err } jww.FEEDBACK.Println(contentPath, "created") editor := s.Cfg.GetString("newContentEditor") if editor != "" { jww.FEEDBACK.Printf("Editing %s with %q ...\n", targetPath, editor) cmd := exec.Command(editor, contentPath) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() } return nil } func targetSite(sites *hugolib.HugoSites, fi hugofs.FileMetaInfo) *hugolib.Site { for _, s := range sites.Sites { if fi.Meta().Lang() == s.Language().Lang { return s } } return sites.Sites[0] } func newContentFromDir( archetypeDir string, sites *hugolib.HugoSites, targetFs afero.Fs, cm archetypeMap, name, targetPath string) error { for _, f := range cm.otherFiles { meta := f.Meta() filename := meta.Path() // Just copy the file to destination. in, err := meta.Open() if err != nil { return errors.Wrap(err, "failed to open non-content file") } targetFilename := filepath.Join(targetPath, strings.TrimPrefix(filename, archetypeDir)) targetDir := filepath.Dir(targetFilename) if err := targetFs.MkdirAll(targetDir, 0777); err != nil && !os.IsExist(err) { return errors.Wrapf(err, "failed to create target directory for %s:", targetDir) } out, err := targetFs.Create(targetFilename) if err != nil { return err } _, err = io.Copy(out, in) if err != nil { return err } in.Close() out.Close() } for _, f := range cm.contentFiles { filename := f.Meta().Path() s := targetSite(sites, f) targetFilename := filepath.Join(targetPath, strings.TrimPrefix(filename, archetypeDir)) content, err := executeArcheTypeAsTemplate(s, name, archetypeDir, targetFilename, filename) if err != nil { return errors.Wrap(err, "failed to execute archetype template") } if err := helpers.SafeWriteToDisk(targetFilename, bytes.NewReader(content), targetFs); err != nil { return errors.Wrap(err, "failed to save results") } } jww.FEEDBACK.Println(targetPath, "created") return nil } type archetypeMap struct { // These needs to be parsed and executed as Go templates. contentFiles []hugofs.FileMetaInfo // These are just copied to destination. otherFiles []hugofs.FileMetaInfo // If the templates needs a fully built site. This can potentially be // expensive, so only do when needed. siteUsed bool } func mapArcheTypeDir( ps *helpers.PathSpec, fs afero.Fs, archetypeDir string) (archetypeMap, error) { var m archetypeMap walkFn := func(path string, fi hugofs.FileMetaInfo, err error) error { if err != nil { return err } if fi.IsDir() { return nil } fil := fi.(hugofs.FileMetaInfo) if files.IsContentFile(path) { m.contentFiles = append(m.contentFiles, fil) if !m.siteUsed { m.siteUsed, err = usesSiteVar(fs, path) if err != nil { return err } } return nil } m.otherFiles = append(m.otherFiles, fil) return nil } walkCfg := hugofs.WalkwayConfig{ WalkFn: walkFn, Fs: fs, Root: archetypeDir, } w := hugofs.NewWalkway(walkCfg) if err := w.Walk(); err != nil { return m, errors.Wrapf(err, "failed to walk archetype dir %q", archetypeDir) } return m, nil } func usesSiteVar(fs afero.Fs, filename string) (bool, error) { f, err := fs.Open(filename) if err != nil { return false, errors.Wrap(err, "failed to open archetype file") } defer f.Close() return helpers.ReaderContains(f, []byte(".Site")), nil } // Resolve the target content path. func resolveContentPath(sites *hugolib.HugoSites, fs afero.Fs, targetPath string) (string, *hugolib.Site) { targetDir := filepath.Dir(targetPath) first := sites.Sites[0] var ( s *hugolib.Site siteContentDir string ) // Try the filename: my-post.en.md for _, ss := range sites.Sites { if strings.Contains(targetPath, "."+ss.Language().Lang+".") { s = ss break } } var dirLang string for _, dir := range sites.BaseFs.Content.Dirs { meta := dir.Meta() contentDir := meta.Filename() if !strings.HasSuffix(contentDir, helpers.FilePathSeparator) { contentDir += helpers.FilePathSeparator } if strings.HasPrefix(targetPath, contentDir) { siteContentDir = contentDir dirLang = meta.Lang() break } } if s == nil && dirLang != "" { for _, ss := range sites.Sites { if ss.Lang() == dirLang { s = ss break } } } if s == nil { s = first } if targetDir != "" && targetDir != "." { exists, _ := helpers.Exists(targetDir, fs) if exists { return targetPath, s } } if siteContentDir == "" { } if siteContentDir != "" { pp := filepath.Join(siteContentDir, strings.TrimPrefix(targetPath, siteContentDir)) return s.PathSpec.AbsPathify(pp), s } else { var contentDir string for _, dir := range sites.BaseFs.Content.Dirs { contentDir = dir.Meta().Filename() if dir.Meta().Lang() == s.Lang() { break } } return s.PathSpec.AbsPathify(filepath.Join(contentDir, targetPath)), s } } // FindArchetype takes a given kind/archetype of content and returns the path // to the archetype in the archetype filesystem, blank if none found. func findArchetype(ps *helpers.PathSpec, kind, ext string) (outpath string, isDir bool) { fs := ps.BaseFs.Archetypes.Fs var pathsToCheck []string if kind != "" { pathsToCheck = append(pathsToCheck, kind+ext) } pathsToCheck = append(pathsToCheck, "default"+ext, "default") for _, p := range pathsToCheck { fi, err := fs.Stat(p) if err == nil { return p, fi.IsDir() } } return "", false } hugo-0.68.3/create/content_template_handler.go000066400000000000000000000107011363637351300214170ustar00rootroot00000000000000// Copyright 2017 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package create import ( "bytes" "fmt" "path/filepath" "strings" "time" "github.com/pkg/errors" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/source" "github.com/gohugoio/hugo/hugolib" "github.com/gohugoio/hugo/tpl" "github.com/spf13/afero" ) // ArchetypeFileData represents the data available to an archetype template. type ArchetypeFileData struct { // The archetype content type, either given as --kind option or extracted // from the target path's section, i.e. "blog/mypost.md" will resolve to // "blog". Type string // The current date and time as a RFC3339 formatted string, suitable for use in front matter. Date string // The Site, fully equipped with all the pages etc. Note: This will only be set if it is actually // used in the archetype template. Also, if this is a multilingual setup, // this site is the site that best matches the target content file, based // on the presence of language code in the filename. Site *hugolib.SiteInfo // Name will in most cases be the same as TranslationBaseName, e.g. "my-post". // But if that value is "index" (bundles), the Name is instead the owning folder. // This is the value you in most cases would want to use to construct the title in your // archetype template. Name string // The target content file. Note that the .Content will be empty, as that // has not been created yet. source.File } const ( // ArchetypeTemplateTemplate is used as initial template when adding an archetype template. ArchetypeTemplateTemplate = `--- title: "{{ replace .Name "-" " " | title }}" date: {{ .Date }} draft: true --- ` ) var ( archetypeShortcodeReplacementsPre = strings.NewReplacer( "{{<", "{x{<", "{{%", "{x{%", ">}}", ">}x}", "%}}", "%}x}") archetypeShortcodeReplacementsPost = strings.NewReplacer( "{x{<", "{{<", "{x{%", "{{%", ">}x}", ">}}", "%}x}", "%}}") ) func executeArcheTypeAsTemplate(s *hugolib.Site, name, kind, targetPath, archetypeFilename string) ([]byte, error) { var ( archetypeContent []byte archetypeTemplate []byte err error ) f, err := s.SourceSpec.NewFileInfoFrom(targetPath, targetPath) if err != nil { return nil, err } if name == "" { name = f.TranslationBaseName() if name == "index" || name == "_index" { // Page bundles; the directory name will hopefully have a better name. dir := strings.TrimSuffix(f.Dir(), helpers.FilePathSeparator) _, name = filepath.Split(dir) } } data := ArchetypeFileData{ Type: kind, Date: time.Now().Format(time.RFC3339), Name: name, File: f, Site: s.Info, } if archetypeFilename == "" { // TODO(bep) archetype revive the issue about wrong tpl funcs arg order archetypeTemplate = []byte(ArchetypeTemplateTemplate) } else { archetypeTemplate, err = afero.ReadFile(s.BaseFs.Archetypes.Fs, archetypeFilename) if err != nil { return nil, fmt.Errorf("failed to read archetype file %s", err) } } // The archetype template may contain shortcodes, and these does not play well // with the Go templates. Need to set some temporary delimiters. archetypeTemplate = []byte(archetypeShortcodeReplacementsPre.Replace(string(archetypeTemplate))) // Reuse the Hugo template setup to get the template funcs properly set up. templateHandler := s.Deps.Tmpl().(tpl.TemplateManager) templateName := helpers.Filename(archetypeFilename) if err := templateHandler.AddTemplate("_text/"+templateName, string(archetypeTemplate)); err != nil { return nil, errors.Wrapf(err, "Failed to parse archetype file %q:", archetypeFilename) } templ, _ := templateHandler.Lookup(templateName) var buff bytes.Buffer if err := templateHandler.Execute(templ, &buff, data); err != nil { return nil, errors.Wrapf(err, "Failed to process archetype file %q:", archetypeFilename) } archetypeContent = []byte(archetypeShortcodeReplacementsPost.Replace(buff.String())) return archetypeContent, nil } hugo-0.68.3/create/content_test.go000066400000000000000000000227141363637351300170750ustar00rootroot00000000000000// Copyright 2016 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package create_test import ( "os" "path/filepath" "strings" "testing" "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/hugolib" "fmt" "github.com/gohugoio/hugo/hugofs" qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/create" "github.com/gohugoio/hugo/helpers" "github.com/spf13/afero" "github.com/spf13/viper" ) func TestNewContent(t *testing.T) { cases := []struct { kind string path string expected []string }{ {"post", "post/sample-1.md", []string{`title = "Post Arch title"`, `test = "test1"`, "date = \"2015-01-12T19:20:04-07:00\""}}, {"post", "post/org-1.org", []string{`#+title: ORG-1`}}, {"emptydate", "post/sample-ed.md", []string{`title = "Empty Date Arch title"`, `test = "test1"`}}, {"stump", "stump/sample-2.md", []string{`title: "Sample 2"`}}, // no archetype file {"", "sample-3.md", []string{`title: "Sample 3"`}}, // no archetype {"product", "product/sample-4.md", []string{`title = "SAMPLE-4"`}}, // empty archetype front matter {"lang", "post/lang-1.md", []string{`Site Lang: en|Name: Lang 1|i18n: Hugo Rocks!`}}, {"lang", "post/lang-2.en.md", []string{`Site Lang: en|Name: Lang 2|i18n: Hugo Rocks!`}}, {"lang", "content/post/lang-3.nn.md", []string{`Site Lang: nn|Name: Lang 3|i18n: Hugo Rokkar!`}}, {"lang", "content_nn/post/lang-4.md", []string{`Site Lang: nn|Name: Lang 4|i18n: Hugo Rokkar!`}}, {"lang", "content_nn/post/lang-5.en.md", []string{`Site Lang: en|Name: Lang 5|i18n: Hugo Rocks!`}}, {"lang", "post/my-bundle/index.md", []string{`Site Lang: en|Name: My Bundle|i18n: Hugo Rocks!`}}, {"lang", "post/my-bundle/index.en.md", []string{`Site Lang: en|Name: My Bundle|i18n: Hugo Rocks!`}}, {"lang", "content/post/my-bundle/index.nn.md", []string{`Site Lang: nn|Name: My Bundle|i18n: Hugo Rokkar!`}}, {"shortcodes", "shortcodes/go.md", []string{ `title = "GO"`, "{{< myshortcode >}}", "{{% myshortcode %}}", "{{}}\n{{%/* comment */%}}"}}, // shortcodes } for i, cas := range cases { cas := cas t.Run(fmt.Sprintf("%s-%d", cas.kind, i), func(t *testing.T) { t.Parallel() c := qt.New(t) mm := afero.NewMemMapFs() c.Assert(initFs(mm), qt.IsNil) cfg, fs := newTestCfg(c, mm) h, err := hugolib.NewHugoSites(deps.DepsCfg{Cfg: cfg, Fs: fs}) c.Assert(err, qt.IsNil) c.Assert(create.NewContent(h, cas.kind, cas.path), qt.IsNil) fname := filepath.FromSlash(cas.path) if !strings.HasPrefix(fname, "content") { fname = filepath.Join("content", fname) } content := readFileFromFs(t, fs.Source, fname) for _, v := range cas.expected { found := strings.Contains(content, v) if !found { t.Fatalf("[%d] %q missing from output:\n%q", i, v, content) } } }) } } func TestNewContentFromDir(t *testing.T) { mm := afero.NewMemMapFs() c := qt.New(t) archetypeDir := filepath.Join("archetypes", "my-bundle") c.Assert(mm.MkdirAll(archetypeDir, 0755), qt.IsNil) archetypeThemeDir := filepath.Join("themes", "mytheme", "archetypes", "my-theme-bundle") c.Assert(mm.MkdirAll(archetypeThemeDir, 0755), qt.IsNil) contentFile := ` File: %s Site Lang: {{ .Site.Language.Lang }} Name: {{ replace .Name "-" " " | title }} i18n: {{ T "hugo" }} ` c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "index.md"), []byte(fmt.Sprintf(contentFile, "index.md")), 0755), qt.IsNil) c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "index.nn.md"), []byte(fmt.Sprintf(contentFile, "index.nn.md")), 0755), qt.IsNil) c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "pages", "bio.md"), []byte(fmt.Sprintf(contentFile, "bio.md")), 0755), qt.IsNil) c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "resources", "hugo1.json"), []byte(`hugo1: {{ printf "no template handling in here" }}`), 0755), qt.IsNil) c.Assert(afero.WriteFile(mm, filepath.Join(archetypeDir, "resources", "hugo2.xml"), []byte(`hugo2: {{ printf "no template handling in here" }}`), 0755), qt.IsNil) c.Assert(afero.WriteFile(mm, filepath.Join(archetypeThemeDir, "index.md"), []byte(fmt.Sprintf(contentFile, "index.md")), 0755), qt.IsNil) c.Assert(afero.WriteFile(mm, filepath.Join(archetypeThemeDir, "resources", "hugo1.json"), []byte(`hugo1: {{ printf "no template handling in here" }}`), 0755), qt.IsNil) c.Assert(initFs(mm), qt.IsNil) cfg, fs := newTestCfg(c, mm) h, err := hugolib.NewHugoSites(deps.DepsCfg{Cfg: cfg, Fs: fs}) c.Assert(err, qt.IsNil) c.Assert(len(h.Sites), qt.Equals, 2) c.Assert(create.NewContent(h, "my-bundle", "post/my-post"), qt.IsNil) cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/resources/hugo1.json")), `hugo1: {{ printf "no template handling in here" }}`) cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/resources/hugo2.xml")), `hugo2: {{ printf "no template handling in here" }}`) // Content files should get the correct site context. // TODO(bep) archetype check i18n cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/index.md")), `File: index.md`, `Site Lang: en`, `Name: My Post`, `i18n: Hugo Rocks!`) cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/index.nn.md")), `File: index.nn.md`, `Site Lang: nn`, `Name: My Post`, `i18n: Hugo Rokkar!`) cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-post/pages/bio.md")), `File: bio.md`, `Site Lang: en`, `Name: My Post`) c.Assert(create.NewContent(h, "my-theme-bundle", "post/my-theme-post"), qt.IsNil) cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-theme-post/index.md")), `File: index.md`, `Site Lang: en`, `Name: My Theme Post`, `i18n: Hugo Rocks!`) cContains(c, readFileFromFs(t, fs.Source, filepath.Join("content", "post/my-theme-post/resources/hugo1.json")), `hugo1: {{ printf "no template handling in here" }}`) } func initFs(fs afero.Fs) error { perm := os.FileMode(0755) var err error // create directories dirs := []string{ "archetypes", "content", filepath.Join("themes", "sample", "archetypes"), } for _, dir := range dirs { err = fs.Mkdir(dir, perm) if err != nil && !os.IsExist(err) { return err } } // create files for _, v := range []struct { path string content string }{ { path: filepath.Join("archetypes", "post.md"), content: "+++\ndate = \"2015-01-12T19:20:04-07:00\"\ntitle = \"Post Arch title\"\ntest = \"test1\"\n+++\n", }, { path: filepath.Join("archetypes", "post.org"), content: "#+title: {{ .BaseFileName | upper }}", }, { path: filepath.Join("archetypes", "product.md"), content: `+++ title = "{{ .BaseFileName | upper }}" +++`, }, { path: filepath.Join("archetypes", "emptydate.md"), content: "+++\ndate =\"\"\ntitle = \"Empty Date Arch title\"\ntest = \"test1\"\n+++\n", }, { path: filepath.Join("archetypes", "lang.md"), content: `Site Lang: {{ .Site.Language.Lang }}|Name: {{ replace .Name "-" " " | title }}|i18n: {{ T "hugo" }}`, }, // #3623x { path: filepath.Join("archetypes", "shortcodes.md"), content: `+++ title = "{{ .BaseFileName | upper }}" +++ {{< myshortcode >}} Some text. {{% myshortcode %}} {{}} {{%/* comment */%}} `, }, } { f, err := fs.Create(v.path) if err != nil { return err } defer f.Close() _, err = f.Write([]byte(v.content)) if err != nil { return err } } return nil } func cContains(c *qt.C, v interface{}, matches ...string) { for _, m := range matches { c.Assert(v, qt.Contains, m) } } // TODO(bep) extract common testing package with this and some others func readFileFromFs(t *testing.T, fs afero.Fs, filename string) string { t.Helper() filename = filepath.FromSlash(filename) b, err := afero.ReadFile(fs, filename) if err != nil { // Print some debug info root := strings.Split(filename, helpers.FilePathSeparator)[0] afero.Walk(fs, root, func(path string, info os.FileInfo, err error) error { if info != nil && !info.IsDir() { fmt.Println(" ", path) } return nil }) t.Fatalf("Failed to read file: %s", err) } return string(b) } func newTestCfg(c *qt.C, mm afero.Fs) (*viper.Viper, *hugofs.Fs) { cfg := ` theme = "mytheme" [languages] [languages.en] weight = 1 languageName = "English" [languages.nn] weight = 2 languageName = "Nynorsk" contentDir = "content_nn" ` if mm == nil { mm = afero.NewMemMapFs() } mm.MkdirAll(filepath.FromSlash("content_nn"), 0777) mm.MkdirAll(filepath.FromSlash("themes/mytheme"), 0777) c.Assert(afero.WriteFile(mm, filepath.Join("i18n", "en.toml"), []byte(`[hugo] other = "Hugo Rocks!"`), 0755), qt.IsNil) c.Assert(afero.WriteFile(mm, filepath.Join("i18n", "nn.toml"), []byte(`[hugo] other = "Hugo Rokkar!"`), 0755), qt.IsNil) c.Assert(afero.WriteFile(mm, "config.toml", []byte(cfg), 0755), qt.IsNil) v, _, err := hugolib.LoadConfig(hugolib.ConfigSourceDescriptor{Fs: mm, Filename: "config.toml"}) c.Assert(err, qt.IsNil) return v, hugofs.NewFrom(mm, v) } hugo-0.68.3/deploy/000077500000000000000000000000001363637351300140605ustar00rootroot00000000000000hugo-0.68.3/deploy/cloudfront.go000066400000000000000000000036231363637351300165720ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package deploy import ( "context" "time" "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/cloudfront" ) // InvalidateCloudFront invalidates the CloudFront cache for distributionID. // It uses the default AWS credentials from the environment. func InvalidateCloudFront(ctx context.Context, distributionID string) error { // SharedConfigEnable enables loading "shared config (~/.aws/config) and // shared credentials (~/.aws/credentials) files". // See https://docs.aws.amazon.com/sdk-for-go/api/aws/session/ for more // details. // This is the same codepath used by Go CDK when creating an s3 URL. // TODO: Update this to a Go CDK helper once available // (https://github.com/google/go-cloud/issues/2003). sess, err := session.NewSessionWithOptions(session.Options{SharedConfigState: session.SharedConfigEnable}) if err != nil { return err } req := &cloudfront.CreateInvalidationInput{ DistributionId: aws.String(distributionID), InvalidationBatch: &cloudfront.InvalidationBatch{ CallerReference: aws.String(time.Now().Format("20060102150405")), Paths: &cloudfront.Paths{ Items: []*string{aws.String("/*")}, Quantity: aws.Int64(1), }, }, } _, err = cloudfront.New(sess).CreateInvalidationWithContext(ctx, req) return err } hugo-0.68.3/deploy/deploy.go000066400000000000000000000476731363637351300157240ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package deploy import ( "bytes" "compress/gzip" "context" "crypto/md5" "fmt" "io" "io/ioutil" "mime" "os" "path/filepath" "regexp" "runtime" "sort" "strings" "sync" "github.com/dustin/go-humanize" "github.com/gobwas/glob" "github.com/gohugoio/hugo/config" "github.com/pkg/errors" "github.com/spf13/afero" jww "github.com/spf13/jwalterweatherman" "golang.org/x/text/unicode/norm" "gocloud.dev/blob" _ "gocloud.dev/blob/fileblob" // import _ "gocloud.dev/blob/gcsblob" // import _ "gocloud.dev/blob/s3blob" // import ) // Deployer supports deploying the site to target cloud providers. type Deployer struct { localFs afero.Fs bucket *blob.Bucket target *target // the target to deploy to matchers []*matcher // matchers to apply to uploaded files ordering []*regexp.Regexp // orders uploads quiet bool // true reduces STDOUT confirm bool // true enables confirmation before making changes dryRun bool // true skips conformations and prints changes instead of applying them force bool // true forces upload of all files invalidateCDN bool // true enables invalidate CDN cache (if possible) maxDeletes int // caps the # of files to delete; -1 to disable // For tests... summary deploySummary // summary of latest Deploy results } type deploySummary struct { NumLocal, NumRemote, NumUploads, NumDeletes int } // New constructs a new *Deployer. func New(cfg config.Provider, localFs afero.Fs) (*Deployer, error) { targetName := cfg.GetString("target") // Load the [deployment] section of the config. dcfg, err := decodeConfig(cfg) if err != nil { return nil, err } if len(dcfg.Targets) == 0 { return nil, errors.New("no deployment targets found") } // Find the target to deploy to. var tgt *target if targetName == "" { // Default to the first target. tgt = dcfg.Targets[0] } else { for _, t := range dcfg.Targets { if t.Name == targetName { tgt = t } } if tgt == nil { return nil, fmt.Errorf("deployment target %q not found", targetName) } } return &Deployer{ localFs: localFs, target: tgt, matchers: dcfg.Matchers, ordering: dcfg.ordering, quiet: cfg.GetBool("quiet"), confirm: cfg.GetBool("confirm"), dryRun: cfg.GetBool("dryRun"), force: cfg.GetBool("force"), invalidateCDN: cfg.GetBool("invalidateCDN"), maxDeletes: cfg.GetInt("maxDeletes"), }, nil } func (d *Deployer) openBucket(ctx context.Context) (*blob.Bucket, error) { if d.bucket != nil { return d.bucket, nil } jww.FEEDBACK.Printf("Deploying to target %q (%s)\n", d.target.Name, d.target.URL) return blob.OpenBucket(ctx, d.target.URL) } // Deploy deploys the site to a target. func (d *Deployer) Deploy(ctx context.Context) error { bucket, err := d.openBucket(ctx) if err != nil { return err } // Load local files from the source directory. var include, exclude glob.Glob if d.target != nil { include, exclude = d.target.includeGlob, d.target.excludeGlob } local, err := walkLocal(d.localFs, d.matchers, include, exclude) if err != nil { return err } jww.INFO.Printf("Found %d local files.\n", len(local)) d.summary.NumLocal = len(local) // Load remote files from the target. remote, err := walkRemote(ctx, bucket, include, exclude) if err != nil { return err } jww.INFO.Printf("Found %d remote files.\n", len(remote)) d.summary.NumRemote = len(remote) // Diff local vs remote to see what changes need to be applied. uploads, deletes := findDiffs(local, remote, d.force) d.summary.NumUploads = len(uploads) d.summary.NumDeletes = len(deletes) if len(uploads)+len(deletes) == 0 { if !d.quiet { jww.FEEDBACK.Println("No changes required.") } return nil } if !d.quiet { jww.FEEDBACK.Println(summarizeChanges(uploads, deletes)) } // Ask for confirmation before proceeding. if d.confirm && !d.dryRun { fmt.Printf("Continue? (Y/n) ") var confirm string if _, err := fmt.Scanln(&confirm); err != nil { return err } if confirm != "" && confirm[0] != 'y' && confirm[0] != 'Y' { return errors.New("aborted") } } // Order the uploads. They are organized in groups; all uploads in a group // must be complete before moving on to the next group. uploadGroups := applyOrdering(d.ordering, uploads) // Apply the changes in parallel, using an inverted worker // pool (https://www.youtube.com/watch?v=5zXAHh5tJqQ&t=26m58s). // sem prevents more than nParallel concurrent goroutines. const nParallel = 10 var errs []error var errMu sync.Mutex // protects errs for _, uploads := range uploadGroups { // Short-circuit for an empty group. if len(uploads) == 0 { continue } // Within the group, apply uploads in parallel. sem := make(chan struct{}, nParallel) for _, upload := range uploads { if d.dryRun { if !d.quiet { jww.FEEDBACK.Printf("[DRY RUN] Would upload: %v\n", upload) } continue } sem <- struct{}{} go func(upload *fileToUpload) { if err := doSingleUpload(ctx, bucket, upload); err != nil { errMu.Lock() defer errMu.Unlock() errs = append(errs, err) } <-sem }(upload) } // Wait for all uploads in the group to finish. for n := nParallel; n > 0; n-- { sem <- struct{}{} } } if d.maxDeletes != -1 && len(deletes) > d.maxDeletes { jww.WARN.Printf("Skipping %d deletes because it is more than --maxDeletes (%d). If this is expected, set --maxDeletes to a larger number, or -1 to disable this check.\n", len(deletes), d.maxDeletes) d.summary.NumDeletes = 0 } else { // Apply deletes in parallel. sort.Slice(deletes, func(i, j int) bool { return deletes[i] < deletes[j] }) sem := make(chan struct{}, nParallel) for _, del := range deletes { if d.dryRun { if !d.quiet { jww.FEEDBACK.Printf("[DRY RUN] Would delete %s\n", del) } continue } sem <- struct{}{} go func(del string) { jww.INFO.Printf("Deleting %s...\n", del) if err := bucket.Delete(ctx, del); err != nil { errMu.Lock() defer errMu.Unlock() errs = append(errs, err) } <-sem }(del) } // Wait for all deletes to finish. for n := nParallel; n > 0; n-- { sem <- struct{}{} } } if len(errs) > 0 { if !d.quiet { jww.FEEDBACK.Printf("Encountered %d errors.\n", len(errs)) } return errs[0] } if !d.quiet { jww.FEEDBACK.Println("Success!") } if d.invalidateCDN { if d.target.CloudFrontDistributionID != "" { jww.FEEDBACK.Println("Invalidating CloudFront CDN...") if err := InvalidateCloudFront(ctx, d.target.CloudFrontDistributionID); err != nil { jww.FEEDBACK.Printf("Failed to invalidate CloudFront CDN: %v\n", err) return err } } if d.target.GoogleCloudCDNOrigin != "" { jww.FEEDBACK.Println("Invalidating Google Cloud CDN...") if err := InvalidateGoogleCloudCDN(ctx, d.target.GoogleCloudCDNOrigin); err != nil { jww.FEEDBACK.Printf("Failed to invalidate Google Cloud CDN: %v\n", err) return err } } jww.FEEDBACK.Println("Success!") } return nil } // summarizeChanges creates a text description of the proposed changes. func summarizeChanges(uploads []*fileToUpload, deletes []string) string { uploadSize := int64(0) for _, u := range uploads { uploadSize += u.Local.UploadSize } return fmt.Sprintf("Identified %d file(s) to upload, totaling %s, and %d file(s) to delete.", len(uploads), humanize.Bytes(uint64(uploadSize)), len(deletes)) } // doSingleUpload executes a single file upload. func doSingleUpload(ctx context.Context, bucket *blob.Bucket, upload *fileToUpload) error { jww.INFO.Printf("Uploading %v...\n", upload) opts := &blob.WriterOptions{ CacheControl: upload.Local.CacheControl(), ContentEncoding: upload.Local.ContentEncoding(), ContentType: upload.Local.ContentType(), } w, err := bucket.NewWriter(ctx, upload.Local.SlashPath, opts) if err != nil { return err } r, err := upload.Local.Reader() if err != nil { return err } defer r.Close() _, err = io.Copy(w, r) if err != nil { return err } if err := w.Close(); err != nil { return err } return nil } // localFile represents a local file from the source. Use newLocalFile to // construct one. type localFile struct { // NativePath is the native path to the file (using file.Separator). NativePath string // SlashPath is NativePath converted to use /. SlashPath string // UploadSize is the size of the content to be uploaded. It may not // be the same as the local file size if the content will be // gzipped before upload. UploadSize int64 fs afero.Fs matcher *matcher md5 []byte // cache gzipped bytes.Buffer // cached of gzipped contents if gzipping } // newLocalFile initializes a *localFile. func newLocalFile(fs afero.Fs, nativePath, slashpath string, m *matcher) (*localFile, error) { f, err := fs.Open(nativePath) if err != nil { return nil, err } defer f.Close() lf := &localFile{ NativePath: nativePath, SlashPath: slashpath, fs: fs, matcher: m, } if m != nil && m.Gzip { // We're going to gzip the content. Do it once now, and cache the result // in gzipped. The UploadSize is the size of the gzipped content. gz := gzip.NewWriter(&lf.gzipped) if _, err := io.Copy(gz, f); err != nil { return nil, err } if err := gz.Close(); err != nil { return nil, err } lf.UploadSize = int64(lf.gzipped.Len()) } else { // Raw content. Just get the UploadSize. info, err := f.Stat() if err != nil { return nil, err } lf.UploadSize = info.Size() } return lf, nil } // Reader returns an io.ReadCloser for reading the content to be uploaded. // The caller must call Close on the returned ReaderCloser. // The reader content may not be the same as the local file content due to // gzipping. func (lf *localFile) Reader() (io.ReadCloser, error) { if lf.matcher != nil && lf.matcher.Gzip { // We've got the gzipped contents cached in gzipped. // Note: we can't use lf.gzipped directly as a Reader, since we it discards // data after it is read, and we may read it more than once. return ioutil.NopCloser(bytes.NewReader(lf.gzipped.Bytes())), nil } // Not expected to fail since we did it successfully earlier in newLocalFile, // but could happen due to changes in the underlying filesystem. return lf.fs.Open(lf.NativePath) } // CacheControl returns the Cache-Control header to use for lf, based on the // first matching matcher (if any). func (lf *localFile) CacheControl() string { if lf.matcher == nil { return "" } return lf.matcher.CacheControl } // ContentEncoding returns the Content-Encoding header to use for lf, based // on the matcher's Content-Encoding and Gzip fields. func (lf *localFile) ContentEncoding() string { if lf.matcher == nil { return "" } if lf.matcher.Gzip { return "gzip" } return lf.matcher.ContentEncoding } // ContentType returns the Content-Type header to use for lf. // It first checks if there's a Content-Type header configured via a matching // matcher; if not, it tries to generate one based on the filename extension. // If this fails, the Content-Type will be the empty string. In this case, Go // Cloud will automatically try to infer a Content-Type based on the file // content. func (lf *localFile) ContentType() string { if lf.matcher != nil && lf.matcher.ContentType != "" { return lf.matcher.ContentType } // TODO: Hugo has a MediaType and a MediaTypes list and also a concept // of custom MIME types. // Use 1) The matcher 2) Hugo's MIME types 3) TypeByExtension. return mime.TypeByExtension(filepath.Ext(lf.NativePath)) } // Force returns true if the file should be forced to re-upload based on the // matching matcher. func (lf *localFile) Force() bool { return lf.matcher != nil && lf.matcher.Force } // MD5 returns an MD5 hash of the content to be uploaded. func (lf *localFile) MD5() []byte { if len(lf.md5) > 0 { return lf.md5 } h := md5.New() r, err := lf.Reader() if err != nil { return nil } defer r.Close() if _, err := io.Copy(h, r); err != nil { return nil } lf.md5 = h.Sum(nil) return lf.md5 } // walkLocal walks the source directory and returns a flat list of files, // using localFile.SlashPath as the map keys. func walkLocal(fs afero.Fs, matchers []*matcher, include, exclude glob.Glob) (map[string]*localFile, error) { retval := map[string]*localFile{} err := afero.Walk(fs, "", func(path string, info os.FileInfo, err error) error { if err != nil { return err } if info.IsDir() { // Skip hidden directories. if path != "" && strings.HasPrefix(info.Name(), ".") { return filepath.SkipDir } return nil } // .DS_Store is an internal MacOS attribute file; skip it. if info.Name() == ".DS_Store" { return nil } // When a file system is HFS+, its filepath is in NFD form. if runtime.GOOS == "darwin" { path = norm.NFC.String(path) } // Check include/exclude matchers. slashpath := filepath.ToSlash(path) if include != nil && !include.Match(slashpath) { jww.INFO.Printf(" dropping %q due to include\n", slashpath) return nil } if exclude != nil && exclude.Match(slashpath) { jww.INFO.Printf(" dropping %q due to exclude\n", slashpath) return nil } // Find the first matching matcher (if any). var m *matcher for _, cur := range matchers { if cur.Matches(slashpath) { m = cur break } } lf, err := newLocalFile(fs, path, slashpath, m) if err != nil { return err } retval[lf.SlashPath] = lf return nil }) if err != nil { return nil, err } return retval, nil } // walkRemote walks the target bucket and returns a flat list. func walkRemote(ctx context.Context, bucket *blob.Bucket, include, exclude glob.Glob) (map[string]*blob.ListObject, error) { retval := map[string]*blob.ListObject{} iter := bucket.List(nil) for { obj, err := iter.Next(ctx) if err == io.EOF { break } if err != nil { return nil, err } // Check include/exclude matchers. if include != nil && !include.Match(obj.Key) { jww.INFO.Printf(" remote dropping %q due to include\n", obj.Key) continue } if exclude != nil && exclude.Match(obj.Key) { jww.INFO.Printf(" remote dropping %q due to exclude\n", obj.Key) continue } // If the remote didn't give us an MD5, compute one. // This can happen for some providers (e.g., fileblob, which uses the // local filesystem), but not for the most common Cloud providers // (S3, GCS, Azure). Although, it can happen for S3 if the blob was uploaded // via a multi-part upload. // Although it's unfortunate to have to read the file, it's likely better // than assuming a delta and re-uploading it. if len(obj.MD5) == 0 { r, err := bucket.NewReader(ctx, obj.Key, nil) if err == nil { h := md5.New() if _, err := io.Copy(h, r); err == nil { obj.MD5 = h.Sum(nil) } r.Close() } } retval[obj.Key] = obj } return retval, nil } // uploadReason is an enum of reasons why a file must be uploaded. type uploadReason string const ( reasonUnknown uploadReason = "unknown" reasonNotFound uploadReason = "not found at target" reasonForce uploadReason = "--force" reasonSize uploadReason = "size differs" reasonMD5Differs uploadReason = "md5 differs" reasonMD5Missing uploadReason = "remote md5 missing" ) // fileToUpload represents a single local file that should be uploaded to // the target. type fileToUpload struct { Local *localFile Reason uploadReason } func (u *fileToUpload) String() string { details := []string{humanize.Bytes(uint64(u.Local.UploadSize))} if s := u.Local.CacheControl(); s != "" { details = append(details, fmt.Sprintf("Cache-Control: %q", s)) } if s := u.Local.ContentEncoding(); s != "" { details = append(details, fmt.Sprintf("Content-Encoding: %q", s)) } if s := u.Local.ContentType(); s != "" { details = append(details, fmt.Sprintf("Content-Type: %q", s)) } return fmt.Sprintf("%s (%s): %v", u.Local.SlashPath, strings.Join(details, ", "), u.Reason) } // findDiffs diffs localFiles vs remoteFiles to see what changes should be // applied to the remote target. It returns a slice of *fileToUpload and a // slice of paths for files to delete. func findDiffs(localFiles map[string]*localFile, remoteFiles map[string]*blob.ListObject, force bool) ([]*fileToUpload, []string) { var uploads []*fileToUpload var deletes []string found := map[string]bool{} for path, lf := range localFiles { upload := false reason := reasonUnknown if remoteFile, ok := remoteFiles[path]; ok { // The file exists in remote. Let's see if we need to upload it anyway. // TODO: We don't register a diff if the metadata (e.g., Content-Type // header) has changed. This would be difficult/expensive to detect; some // providers return metadata along with their "List" result, but others // (notably AWS S3) do not, so gocloud.dev's blob.Bucket doesn't expose // it in the list result. It would require a separate request per blob // to fetch. At least for now, we work around this by documenting it and // providing a "force" flag (to re-upload everything) and a "force" bool // per matcher (to re-upload all files in a matcher whose headers may have // changed). // Idea: extract a sample set of 1 file per extension + 1 file per matcher // and check those files? if force { upload = true reason = reasonForce } else if lf.Force() { upload = true reason = reasonForce } else if lf.UploadSize != remoteFile.Size { upload = true reason = reasonSize } else if len(remoteFile.MD5) == 0 { // This shouldn't happen unless the remote didn't give us an MD5 hash // from List, AND we failed to compute one by reading the remote file. // Default to considering the files different. upload = true reason = reasonMD5Missing } else if !bytes.Equal(lf.MD5(), remoteFile.MD5) { upload = true reason = reasonMD5Differs } else { // Nope! Leave uploaded = false. } found[path] = true } else { // The file doesn't exist in remote. upload = true reason = reasonNotFound } if upload { jww.DEBUG.Printf("%s needs to be uploaded: %v\n", path, reason) uploads = append(uploads, &fileToUpload{lf, reason}) } else { jww.DEBUG.Printf("%s exists at target and does not need to be uploaded", path) } } // Remote files that weren't found locally should be deleted. for path := range remoteFiles { if !found[path] { deletes = append(deletes, path) } } return uploads, deletes } // applyOrdering returns an ordered slice of slices of uploads. // // The returned slice will have length len(ordering)+1. // // The subslice at index i, for i = 0 ... len(ordering)-1, will have all of the // uploads whose Local.SlashPath matched the regex at ordering[i] (but not any // previous ordering regex). // The subslice at index len(ordering) will have the remaining uploads that // didn't match any ordering regex. // // The subslices are sorted by Local.SlashPath. func applyOrdering(ordering []*regexp.Regexp, uploads []*fileToUpload) [][]*fileToUpload { // Sort the whole slice by Local.SlashPath first. sort.Slice(uploads, func(i, j int) bool { return uploads[i].Local.SlashPath < uploads[j].Local.SlashPath }) retval := make([][]*fileToUpload, len(ordering)+1) for _, u := range uploads { matched := false for i, re := range ordering { if re.MatchString(u.Local.SlashPath) { retval[i] = append(retval[i], u) matched = true break } } if !matched { retval[len(ordering)] = append(retval[len(ordering)], u) } } return retval } hugo-0.68.3/deploy/deployConfig.go000066400000000000000000000077641363637351300170470ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package deploy import ( "fmt" "regexp" "github.com/gobwas/glob" "github.com/gohugoio/hugo/config" hglob "github.com/gohugoio/hugo/hugofs/glob" "github.com/mitchellh/mapstructure" ) const deploymentConfigKey = "deployment" // deployConfig is the complete configuration for deployment. type deployConfig struct { Targets []*target Matchers []*matcher Order []string ordering []*regexp.Regexp // compiled Order } type target struct { Name string URL string CloudFrontDistributionID string // GoogleCloudCDNOrigin specifies the Google Cloud project and CDN origin to // invalidate when deploying this target. It is specified as /. GoogleCloudCDNOrigin string // Optional patterns of files to include/exclude for this target. // Parsed using github.com/gobwas/glob. Include string Exclude string // Parsed versions of Include/Exclude. includeGlob glob.Glob excludeGlob glob.Glob } func (tgt *target) parseIncludeExclude() error { var err error if tgt.Include != "" { tgt.includeGlob, err = hglob.GetGlob(tgt.Include) if err != nil { return fmt.Errorf("invalid deployment.target.include %q: %v", tgt.Include, err) } } if tgt.Exclude != "" { tgt.excludeGlob, err = hglob.GetGlob(tgt.Exclude) if err != nil { return fmt.Errorf("invalid deployment.target.exclude %q: %v", tgt.Exclude, err) } } return nil } // matcher represents configuration to be applied to files whose paths match // a specified pattern. type matcher struct { // Pattern is the string pattern to match against paths. // Matching is done against paths converted to use / as the path separator. Pattern string // CacheControl specifies caching attributes to use when serving the blob. // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control CacheControl string // ContentEncoding specifies the encoding used for the blob's content, if any. // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding ContentEncoding string // ContentType specifies the MIME type of the blob being written. // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type ContentType string // Gzip determines whether the file should be gzipped before upload. // If so, the ContentEncoding field will automatically be set to "gzip". Gzip bool // Force indicates that matching files should be re-uploaded. Useful when // other route-determined metadata (e.g., ContentType) has changed. Force bool // re is Pattern compiled. re *regexp.Regexp } func (m *matcher) Matches(path string) bool { return m.re.MatchString(path) } // decode creates a config from a given Hugo configuration. func decodeConfig(cfg config.Provider) (deployConfig, error) { var dcfg deployConfig if !cfg.IsSet(deploymentConfigKey) { return dcfg, nil } if err := mapstructure.WeakDecode(cfg.GetStringMap(deploymentConfigKey), &dcfg); err != nil { return dcfg, err } for _, tgt := range dcfg.Targets { if err := tgt.parseIncludeExclude(); err != nil { return dcfg, err } } var err error for _, m := range dcfg.Matchers { m.re, err = regexp.Compile(m.Pattern) if err != nil { return dcfg, fmt.Errorf("invalid deployment.matchers.pattern: %v", err) } } for _, o := range dcfg.Order { re, err := regexp.Compile(o) if err != nil { return dcfg, fmt.Errorf("invalid deployment.orderings.pattern: %v", err) } dcfg.ordering = append(dcfg.ordering, re) } return dcfg, nil } hugo-0.68.3/deploy/deployConfig_test.go000066400000000000000000000100501363637351300200640ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package deploy import ( "fmt" "testing" qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/config" "github.com/spf13/viper" ) func TestDecodeConfigFromTOML(t *testing.T) { c := qt.New(t) tomlConfig := ` someOtherValue = "foo" [deployment] order = ["o1", "o2"] # All lowercase. [[deployment.targets]] name = "name0" url = "url0" cloudfrontdistributionid = "cdn0" include = "*.html" # All uppercase. [[deployment.targets]] NAME = "name1" URL = "url1" CLOUDFRONTDISTRIBUTIONID = "cdn1" INCLUDE = "*.jpg" # Camelcase. [[deployment.targets]] name = "name2" url = "url2" cloudFrontDistributionID = "cdn2" exclude = "*.png" # All lowercase. [[deployment.matchers]] pattern = "^pattern0$" cachecontrol = "cachecontrol0" contentencoding = "contentencoding0" contenttype = "contenttype0" # All uppercase. [[deployment.matchers]] PATTERN = "^pattern1$" CACHECONTROL = "cachecontrol1" CONTENTENCODING = "contentencoding1" CONTENTTYPE = "contenttype1" GZIP = true FORCE = true # Camelcase. [[deployment.matchers]] pattern = "^pattern2$" cacheControl = "cachecontrol2" contentEncoding = "contentencoding2" contentType = "contenttype2" gzip = true force = true ` cfg, err := config.FromConfigString(tomlConfig, "toml") c.Assert(err, qt.IsNil) dcfg, err := decodeConfig(cfg) c.Assert(err, qt.IsNil) // Order. c.Assert(len(dcfg.Order), qt.Equals, 2) c.Assert(dcfg.Order[0], qt.Equals, "o1") c.Assert(dcfg.Order[1], qt.Equals, "o2") c.Assert(len(dcfg.ordering), qt.Equals, 2) // Targets. c.Assert(len(dcfg.Targets), qt.Equals, 3) wantInclude := []string{"*.html", "*.jpg", ""} wantExclude := []string{"", "", "*.png"} for i := 0; i < 3; i++ { tgt := dcfg.Targets[i] c.Assert(tgt.Name, qt.Equals, fmt.Sprintf("name%d", i)) c.Assert(tgt.URL, qt.Equals, fmt.Sprintf("url%d", i)) c.Assert(tgt.CloudFrontDistributionID, qt.Equals, fmt.Sprintf("cdn%d", i)) c.Assert(tgt.Include, qt.Equals, wantInclude[i]) if wantInclude[i] != "" { c.Assert(tgt.includeGlob, qt.Not(qt.IsNil)) } c.Assert(tgt.Exclude, qt.Equals, wantExclude[i]) if wantExclude[i] != "" { c.Assert(tgt.excludeGlob, qt.Not(qt.IsNil)) } } // Matchers. c.Assert(len(dcfg.Matchers), qt.Equals, 3) for i := 0; i < 3; i++ { m := dcfg.Matchers[i] c.Assert(m.Pattern, qt.Equals, fmt.Sprintf("^pattern%d$", i)) c.Assert(m.re, qt.Not(qt.IsNil)) c.Assert(m.CacheControl, qt.Equals, fmt.Sprintf("cachecontrol%d", i)) c.Assert(m.ContentEncoding, qt.Equals, fmt.Sprintf("contentencoding%d", i)) c.Assert(m.ContentType, qt.Equals, fmt.Sprintf("contenttype%d", i)) c.Assert(m.Gzip, qt.Equals, i != 0) c.Assert(m.Force, qt.Equals, i != 0) } } func TestInvalidOrderingPattern(t *testing.T) { c := qt.New(t) tomlConfig := ` someOtherValue = "foo" [deployment] order = ["["] # invalid regular expression ` cfg, err := config.FromConfigString(tomlConfig, "toml") c.Assert(err, qt.IsNil) _, err = decodeConfig(cfg) c.Assert(err, qt.Not(qt.IsNil)) } func TestInvalidMatcherPattern(t *testing.T) { c := qt.New(t) tomlConfig := ` someOtherValue = "foo" [deployment] [[deployment.matchers]] Pattern = "[" # invalid regular expression ` cfg, err := config.FromConfigString(tomlConfig, "toml") c.Assert(err, qt.IsNil) _, err = decodeConfig(cfg) c.Assert(err, qt.Not(qt.IsNil)) } func TestDecodeConfigDefault(t *testing.T) { c := qt.New(t) dcfg, err := decodeConfig(viper.New()) c.Assert(err, qt.IsNil) c.Assert(len(dcfg.Targets), qt.Equals, 0) c.Assert(len(dcfg.Matchers), qt.Equals, 0) } hugo-0.68.3/deploy/deploy_azure.go000066400000000000000000000013201363637351300171050ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // +build !solaris package deploy import ( _ "gocloud.dev/blob" _ "gocloud.dev/blob/azureblob" // import ) hugo-0.68.3/deploy/deploy_test.go000066400000000000000000000666211363637351300167550ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package deploy import ( "bytes" "compress/gzip" "context" "crypto/md5" "fmt" "io" "io/ioutil" "os" "path" "path/filepath" "regexp" "sort" "testing" "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" "github.com/spf13/afero" "gocloud.dev/blob" "gocloud.dev/blob/fileblob" "gocloud.dev/blob/memblob" ) func TestFindDiffs(t *testing.T) { hash1 := []byte("hash 1") hash2 := []byte("hash 2") makeLocal := func(path string, size int64, hash []byte) *localFile { return &localFile{NativePath: path, SlashPath: filepath.ToSlash(path), UploadSize: size, md5: hash} } makeRemote := func(path string, size int64, hash []byte) *blob.ListObject { return &blob.ListObject{Key: path, Size: size, MD5: hash} } tests := []struct { Description string Local []*localFile Remote []*blob.ListObject Force bool WantUpdates []*fileToUpload WantDeletes []string }{ { Description: "empty -> no diffs", }, { Description: "local == remote -> no diffs", Local: []*localFile{ makeLocal("aaa", 1, hash1), makeLocal("bbb", 2, hash1), makeLocal("ccc", 3, hash2), }, Remote: []*blob.ListObject{ makeRemote("aaa", 1, hash1), makeRemote("bbb", 2, hash1), makeRemote("ccc", 3, hash2), }, }, { Description: "local w/ separators == remote -> no diffs", Local: []*localFile{ makeLocal(filepath.Join("aaa", "aaa"), 1, hash1), makeLocal(filepath.Join("bbb", "bbb"), 2, hash1), makeLocal(filepath.Join("ccc", "ccc"), 3, hash2), }, Remote: []*blob.ListObject{ makeRemote("aaa/aaa", 1, hash1), makeRemote("bbb/bbb", 2, hash1), makeRemote("ccc/ccc", 3, hash2), }, }, { Description: "local == remote with force flag true -> diffs", Local: []*localFile{ makeLocal("aaa", 1, hash1), makeLocal("bbb", 2, hash1), makeLocal("ccc", 3, hash2), }, Remote: []*blob.ListObject{ makeRemote("aaa", 1, hash1), makeRemote("bbb", 2, hash1), makeRemote("ccc", 3, hash2), }, Force: true, WantUpdates: []*fileToUpload{ {makeLocal("aaa", 1, nil), reasonForce}, {makeLocal("bbb", 2, nil), reasonForce}, {makeLocal("ccc", 3, nil), reasonForce}, }, }, { Description: "local == remote with route.Force true -> diffs", Local: []*localFile{ {NativePath: "aaa", SlashPath: "aaa", UploadSize: 1, matcher: &matcher{Force: true}, md5: hash1}, makeLocal("bbb", 2, hash1), }, Remote: []*blob.ListObject{ makeRemote("aaa", 1, hash1), makeRemote("bbb", 2, hash1), }, WantUpdates: []*fileToUpload{ {makeLocal("aaa", 1, nil), reasonForce}, }, }, { Description: "extra local file -> upload", Local: []*localFile{ makeLocal("aaa", 1, hash1), makeLocal("bbb", 2, hash2), }, Remote: []*blob.ListObject{ makeRemote("aaa", 1, hash1), }, WantUpdates: []*fileToUpload{ {makeLocal("bbb", 2, nil), reasonNotFound}, }, }, { Description: "extra remote file -> delete", Local: []*localFile{ makeLocal("aaa", 1, hash1), }, Remote: []*blob.ListObject{ makeRemote("aaa", 1, hash1), makeRemote("bbb", 2, hash2), }, WantDeletes: []string{"bbb"}, }, { Description: "diffs in size or md5 -> upload", Local: []*localFile{ makeLocal("aaa", 1, hash1), makeLocal("bbb", 2, hash1), makeLocal("ccc", 1, hash2), }, Remote: []*blob.ListObject{ makeRemote("aaa", 1, nil), makeRemote("bbb", 1, hash1), makeRemote("ccc", 1, hash1), }, WantUpdates: []*fileToUpload{ {makeLocal("aaa", 1, nil), reasonMD5Missing}, {makeLocal("bbb", 2, nil), reasonSize}, {makeLocal("ccc", 1, nil), reasonMD5Differs}, }, }, { Description: "mix of updates and deletes", Local: []*localFile{ makeLocal("same", 1, hash1), makeLocal("updated", 2, hash1), makeLocal("updated2", 1, hash2), makeLocal("new", 1, hash1), makeLocal("new2", 2, hash2), }, Remote: []*blob.ListObject{ makeRemote("same", 1, hash1), makeRemote("updated", 1, hash1), makeRemote("updated2", 1, hash1), makeRemote("stale", 1, hash1), makeRemote("stale2", 1, hash1), }, WantUpdates: []*fileToUpload{ {makeLocal("new", 1, nil), reasonNotFound}, {makeLocal("new2", 2, nil), reasonNotFound}, {makeLocal("updated", 2, nil), reasonSize}, {makeLocal("updated2", 1, nil), reasonMD5Differs}, }, WantDeletes: []string{"stale", "stale2"}, }, } for _, tc := range tests { t.Run(tc.Description, func(t *testing.T) { local := map[string]*localFile{} for _, l := range tc.Local { local[l.SlashPath] = l } remote := map[string]*blob.ListObject{} for _, r := range tc.Remote { remote[r.Key] = r } gotUpdates, gotDeletes := findDiffs(local, remote, tc.Force) gotUpdates = applyOrdering(nil, gotUpdates)[0] sort.Slice(gotDeletes, func(i, j int) bool { return gotDeletes[i] < gotDeletes[j] }) if diff := cmp.Diff(gotUpdates, tc.WantUpdates, cmpopts.IgnoreUnexported(localFile{})); diff != "" { t.Errorf("updates differ:\n%s", diff) } if diff := cmp.Diff(gotDeletes, tc.WantDeletes); diff != "" { t.Errorf("deletes differ:\n%s", diff) } }) } } func TestLocalFile(t *testing.T) { const ( content = "hello world!" ) contentBytes := []byte(content) contentLen := int64(len(contentBytes)) contentMD5 := md5.Sum(contentBytes) var buf bytes.Buffer gz := gzip.NewWriter(&buf) if _, err := gz.Write(contentBytes); err != nil { t.Fatal(err) } gz.Close() gzBytes := buf.Bytes() gzLen := int64(len(gzBytes)) gzMD5 := md5.Sum(gzBytes) tests := []struct { Description string Path string Matcher *matcher WantContent []byte WantSize int64 WantMD5 []byte WantContentType string // empty string is always OK, since content type detection is OS-specific WantCacheControl string WantContentEncoding string }{ { Description: "file with no suffix", Path: "foo", WantContent: contentBytes, WantSize: contentLen, WantMD5: contentMD5[:], }, { Description: "file with .txt suffix", Path: "foo.txt", WantContent: contentBytes, WantSize: contentLen, WantMD5: contentMD5[:], }, { Description: "CacheControl from matcher", Path: "foo.txt", Matcher: &matcher{CacheControl: "max-age=630720000"}, WantContent: contentBytes, WantSize: contentLen, WantMD5: contentMD5[:], WantCacheControl: "max-age=630720000", }, { Description: "ContentEncoding from matcher", Path: "foo.txt", Matcher: &matcher{ContentEncoding: "foobar"}, WantContent: contentBytes, WantSize: contentLen, WantMD5: contentMD5[:], WantContentEncoding: "foobar", }, { Description: "ContentType from matcher", Path: "foo.txt", Matcher: &matcher{ContentType: "foo/bar"}, WantContent: contentBytes, WantSize: contentLen, WantMD5: contentMD5[:], WantContentType: "foo/bar", }, { Description: "gzipped content", Path: "foo.txt", Matcher: &matcher{Gzip: true}, WantContent: gzBytes, WantSize: gzLen, WantMD5: gzMD5[:], WantContentEncoding: "gzip", }, } for _, tc := range tests { t.Run(tc.Description, func(t *testing.T) { fs := new(afero.MemMapFs) if err := afero.WriteFile(fs, tc.Path, []byte(content), os.ModePerm); err != nil { t.Fatal(err) } lf, err := newLocalFile(fs, tc.Path, filepath.ToSlash(tc.Path), tc.Matcher) if err != nil { t.Fatal(err) } if got := lf.UploadSize; got != tc.WantSize { t.Errorf("got size %d want %d", got, tc.WantSize) } if got := lf.MD5(); !bytes.Equal(got, tc.WantMD5) { t.Errorf("got MD5 %x want %x", got, tc.WantMD5) } if got := lf.CacheControl(); got != tc.WantCacheControl { t.Errorf("got CacheControl %q want %q", got, tc.WantCacheControl) } if got := lf.ContentEncoding(); got != tc.WantContentEncoding { t.Errorf("got ContentEncoding %q want %q", got, tc.WantContentEncoding) } if tc.WantContentType != "" { if got := lf.ContentType(); got != tc.WantContentType { t.Errorf("got ContentType %q want %q", got, tc.WantContentType) } } // Verify the reader last to ensure the previous operations don't // interfere with it. r, err := lf.Reader() if err != nil { t.Fatal(err) } gotContent, err := ioutil.ReadAll(r) if err != nil { t.Fatal(err) } if !bytes.Equal(gotContent, tc.WantContent) { t.Errorf("got content %q want %q", string(gotContent), string(tc.WantContent)) } r.Close() // Verify we can read again. r, err = lf.Reader() if err != nil { t.Fatal(err) } gotContent, err = ioutil.ReadAll(r) if err != nil { t.Fatal(err) } r.Close() if !bytes.Equal(gotContent, tc.WantContent) { t.Errorf("got content %q want %q", string(gotContent), string(tc.WantContent)) } }) } } func TestOrdering(t *testing.T) { tests := []struct { Description string Uploads []string Ordering []*regexp.Regexp Want [][]string }{ { Description: "empty", Want: [][]string{nil}, }, { Description: "no ordering", Uploads: []string{"c", "b", "a", "d"}, Want: [][]string{{"a", "b", "c", "d"}}, }, { Description: "one ordering", Uploads: []string{"db", "c", "b", "a", "da"}, Ordering: []*regexp.Regexp{regexp.MustCompile("^d")}, Want: [][]string{{"da", "db"}, {"a", "b", "c"}}, }, { Description: "two orderings", Uploads: []string{"db", "c", "b", "a", "da"}, Ordering: []*regexp.Regexp{ regexp.MustCompile("^d"), regexp.MustCompile("^b"), }, Want: [][]string{{"da", "db"}, {"b"}, {"a", "c"}}, }, } for _, tc := range tests { t.Run(tc.Description, func(t *testing.T) { uploads := make([]*fileToUpload, len(tc.Uploads)) for i, u := range tc.Uploads { uploads[i] = &fileToUpload{Local: &localFile{SlashPath: u}} } gotUploads := applyOrdering(tc.Ordering, uploads) var got [][]string for _, subslice := range gotUploads { var gotsubslice []string for _, u := range subslice { gotsubslice = append(gotsubslice, u.Local.SlashPath) } got = append(got, gotsubslice) } if diff := cmp.Diff(got, tc.Want); diff != "" { t.Error(diff) } }) } } type fileData struct { Name string // name of the file Contents string // contents of the file } // initLocalFs initializes fs with some test files. func initLocalFs(ctx context.Context, fs afero.Fs) ([]*fileData, error) { // The initial local filesystem. local := []*fileData{ {"aaa", "aaa"}, {"bbb", "bbb"}, {"subdir/aaa", "subdir-aaa"}, {"subdir/nested/aaa", "subdir-nested-aaa"}, {"subdir2/bbb", "subdir2-bbb"}, } if err := writeFiles(fs, local); err != nil { return nil, err } return local, nil } // fsTest represents an (afero.FS, Go CDK blob.Bucket) against which end-to-end // tests can be run. type fsTest struct { name string fs afero.Fs bucket *blob.Bucket } // initFsTests initializes a pair of tests for end-to-end test: // 1. An in-memory afero.Fs paired with an in-memory Go CDK bucket. // 2. A filesystem-based afero.Fs paired with an filesystem-based Go CDK bucket. // It returns the pair of tests and a cleanup function. func initFsTests() ([]*fsTest, func(), error) { tmpfsdir, err := ioutil.TempDir("", "fs") if err != nil { return nil, nil, err } tmpbucketdir, err := ioutil.TempDir("", "bucket") if err != nil { return nil, nil, err } memfs := afero.NewMemMapFs() membucket := memblob.OpenBucket(nil) filefs := afero.NewBasePathFs(afero.NewOsFs(), tmpfsdir) filebucket, err := fileblob.OpenBucket(tmpbucketdir, nil) if err != nil { return nil, nil, err } tests := []*fsTest{ {"mem", memfs, membucket}, {"file", filefs, filebucket}, } cleanup := func() { membucket.Close() filebucket.Close() os.RemoveAll(tmpfsdir) os.RemoveAll(tmpbucketdir) } return tests, cleanup, nil } // TestEndToEndSync verifies that basic adds, updates, and deletes are working // correctly. func TestEndToEndSync(t *testing.T) { ctx := context.Background() tests, cleanup, err := initFsTests() if err != nil { t.Fatal(err) } defer cleanup() for _, test := range tests { t.Run(test.name, func(t *testing.T) { local, err := initLocalFs(ctx, test.fs) if err != nil { t.Fatal(err) } deployer := &Deployer{ localFs: test.fs, maxDeletes: -1, bucket: test.bucket, } // Initial deployment should sync remote with local. if err := deployer.Deploy(ctx); err != nil { t.Errorf("initial deploy: failed: %v", err) } wantSummary := deploySummary{NumLocal: 5, NumRemote: 0, NumUploads: 5, NumDeletes: 0} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("initial deploy: got %v, want %v", deployer.summary, wantSummary) } if diff, err := verifyRemote(ctx, deployer.bucket, local); err != nil { t.Errorf("initial deploy: failed to verify remote: %v", err) } else if diff != "" { t.Errorf("initial deploy: remote snapshot doesn't match expected:\n%v", diff) } // A repeat deployment shouldn't change anything. if err := deployer.Deploy(ctx); err != nil { t.Errorf("no-op deploy: %v", err) } wantSummary = deploySummary{NumLocal: 5, NumRemote: 5, NumUploads: 0, NumDeletes: 0} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("no-op deploy: got %v, want %v", deployer.summary, wantSummary) } // Make some changes to the local filesystem: // 1. Modify file [0]. // 2. Delete file [1]. // 3. Add a new file (sorted last). updatefd := local[0] updatefd.Contents = "new contents" deletefd := local[1] local = append(local[:1], local[2:]...) // removing deleted [1] newfd := &fileData{"zzz", "zzz"} local = append(local, newfd) if err := writeFiles(test.fs, []*fileData{updatefd, newfd}); err != nil { t.Fatal(err) } if err := test.fs.Remove(deletefd.Name); err != nil { t.Fatal(err) } // A deployment should apply those 3 changes. if err := deployer.Deploy(ctx); err != nil { t.Errorf("deploy after changes: failed: %v", err) } wantSummary = deploySummary{NumLocal: 5, NumRemote: 5, NumUploads: 2, NumDeletes: 1} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("deploy after changes: got %v, want %v", deployer.summary, wantSummary) } if diff, err := verifyRemote(ctx, deployer.bucket, local); err != nil { t.Errorf("deploy after changes: failed to verify remote: %v", err) } else if diff != "" { t.Errorf("deploy after changes: remote snapshot doesn't match expected:\n%v", diff) } // Again, a repeat deployment shouldn't change anything. if err := deployer.Deploy(ctx); err != nil { t.Errorf("no-op deploy: %v", err) } wantSummary = deploySummary{NumLocal: 5, NumRemote: 5, NumUploads: 0, NumDeletes: 0} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("no-op deploy: got %v, want %v", deployer.summary, wantSummary) } }) } } // TestMaxDeletes verifies that the "maxDeletes" flag is working correctly. func TestMaxDeletes(t *testing.T) { ctx := context.Background() tests, cleanup, err := initFsTests() if err != nil { t.Fatal(err) } defer cleanup() for _, test := range tests { t.Run(test.name, func(t *testing.T) { local, err := initLocalFs(ctx, test.fs) if err != nil { t.Fatal(err) } deployer := &Deployer{ localFs: test.fs, maxDeletes: -1, bucket: test.bucket, } // Sync remote with local. if err := deployer.Deploy(ctx); err != nil { t.Errorf("initial deploy: failed: %v", err) } wantSummary := deploySummary{NumLocal: 5, NumRemote: 0, NumUploads: 5, NumDeletes: 0} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("initial deploy: got %v, want %v", deployer.summary, wantSummary) } // Delete two files, [1] and [2]. if err := test.fs.Remove(local[1].Name); err != nil { t.Fatal(err) } if err := test.fs.Remove(local[2].Name); err != nil { t.Fatal(err) } // A deployment with maxDeletes=0 shouldn't change anything. deployer.maxDeletes = 0 if err := deployer.Deploy(ctx); err != nil { t.Errorf("deploy failed: %v", err) } wantSummary = deploySummary{NumLocal: 3, NumRemote: 5, NumUploads: 0, NumDeletes: 0} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("deploy: got %v, want %v", deployer.summary, wantSummary) } // A deployment with maxDeletes=1 shouldn't change anything either. deployer.maxDeletes = 1 if err := deployer.Deploy(ctx); err != nil { t.Errorf("deploy failed: %v", err) } wantSummary = deploySummary{NumLocal: 3, NumRemote: 5, NumUploads: 0, NumDeletes: 0} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("deploy: got %v, want %v", deployer.summary, wantSummary) } // A deployment with maxDeletes=2 should make the changes. deployer.maxDeletes = 2 if err := deployer.Deploy(ctx); err != nil { t.Errorf("deploy failed: %v", err) } wantSummary = deploySummary{NumLocal: 3, NumRemote: 5, NumUploads: 0, NumDeletes: 2} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("deploy: got %v, want %v", deployer.summary, wantSummary) } // Delete two more files, [0] and [3]. if err := test.fs.Remove(local[0].Name); err != nil { t.Fatal(err) } if err := test.fs.Remove(local[3].Name); err != nil { t.Fatal(err) } // A deployment with maxDeletes=-1 should make the changes. deployer.maxDeletes = -1 if err := deployer.Deploy(ctx); err != nil { t.Errorf("deploy failed: %v", err) } wantSummary = deploySummary{NumLocal: 1, NumRemote: 3, NumUploads: 0, NumDeletes: 2} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("deploy: got %v, want %v", deployer.summary, wantSummary) } }) } } // TestIncludeExclude verifies that the include/exclude options for targets work. func TestIncludeExclude(t *testing.T) { ctx := context.Background() tests := []struct { Include string Exclude string Want deploySummary }{ { Want: deploySummary{NumLocal: 5, NumUploads: 5}, }, { Include: "**aaa", Want: deploySummary{NumLocal: 3, NumUploads: 3}, }, { Include: "**bbb", Want: deploySummary{NumLocal: 2, NumUploads: 2}, }, { Include: "aaa", Want: deploySummary{NumLocal: 1, NumUploads: 1}, }, { Exclude: "**aaa", Want: deploySummary{NumLocal: 2, NumUploads: 2}, }, { Exclude: "**bbb", Want: deploySummary{NumLocal: 3, NumUploads: 3}, }, { Exclude: "aaa", Want: deploySummary{NumLocal: 4, NumUploads: 4}, }, { Include: "**aaa", Exclude: "**nested**", Want: deploySummary{NumLocal: 2, NumUploads: 2}, }, } for _, test := range tests { t.Run(fmt.Sprintf("include %q exclude %q", test.Include, test.Exclude), func(t *testing.T) { fsTests, cleanup, err := initFsTests() if err != nil { t.Fatal(err) } defer cleanup() fsTest := fsTests[1] // just do file-based test _, err = initLocalFs(ctx, fsTest.fs) if err != nil { t.Fatal(err) } tgt := &target{ Include: test.Include, Exclude: test.Exclude, } if err := tgt.parseIncludeExclude(); err != nil { t.Error(err) } deployer := &Deployer{ localFs: fsTest.fs, maxDeletes: -1, bucket: fsTest.bucket, target: tgt, } // Sync remote with local. if err := deployer.Deploy(ctx); err != nil { t.Errorf("deploy: failed: %v", err) } if !cmp.Equal(deployer.summary, test.Want) { t.Errorf("deploy: got %v, want %v", deployer.summary, test.Want) } }) } } // TestIncludeExcludeRemoteDelete verifies deleted local files that don't match include/exclude patterns // are not deleted on the remote. func TestIncludeExcludeRemoteDelete(t *testing.T) { ctx := context.Background() tests := []struct { Include string Exclude string Want deploySummary }{ { Want: deploySummary{NumLocal: 3, NumRemote: 5, NumUploads: 0, NumDeletes: 2}, }, { Include: "**aaa", Want: deploySummary{NumLocal: 2, NumRemote: 3, NumUploads: 0, NumDeletes: 1}, }, { Include: "subdir/**", Want: deploySummary{NumLocal: 1, NumRemote: 2, NumUploads: 0, NumDeletes: 1}, }, { Exclude: "**bbb", Want: deploySummary{NumLocal: 2, NumRemote: 3, NumUploads: 0, NumDeletes: 1}, }, { Exclude: "bbb", Want: deploySummary{NumLocal: 3, NumRemote: 4, NumUploads: 0, NumDeletes: 1}, }, } for _, test := range tests { t.Run(fmt.Sprintf("include %q exclude %q", test.Include, test.Exclude), func(t *testing.T) { fsTests, cleanup, err := initFsTests() if err != nil { t.Fatal(err) } defer cleanup() fsTest := fsTests[1] // just do file-based test local, err := initLocalFs(ctx, fsTest.fs) if err != nil { t.Fatal(err) } deployer := &Deployer{ localFs: fsTest.fs, maxDeletes: -1, bucket: fsTest.bucket, } // Initial sync to get the files on the remote if err := deployer.Deploy(ctx); err != nil { t.Errorf("deploy: failed: %v", err) } // Delete two files, [1] and [2]. if err := fsTest.fs.Remove(local[1].Name); err != nil { t.Fatal(err) } if err := fsTest.fs.Remove(local[2].Name); err != nil { t.Fatal(err) } // Second sync tgt := &target{ Include: test.Include, Exclude: test.Exclude, } if err := tgt.parseIncludeExclude(); err != nil { t.Error(err) } deployer.target = tgt if err := deployer.Deploy(ctx); err != nil { t.Errorf("deploy: failed: %v", err) } if !cmp.Equal(deployer.summary, test.Want) { t.Errorf("deploy: got %v, want %v", deployer.summary, test.Want) } }) } } // TestCompression verifies that gzip compression works correctly. // In particular, MD5 hashes must be of the compressed content. func TestCompression(t *testing.T) { ctx := context.Background() tests, cleanup, err := initFsTests() if err != nil { t.Fatal(err) } defer cleanup() for _, test := range tests { t.Run(test.name, func(t *testing.T) { local, err := initLocalFs(ctx, test.fs) if err != nil { t.Fatal(err) } deployer := &Deployer{ localFs: test.fs, bucket: test.bucket, matchers: []*matcher{{Pattern: ".*", Gzip: true, re: regexp.MustCompile(".*")}}, } // Initial deployment should sync remote with local. if err := deployer.Deploy(ctx); err != nil { t.Errorf("initial deploy: failed: %v", err) } wantSummary := deploySummary{NumLocal: 5, NumRemote: 0, NumUploads: 5, NumDeletes: 0} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("initial deploy: got %v, want %v", deployer.summary, wantSummary) } // A repeat deployment shouldn't change anything. if err := deployer.Deploy(ctx); err != nil { t.Errorf("no-op deploy: %v", err) } wantSummary = deploySummary{NumLocal: 5, NumRemote: 5, NumUploads: 0, NumDeletes: 0} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("no-op deploy: got %v, want %v", deployer.summary, wantSummary) } // Make an update to the local filesystem, on [1]. updatefd := local[1] updatefd.Contents = "new contents" if err := writeFiles(test.fs, []*fileData{updatefd}); err != nil { t.Fatal(err) } // A deployment should apply the changes. if err := deployer.Deploy(ctx); err != nil { t.Errorf("deploy after changes: failed: %v", err) } wantSummary = deploySummary{NumLocal: 5, NumRemote: 5, NumUploads: 1, NumDeletes: 0} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("deploy after changes: got %v, want %v", deployer.summary, wantSummary) } }) } } // TestMatching verifies that matchers match correctly, and that the Force // attribute for matcher works. func TestMatching(t *testing.T) { ctx := context.Background() tests, cleanup, err := initFsTests() if err != nil { t.Fatal(err) } defer cleanup() for _, test := range tests { t.Run(test.name, func(t *testing.T) { _, err := initLocalFs(ctx, test.fs) if err != nil { t.Fatal(err) } deployer := &Deployer{ localFs: test.fs, bucket: test.bucket, matchers: []*matcher{{Pattern: "^subdir/aaa$", Force: true, re: regexp.MustCompile("^subdir/aaa$")}}, } // Initial deployment to sync remote with local. if err := deployer.Deploy(ctx); err != nil { t.Errorf("initial deploy: failed: %v", err) } wantSummary := deploySummary{NumLocal: 5, NumRemote: 0, NumUploads: 5, NumDeletes: 0} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("initial deploy: got %v, want %v", deployer.summary, wantSummary) } // A repeat deployment should upload a single file, the one that matched the Force matcher. // Note that matching happens based on the ToSlash form, so this matches // even on Windows. if err := deployer.Deploy(ctx); err != nil { t.Errorf("no-op deploy with single force matcher: %v", err) } wantSummary = deploySummary{NumLocal: 5, NumRemote: 5, NumUploads: 1, NumDeletes: 0} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("no-op deploy with single force matcher: got %v, want %v", deployer.summary, wantSummary) } // Repeat with a matcher that should now match 3 files. deployer.matchers = []*matcher{{Pattern: "aaa", Force: true, re: regexp.MustCompile("aaa")}} if err := deployer.Deploy(ctx); err != nil { t.Errorf("no-op deploy with triple force matcher: %v", err) } wantSummary = deploySummary{NumLocal: 5, NumRemote: 5, NumUploads: 3, NumDeletes: 0} if !cmp.Equal(deployer.summary, wantSummary) { t.Errorf("no-op deploy with triple force matcher: got %v, want %v", deployer.summary, wantSummary) } }) } } // writeFiles writes the files in fds to fd. func writeFiles(fs afero.Fs, fds []*fileData) error { for _, fd := range fds { dir := path.Dir(fd.Name) if dir != "." { err := fs.MkdirAll(dir, os.ModePerm) if err != nil { return err } } f, err := fs.Create(fd.Name) if err != nil { return err } defer f.Close() _, err = f.WriteString(fd.Contents) if err != nil { return err } } return nil } // verifyRemote that the current contents of bucket matches local. // It returns an empty string if the contents matched, and a non-empty string // capturing the diff if they didn't. func verifyRemote(ctx context.Context, bucket *blob.Bucket, local []*fileData) (string, error) { var cur []*fileData iter := bucket.List(nil) for { obj, err := iter.Next(ctx) if err == io.EOF { break } if err != nil { return "", err } contents, err := bucket.ReadAll(ctx, obj.Key) if err != nil { return "", err } cur = append(cur, &fileData{obj.Key, string(contents)}) } if cmp.Equal(cur, local) { return "", nil } diff := "got: \n" for _, f := range cur { diff += fmt.Sprintf(" %s: %s\n", f.Name, f.Contents) } diff += "want: \n" for _, f := range local { diff += fmt.Sprintf(" %s: %s\n", f.Name, f.Contents) } return diff, nil } hugo-0.68.3/deploy/google.go000066400000000000000000000022471363637351300156700ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package deploy import ( "context" "fmt" "strings" "google.golang.org/api/compute/v1" ) // Invalidate all of the content in a Google Cloud CDN distribution. func InvalidateGoogleCloudCDN(ctx context.Context, origin string) error { parts := strings.Split(origin, "/") if len(parts) != 2 { return fmt.Errorf("origin must be /") } service, err := compute.NewService(ctx) if err != nil { return err } rule := &compute.CacheInvalidationRule{Path: "/*"} _, err = service.UrlMaps.InvalidateCache(parts[0], parts[1], rule).Context(ctx).Do() return err } hugo-0.68.3/deps/000077500000000000000000000000001363637351300135175ustar00rootroot00000000000000hugo-0.68.3/deps/deps.go000066400000000000000000000217161363637351300150100ustar00rootroot00000000000000package deps import ( "sync" "time" "github.com/pkg/errors" "github.com/gohugoio/hugo/cache/filecache" "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/langs" "github.com/gohugoio/hugo/media" "github.com/gohugoio/hugo/resources/page" "github.com/gohugoio/hugo/metrics" "github.com/gohugoio/hugo/output" "github.com/gohugoio/hugo/resources" "github.com/gohugoio/hugo/source" "github.com/gohugoio/hugo/tpl" jww "github.com/spf13/jwalterweatherman" ) // Deps holds dependencies used by many. // There will be normally only one instance of deps in play // at a given time, i.e. one per Site built. type Deps struct { // The logger to use. Log *loggers.Logger `json:"-"` // Used to log errors that may repeat itself many times. DistinctErrorLog *helpers.DistinctLogger // Used to log warnings that may repeat itself many times. DistinctWarningLog *helpers.DistinctLogger // The templates to use. This will usually implement the full tpl.TemplateManager. tmpl tpl.TemplateHandler // We use this to parse and execute ad-hoc text templates. textTmpl tpl.TemplateParseFinder // The file systems to use. Fs *hugofs.Fs `json:"-"` // The PathSpec to use *helpers.PathSpec `json:"-"` // The ContentSpec to use *helpers.ContentSpec `json:"-"` // The SourceSpec to use SourceSpec *source.SourceSpec `json:"-"` // The Resource Spec to use ResourceSpec *resources.Spec // The configuration to use Cfg config.Provider `json:"-"` // The file cache to use. FileCaches filecache.Caches // The translation func to use Translate func(translationID string, args ...interface{}) string `json:"-"` // The language in use. TODO(bep) consolidate with site Language *langs.Language // The site building. Site page.Site // All the output formats available for the current site. OutputFormatsConfig output.Formats templateProvider ResourceProvider WithTemplate func(templ tpl.TemplateManager) error `json:"-"` // Used in tests OverloadedTemplateFuncs map[string]interface{} translationProvider ResourceProvider Metrics metrics.Provider // Timeout is configurable in site config. Timeout time.Duration // BuildStartListeners will be notified before a build starts. BuildStartListeners *Listeners // Atomic flags set during a build. BuildFlags *BuildFlags *globalErrHandler } type globalErrHandler struct { // Channel for some "hard to get to" build errors buildErrors chan error } // SendErr sends the error on a channel to be handled later. // This can be used in situations where returning and aborting the current // operation isn't practical. func (e *globalErrHandler) SendError(err error) { if e.buildErrors != nil { select { case e.buildErrors <- err: default: } return } jww.ERROR.Println(err) } func (e *globalErrHandler) StartErrorCollector() chan error { e.buildErrors = make(chan error, 10) return e.buildErrors } // Listeners represents an event listener. type Listeners struct { sync.Mutex // A list of funcs to be notified about an event. listeners []func() } // Add adds a function to a Listeners instance. func (b *Listeners) Add(f func()) { if b == nil { return } b.Lock() defer b.Unlock() b.listeners = append(b.listeners, f) } // Notify executes all listener functions. func (b *Listeners) Notify() { b.Lock() defer b.Unlock() for _, notify := range b.listeners { notify() } } // ResourceProvider is used to create and refresh, and clone resources needed. type ResourceProvider interface { Update(deps *Deps) error Clone(deps *Deps) error } func (d *Deps) Tmpl() tpl.TemplateHandler { return d.tmpl } func (d *Deps) TextTmpl() tpl.TemplateParseFinder { return d.textTmpl } func (d *Deps) SetTmpl(tmpl tpl.TemplateHandler) { d.tmpl = tmpl } func (d *Deps) SetTextTmpl(tmpl tpl.TemplateParseFinder) { d.textTmpl = tmpl } // LoadResources loads translations and templates. func (d *Deps) LoadResources() error { // Note that the translations need to be loaded before the templates. if err := d.translationProvider.Update(d); err != nil { return errors.Wrap(err, "loading translations") } if err := d.templateProvider.Update(d); err != nil { return errors.Wrap(err, "loading templates") } return nil } // New initializes a Dep struct. // Defaults are set for nil values, // but TemplateProvider, TranslationProvider and Language are always required. func New(cfg DepsCfg) (*Deps, error) { var ( logger = cfg.Logger fs = cfg.Fs ) if cfg.TemplateProvider == nil { panic("Must have a TemplateProvider") } if cfg.TranslationProvider == nil { panic("Must have a TranslationProvider") } if cfg.Language == nil { panic("Must have a Language") } if logger == nil { logger = loggers.NewErrorLogger() } if fs == nil { // Default to the production file system. fs = hugofs.NewDefault(cfg.Language) } if cfg.MediaTypes == nil { cfg.MediaTypes = media.DefaultTypes } if cfg.OutputFormats == nil { cfg.OutputFormats = output.DefaultFormats } ps, err := helpers.NewPathSpec(fs, cfg.Language, logger) if err != nil { return nil, errors.Wrap(err, "create PathSpec") } fileCaches, err := filecache.NewCaches(ps) if err != nil { return nil, errors.WithMessage(err, "failed to create file caches from configuration") } errorHandler := &globalErrHandler{} resourceSpec, err := resources.NewSpec(ps, fileCaches, logger, errorHandler, cfg.OutputFormats, cfg.MediaTypes) if err != nil { return nil, err } contentSpec, err := helpers.NewContentSpec(cfg.Language, logger, ps.BaseFs.Content.Fs) if err != nil { return nil, err } sp := source.NewSourceSpec(ps, fs.Source) timeoutms := cfg.Language.GetInt("timeout") if timeoutms <= 0 { timeoutms = 3000 } distinctErrorLogger := helpers.NewDistinctLogger(logger.ERROR) distinctWarnLogger := helpers.NewDistinctLogger(logger.WARN) d := &Deps{ Fs: fs, Log: logger, DistinctErrorLog: distinctErrorLogger, DistinctWarningLog: distinctWarnLogger, templateProvider: cfg.TemplateProvider, translationProvider: cfg.TranslationProvider, WithTemplate: cfg.WithTemplate, OverloadedTemplateFuncs: cfg.OverloadedTemplateFuncs, PathSpec: ps, ContentSpec: contentSpec, SourceSpec: sp, ResourceSpec: resourceSpec, Cfg: cfg.Language, Language: cfg.Language, Site: cfg.Site, FileCaches: fileCaches, BuildStartListeners: &Listeners{}, BuildFlags: &BuildFlags{}, Timeout: time.Duration(timeoutms) * time.Millisecond, globalErrHandler: errorHandler, } if cfg.Cfg.GetBool("templateMetrics") { d.Metrics = metrics.NewProvider(cfg.Cfg.GetBool("templateMetricsHints")) } return d, nil } // ForLanguage creates a copy of the Deps with the language dependent // parts switched out. func (d Deps) ForLanguage(cfg DepsCfg, onCreated func(d *Deps) error) (*Deps, error) { l := cfg.Language var err error d.PathSpec, err = helpers.NewPathSpecWithBaseBaseFsProvided(d.Fs, l, d.Log, d.BaseFs) if err != nil { return nil, err } d.ContentSpec, err = helpers.NewContentSpec(l, d.Log, d.BaseFs.Content.Fs) if err != nil { return nil, err } d.Site = cfg.Site // The resource cache is global so reuse. // TODO(bep) clean up these inits. resourceCache := d.ResourceSpec.ResourceCache d.ResourceSpec, err = resources.NewSpec(d.PathSpec, d.ResourceSpec.FileCaches, d.Log, d.globalErrHandler, cfg.OutputFormats, cfg.MediaTypes) if err != nil { return nil, err } d.ResourceSpec.ResourceCache = resourceCache d.Cfg = l d.Language = l if onCreated != nil { if err = onCreated(&d); err != nil { return nil, err } } if err := d.translationProvider.Clone(&d); err != nil { return nil, err } if err := d.templateProvider.Clone(&d); err != nil { return nil, err } d.BuildStartListeners = &Listeners{} return &d, nil } // DepsCfg contains configuration options that can be used to configure Hugo // on a global level, i.e. logging etc. // Nil values will be given default values. type DepsCfg struct { // The Logger to use. Logger *loggers.Logger // The file systems to use Fs *hugofs.Fs // The language to use. Language *langs.Language // The Site in use Site page.Site // The configuration to use. Cfg config.Provider // The media types configured. MediaTypes media.Types // The output formats configured. OutputFormats output.Formats // Template handling. TemplateProvider ResourceProvider WithTemplate func(templ tpl.TemplateManager) error // Used in tests OverloadedTemplateFuncs map[string]interface{} // i18n handling. TranslationProvider ResourceProvider // Whether we are in running (server) mode Running bool } // BuildFlags are flags that may be turned on during a build. type BuildFlags struct { } func NewBuildFlags() BuildFlags { return BuildFlags{} } hugo-0.68.3/deps/deps_test.go000066400000000000000000000012551363637351300160430ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package deps import ( "testing" ) func TestBuildFlags(t *testing.T) { } hugo-0.68.3/docs/000077500000000000000000000000001363637351300135145ustar00rootroot00000000000000hugo-0.68.3/docs/.editorconfig000066400000000000000000000004131363637351300161670ustar00rootroot00000000000000# https://editorconfig.org root = true [*] charset = utf-8 end_of_line = lf indent_size = 2 indent_style = space trim_trailing_whitespace = true [*.go] indent_size = 8 indent_style = tab [*.js] insert_final_newline = true [*.md] trim_trailing_whitespace = false hugo-0.68.3/docs/.github/000077500000000000000000000000001363637351300150545ustar00rootroot00000000000000hugo-0.68.3/docs/.github/stale.yml000066400000000000000000000016001363637351300167040ustar00rootroot00000000000000# Number of days of inactivity before an issue becomes stale daysUntilStale: 120 # Number of days of inactivity before a stale issue is closed daysUntilClose: 30 # Issues with these labels will never be considered stale exemptLabels: - Keep - Security - UndocumentedFeature # Label to use when marking an issue as stale staleLabel: Stale # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > This issue has been automatically marked as stale because it has not had recent activity. The resources of the Hugo team are limited, and so we are asking for your help. If you still think this is important, please tell us why. This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions. # Comment to post when closing a stale issue. Set to `false` to disable closeComment: false hugo-0.68.3/docs/.github/workflows/000077500000000000000000000000001363637351300171115ustar00rootroot00000000000000hugo-0.68.3/docs/.github/workflows/calibreapp-image-actions.yml000066400000000000000000000005041363637351300244530ustar00rootroot00000000000000name: Compress images on: pull_request jobs: build: name: calibreapp/image-actions runs-on: ubuntu-latest steps: - uses: actions/checkout@master - name: calibreapp/image-actions uses: docker://calibreapp/github-image-actions env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} hugo-0.68.3/docs/.gitignore000066400000000000000000000000541363637351300155030ustar00rootroot00000000000000/.idea /public nohup.out .DS_Store trace.outhugo-0.68.3/docs/LICENSE.md000066400000000000000000000243601363637351300151250ustar00rootroot00000000000000Apache License ============== _Version 2.0, January 2004_ _<>_ ### Terms and Conditions for use, reproduction, and distribution #### 1. Definitions “License” shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. “Licensor” shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. “Legal Entity” shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, “control” means **(i)** the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the outstanding shares, or **(iii)** beneficial ownership of such entity. “You” (or “Your”) shall mean an individual or Legal Entity exercising permissions granted by this License. “Source” form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. “Object” form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. “Work” shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). “Derivative Works” shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. “Contribution” shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, “submitted” means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as “Not a Contribution.” “Contributor” shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. #### 2. Grant of Copyright License Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. #### 3. Grant of Patent License Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. #### 4. Redistribution You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: * **(a)** You must give any other recipients of the Work or Derivative Works a copy of this License; and * **(b)** You must cause any modified files to carry prominent notices stating that You changed the files; and * **(c)** You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and * **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. #### 5. Submission of Contributions Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. #### 6. Trademarks This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. #### 7. Disclaimer of Warranty Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. #### 8. Limitation of Liability In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. #### 9. Accepting Warranty or Additional Liability While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. _END OF TERMS AND CONDITIONS_ ### APPENDIX: How to apply the Apache License to your work To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets `[]` replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same “printed page” as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. hugo-0.68.3/docs/README.md000066400000000000000000000054031363637351300147750ustar00rootroot00000000000000[![Netlify Status](https://api.netlify.com/api/v1/badges/e0dbbfc7-34f1-4393-a679-c16e80162705/deploy-status)](https://app.netlify.com/sites/gohugoio/deploys) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://gohugo.io/contribute/documentation/) # Hugo Docs Documentation site for [Hugo](https://github.com/gohugoio/hugo), the very fast and flexible static site generator built with love in Go. ## Contributing We welcome contributions to Hugo of any kind including documentation, suggestions, bug reports, pull requests etc. Also check out our [contribution guide](https://gohugo.io/contribute/documentation/). We would love to hear from you. Note that this repository contains solely the documentation for Hugo. For contributions that aren't documentation-related please refer to the [hugo](https://github.com/gohugoio/hugo) repository. *Pull requests shall **only** contain changes to the actual documentation. However, changes on the code base of Hugo **and** the documentation shall be a single, atomic pull request in the [hugo](https://github.com/gohugoio/hugo) repository.* Spelling fixes are most welcomed, and if you want to contribute longer sections to the documentation, it would be great if you had the following criteria in mind when writing: * Short is good. People go to the library to read novels. If there is more than one way to _do a thing_ in Hugo, describe the current _best practice_ (avoid "… but you can also do …" and "… in older versions of Hugo you had to …". * For example, try to find short snippets that teaches people about the concept. If the example is also useful as-is (copy and paste), then great. Don't list long and similar examples just so people can use them on their sites. * Hugo has users from all over the world, so easy to understand and [simple English](https://simple.wikipedia.org/wiki/Basic_English) is good. ## Branches * The `master` branch is where the site is automatically built from, and is the place to put changes relevant to the current Hugo version. * The `next` branch is where we store changes that are related to the next Hugo release. This can be previewed here: https://next--gohugoio.netlify.com/ ## Build To view the documentation site locally, you need to clone this repository: ```bash git clone https://github.com/gohugoio/hugoDocs.git ``` Also note that the documentation version for a given version of Hugo can also be found in the `/docs` sub-folder of the [Hugo source repository](https://github.com/gohugoio/hugo). Then to view the docs in your browser, run Hugo and open up the link: ```bash ▶ hugo server Started building sites ... . . Serving pages from memory Web Server is available at http://localhost:1313/ (bind address 127.0.0.1) Press Ctrl+C to stop ``` hugo-0.68.3/docs/_vendor/000077500000000000000000000000001363637351300151505ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/000077500000000000000000000000001363637351300172075ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/000077500000000000000000000000001363637351300210275ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/000077500000000000000000000000001363637351300236325ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/000077500000000000000000000000001363637351300251345ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/000077500000000000000000000000001363637351300257245ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_algolia.css000066400000000000000000000454051363637351300302150ustar00rootroot00000000000000.searchbox{display:inline-block;position:relative;width:200px;height:32px!important;white-space:nowrap;box-sizing:border-box;visibility:visible!important}.searchbox .algolia-autocomplete{display:block;width:100%;height:100%}.searchbox__wrapper{width:100%;height:100%;z-index:999;position:relative}.searchbox__input{display:inline-block;box-sizing:border-box;transition:box-shadow .4s ease,background .4s ease;border:0;border-radius:16px;box-shadow:inset 0 0 0 1px #ccc;background:#fff!important;padding:0 26px 0 32px;width:100%;height:100%;vertical-align:middle;white-space:normal;font-size:12px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbox__input::-webkit-search-cancel-button,.searchbox__input::-webkit-search-decoration,.searchbox__input::-webkit-search-results-button,.searchbox__input::-webkit-search-results-decoration{display:none}.searchbox__input:hover{box-shadow:inset 0 0 0 1px #b3b3b3}.searchbox__input:active,.searchbox__input:focus{outline:0;box-shadow:inset 0 0 0 1px #aaa;background:#fff}.searchbox__input::-webkit-input-placeholder{color:#aaa}.searchbox__input:-ms-input-placeholder{color:#aaa}.searchbox__input::-ms-input-placeholder{color:#aaa}.searchbox__input::placeholder{color:#aaa}.searchbox__submit{position:absolute;top:0;margin:0;border:0;border-radius:16px 0 0 16px;background-color:rgba(69,142,225,0);padding:0;width:32px;height:100%;vertical-align:middle;text-align:center;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;right:inherit;left:0}.searchbox__submit:before{display:inline-block;margin-right:-4px;height:100%;vertical-align:middle;content:""}.searchbox__submit:active,.searchbox__submit:hover{cursor:pointer}.searchbox__submit:focus{outline:0}.searchbox__submit svg{width:14px;height:14px;vertical-align:middle;fill:#6d7e96}.searchbox__reset{display:block;position:absolute;top:8px;right:8px;margin:0;border:0;background:none;cursor:pointer;padding:0;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;fill:rgba(0,0,0,.5)}.searchbox__reset.hide{display:none}.searchbox__reset:focus{outline:0}.searchbox__reset svg{display:block;margin:4px;width:8px;height:8px}.searchbox__input:valid~.searchbox__reset{display:block;-webkit-animation-name:sbx-reset-in;animation-name:sbx-reset-in;-webkit-animation-duration:.15s;animation-duration:.15s}@-webkit-keyframes sbx-reset-in{0%{-webkit-transform:translate3d(-20%,0,0);transform:translate3d(-20%,0,0);opacity:0}to{-webkit-transform:none;transform:none;opacity:1}}@keyframes sbx-reset-in{0%{-webkit-transform:translate3d(-20%,0,0);transform:translate3d(-20%,0,0);opacity:0}to{-webkit-transform:none;transform:none;opacity:1}}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu{right:0!important;left:inherit!important}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu:before{right:48px}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu{left:0!important;right:inherit!important}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu:before{left:48px}.algolia-autocomplete .ds-dropdown-menu{top:-6px;border-radius:4px;margin:6px 0 0;padding:0;text-align:left;height:auto;position:relative;background:transparent;border:none;z-index:999;max-width:600px;min-width:500px;box-shadow:0 1px 0 0 rgba(0,0,0,.2),0 2px 3px 0 rgba(0,0,0,.1)}.algolia-autocomplete .ds-dropdown-menu:before{display:block;position:absolute;content:"";width:14px;height:14px;background:#fff;z-index:1000;top:-7px;border-top:1px solid #d9d9d9;border-right:1px solid #d9d9d9;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);border-radius:2px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions{position:relative;z-index:1000;margin-top:8px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions a:hover{text-decoration:none}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion{cursor:pointer}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion.suggestion-layout-simple,.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion:not(.suggestion-layout-simple) .algolia-docsearch-suggestion--content{background-color:rgba(69,142,225,.05)}.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{position:relative;border:1px solid #d9d9d9;background:#fff;border-radius:4px;overflow:auto;padding:0 8px 8px}.algolia-autocomplete .ds-dropdown-menu *{box-sizing:border-box}.algolia-autocomplete .algolia-docsearch-suggestion{display:block;position:relative;padding:0 8px;background:#fff;color:#02060c;overflow:hidden}.algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#174d8c;background:rgba(143,187,237,.1);padding:.1em .05em}.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl0 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl1 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{padding:0 0 1px;background:inherit;box-shadow:inset 0 -2px 0 0 rgba(69,142,225,.8);color:inherit}.algolia-autocomplete .algolia-docsearch-suggestion--content{display:block;float:right;width:70%;position:relative;padding:5.33333px 0 5.33333px 10.66667px;cursor:pointer}.algolia-autocomplete .algolia-docsearch-suggestion--content:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;left:-1px}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{position:relative;border-bottom:1px solid #ddd;display:none;margin-top:8px;padding:4px 0;font-size:1em;color:#33363d}.algolia-autocomplete .algolia-docsearch-suggestion--wrapper{width:100%;float:left;padding:8px 0 0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{float:left;width:30%;text-align:right;position:relative;padding:5.33333px 10.66667px;color:#a4a7ae;font-size:.9em;word-wrap:break-word}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;right:0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline{display:none}.algolia-autocomplete .algolia-docsearch-suggestion--title{margin-bottom:4px;color:#02060c;font-size:.9em;font-weight:700}.algolia-autocomplete .algolia-docsearch-suggestion--text{display:block;line-height:1.2em;font-size:.85em;color:#63676d}.algolia-autocomplete .algolia-docsearch-suggestion--no-results{width:100%;padding:8px 0;text-align:center;font-size:1.2em}.algolia-autocomplete .algolia-docsearch-suggestion--no-results:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion code{padding:1px 5px;font-size:90%;border:none;color:#222;background-color:#ebebeb;border-radius:3px;font-family:Menlo,Monaco,Consolas,Courier New,monospace}.algolia-autocomplete .algolia-docsearch-suggestion code .algolia-docsearch-suggestion--highlight{background:none}.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--category-header,.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__secondary{display:block}@media (min-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:block}}@media (max-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:inline-block;width:auto;float:left;padding:0;color:#02060c;font-size:.9em;font-weight:700;text-align:left;opacity:.5}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{content:"|"}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{display:inline-block;width:auto;text-align:left;float:left;padding:0}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content:before{display:none}}.algolia-autocomplete .suggestion-layout-simple.algolia-docsearch-suggestion{border-bottom:1px solid #eee;padding:8px;margin:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content{width:100%;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content:before{display:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header{margin:0;padding:0;display:block;width:100%;border:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl0,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1{opacity:.6;font-size:.85em}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1:before{background-image:url('data:image/svg+xml;utf8,');content:"";width:10px;height:10px;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--wrapper{width:100%;float:left;margin:0;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--duplicate-content,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--subcategory-inline{display:none!important}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title{margin:0;color:#458ee1;font-size:.9em;font-weight:400}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title:before{content:"#";font-weight:700;color:#458ee1;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text{margin:4px 0 0;display:block;line-height:1.4em;padding:5.33333px 8px;background:#f8f8f8;font-size:.85em;opacity:.8}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{color:#3f4145;font-weight:700;box-shadow:none}.algolia-autocomplete .algolia-docsearch-footer{width:134px;height:20px;z-index:2000;margin-top:10.66667px;float:right;font-size:0;line-height:0}.algolia-autocomplete .algolia-docsearch-footer--logo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='168' height='24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath d='M78.988.938h16.594a2.968 2.968 0 0 1 2.966 2.966V20.5a2.967 2.967 0 0 1-2.966 2.964H78.988a2.967 2.967 0 0 1-2.966-2.964V3.897A2.961 2.961 0 0 1 78.988.938zm41.937 17.866c-4.386.02-4.386-3.54-4.386-4.106l-.007-13.336 2.675-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-10.846-2.18c.821 0 1.43-.047 1.855-.129v-2.719a6.334 6.334 0 0 0-1.574-.199 5.7 5.7 0 0 0-.897.069 2.699 2.699 0 0 0-.814.24c-.24.116-.439.28-.582.491-.15.212-.219.335-.219.656 0 .628.219.991.616 1.23s.938.362 1.615.362zm-.233-9.7c.883 0 1.629.109 2.231.328.602.218 1.088.525 1.444.915.363.396.609.922.76 1.483.157.56.232 1.175.232 1.85v6.874a32.5 32.5 0 0 1-1.868.314c-.834.123-1.772.185-2.813.185-.69 0-1.327-.069-1.895-.198a4.001 4.001 0 0 1-1.471-.636 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.803 0-.656.13-1.073.384-1.525a3.24 3.24 0 0 1 1.047-1.106c.445-.287.95-.492 1.532-.615a8.8 8.8 0 0 1 1.82-.185 8.404 8.404 0 0 1 1.972.24v-.438c0-.307-.035-.6-.11-.874a1.88 1.88 0 0 0-.384-.73 1.784 1.784 0 0 0-.724-.493 3.164 3.164 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.735 7.735 0 0 0-1.26.307l-.321-2.192c.335-.117.834-.233 1.478-.349a10.98 10.98 0 0 1 2.073-.178zm52.842 9.626c.822 0 1.43-.048 1.854-.13V13.7a6.347 6.347 0 0 0-1.574-.199c-.294 0-.595.021-.896.069a2.7 2.7 0 0 0-.814.24 1.46 1.46 0 0 0-.582.491c-.15.212-.218.335-.218.656 0 .628.218.991.615 1.23.404.245.938.362 1.615.362zm-.226-9.694c.883 0 1.629.108 2.231.327.602.219 1.088.526 1.444.915.355.39.609.923.759 1.483a6.8 6.8 0 0 1 .233 1.852v6.873c-.41.088-1.034.19-1.868.314-.834.123-1.772.184-2.813.184-.69 0-1.327-.068-1.895-.198a4.001 4.001 0 0 1-1.471-.635 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.804 0-.656.13-1.073.384-1.524.26-.45.608-.82 1.047-1.107.445-.286.95-.491 1.532-.614a8.803 8.803 0 0 1 2.751-.13c.329.034.671.096 1.04.185v-.437a3.3 3.3 0 0 0-.109-.875 1.873 1.873 0 0 0-.384-.731 1.784 1.784 0 0 0-.724-.492 3.165 3.165 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.75 7.75 0 0 0-1.26.307l-.321-2.193c.335-.116.834-.232 1.478-.348a11.633 11.633 0 0 1 2.073-.177zm-8.034-1.271a1.626 1.626 0 0 1-1.628-1.62c0-.895.725-1.62 1.628-1.62.904 0 1.63.725 1.63 1.62 0 .895-.733 1.62-1.63 1.62zm1.348 13.22h-2.689V7.27l2.69-.423v11.956zm-4.714 0c-4.386.02-4.386-3.54-4.386-4.107l-.008-13.336 2.676-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-8.698-5.903c0-1.156-.253-2.119-.746-2.788-.493-.677-1.183-1.01-2.067-1.01-.882 0-1.574.333-2.065 1.01-.493.676-.733 1.632-.733 2.788 0 1.168.246 1.953.74 2.63.492.683 1.183 1.018 2.066 1.018.882 0 1.574-.342 2.067-1.019.492-.683.738-1.46.738-2.63zm2.737-.007c0 .902-.13 1.584-.397 2.33a5.52 5.52 0 0 1-1.128 1.906 4.986 4.986 0 0 1-1.752 1.223c-.685.286-1.739.45-2.265.45-.528-.006-1.574-.157-2.252-.45a5.096 5.096 0 0 1-1.744-1.223c-.487-.527-.863-1.162-1.137-1.906a6.345 6.345 0 0 1-.41-2.33c0-.902.123-1.77.397-2.508a5.554 5.554 0 0 1 1.15-1.892 5.133 5.133 0 0 1 1.75-1.216c.679-.287 1.425-.423 2.232-.423.808 0 1.553.142 2.237.423a4.88 4.88 0 0 1 1.753 1.216 5.644 5.644 0 0 1 1.135 1.892c.287.738.431 1.606.431 2.508zm-20.138 0c0 1.12.246 2.363.738 2.882.493.52 1.13.78 1.91.78.424 0 .828-.062 1.204-.178.377-.116.677-.253.917-.417V9.33a10.476 10.476 0 0 0-1.766-.226c-.971-.028-1.71.37-2.23 1.004-.513.636-.773 1.75-.773 2.788zm7.438 5.274c0 1.824-.466 3.156-1.404 4.004-.936.846-2.367 1.27-4.296 1.27-.705 0-2.17-.137-3.34-.396l.431-2.118c.98.205 2.272.26 2.95.26 1.074 0 1.84-.219 2.299-.656.459-.437.684-1.086.684-1.948v-.437a8.07 8.07 0 0 1-1.047.397c-.43.13-.93.198-1.492.198-.739 0-1.41-.116-2.018-.349a4.206 4.206 0 0 1-1.567-1.025c-.431-.45-.774-1.017-1.013-1.694-.24-.677-.363-1.885-.363-2.773 0-.834.13-1.88.384-2.577.26-.696.629-1.298 1.129-1.796.493-.498 1.095-.881 1.8-1.162a6.605 6.605 0 0 1 2.428-.457c.87 0 1.67.109 2.45.24.78.129 1.444.265 1.985.415V18.17z' fill='%235468FF'/%3E%3Cpath d='M6.972 6.677v1.627c-.712-.446-1.52-.67-2.425-.67-.585 0-1.045.13-1.38.391a1.24 1.24 0 0 0-.502 1.03c0 .425.164.765.494 1.02.33.256.835.532 1.516.83.447.192.795.356 1.045.495.25.138.537.332.862.582.324.25.563.548.718.894.154.345.23.741.23 1.188 0 .947-.334 1.691-1.004 2.234-.67.542-1.537.814-2.601.814-1.18 0-2.16-.229-2.936-.686v-1.708c.84.628 1.814.942 2.92.942.585 0 1.048-.136 1.388-.407.34-.271.51-.646.51-1.125 0-.287-.1-.55-.302-.79-.203-.24-.42-.42-.655-.542-.234-.123-.585-.29-1.053-.503a61.27 61.27 0 0 1-.582-.271 13.67 13.67 0 0 1-.55-.287 4.275 4.275 0 0 1-.567-.351 6.92 6.92 0 0 1-.455-.4c-.18-.17-.31-.34-.39-.51-.08-.17-.155-.37-.224-.598a2.553 2.553 0 0 1-.104-.742c0-.915.333-1.638.998-2.17.664-.532 1.523-.798 2.576-.798.968 0 1.793.17 2.473.51zm7.468 5.696v-.287c-.022-.607-.187-1.088-.495-1.444-.309-.357-.75-.535-1.324-.535-.532 0-.99.194-1.373.583-.382.388-.622.949-.717 1.683h3.909zm1.005 2.792v1.404c-.596.34-1.383.51-2.362.51-1.255 0-2.255-.377-3-1.132-.744-.755-1.116-1.744-1.116-2.968 0-1.297.34-2.316 1.021-3.055.68-.74 1.548-1.11 2.6-1.11 1.033 0 1.852.323 2.458.966.606.644.91 1.572.91 2.784 0 .33-.033.676-.096 1.038h-5.314c.107.702.405 1.239.894 1.611.49.372 1.106.558 1.85.558.862 0 1.58-.202 2.155-.606zm6.605-1.77h-1.212c-.596 0-1.045.116-1.349.35-.303.234-.454.532-.454.894 0 .372.117.664.35.877.235.213.575.32 1.022.32.51 0 .912-.142 1.204-.424.293-.281.44-.651.44-1.108v-.91zm-4.068-2.554V9.325c.627-.361 1.457-.542 2.489-.542 2.116 0 3.175 1.026 3.175 3.08V17h-1.548v-.957c-.415.68-1.143 1.02-2.186 1.02-.766 0-1.38-.22-1.843-.661-.462-.442-.694-1.003-.694-1.684 0-.776.293-1.38.878-1.81.585-.431 1.404-.647 2.457-.647h1.34V11.8c0-.554-.133-.971-.399-1.253-.266-.282-.707-.423-1.324-.423a4.07 4.07 0 0 0-2.345.718zm9.333-1.93v1.42c.394-1 1.101-1.5 2.123-1.5.148 0 .313.016.494.048v1.531a1.885 1.885 0 0 0-.75-.143c-.542 0-.989.24-1.34.718-.351.479-.527 1.048-.527 1.707V17h-1.563V8.91h1.563zm5.01 4.084c.022.82.272 1.492.75 2.019.479.526 1.15.79 2.01.79.639 0 1.235-.176 1.788-.527v1.404c-.521.319-1.186.479-1.995.479-1.265 0-2.276-.4-3.031-1.197-.755-.798-1.133-1.792-1.133-2.984 0-1.16.38-2.151 1.14-2.975.761-.825 1.79-1.237 3.088-1.237.702 0 1.346.149 1.93.447v1.436a3.242 3.242 0 0 0-1.77-.495c-.84 0-1.513.266-2.019.798-.505.532-.758 1.213-.758 2.042zM40.24 5.72v4.579c.458-1 1.293-1.5 2.505-1.5.787 0 1.42.245 1.899.734.479.49.718 1.17.718 2.042V17h-1.564v-5.106c0-.553-.14-.98-.422-1.284-.282-.303-.652-.455-1.11-.455-.531 0-1.002.202-1.411.606-.41.405-.615 1.022-.615 1.851V17h-1.563V5.72h1.563zm14.966 10.02c.596 0 1.096-.253 1.5-.758.404-.506.606-1.157.606-1.955 0-.915-.202-1.62-.606-2.114-.404-.495-.92-.742-1.548-.742-.553 0-1.05.224-1.491.67-.442.447-.662 1.133-.662 2.058 0 .958.212 1.67.638 2.138.425.469.946.703 1.563.703zM53.004 5.72v4.42c.574-.894 1.388-1.341 2.44-1.341 1.022 0 1.857.383 2.506 1.149.649.766.973 1.781.973 3.047 0 1.138-.309 2.109-.925 2.912-.617.803-1.463 1.205-2.537 1.205-1.075 0-1.894-.447-2.457-1.34V17h-1.58V5.72h1.58zm9.908 11.104l-3.223-7.913h1.739l1.005 2.632 1.26 3.415c.096-.32.48-1.458 1.15-3.415l.909-2.632h1.66l-2.92 7.866c-.777 2.074-1.963 3.11-3.559 3.11a2.92 2.92 0 0 1-.734-.079v-1.34c.17.042.351.064.543.064 1.032 0 1.755-.57 2.17-1.708z' fill='%235D6494'/%3E%3Cpath d='M89.632 5.967v-.772a.978.978 0 0 0-.978-.977h-2.28a.978.978 0 0 0-.978.977v.793c0 .088.082.15.171.13a7.127 7.127 0 0 1 1.984-.28c.65 0 1.295.088 1.917.259.082.02.164-.04.164-.13m-6.248 1.01l-.39-.389a.977.977 0 0 0-1.382 0l-.465.465a.973.973 0 0 0 0 1.38l.383.383c.062.061.15.047.205-.014.226-.307.472-.601.746-.874.281-.28.568-.526.883-.751.068-.042.075-.137.02-.2m4.16 2.453v3.341c0 .096.104.165.192.117l2.97-1.537c.068-.034.089-.117.055-.184a3.695 3.695 0 0 0-3.08-1.866c-.068 0-.136.054-.136.13m0 8.048a4.489 4.489 0 0 1-4.49-4.482 4.488 4.488 0 0 1 4.49-4.482 4.488 4.488 0 0 1 4.489 4.482 4.484 4.484 0 0 1-4.49 4.482m0-10.85a6.363 6.363 0 1 0 0 12.729 6.37 6.37 0 0 0 6.372-6.368 6.358 6.358 0 0 0-6.371-6.36' fill='%23FFF'/%3E%3C/g%3E%3C/svg%3E");background-repeat:no-repeat;background-position:50%;background-size:100%;overflow:hidden;text-indent:-9000px;padding:0!important;width:100%;height:100%;display:block} /*# sourceMappingURL=docsearch.min.css.map */ a.algolia-docsearch-suggestion { text-decoration: none !important; } .algolia-docsearch-suggestion--category-header { background: #0594cb; padding-left: .25rem !important; color: white !important; border-radius: 3px; } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_anchorforid.css000066400000000000000000000005061363637351300310740ustar00rootroot00000000000000 .header-link:after { position: relative; left: 0.5em; opacity: 0; font-size: 0.8em; -moz-transition: opacity 0.2s ease-in-out 0.1s; -ms-transition: opacity 0.2s ease-in-out 0.1s; } h2:hover .header-link, h3:hover .header-link, h4:hover .header-link, h5:hover .header-link, h6:hover .header-link { opacity: 1; } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_animation.css000066400000000000000000000004311363637351300305520ustar00rootroot00000000000000.animated { animation-duration: .5s; animation-fill-mode: forwards; animation-timing-function: ease-in-out; } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .fadeIn { animation-name: fadeIn; } .animated-delay-1 { animation-delay: 0.5s; } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_carousel.css000066400000000000000000000011651363637351300304150ustar00rootroot00000000000000/* These styles enhance the home page carousel, located here: themes/gohugoioTheme/layouts/partials/home-page-sections/showcase.html */ .overflow-x-scroll{ -webkit-overflow-scrolling: touch; } .row { transition: 450ms transform; font-size: 0; } .tile { transition: 450ms all; } .details { background: -webkit-gradient(linear, left bottom, left top, from(rgba(0,0,0,0.9)), to(rgba(0,0,0,0))); background: linear-gradient(to top, rgba(0,0,0,0.9) 0%, rgba(0,0,0,0) 100%); transition: 450ms opacity; } .tile:hover .details { opacity: 1; } .row:hover .tile { opacity: 0.3; } .row:hover .tile:hover { opacity: 1; } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_chroma.css000066400000000000000000000076221363637351300300550ustar00rootroot00000000000000/* Background */ .chroma { background-color: #ffffff } /* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2 } /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block; } /* LineHighlight */ .chroma .hl { display: block; width: 100%;background-color: #ffffcc } /* LineNumbersTable */ .chroma .lnt { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; } /* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; } /* Keyword */ .chroma .k { font-weight: bold } /* KeywordConstant */ .chroma .kc { font-weight: bold } /* KeywordDeclaration */ .chroma .kd { font-weight: bold } /* KeywordNamespace */ .chroma .kn { font-weight: bold } /* KeywordPseudo */ .chroma .kp { font-weight: bold } /* KeywordReserved */ .chroma .kr { font-weight: bold } /* KeywordType */ .chroma .kt { color: #445588; font-weight: bold } /* NameAttribute */ .chroma .na { color: #008080 } /* NameBuiltin */ .chroma .nb { color: #999999 } /* NameClass */ .chroma .nc { color: #445588; font-weight: bold } /* NameConstant */ .chroma .no { color: #008080 } /* NameEntity */ .chroma .ni { color: #800080 } /* NameException */ .chroma .ne { color: #990000; font-weight: bold } /* NameFunction */ .chroma .nf { color: #990000; font-weight: bold } /* NameNamespace */ .chroma .nn { color: #555555 } /* NameTag */ .chroma .nt { color: #000080 } /* NameVariable */ .chroma .nv { color: #008080 } /* LiteralString */ .chroma .s { color: #bb8844 } /* LiteralStringAffix */ .chroma .sa { color: #bb8844 } /* LiteralStringBacktick */ .chroma .sb { color: #bb8844 } /* LiteralStringChar */ .chroma .sc { color: #bb8844 } /* LiteralStringDelimiter */ .chroma .dl { color: #bb8844 } /* LiteralStringDoc */ .chroma .sd { color: #bb8844 } /* LiteralStringDouble */ .chroma .s2 { color: #bb8844 } /* LiteralStringEscape */ .chroma .se { color: #bb8844 } /* LiteralStringHeredoc */ .chroma .sh { color: #bb8844 } /* LiteralStringInterpol */ .chroma .si { color: #bb8844 } /* LiteralStringOther */ .chroma .sx { color: #bb8844 } /* LiteralStringRegex */ .chroma .sr { color: #808000 } /* LiteralStringSingle */ .chroma .s1 { color: #bb8844 } /* LiteralStringSymbol */ .chroma .ss { color: #bb8844 } /* LiteralNumber */ .chroma .m { color: #009999 } /* LiteralNumberBin */ .chroma .mb { color: #009999 } /* LiteralNumberFloat */ .chroma .mf { color: #009999 } /* LiteralNumberHex */ .chroma .mh { color: #009999 } /* LiteralNumberInteger */ .chroma .mi { color: #009999 } /* LiteralNumberIntegerLong */ .chroma .il { color: #009999 } /* LiteralNumberOct */ .chroma .mo { color: #009999 } /* Operator */ .chroma .o { font-weight: bold } /* OperatorWord */ .chroma .ow { font-weight: bold } /* Comment */ .chroma .c { color: #999988; font-style: italic } /* CommentHashbang */ .chroma .ch { color: #999988; font-style: italic } /* CommentMultiline */ .chroma .cm { color: #999988; font-style: italic } /* CommentSingle */ .chroma .c1 { color: #999988; font-style: italic } /* CommentSpecial */ .chroma .cs { color: #999999; font-weight: bold; font-style: italic } /* CommentPreproc */ .chroma .cp { color: #999999; font-weight: bold } /* CommentPreprocFile */ .chroma .cpf { color: #999999; font-weight: bold } /* GenericDeleted */ .chroma .gd { color: #000000; background-color: #ffdddd } /* GenericEmph */ .chroma .ge { font-style: italic } /* GenericError */ .chroma .gr { color: #aa0000 } /* GenericHeading */ .chroma .gh { color: #999999 } /* GenericInserted */ .chroma .gi { color: #000000; background-color: #ddffdd } /* GenericOutput */ .chroma .go { color: #888888 } /* GenericPrompt */ .chroma .gp { color: #555555 } /* GenericStrong */ .chroma .gs { font-weight: bold } /* GenericSubheading */ .chroma .gu { color: #aaaaaa } /* GenericTraceback */ .chroma .gt { color: #aa0000 } /* TextWhitespace */ .chroma .w { color: #bbbbbb } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_code.css000066400000000000000000000030671363637351300275150ustar00rootroot00000000000000.chroma .lntable pre { padding: 0; margin: 0; border: 0; } .chroma .lntable pre code { padding: 0; margin: 0; } pre, .pre { overflow-x: auto; overflow-y: hidden; overflow: scroll; } code { padding: 0.2em; margin: 0; font-size: 85%; background-color: rgba(27,31,35,0.05); border-radius: 3px; } pre code { display: block; padding: 1.5em 1.5em; font-size: .875rem; line-height: 2; overflow-x: auto; } pre { background-color: #fff; color: #333; white-space: pre; hyphens: none; position: relative; border-width: 1px; border-color: #ccc; border-style: solid; } /* The Pygments highlighter comes with its own styles. */ .highlight pre { background-color: inherit; color: inherit; padding: 0.5em; font-size: .875rem; } /*We are adding the copy button content here so we can change it with javascript. See the "Clipboard scripts"*/ .copy:after { content: "Copy" } .copied:after { content: "Copied" } @media (--breakpoint-large) { .full-width, pre.expand:hover { /*width: 100vw; position: relative; left: 50%; right: 50%; margin-left: -50vw; margin-right: -50vw;*/ /*width: 60vw;*/ /*position: relative; left: 50%; right: 50%;*/ /*margin-left: -30vw;*/ margin-right: -30vw; max-width: 100vw; } } .code-block .line-numbers-rows { background: #2f3a46; border: none; bottom: -50px; color: #98a4b3; left: -178px; padding: 50px 0; top: -50px; width: 138px } .code-block .line-numbers-rows>span:before { color: inherit; padding-right: 30px } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_color-scheme.css000066400000000000000000000035731363637351300311650ustar00rootroot00000000000000.primary-color {color: var(--primary-color)} .bg-primary-color {background-color: var(--primary-color)} .hover-bg-primary-color:hover {background-color: var(--primary-color)} .primary-color-dark {color: var(--primary-color-dark)} .bg-primary-color-dark {background-color: var(--primary-color-dark)} .hover-bg-primary-color-dark:hover {background-color: var(--primary-color-dark)} .primary-color-light {color: var(--primary-color-light)} .bg-primary-color-light {background-color: var(--primary-color-light)} .hover-bg-primary-color-light:hover {background-color: var(--primary-color-light)} .accent-color {color: var(--accent-color)} .bg-accent-color {background-color: var(--accent-color)} .hover-bg-accent-color:hover {background-color: var(--accent-color)} .accent-color-light {color: var(--accent-color-light)} .hover-accent-color-light:hover {color: var(--accent-color-light)} .bg-accent-color-light {background-color: var(--accent-color-light)} .hover-bg-accent-color-light:hover {background-color: var(--accent-color-light)} .accent-color-dark {color: var(--accent-color-dark)} .bg-accent-color-dark {background-color: var(--accent-color-dark)} .hover-bg-accent-color-dark:hover {background-color: var(--accent-color-dark)} .text-color-primary {color: var(--text-color-primary)} .text-on-primary-color {color: var(--text-on-primary-color)} .text-color-secondary {color: var(--text-color-secondary)} .text-color-disabled {color: var(--text-color-disabled)} .divider-color {color: var(--divider-color)} .warn-color {color: var(--warn-color)} .nested-links a { color: var(--primary-color); text-decoration: none; } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_columns.css000066400000000000000000000004471363637351300302620ustar00rootroot00000000000000.column-count-2 {column-count: 1} .column-gap-1 {column-gap: 0} .break-inside-avoid {break-inside: auto} @media (--breakpoint-large) { .column-count-3-l {column-count: 3} .column-count-2-l {column-count: 2} .column-gap-1-l {column-gap: 1} .break-inside-avoid-l {break-inside: avoid} } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_content-tables.css000066400000000000000000000011231363637351300315140ustar00rootroot00000000000000.prose table { width: 100%; margin-bottom: 3em; border-collapse: collapse; border-spacing: 0; font-size: 1em; border: 1px solid var(--light-gray); & th { background-color: var(--primary-color); border-bottom: 1px solid var(--primary-color); color: white; font-weight: 400; text-align: left; padding: .375em .5em; } & td, & tc { padding: .75em .5em; text-align: left; border-right: 1px solid var(--light-gray); } } .prose table tr:nth-child(even) { background-color: var(--light-gray); } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_content.css000066400000000000000000000010421363637351300302440ustar00rootroot00000000000000.prose ul, .prose ol { margin-bottom: 2em; } .prose ul li, .prose ol li { margin-bottom: .5em; } .prose li:hover { background-color: var(--light-gray) } .prose ::selection { background: var(--primary-color); /* WebKit/Blink Browsers */ color: white; } body { line-height: 1.45; } p {margin-bottom: 1.3em;} h1, h2, h3, h4 { margin: 1.414em 0 0.5em; line-height: 1.2; } h1 { margin-top: 0; font-size: 2.441em; } h2 {font-size: 1.953em;} h3 {font-size: 1.563em;} h4 {font-size: 1.25em;} small, .font_small {font-size: 0.8em;} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_definition-lists.css000066400000000000000000000001441363637351300320600ustar00rootroot00000000000000 dl dt { font-weight: bold; font-size: 1.125rem; } dd { margin: .5em 0 2em 0; padding: 0; } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_documentation-styles.css000066400000000000000000000017561363637351300330000ustar00rootroot00000000000000.note, .warning { border-left-width: 4px; border-left-style: solid; position: relative; border-color: var(--primary-color); display: block; } .note #exclamation-icon, .warning #exclamation-icon { fill: var(--primary-color); position: absolute; top: 35%; left: -12px; /*background-color: white;*/ } .admonition-content { display: block; margin: 0px; padding: .125em 1em; /*margin-left: 1em;*/ margin-top: 2em; margin-bottom: 2em; overflow-x: auto; /*font-size: .9375em;*/ background-color: var(--black-05); } .hide-child-menu .child-menu { display: none; } .hide-child-menu:hover .child-menu, .hide-child-menu:focus .child-menu, .hide-child-menu:active .child-menu { display: block; } /*documentation-copy headings exaggerate spacing and size to chunk content */ .documentation-copy h2 { margin-top: 3em; &.minor { font-size: inherit; margin-top: inherit; border-bottom: none; } } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_fluid-type.css000066400000000000000000000002551363637351300306610ustar00rootroot00000000000000.f2-fluid { font-size: 2.25rem; } @media (--breakpoint-large) { .f2-fluid { font-size: 1.25rem; font-size: calc(0.875rem + 0.5 * ((100vw - 20rem) / 60)); } } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_font-family.css000066400000000000000000000024021363637351300310200ustar00rootroot00000000000000/* From http://cssfontstack.com */ code, .code, pre code, .highlight pre { font-family: 'inconsolata',Menlo,Monaco,'Courier New',monospace; } .sans-serif { font-family: 'Muli', avenir, 'helvetica neue', helvetica, ubuntu, roboto, noto, 'segoe ui', arial, sans-serif; } .serif { font-family: Palatino,"Palatino Linotype","Palatino LT STD","Book Antiqua",Georgia,serif; } /* Monospaced Typefaces (for code) */ .courier { font-family: 'Courier Next', courier, monospace; } /* Sans-Serif Typefaces */ .helvetica { font-family: 'helvetica neue', helvetica, sans-serif; } .avenir { font-family: 'avenir next', avenir, sans-serif; } /* Serif Typefaces */ .athelas { font-family: athelas, georgia, serif; } .georgia { font-family: georgia, serif; } .times { font-family: times, serif; } .bodoni { font-family: "Bodoni MT", serif; } .calisto { font-family: "Calisto MT", serif; } .garamond { font-family: garamond, serif; } .baskerville { font-family: baskerville, serif; } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_hljs.css000066400000000000000000000003631363637351300275370ustar00rootroot00000000000000/* modified from:*/ @import 'highlight.js/styles/atom-one-light.css'; /* hljs-template-variable covers the handlebars templating*/ .hljs-template-variable { color: var(--primary-color); } .hljs-attr { color: var(--accent-color-light); } _hugo-internal-template-styling.css000066400000000000000000000017051363637351300345750ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/* pagination.html: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/template_embedded.go#L117 */ .pagination { margin: 3rem 0; } .pagination li { display: inline-block; margin-right: .375rem; font-size: .875rem; margin-bottom: 2.5em; } .pagination li a { padding: .5rem .625rem; background-color: white; color: #333; border: 1px solid #ddd; border-radius: 3px; text-decoration: none; } .pagination li.disabled { display: none; } .pagination li.active a:link, .pagination li.active a:active, .pagination li.active a:visited { background-color: #ddd; } /* Hides non-meaningful TOC items*/ #TableOfContents ul li ul li ul li{ display: none; } #TableOfContents ul li { color: black; display: block; margin-bottom: .375em; line-height: 1.375; } #TableOfContents ul li a{ width: 100%; padding: .25em .375em; margin-left: -.375em; } #TableOfContents ul li a:hover { background-color: #999; color: white; } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_no-js.css000066400000000000000000000001461363637351300276240ustar00rootroot00000000000000.no-js .needs-js { opacity: 0 } .js .needs-js { opacity: 1; transition: opacity .15s ease-in; } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_social-icons.css000066400000000000000000000003651363637351300311640ustar00rootroot00000000000000.facebook, .twitter, .instagram, .youtube { fill: #BABABA; } .facebook:hover { fill: #3b5998; } .twitter { fill: #55acee; } .twitter:hover { fill: #BABABA; } .instagram:hover { fill: #e95950; } .youtube:hover { fill: #bb0000; } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_stickyheader.css000066400000000000000000000003221363637351300312510ustar00rootroot00000000000000 @media (min-width: 75em) { [data-scrolldir="down"] .sticky { position: fixed; top:100px; right:0; } [data-scrolldir="up"] .sticky { position: fixed; top:100px; right:0; } } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_svg.css000066400000000000000000000000461363637351300273740ustar00rootroot00000000000000.fill-current { fill: currentColor; } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_tabs.css000066400000000000000000000011721363637351300275270ustar00rootroot00000000000000.tab-button{ margin-bottom:1px; position: relative; z-index: 1; color:#333; border-color:#ccc; outline: none; background-color:white; } .tab-pane code{ background:#f1f2f2; border-radius:0; } .tab-pane .chroma{ background:none; padding:0; } .tab-button.active{ border-bottom-color:#f1f2f2; background-color: #f1f2f2; } .tab-content .tab-pane{ display: none; } .tab-content .tab-pane.active{ display: block; } /* Treatment of copy buttons inside a tab module */ .tab-content .copy, .tab-content .copied{ display: none; } .tab-content .tab-pane.active + .copy, .tab-content .tab-pane.active + .copied{ display: block; }hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_tachyons.css000066400000000000000000000057341363637351300304360ustar00rootroot00000000000000/*! TACHYONS v4.7.0 | http://tachyons.io */ /* * NOTE: The Tachyons folder is for backup/reference only. This file references the module * ________ ______ * ___ __/_____ _________ /______ ______________________ * __ / _ __ `/ ___/_ __ \_ / / / __ \_ __ \_ ___/ * _ / / /_/ // /__ _ / / / /_/ // /_/ / / / /(__ ) * /_/ \__,_/ \___/ /_/ /_/_\__, / \____//_/ /_//____/ * /____/ * * TABLE OF CONTENTS * * 1. External Library Includes * - Normalize.css | http://normalize.css.github.io * 2. Tachyons Modules * 3. Variables * - Media Queries * - Colors * 4. Debugging * - Debug all * - Debug children * */ /* External Library Includes */ @import 'tachyons/src/_normalize'; /* Modules */ @import 'tachyons/src/_box-sizing'; /*@import 'tachyons/src/_aspect-ratios';*/ @import 'tachyons/src/_images'; @import 'tachyons/src/_background-size'; @import 'tachyons/src/_background-position'; /*@import 'tachyons/src/_outlines';*/ @import 'tachyons/src/_borders'; @import 'tachyons/src/_border-colors'; @import 'tachyons/src/_border-radius'; @import 'tachyons/src/_border-style'; @import 'tachyons/src/_border-widths'; @import 'tachyons/src/_box-shadow'; /*@import 'tachyons/src/_code';*/ @import 'tachyons/src/_coordinates'; @import 'tachyons/src/_clears'; @import 'tachyons/src/_display'; @import 'tachyons/src/_flexbox'; @import 'tachyons/src/_floats'; /*@import 'tachyons/src/_font-family';*/ @import 'tachyons/src/_font-style'; @import 'tachyons/src/_font-weight'; @import 'tachyons/src/_forms'; @import 'tachyons/src/_heights'; @import 'tachyons/src/_letter-spacing'; @import 'tachyons/src/_line-height'; @import 'tachyons/src/_links'; @import 'tachyons/src/_lists'; @import 'tachyons/src/_max-widths'; @import 'tachyons/src/_widths'; @import 'tachyons/src/_overflow'; @import 'tachyons/src/_position'; @import 'tachyons/src/_opacity'; /*@import 'tachyons/src/_rotations';*/ @import 'tachyons/src/_skins'; @import 'tachyons/src/_skins-pseudo'; @import 'tachyons/src/_spacing'; @import 'tachyons/src/_negative-margins'; @import 'tachyons/src/_tables'; @import 'tachyons/src/_text-decoration'; @import 'tachyons/src/_text-align'; @import 'tachyons/src/_text-transform'; @import 'tachyons/src/_type-scale'; @import 'tachyons/src/_typography'; @import 'tachyons/src/_utilities'; @import 'tachyons/src/_visibility'; @import 'tachyons/src/_white-space'; @import 'tachyons/src/_vertical-align'; @import 'tachyons/src/_hovers'; @import 'tachyons/src/_z-index'; @import 'tachyons/src/_nested'; /*@import 'tachyons/src/_styles';*/ /* Variables */ /* Importing here will allow you to override any variables in the modules */ @import 'tachyons/src/_colors'; @import 'tachyons/src/_media-queries'; /* Debugging */ /*@import 'tachyons/src/_debug-children'; @import 'tachyons/src/_debug-grid';*/ /* Uncomment out the line below to help debug layout issues */ /* @import 'tachyons/src/_debug'; */ hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/_variables.css000066400000000000000000000006741363637351300305540ustar00rootroot00000000000000:root { --primary-color: #0594CB; --primary-color-dark: #0A1922; --primary-color-light: #f9f9f9; --accent-color: #EBB951; --accent-color-light: #FF4088; --accent-color-dark: #33ba91; --text-color-primary: #373737; --text-on-primary-color: #fff; --text-color-secondary: #ccc; --text-color-disabled: #F7f7f7; --divider-color: #f6f6f6; --warn-color: red; --blue: var(--primary-color); } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/css/main.css000066400000000000000000000013701363637351300273630ustar00rootroot00000000000000/*Base Styles*/ @import '_tachyons'; /* purgecss start ignore */ @import '_anchorforid'; @import '_animation'; @import '_documentation-styles'; @import 'docsearch.js/dist/cdn/docsearch.min'; @import '_carousel'; @import '_code'; @import '_tabs'; @import '_color-scheme'; @import '_columns'; @import '_content'; @import '_content-tables'; @import '_definition-lists'; @import '_fluid-type'; @import '_font-family'; @import '_hugo-internal-template-styling'; @import '_no-js'; @import '_social-icons'; @import '_stickyheader'; @import '_svg'; @import '_chroma'; @import '_variables'; .nested-blockquote blockquote { border-left: 4px solid var(--primary-color); padding-left: 1em; /*margin: 0;*/ } .mw-90 { max-width:90%; } /* purgecss end ignore */hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/index.js000066400000000000000000000005441363637351300266040ustar00rootroot00000000000000require("typeface-muli") import styles from './css/main.css'; import './js/anchorforid.js' import './js/clipboardjs.js' import './js/codeblocks.js' import './js/docsearch.js' import './js/hljs.js' import './js/lazysizes.js' import './js/menutoggle.js' import './js/scrolldir.js' import './js/smoothscroll.js' import './js/tabs.js' import './js/nojs.js' hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/js/000077500000000000000000000000001363637351300255505ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/js/anchorforid.js000066400000000000000000000023511363637351300304050ustar00rootroot00000000000000/** * Anchor for ID BPNY **/ var anchorForId = function (id) { var anchor = document.createElement("a"); anchor.className = "header-link"; anchor.href = "#" + id; anchor.innerHTML = ' '; return anchor; }; var linkifyAnchors = function (level, containingElement) { var headers = containingElement.getElementsByTagName("h" + level); for (var h = 0; h < headers.length; h++) { var header = headers[h]; if (typeof header.id !== "undefined" && header.id !== "") { header.appendChild(anchorForId(header.id)); } } }; document.onreadystatechange = function () { if (this.readyState === "complete") { var contentBlock = document.getElementsByClassName("prose")[0] if (!contentBlock) { return; } for (var level = 2; level <= 4; level++) { linkifyAnchors(level, contentBlock); } } }; hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/js/clipboardjs.js000066400000000000000000000016351363637351300304070ustar00rootroot00000000000000var Clipboard = require('clipboard/dist/clipboard.js'); new Clipboard('.copy', { target: function(trigger) { if(trigger.classList.contains('copy-toggle')){ return trigger.previousElementSibling; } return trigger.nextElementSibling; } }).on('success', function(e) { successMessage(e.trigger, 'Copied!'); e.clearSelection(); }).on('error', function(e) { successMessage(e.trigger, fallbackMessage(e.action)); }); function successMessage(elem, msg) { elem.setAttribute('class', 'copied bg-primary-color-dark f6 absolute top-0 right-0 lh-solid hover-bg-primary-color-dark bn white ph3 pv2'); elem.setAttribute('aria-label', msg); } function fallbackMessage(elem, action) { var actionMsg = ''; var actionKey = (action === 'cut' ? 'X' : 'C'); if (isMac) { actionMsg = 'Press ⌘-' + actionKey; } else { actionMsg = 'Press Ctrl-' + actionKey; } return actionMsg; } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/js/codeblocks.js000066400000000000000000000005051363637351300302160ustar00rootroot00000000000000let article = document.getElementById('prose') if (article) { let codeBlocks = article.getElementsByTagName('code') for (let [key, codeBlock] of Object.entries(codeBlocks)){ var widthDif = codeBlock.scrollWidth - codeBlock.clientWidth if (widthDif > 0) codeBlock.parentNode.classList.add('expand') } } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/js/docsearch.js000066400000000000000000000003771363637351300300500ustar00rootroot00000000000000var docsearch = require('docsearch.js/dist/cdn/docsearch.js'); docsearch({ apiKey: '167e7998590aebda7f9fedcf86bc4a55', indexName: 'hugodocs', inputSelector: '#search-input', debug: true // Set debug to true if you want to inspect the dropdown }); hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/js/filesaver.js000066400000000000000000000000001363637351300300540ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/js/hljs.js000066400000000000000000000034721363637351300270540ustar00rootroot00000000000000var hljs = require('highlight.js/lib/highlight.js'); hljs.registerLanguage('bash', require('highlight.js/lib/languages/bash')); hljs.registerLanguage('css', require('highlight.js/lib/languages/css')); hljs.registerLanguage('markdown', require('highlight.js/lib/languages/markdown')); hljs.registerLanguage('diff', require('highlight.js/lib/languages/diff')); // hljs.registerLanguage('go', require('highlight.js/lib/languages/go')); hljs.registerLanguage('javascript', require('highlight.js/lib/languages/javascript')); hljs.registerLanguage('json', require('highlight.js/lib/languages/json')); hljs.registerLanguage('yaml', require('highlight.js/lib/languages/yaml')); hljs.registerLanguage('xml', require('highlight.js/lib/languages/xml')); hljs.registerLanguage('html', require('highlight.js/lib/languages/handlebars')); hljs.registerLanguage("go", function(e) { var t = { keyword: "code output note warning break default func interface select case map struct chan else goto package switch const fallthrough if range end type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune id autoplay Get", literal: "file download copy true false iota nil Pages with", built_in: "append cap close complex highlight copy imag len make new panic print println real recover delete Site Data tweet youtube ref relref vimeo instagram gist figure innershortcode" }; return { aliases: ["golang","hugo"], k: t, i: "Jquery is working

'); // hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/js/menutoggle.js000066400000000000000000000025731363637351300302630ustar00rootroot00000000000000// Grab any element that has the 'js-toggle' class and add an event listner for the toggleClass function var toggleBtns = document.getElementsByClassName('js-toggle') for (var i = 0; i < toggleBtns.length; i++) { toggleBtns[i].addEventListener('click', toggleClass, false) } function toggleClass() { // Define the data target via the dataset "target" (e.g. data-target=".docsmenu") var content = this.dataset.target.split(' ') // Find any menu items that are open var mobileCurrentlyOpen = document.querySelector('.mobilemenu:not(.dn)') var desktopCurrentlyOpen = document.querySelector('.desktopmenu:not(.dn)') var desktopActive = document.querySelector('.desktopmenu:not(.dn)') // Loop through the targets' divs for (var i = 0; i < content.length; i++) { var matches = document.querySelectorAll(content[i]); //for each, if the div has the 'dn' class (which is "display:none;"), remove it, otherwise, add that class [].forEach.call(matches, function(dom) { dom.classList.contains('dn') ? dom.classList.remove('dn') : dom.classList.add('dn'); return false; }); // close the currently open menu items if (mobileCurrentlyOpen) mobileCurrentlyOpen.classList.add('dn') if (desktopCurrentlyOpen) desktopCurrentlyOpen.classList.add('dn') if (desktopActive) desktopActive.classList.remove('db') } } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/js/nojs.js000066400000000000000000000001441363637351300270560ustar00rootroot00000000000000document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/, 'js'); hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/js/scrolldir.js000066400000000000000000000001011363637351300300730ustar00rootroot00000000000000var scrollDir = require('scrolldir/dist/scrolldir.auto.min.js'); hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/js/smoothscroll.js000066400000000000000000000044761363637351300306510ustar00rootroot00000000000000// query selector targets Hugo TOC (function() { 'use strict'; // Feature Test if ('querySelector' in document && 'addEventListener' in window && Array.prototype.forEach) { // Function to animate the scroll var smoothScroll = function(anchor, duration) { // Calculate how far and how fast to scroll var startLocation = window.pageYOffset; var endLocation = anchor.offsetTop; var distance = endLocation - startLocation; var increments = distance / (duration / 16); var stopAnimation; // Scroll the page by an increment, and check if it's time to stop var animateScroll = function() { window.scrollBy(0, increments); stopAnimation(); }; // If scrolling down if (increments >= 0) { // Stop animation when you reach the anchor OR the bottom of the page stopAnimation = function() { var travelled = window.pageYOffset; if ((travelled >= (endLocation - increments)) || ((window.innerHeight + travelled) >= document.body.offsetHeight)) { clearInterval(runAnimation); } }; } // If scrolling up else { // Stop animation when you reach the anchor OR the top of the page stopAnimation = function() { var travelled = window.pageYOffset; if (travelled <= (endLocation || 0)) { clearInterval(runAnimation); } }; } // Loop the animation function var runAnimation = setInterval(animateScroll, 16); }; // Define smooth scroll links var scrollToggle = document.querySelectorAll('#TableOfContents ul li a'); // For each smooth scroll link [].forEach.call(scrollToggle, function(toggle) { // When the smooth scroll link is clicked toggle.addEventListener('click', function(e) { // Prevent the default link behavior e.preventDefault(); // Get anchor link and calculate distance from the top var dataID = toggle.getAttribute('href'); var dataTarget = document.querySelector(dataID); var dataSpeed = toggle.getAttribute('data-speed'); // If the anchor exists if (dataTarget) { // Scroll to the anchor smoothScroll(dataTarget, dataSpeed || 500); } }, false); }); } })(); hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/js/tabs.js000066400000000000000000000024351363637351300270430ustar00rootroot00000000000000/** * Scripts which manages Code Toggle tabs. */ var i; // store tabs variable var allTabs = document.querySelectorAll("[data-toggle-tab]"); var allPanes = document.querySelectorAll("[data-pane]"); function toggleTabs(event) { if(event.target){ event.preventDefault(); var clickedTab = event.currentTarget; var targetKey = clickedTab.getAttribute("data-toggle-tab") }else { var targetKey = event } // We store the config language selected in users' localStorage if(window.localStorage){ window.localStorage.setItem("configLangPref", targetKey) } var selectedTabs = document.querySelectorAll("[data-toggle-tab='" + targetKey + "']"); var selectedPanes = document.querySelectorAll("[data-pane='" + targetKey + "']"); for (var i = 0; i < allTabs.length; i++) { allTabs[i].classList.remove("active"); allPanes[i].classList.remove("active"); } for (var i = 0; i < selectedTabs.length; i++) { selectedTabs[i].classList.add("active"); selectedPanes[i].classList.add("active"); } } for (i = 0; i < allTabs.length; i++) { allTabs[i].addEventListener("click", toggleTabs) } // Upon page load, if user has a preferred language in its localStorage, tabs are set to it. if(window.localStorage.getItem('configLangPref')) { toggleTabs(window.localStorage.getItem('configLangPref')) } hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/output/000077500000000000000000000000001363637351300264745ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/output/css/000077500000000000000000000000001363637351300272645ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/output/css/app.css000066400000000000000000004775211363637351300305760ustar00rootroot00000000000000/* muli-200normal - latin */ @font-face { font-family: 'Muli'; font-style: normal; font-display: swap; font-weight: 200; src: local('Muli Extra Light '), local('Muli-Extra Light'), url(/fonts/muli-latin-200.woff2) format('woff2'), url(/fonts/muli-latin-200.woff) format('woff'); /* Modern Browsers */ } /* muli-200italic - latin */ @font-face { font-family: 'Muli'; font-style: italic; font-display: swap; font-weight: 200; src: local('Muli Extra Light italic'), local('Muli-Extra Lightitalic'), url(/fonts/muli-latin-200italic.woff2) format('woff2'), url(/fonts/muli-latin-200italic.woff) format('woff'); /* Modern Browsers */ } /* muli-300normal - latin */ @font-face { font-family: 'Muli'; font-style: normal; font-display: swap; font-weight: 300; src: local('Muli Light '), local('Muli-Light'), url(/fonts/muli-latin-300.woff2) format('woff2'), url(/fonts/muli-latin-300.woff) format('woff'); /* Modern Browsers */ } /* muli-300italic - latin */ @font-face { font-family: 'Muli'; font-style: italic; font-display: swap; font-weight: 300; src: local('Muli Light italic'), local('Muli-Lightitalic'), url(/fonts/muli-latin-300italic.woff2) format('woff2'), url(/fonts/muli-latin-300italic.woff) format('woff'); /* Modern Browsers */ } /* muli-400normal - latin */ @font-face { font-family: 'Muli'; font-style: normal; font-display: swap; font-weight: 400; src: local('Muli Regular '), local('Muli-Regular'), url(/fonts/muli-latin-400.woff2) format('woff2'), url(/fonts/muli-latin-400.woff) format('woff'); /* Modern Browsers */ } /* muli-400italic - latin */ @font-face { font-family: 'Muli'; font-style: italic; font-display: swap; font-weight: 400; src: local('Muli Regular italic'), local('Muli-Regularitalic'), url(/fonts/muli-latin-400italic.woff2) format('woff2'), url(/fonts/muli-latin-400italic.woff) format('woff'); /* Modern Browsers */ } /* muli-600normal - latin */ @font-face { font-family: 'Muli'; font-style: normal; font-display: swap; font-weight: 600; src: local('Muli SemiBold '), local('Muli-SemiBold'), url(/fonts/muli-latin-600.woff2) format('woff2'), url(/fonts/muli-latin-600.woff) format('woff'); /* Modern Browsers */ } /* muli-600italic - latin */ @font-face { font-family: 'Muli'; font-style: italic; font-display: swap; font-weight: 600; src: local('Muli SemiBold italic'), local('Muli-SemiBolditalic'), url(/fonts/muli-latin-600italic.woff2) format('woff2'), url(/fonts/muli-latin-600italic.woff) format('woff'); /* Modern Browsers */ } /* muli-700normal - latin */ @font-face { font-family: 'Muli'; font-style: normal; font-display: swap; font-weight: 700; src: local('Muli Bold '), local('Muli-Bold'), url(/fonts/muli-latin-700.woff2) format('woff2'), url(/fonts/muli-latin-700.woff) format('woff'); /* Modern Browsers */ } /* muli-700italic - latin */ @font-face { font-family: 'Muli'; font-style: italic; font-display: swap; font-weight: 700; src: local('Muli Bold italic'), local('Muli-Bolditalic'), url(/fonts/muli-latin-700italic.woff2) format('woff2'), url(/fonts/muli-latin-700italic.woff) format('woff'); /* Modern Browsers */ } /* muli-800normal - latin */ @font-face { font-family: 'Muli'; font-style: normal; font-display: swap; font-weight: 800; src: local('Muli ExtraBold '), local('Muli-ExtraBold'), url(/fonts/muli-latin-800.woff2) format('woff2'), url(/fonts/muli-latin-800.woff) format('woff'); /* Modern Browsers */ } /* muli-800italic - latin */ @font-face { font-family: 'Muli'; font-style: italic; font-display: swap; font-weight: 800; src: local('Muli ExtraBold italic'), local('Muli-ExtraBolditalic'), url(/fonts/muli-latin-800italic.woff2) format('woff2'), url(/fonts/muli-latin-800italic.woff) format('woff'); /* Modern Browsers */ } /* muli-900normal - latin */ @font-face { font-family: 'Muli'; font-style: normal; font-display: swap; font-weight: 900; src: local('Muli Black '), local('Muli-Black'), url(/fonts/muli-latin-900.woff2) format('woff2'), url(/fonts/muli-latin-900.woff) format('woff'); /* Modern Browsers */ } /* muli-900italic - latin */ @font-face { font-family: 'Muli'; font-style: italic; font-display: swap; font-weight: 900; src: local('Muli Black italic'), local('Muli-Blackitalic'), url(/fonts/muli-latin-900italic.woff2) format('woff2'), url(/fonts/muli-latin-900italic.woff) format('woff'); /* Modern Browsers */ } /*Base Styles*/ /*! TACHYONS v4.7.0 | http://tachyons.io */ /* * NOTE: The Tachyons folder is for backup/reference only. This file references the module * ________ ______ * ___ __/_____ _________ /______ ______________________ * __ / _ __ `/ ___/_ __ \_ / / / __ \_ __ \_ ___/ * _ / / /_/ // /__ _ / / / /_/ // /_/ / / / /(__ ) * /_/ \__,_/ \___/ /_/ /_/_\__, / \____//_/ /_//____/ * /____/ * * TABLE OF CONTENTS * * 1. External Library Includes * - Normalize.css | http://normalize.css.github.io * 2. Tachyons Modules * 3. Variables * - Media Queries * - Colors * 4. Debugging * - Debug all * - Debug children * */ /* External Library Includes */ /*! normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css */ /* Document ========================================================================== */ /** * 1. Correct the line height in all browsers. * 2. Prevent adjustments of font size after orientation changes in iOS. */ html { line-height: 1.15; /* 1 */ -webkit-text-size-adjust: 100%; /* 2 */ } /* Sections ========================================================================== */ /** * Remove the margin in all browsers. */ body { margin: 0; } /** * Correct the font size and margin on `h1` elements within `section` and * `article` contexts in Chrome, Firefox, and Safari. */ h1 { font-size: 2em; margin: 0.67em 0; } /* Grouping content ========================================================================== */ /** * 1. Add the correct box sizing in Firefox. * 2. Show the overflow in Edge and IE. */ hr { -webkit-box-sizing: content-box; box-sizing: content-box; /* 1 */ height: 0; /* 1 */ overflow: visible; /* 2 */ } /** * 1. Correct the inheritance and scaling of font size in all browsers. * 2. Correct the odd `em` font sizing in all browsers. */ pre { font-family: monospace, monospace; /* 1 */ font-size: 1em; /* 2 */ } /* Text-level semantics ========================================================================== */ /** * Remove the gray background on active links in IE 10. */ a { background-color: transparent; } /** * 1. Remove the bottom border in Chrome 57- * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. */ abbr[title] { border-bottom: none; /* 1 */ text-decoration: underline; /* 2 */ -webkit-text-decoration: underline dotted; text-decoration: underline dotted; /* 2 */ } /** * Add the correct font weight in Chrome, Edge, and Safari. */ b, strong { font-weight: bolder; } /** * 1. Correct the inheritance and scaling of font size in all browsers. * 2. Correct the odd `em` font sizing in all browsers. */ code, kbd, samp { font-family: monospace, monospace; /* 1 */ font-size: 1em; /* 2 */ } /** * Add the correct font size in all browsers. */ small { font-size: 80%; } /** * Prevent `sub` and `sup` elements from affecting the line height in * all browsers. */ sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sub { bottom: -0.25em; } sup { top: -0.5em; } /* Embedded content ========================================================================== */ /** * Remove the border on images inside links in IE 10. */ img { border-style: none; } /* Forms ========================================================================== */ /** * 1. Change the font styles in all browsers. * 2. Remove the margin in Firefox and Safari. */ button, input, optgroup, select, textarea { font-family: inherit; /* 1 */ font-size: 100%; /* 1 */ line-height: 1.15; /* 1 */ margin: 0; /* 2 */ } /** * Show the overflow in IE. * 1. Show the overflow in Edge. */ button, input { /* 1 */ overflow: visible; } /** * Remove the inheritance of text transform in Edge, Firefox, and IE. * 1. Remove the inheritance of text transform in Firefox. */ button, select { /* 1 */ text-transform: none; } /** * Correct the inability to style clickable types in iOS and Safari. */ button, [type="button"], [type="reset"], [type="submit"] { -webkit-appearance: button; } /** * Remove the inner border and padding in Firefox. */ button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { border-style: none; padding: 0; } /** * Restore the focus styles unset by the previous rule. */ button:-moz-focusring, [type="button"]:-moz-focusring, [type="reset"]:-moz-focusring, [type="submit"]:-moz-focusring { outline: 1px dotted ButtonText; } /** * Correct the padding in Firefox. */ fieldset { padding: 0.35em 0.75em 0.625em; } /** * 1. Correct the text wrapping in Edge and IE. * 2. Correct the color inheritance from `fieldset` elements in IE. * 3. Remove the padding so developers are not caught out when they zero out * `fieldset` elements in all browsers. */ legend { -webkit-box-sizing: border-box; box-sizing: border-box; /* 1 */ color: inherit; /* 2 */ display: table; /* 1 */ max-width: 100%; /* 1 */ padding: 0; /* 3 */ white-space: normal; /* 1 */ } /** * Add the correct vertical alignment in Chrome, Firefox, and Opera. */ progress { vertical-align: baseline; } /** * Remove the default vertical scrollbar in IE 10+. */ textarea { overflow: auto; } /** * 1. Add the correct box sizing in IE 10. * 2. Remove the padding in IE 10. */ [type="checkbox"], [type="radio"] { -webkit-box-sizing: border-box; box-sizing: border-box; /* 1 */ padding: 0; /* 2 */ } /** * Correct the cursor style of increment and decrement buttons in Chrome. */ [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { height: auto; } /** * 1. Correct the odd appearance in Chrome and Safari. * 2. Correct the outline style in Safari. */ [type="search"] { -webkit-appearance: textfield; /* 1 */ outline-offset: -2px; /* 2 */ } /** * Remove the inner padding in Chrome and Safari on macOS. */ [type="search"]::-webkit-search-decoration { -webkit-appearance: none; } /** * 1. Correct the inability to style clickable types in iOS and Safari. * 2. Change font properties to `inherit` in Safari. */ ::-webkit-file-upload-button { -webkit-appearance: button; /* 1 */ font: inherit; /* 2 */ } /* Interactive ========================================================================== */ /* * Add the correct display in Edge, IE 10+, and Firefox. */ details { display: block; } /* * Add the correct display in all browsers. */ summary { display: list-item; } /* Misc ========================================================================== */ /** * Add the correct display in IE 10+. */ template { display: none; } /** * Add the correct display in IE 10. */ [hidden] { display: none; } /* Modules */ /* BOX SIZING */ html, body, div, article, aside, section, main, nav, footer, header, form, fieldset, legend, pre, code, a, h1,h2,h3,h4,h5,h6, p, ul, ol, li, dl, dt, dd, blockquote, figcaption, figure, textarea, table, td, th, tr, input[type="email"], input[type="number"], input[type="password"], input[type="tel"], input[type="text"], input[type="url"], .border-box { -webkit-box-sizing: border-box; box-sizing: border-box; } /*@import 'tachyons/src/_aspect-ratios';*/ /* IMAGES Docs: http://tachyons.io/docs/elements/images/ */ /* Responsive images! */ img { max-width: 100%; } /* BACKGROUND SIZE Docs: http://tachyons.io/docs/themes/background-size/ Media Query Extensions: -ns = not-small -m = medium -l = large */ /* Often used in combination with background image set as an inline style on an html element. */ .cover { background-size: cover!important; } .contain { background-size: contain!important; } @media screen and (min-width: 30em) { .cover-ns { background-size: cover!important; } .contain-ns { background-size: contain!important; } } @media screen and (min-width: 30em) and (max-width: 60em) { .cover-m { background-size: cover!important; } .contain-m { background-size: contain!important; } } @media screen and (min-width: 60em) { .cover-l { background-size: cover!important; } .contain-l { background-size: contain!important; } } /* BACKGROUND POSITION Base: bg = background Modifiers: -center = center center -top = top center -right = center right -bottom = bottom center -left = center left Media Query Extensions: -ns = not-small -m = medium -l = large */ .bg-center { background-repeat: no-repeat; background-position: center center; } .bg-top { background-repeat: no-repeat; background-position: top center; } .bg-right { background-repeat: no-repeat; background-position: center right; } .bg-bottom { background-repeat: no-repeat; background-position: bottom center; } .bg-left { background-repeat: no-repeat; background-position: center left; } @media screen and (min-width: 30em) { .bg-center-ns { background-repeat: no-repeat; background-position: center center; } .bg-top-ns { background-repeat: no-repeat; background-position: top center; } .bg-right-ns { background-repeat: no-repeat; background-position: center right; } .bg-bottom-ns { background-repeat: no-repeat; background-position: bottom center; } .bg-left-ns { background-repeat: no-repeat; background-position: center left; } } @media screen and (min-width: 30em) and (max-width: 60em) { .bg-center-m { background-repeat: no-repeat; background-position: center center; } .bg-top-m { background-repeat: no-repeat; background-position: top center; } .bg-right-m { background-repeat: no-repeat; background-position: center right; } .bg-bottom-m { background-repeat: no-repeat; background-position: bottom center; } .bg-left-m { background-repeat: no-repeat; background-position: center left; } } @media screen and (min-width: 60em) { .bg-center-l { background-repeat: no-repeat; background-position: center center; } .bg-top-l { background-repeat: no-repeat; background-position: top center; } .bg-right-l { background-repeat: no-repeat; background-position: center right; } .bg-bottom-l { background-repeat: no-repeat; background-position: bottom center; } .bg-left-l { background-repeat: no-repeat; background-position: center left; } } /*@import 'tachyons/src/_outlines';*/ /* BORDERS Docs: http://tachyons.io/docs/themes/borders/ Base: b = border Modifiers: a = all t = top r = right b = bottom l = left n = none Media Query Extensions: -ns = not-small -m = medium -l = large */ .ba { border-style: solid; border-width: 1px; } .bt { border-top-style: solid; border-top-width: 1px; } .br { border-right-style: solid; border-right-width: 1px; } .bb { border-bottom-style: solid; border-bottom-width: 1px; } .bl { border-left-style: solid; border-left-width: 1px; } .bn { border-style: none; border-width: 0; } @media screen and (min-width: 30em) { .ba-ns { border-style: solid; border-width: 1px; } .bt-ns { border-top-style: solid; border-top-width: 1px; } .br-ns { border-right-style: solid; border-right-width: 1px; } .bb-ns { border-bottom-style: solid; border-bottom-width: 1px; } .bl-ns { border-left-style: solid; border-left-width: 1px; } .bn-ns { border-style: none; border-width: 0; } } @media screen and (min-width: 30em) and (max-width: 60em) { .ba-m { border-style: solid; border-width: 1px; } .bt-m { border-top-style: solid; border-top-width: 1px; } .br-m { border-right-style: solid; border-right-width: 1px; } .bb-m { border-bottom-style: solid; border-bottom-width: 1px; } .bl-m { border-left-style: solid; border-left-width: 1px; } .bn-m { border-style: none; border-width: 0; } } @media screen and (min-width: 60em) { .ba-l { border-style: solid; border-width: 1px; } .bt-l { border-top-style: solid; border-top-width: 1px; } .br-l { border-right-style: solid; border-right-width: 1px; } .bb-l { border-bottom-style: solid; border-bottom-width: 1px; } .bl-l { border-left-style: solid; border-left-width: 1px; } .bn-l { border-style: none; border-width: 0; } } /* BORDER COLORS Docs: http://tachyons.io/docs/themes/borders/ Border colors can be used to extend the base border classes ba,bt,bb,br,bl found in the _borders.css file. The base border class by default will set the color of the border to that of the current text color. These classes are for the cases where you desire for the text and border colors to be different. Base: b = border Modifiers: --color-name = each color variable name is also a border color name */ .b--black { border-color: #000; } .b--near-black { border-color: #111; } .b--dark-gray { border-color: #333; } .b--mid-gray { border-color: #555; } .b--gray { border-color: #777; } .b--silver { border-color: #999; } .b--light-silver { border-color: #aaa; } .b--moon-gray { border-color: #ccc; } .b--light-gray { border-color: #eee; } .b--near-white { border-color: #f4f4f4; } .b--white { border-color: #fff; } .b--white-90 { border-color: rgba(255, 255, 255, .9); } .b--white-80 { border-color: rgba(255, 255, 255, .8); } .b--white-70 { border-color: rgba(255, 255, 255, .7); } .b--white-60 { border-color: rgba(255, 255, 255, .6); } .b--white-50 { border-color: rgba(255, 255, 255, .5); } .b--white-40 { border-color: rgba(255, 255, 255, .4); } .b--white-30 { border-color: rgba(255, 255, 255, .3); } .b--white-20 { border-color: rgba(255, 255, 255, .2); } .b--white-10 { border-color: rgba(255, 255, 255, .1); } .b--white-05 { border-color: rgba(255, 255, 255, .05); } .b--white-025 { border-color: rgba(255, 255, 255, .025); } .b--white-0125 { border-color: rgba(255, 255, 255, .0125); } .b--black-90 { border-color: rgba(0, 0, 0, .9); } .b--black-80 { border-color: rgba(0, 0, 0, .8); } .b--black-70 { border-color: rgba(0, 0, 0, .7); } .b--black-60 { border-color: rgba(0, 0, 0, .6); } .b--black-50 { border-color: rgba(0, 0, 0, .5); } .b--black-40 { border-color: rgba(0, 0, 0, .4); } .b--black-30 { border-color: rgba(0, 0, 0, .3); } .b--black-20 { border-color: rgba(0, 0, 0, .2); } .b--black-10 { border-color: rgba(0, 0, 0, .1); } .b--black-05 { border-color: rgba(0, 0, 0, .05); } .b--black-025 { border-color: rgba(0, 0, 0, .025); } .b--black-0125 { border-color: rgba(0, 0, 0, .0125); } .b--dark-red { border-color: #e7040f; } .b--red { border-color: #ff4136; } .b--light-red { border-color: #ff725c; } .b--orange { border-color: #ff6300; } .b--gold { border-color: #ffb700; } .b--yellow { border-color: #ffd700; } .b--light-yellow { border-color: #fbf1a9; } .b--purple { border-color: #5e2ca5; } .b--light-purple { border-color: #a463f2; } .b--dark-pink { border-color: #d5008f; } .b--hot-pink { border-color: #ff41b4; } .b--pink { border-color: #ff80cc; } .b--light-pink { border-color: #ffa3d7; } .b--dark-green { border-color: #137752; } .b--green { border-color: #19a974; } .b--light-green { border-color: #9eebcf; } .b--navy { border-color: #001b44; } .b--dark-blue { border-color: #00449e; } .b--blue { border-color: #0594CB; } .b--light-blue { border-color: #96ccff; } .b--lightest-blue { border-color: #cdecff; } .b--washed-blue { border-color: #f6fffe; } .b--washed-green { border-color: #e8fdf5; } .b--washed-yellow { border-color: #fffceb; } .b--washed-red { border-color: #ffdfdf; } .b--transparent { border-color: transparent; } .b--inherit { border-color: inherit; } /* BORDER RADIUS Docs: http://tachyons.io/docs/themes/border-radius/ Base: br = border-radius Modifiers: 0 = 0/none 1 = 1st step in scale 2 = 2nd step in scale 3 = 3rd step in scale 4 = 4th step in scale Literal values: -100 = 100% -pill = 9999px Media Query Extensions: -ns = not-small -m = medium -l = large */ .br0 { border-radius: 0; } .br1 { border-radius: .125rem; } .br2 { border-radius: .25rem; } .br3 { border-radius: .5rem; } .br4 { border-radius: 1rem; } .br-100 { border-radius: 100%; } .br-pill { border-radius: 9999px; } .br--bottom { border-top-left-radius: 0; border-top-right-radius: 0; } .br--top { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .br--right { border-top-left-radius: 0; border-bottom-left-radius: 0; } .br--left { border-top-right-radius: 0; border-bottom-right-radius: 0; } @media screen and (min-width: 30em) { .br0-ns { border-radius: 0; } .br1-ns { border-radius: .125rem; } .br2-ns { border-radius: .25rem; } .br3-ns { border-radius: .5rem; } .br4-ns { border-radius: 1rem; } .br-100-ns { border-radius: 100%; } .br-pill-ns { border-radius: 9999px; } .br--bottom-ns { border-top-left-radius: 0; border-top-right-radius: 0; } .br--top-ns { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .br--right-ns { border-top-left-radius: 0; border-bottom-left-radius: 0; } .br--left-ns { border-top-right-radius: 0; border-bottom-right-radius: 0; } } @media screen and (min-width: 30em) and (max-width: 60em) { .br0-m { border-radius: 0; } .br1-m { border-radius: .125rem; } .br2-m { border-radius: .25rem; } .br3-m { border-radius: .5rem; } .br4-m { border-radius: 1rem; } .br-100-m { border-radius: 100%; } .br-pill-m { border-radius: 9999px; } .br--bottom-m { border-top-left-radius: 0; border-top-right-radius: 0; } .br--top-m { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .br--right-m { border-top-left-radius: 0; border-bottom-left-radius: 0; } .br--left-m { border-top-right-radius: 0; border-bottom-right-radius: 0; } } @media screen and (min-width: 60em) { .br0-l { border-radius: 0; } .br1-l { border-radius: .125rem; } .br2-l { border-radius: .25rem; } .br3-l { border-radius: .5rem; } .br4-l { border-radius: 1rem; } .br-100-l { border-radius: 100%; } .br-pill-l { border-radius: 9999px; } .br--bottom-l { border-top-left-radius: 0; border-top-right-radius: 0; } .br--top-l { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .br--right-l { border-top-left-radius: 0; border-bottom-left-radius: 0; } .br--left-l { border-top-right-radius: 0; border-bottom-right-radius: 0; } } /* BORDER STYLES Docs: http://tachyons.io/docs/themes/borders/ Depends on base border module in _borders.css Base: b = border-style Modifiers: --none = none --dotted = dotted --dashed = dashed --solid = solid Media Query Extensions: -ns = not-small -m = medium -l = large */ .b--dotted { border-style: dotted; } .b--dashed { border-style: dashed; } .b--solid { border-style: solid; } .b--none { border-style: none; } @media screen and (min-width: 30em) { .b--dotted-ns { border-style: dotted; } .b--dashed-ns { border-style: dashed; } .b--solid-ns { border-style: solid; } .b--none-ns { border-style: none; } } @media screen and (min-width: 30em) and (max-width: 60em) { .b--dotted-m { border-style: dotted; } .b--dashed-m { border-style: dashed; } .b--solid-m { border-style: solid; } .b--none-m { border-style: none; } } @media screen and (min-width: 60em) { .b--dotted-l { border-style: dotted; } .b--dashed-l { border-style: dashed; } .b--solid-l { border-style: solid; } .b--none-l { border-style: none; } } /* BORDER WIDTHS Docs: http://tachyons.io/docs/themes/borders/ Base: bw = border-width Modifiers: 0 = 0 width border 1 = 1st step in border-width scale 2 = 2nd step in border-width scale 3 = 3rd step in border-width scale 4 = 4th step in border-width scale 5 = 5th step in border-width scale Media Query Extensions: -ns = not-small -m = medium -l = large */ .bw0 { border-width: 0; } .bw1 { border-width: .125rem; } .bw2 { border-width: .25rem; } .bw3 { border-width: .5rem; } .bw4 { border-width: 1rem; } .bw5 { border-width: 2rem; } /* Resets */ .bt-0 { border-top-width: 0; } .br-0 { border-right-width: 0; } .bb-0 { border-bottom-width: 0; } .bl-0 { border-left-width: 0; } @media screen and (min-width: 30em) { .bw0-ns { border-width: 0; } .bw1-ns { border-width: .125rem; } .bw2-ns { border-width: .25rem; } .bw3-ns { border-width: .5rem; } .bw4-ns { border-width: 1rem; } .bw5-ns { border-width: 2rem; } .bt-0-ns { border-top-width: 0; } .br-0-ns { border-right-width: 0; } .bb-0-ns { border-bottom-width: 0; } .bl-0-ns { border-left-width: 0; } } @media screen and (min-width: 30em) and (max-width: 60em) { .bw0-m { border-width: 0; } .bw1-m { border-width: .125rem; } .bw2-m { border-width: .25rem; } .bw3-m { border-width: .5rem; } .bw4-m { border-width: 1rem; } .bw5-m { border-width: 2rem; } .bt-0-m { border-top-width: 0; } .br-0-m { border-right-width: 0; } .bb-0-m { border-bottom-width: 0; } .bl-0-m { border-left-width: 0; } } @media screen and (min-width: 60em) { .bw0-l { border-width: 0; } .bw1-l { border-width: .125rem; } .bw2-l { border-width: .25rem; } .bw3-l { border-width: .5rem; } .bw4-l { border-width: 1rem; } .bw5-l { border-width: 2rem; } .bt-0-l { border-top-width: 0; } .br-0-l { border-right-width: 0; } .bb-0-l { border-bottom-width: 0; } .bl-0-l { border-left-width: 0; } } /* BOX-SHADOW Docs: http://tachyons.io/docs/themes/box-shadow/ Media Query Extensions: -ns = not-small -m = medium -l = large */ .shadow-1 { -webkit-box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } .shadow-2 { -webkit-box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } .shadow-3 { -webkit-box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } .shadow-4 { -webkit-box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } .shadow-5 { -webkit-box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } @media screen and (min-width: 30em) { .shadow-1-ns { -webkit-box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } .shadow-2-ns { -webkit-box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } .shadow-3-ns { -webkit-box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } .shadow-4-ns { -webkit-box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } .shadow-5-ns { -webkit-box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } } @media screen and (min-width: 30em) and (max-width: 60em) { .shadow-1-m { -webkit-box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } .shadow-2-m { -webkit-box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } .shadow-3-m { -webkit-box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } .shadow-4-m { -webkit-box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } .shadow-5-m { -webkit-box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } } @media screen and (min-width: 60em) { .shadow-1-l { -webkit-box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, .2); } .shadow-2-l { -webkit-box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, .2); } .shadow-3-l { -webkit-box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); box-shadow: 2px 2px 4px 2px rgba(0, 0, 0, .2); } .shadow-4-l { -webkit-box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); box-shadow: 2px 2px 8px 0px rgba(0, 0, 0, .2); } .shadow-5-l { -webkit-box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); box-shadow: 4px 4px 8px 0px rgba(0, 0, 0, .2); } } /*@import 'tachyons/src/_code';*/ /* COORDINATES Docs: http://tachyons.io/docs/layout/position/ Use in combination with the position module. Base: top bottom right left Modifiers: -0 = literal value 0 -1 = literal value 1 -2 = literal value 2 --1 = literal value -1 --2 = literal value -2 Media Query Extensions: -ns = not-small -m = medium -l = large */ .top-0 { top: 0; } .right-0 { right: 0; } .bottom-0 { bottom: 0; } .left-0 { left: 0; } .top-1 { top: 1rem; } .right-1 { right: 1rem; } .bottom-1 { bottom: 1rem; } .left-1 { left: 1rem; } .top-2 { top: 2rem; } .right-2 { right: 2rem; } .bottom-2 { bottom: 2rem; } .left-2 { left: 2rem; } .top--1 { top: -1rem; } .right--1 { right: -1rem; } .bottom--1 { bottom: -1rem; } .left--1 { left: -1rem; } .top--2 { top: -2rem; } .right--2 { right: -2rem; } .bottom--2 { bottom: -2rem; } .left--2 { left: -2rem; } .absolute--fill { top: 0; right: 0; bottom: 0; left: 0; } @media screen and (min-width: 30em) { .top-0-ns { top: 0; } .left-0-ns { left: 0; } .right-0-ns { right: 0; } .bottom-0-ns { bottom: 0; } .top-1-ns { top: 1rem; } .left-1-ns { left: 1rem; } .right-1-ns { right: 1rem; } .bottom-1-ns { bottom: 1rem; } .top-2-ns { top: 2rem; } .left-2-ns { left: 2rem; } .right-2-ns { right: 2rem; } .bottom-2-ns { bottom: 2rem; } .top--1-ns { top: -1rem; } .right--1-ns { right: -1rem; } .bottom--1-ns { bottom: -1rem; } .left--1-ns { left: -1rem; } .top--2-ns { top: -2rem; } .right--2-ns { right: -2rem; } .bottom--2-ns { bottom: -2rem; } .left--2-ns { left: -2rem; } .absolute--fill-ns { top: 0; right: 0; bottom: 0; left: 0; } } @media screen and (min-width: 30em) and (max-width: 60em) { .top-0-m { top: 0; } .left-0-m { left: 0; } .right-0-m { right: 0; } .bottom-0-m { bottom: 0; } .top-1-m { top: 1rem; } .left-1-m { left: 1rem; } .right-1-m { right: 1rem; } .bottom-1-m { bottom: 1rem; } .top-2-m { top: 2rem; } .left-2-m { left: 2rem; } .right-2-m { right: 2rem; } .bottom-2-m { bottom: 2rem; } .top--1-m { top: -1rem; } .right--1-m { right: -1rem; } .bottom--1-m { bottom: -1rem; } .left--1-m { left: -1rem; } .top--2-m { top: -2rem; } .right--2-m { right: -2rem; } .bottom--2-m { bottom: -2rem; } .left--2-m { left: -2rem; } .absolute--fill-m { top: 0; right: 0; bottom: 0; left: 0; } } @media screen and (min-width: 60em) { .top-0-l { top: 0; } .left-0-l { left: 0; } .right-0-l { right: 0; } .bottom-0-l { bottom: 0; } .top-1-l { top: 1rem; } .left-1-l { left: 1rem; } .right-1-l { right: 1rem; } .bottom-1-l { bottom: 1rem; } .top-2-l { top: 2rem; } .left-2-l { left: 2rem; } .right-2-l { right: 2rem; } .bottom-2-l { bottom: 2rem; } .top--1-l { top: -1rem; } .right--1-l { right: -1rem; } .bottom--1-l { bottom: -1rem; } .left--1-l { left: -1rem; } .top--2-l { top: -2rem; } .right--2-l { right: -2rem; } .bottom--2-l { bottom: -2rem; } .left--2-l { left: -2rem; } .absolute--fill-l { top: 0; right: 0; bottom: 0; left: 0; } } /* CLEARFIX http://tachyons.io/docs/layout/clearfix/ */ /* Nicolas Gallaghers Clearfix solution Ref: http://nicolasgallagher.com/micro-clearfix-hack/ */ .cf:before, .cf:after { content: " "; display: table; } .cf:after { clear: both; } .cf { *zoom: 1; } .cl { clear: left; } .cr { clear: right; } .cb { clear: both; } .cn { clear: none; } @media screen and (min-width: 30em) { .cl-ns { clear: left; } .cr-ns { clear: right; } .cb-ns { clear: both; } .cn-ns { clear: none; } } @media screen and (min-width: 30em) and (max-width: 60em) { .cl-m { clear: left; } .cr-m { clear: right; } .cb-m { clear: both; } .cn-m { clear: none; } } @media screen and (min-width: 60em) { .cl-l { clear: left; } .cr-l { clear: right; } .cb-l { clear: both; } .cn-l { clear: none; } } /* DISPLAY Docs: http://tachyons.io/docs/layout/display Base: d = display Modifiers: n = none b = block ib = inline-block it = inline-table t = table tc = table-cell t-row = table-row t-columm = table-column t-column-group = table-column-group Media Query Extensions: -ns = not-small -m = medium -l = large */ .dn { display: none; } .di { display: inline; } .db { display: block; } .dib { display: inline-block; } .dit { display: inline-table; } .dt { display: table; } .dtc { display: table-cell; } .dt-row { display: table-row; } .dt-row-group { display: table-row-group; } .dt-column { display: table-column; } .dt-column-group { display: table-column-group; } /* This will set table to full width and then all cells will be equal width */ .dt--fixed { table-layout: fixed; width: 100%; } @media screen and (min-width: 30em) { .dn-ns { display: none; } .di-ns { display: inline; } .db-ns { display: block; } .dib-ns { display: inline-block; } .dit-ns { display: inline-table; } .dt-ns { display: table; } .dtc-ns { display: table-cell; } .dt-row-ns { display: table-row; } .dt-row-group-ns { display: table-row-group; } .dt-column-ns { display: table-column; } .dt-column-group-ns { display: table-column-group; } .dt--fixed-ns { table-layout: fixed; width: 100%; } } @media screen and (min-width: 30em) and (max-width: 60em) { .dn-m { display: none; } .di-m { display: inline; } .db-m { display: block; } .dib-m { display: inline-block; } .dit-m { display: inline-table; } .dt-m { display: table; } .dtc-m { display: table-cell; } .dt-row-m { display: table-row; } .dt-row-group-m { display: table-row-group; } .dt-column-m { display: table-column; } .dt-column-group-m { display: table-column-group; } .dt--fixed-m { table-layout: fixed; width: 100%; } } @media screen and (min-width: 60em) { .dn-l { display: none; } .di-l { display: inline; } .db-l { display: block; } .dib-l { display: inline-block; } .dit-l { display: inline-table; } .dt-l { display: table; } .dtc-l { display: table-cell; } .dt-row-l { display: table-row; } .dt-row-group-l { display: table-row-group; } .dt-column-l { display: table-column; } .dt-column-group-l { display: table-column-group; } .dt--fixed-l { table-layout: fixed; width: 100%; } } /* FLEXBOX Media Query Extensions: -ns = not-small -m = medium -l = large */ .flex { display: -webkit-box; display: -ms-flexbox; display: flex; } .inline-flex { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } /* 1. Fix for Chrome 44 bug. * https://code.google.com/p/chromium/issues/detail?id=506893 */ .flex-auto { -webkit-box-flex: 1; -ms-flex: 1 1 auto; flex: 1 1 auto; min-width: 0; /* 1 */ min-height: 0; /* 1 */ } .flex-none { -webkit-box-flex: 0; -ms-flex: none; flex: none; } .flex-column { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } .flex-row { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } .flex-wrap { -ms-flex-wrap: wrap; flex-wrap: wrap; } .flex-nowrap { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } .flex-wrap-reverse { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } .flex-column-reverse { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } .flex-row-reverse { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } .items-start { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } .items-end { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } .items-center { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } .items-baseline { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } .items-stretch { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } .self-start { -ms-flex-item-align: start; align-self: flex-start; } .self-end { -ms-flex-item-align: end; align-self: flex-end; } .self-center { -ms-flex-item-align: center; align-self: center; } .self-baseline { -ms-flex-item-align: baseline; align-self: baseline; } .self-stretch { -ms-flex-item-align: stretch; align-self: stretch; } .justify-start { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } .justify-end { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } .justify-center { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } .justify-between { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } .justify-around { -ms-flex-pack: distribute; justify-content: space-around; } .content-start { -ms-flex-line-pack: start; align-content: flex-start; } .content-end { -ms-flex-line-pack: end; align-content: flex-end; } .content-center { -ms-flex-line-pack: center; align-content: center; } .content-between { -ms-flex-line-pack: justify; align-content: space-between; } .content-around { -ms-flex-line-pack: distribute; align-content: space-around; } .content-stretch { -ms-flex-line-pack: stretch; align-content: stretch; } .order-0 { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } .order-1 { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } .order-2 { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } .order-3 { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } .order-4 { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } .order-5 { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } .order-6 { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } .order-7 { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } .order-8 { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } .order-last { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } .flex-grow-0 { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } .flex-grow-1 { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } .flex-shrink-0 { -ms-flex-negative: 0; flex-shrink: 0; } .flex-shrink-1 { -ms-flex-negative: 1; flex-shrink: 1; } @media screen and (min-width: 30em) { .flex-ns { display: -webkit-box; display: -ms-flexbox; display: flex; } .inline-flex-ns { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } .flex-auto-ns { -webkit-box-flex: 1; -ms-flex: 1 1 auto; flex: 1 1 auto; min-width: 0; /* 1 */ min-height: 0; /* 1 */ } .flex-none-ns { -webkit-box-flex: 0; -ms-flex: none; flex: none; } .flex-column-ns { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } .flex-row-ns { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } .flex-wrap-ns { -ms-flex-wrap: wrap; flex-wrap: wrap; } .flex-nowrap-ns { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } .flex-wrap-reverse-ns { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } .flex-column-reverse-ns { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } .flex-row-reverse-ns { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } .items-start-ns { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } .items-end-ns { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } .items-center-ns { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } .items-baseline-ns { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } .items-stretch-ns { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } .self-start-ns { -ms-flex-item-align: start; align-self: flex-start; } .self-end-ns { -ms-flex-item-align: end; align-self: flex-end; } .self-center-ns { -ms-flex-item-align: center; align-self: center; } .self-baseline-ns { -ms-flex-item-align: baseline; align-self: baseline; } .self-stretch-ns { -ms-flex-item-align: stretch; align-self: stretch; } .justify-start-ns { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } .justify-end-ns { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } .justify-center-ns { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } .justify-between-ns { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } .justify-around-ns { -ms-flex-pack: distribute; justify-content: space-around; } .content-start-ns { -ms-flex-line-pack: start; align-content: flex-start; } .content-end-ns { -ms-flex-line-pack: end; align-content: flex-end; } .content-center-ns { -ms-flex-line-pack: center; align-content: center; } .content-between-ns { -ms-flex-line-pack: justify; align-content: space-between; } .content-around-ns { -ms-flex-line-pack: distribute; align-content: space-around; } .content-stretch-ns { -ms-flex-line-pack: stretch; align-content: stretch; } .order-0-ns { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } .order-1-ns { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } .order-2-ns { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } .order-3-ns { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } .order-4-ns { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } .order-5-ns { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } .order-6-ns { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } .order-7-ns { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } .order-8-ns { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } .order-last-ns { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } .flex-grow-0-ns { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } .flex-grow-1-ns { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } .flex-shrink-0-ns { -ms-flex-negative: 0; flex-shrink: 0; } .flex-shrink-1-ns { -ms-flex-negative: 1; flex-shrink: 1; } } @media screen and (min-width: 30em) and (max-width: 60em) { .flex-m { display: -webkit-box; display: -ms-flexbox; display: flex; } .inline-flex-m { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } .flex-auto-m { -webkit-box-flex: 1; -ms-flex: 1 1 auto; flex: 1 1 auto; min-width: 0; /* 1 */ min-height: 0; /* 1 */ } .flex-none-m { -webkit-box-flex: 0; -ms-flex: none; flex: none; } .flex-column-m { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } .flex-row-m { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } .flex-wrap-m { -ms-flex-wrap: wrap; flex-wrap: wrap; } .flex-nowrap-m { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } .flex-wrap-reverse-m { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } .flex-column-reverse-m { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } .flex-row-reverse-m { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } .items-start-m { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } .items-end-m { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } .items-center-m { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } .items-baseline-m { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } .items-stretch-m { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } .self-start-m { -ms-flex-item-align: start; align-self: flex-start; } .self-end-m { -ms-flex-item-align: end; align-self: flex-end; } .self-center-m { -ms-flex-item-align: center; align-self: center; } .self-baseline-m { -ms-flex-item-align: baseline; align-self: baseline; } .self-stretch-m { -ms-flex-item-align: stretch; align-self: stretch; } .justify-start-m { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } .justify-end-m { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } .justify-center-m { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } .justify-between-m { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } .justify-around-m { -ms-flex-pack: distribute; justify-content: space-around; } .content-start-m { -ms-flex-line-pack: start; align-content: flex-start; } .content-end-m { -ms-flex-line-pack: end; align-content: flex-end; } .content-center-m { -ms-flex-line-pack: center; align-content: center; } .content-between-m { -ms-flex-line-pack: justify; align-content: space-between; } .content-around-m { -ms-flex-line-pack: distribute; align-content: space-around; } .content-stretch-m { -ms-flex-line-pack: stretch; align-content: stretch; } .order-0-m { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } .order-1-m { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } .order-2-m { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } .order-3-m { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } .order-4-m { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } .order-5-m { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } .order-6-m { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } .order-7-m { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } .order-8-m { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } .order-last-m { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } .flex-grow-0-m { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } .flex-grow-1-m { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } .flex-shrink-0-m { -ms-flex-negative: 0; flex-shrink: 0; } .flex-shrink-1-m { -ms-flex-negative: 1; flex-shrink: 1; } } @media screen and (min-width: 60em) { .flex-l { display: -webkit-box; display: -ms-flexbox; display: flex; } .inline-flex-l { display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; } .flex-auto-l { -webkit-box-flex: 1; -ms-flex: 1 1 auto; flex: 1 1 auto; min-width: 0; /* 1 */ min-height: 0; /* 1 */ } .flex-none-l { -webkit-box-flex: 0; -ms-flex: none; flex: none; } .flex-column-l { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } .flex-row-l { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; } .flex-wrap-l { -ms-flex-wrap: wrap; flex-wrap: wrap; } .flex-nowrap-l { -ms-flex-wrap: nowrap; flex-wrap: nowrap; } .flex-wrap-reverse-l { -ms-flex-wrap: wrap-reverse; flex-wrap: wrap-reverse; } .flex-column-reverse-l { -webkit-box-orient: vertical; -webkit-box-direction: reverse; -ms-flex-direction: column-reverse; flex-direction: column-reverse; } .flex-row-reverse-l { -webkit-box-orient: horizontal; -webkit-box-direction: reverse; -ms-flex-direction: row-reverse; flex-direction: row-reverse; } .items-start-l { -webkit-box-align: start; -ms-flex-align: start; align-items: flex-start; } .items-end-l { -webkit-box-align: end; -ms-flex-align: end; align-items: flex-end; } .items-center-l { -webkit-box-align: center; -ms-flex-align: center; align-items: center; } .items-baseline-l { -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } .items-stretch-l { -webkit-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; } .self-start-l { -ms-flex-item-align: start; align-self: flex-start; } .self-end-l { -ms-flex-item-align: end; align-self: flex-end; } .self-center-l { -ms-flex-item-align: center; align-self: center; } .self-baseline-l { -ms-flex-item-align: baseline; align-self: baseline; } .self-stretch-l { -ms-flex-item-align: stretch; align-self: stretch; } .justify-start-l { -webkit-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; } .justify-end-l { -webkit-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; } .justify-center-l { -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; } .justify-between-l { -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; } .justify-around-l { -ms-flex-pack: distribute; justify-content: space-around; } .content-start-l { -ms-flex-line-pack: start; align-content: flex-start; } .content-end-l { -ms-flex-line-pack: end; align-content: flex-end; } .content-center-l { -ms-flex-line-pack: center; align-content: center; } .content-between-l { -ms-flex-line-pack: justify; align-content: space-between; } .content-around-l { -ms-flex-line-pack: distribute; align-content: space-around; } .content-stretch-l { -ms-flex-line-pack: stretch; align-content: stretch; } .order-0-l { -webkit-box-ordinal-group: 1; -ms-flex-order: 0; order: 0; } .order-1-l { -webkit-box-ordinal-group: 2; -ms-flex-order: 1; order: 1; } .order-2-l { -webkit-box-ordinal-group: 3; -ms-flex-order: 2; order: 2; } .order-3-l { -webkit-box-ordinal-group: 4; -ms-flex-order: 3; order: 3; } .order-4-l { -webkit-box-ordinal-group: 5; -ms-flex-order: 4; order: 4; } .order-5-l { -webkit-box-ordinal-group: 6; -ms-flex-order: 5; order: 5; } .order-6-l { -webkit-box-ordinal-group: 7; -ms-flex-order: 6; order: 6; } .order-7-l { -webkit-box-ordinal-group: 8; -ms-flex-order: 7; order: 7; } .order-8-l { -webkit-box-ordinal-group: 9; -ms-flex-order: 8; order: 8; } .order-last-l { -webkit-box-ordinal-group: 100000; -ms-flex-order: 99999; order: 99999; } .flex-grow-0-l { -webkit-box-flex: 0; -ms-flex-positive: 0; flex-grow: 0; } .flex-grow-1-l { -webkit-box-flex: 1; -ms-flex-positive: 1; flex-grow: 1; } .flex-shrink-0-l { -ms-flex-negative: 0; flex-shrink: 0; } .flex-shrink-1-l { -ms-flex-negative: 1; flex-shrink: 1; } } /* FLOATS http://tachyons.io/docs/layout/floats/ 1. Floated elements are automatically rendered as block level elements. Setting floats to display inline will fix the double margin bug in ie6. You know... just in case. 2. Don't forget to clearfix your floats with .cf Base: f = float Modifiers: l = left r = right n = none Media Query Extensions: -ns = not-small -m = medium -l = large */ .fl { float: left; _display: inline; } .fr { float: right; _display: inline; } .fn { float: none; } @media screen and (min-width: 30em) { .fl-ns { float: left; _display: inline; } .fr-ns { float: right; _display: inline; } .fn-ns { float: none; } } @media screen and (min-width: 30em) and (max-width: 60em) { .fl-m { float: left; _display: inline; } .fr-m { float: right; _display: inline; } .fn-m { float: none; } } @media screen and (min-width: 60em) { .fl-l { float: left; _display: inline; } .fr-l { float: right; _display: inline; } .fn-l { float: none; } } /*@import 'tachyons/src/_font-family';*/ /* FONT STYLE Docs: http://tachyons.io/docs/typography/font-style/ Media Query Extensions: -ns = not-small -m = medium -l = large */ .i { font-style: italic; } .fs-normal { font-style: normal; } @media screen and (min-width: 30em) { .i-ns { font-style: italic; } .fs-normal-ns { font-style: normal; } } @media screen and (min-width: 30em) and (max-width: 60em) { .i-m { font-style: italic; } .fs-normal-m { font-style: normal; } } @media screen and (min-width: 60em) { .i-l { font-style: italic; } .fs-normal-l { font-style: normal; } } /* FONT WEIGHT Docs: http://tachyons.io/docs/typography/font-weight/ Base fw = font-weight Modifiers: 1 = literal value 100 2 = literal value 200 3 = literal value 300 4 = literal value 400 5 = literal value 500 6 = literal value 600 7 = literal value 700 8 = literal value 800 9 = literal value 900 Media Query Extensions: -ns = not-small -m = medium -l = large */ .normal { font-weight: normal; } .b { font-weight: bold; } .fw1 { font-weight: 100; } .fw2 { font-weight: 200; } .fw3 { font-weight: 300; } .fw4 { font-weight: 400; } .fw5 { font-weight: 500; } .fw6 { font-weight: 600; } .fw7 { font-weight: 700; } .fw8 { font-weight: 800; } .fw9 { font-weight: 900; } @media screen and (min-width: 30em) { .normal-ns { font-weight: normal; } .b-ns { font-weight: bold; } .fw1-ns { font-weight: 100; } .fw2-ns { font-weight: 200; } .fw3-ns { font-weight: 300; } .fw4-ns { font-weight: 400; } .fw5-ns { font-weight: 500; } .fw6-ns { font-weight: 600; } .fw7-ns { font-weight: 700; } .fw8-ns { font-weight: 800; } .fw9-ns { font-weight: 900; } } @media screen and (min-width: 30em) and (max-width: 60em) { .normal-m { font-weight: normal; } .b-m { font-weight: bold; } .fw1-m { font-weight: 100; } .fw2-m { font-weight: 200; } .fw3-m { font-weight: 300; } .fw4-m { font-weight: 400; } .fw5-m { font-weight: 500; } .fw6-m { font-weight: 600; } .fw7-m { font-weight: 700; } .fw8-m { font-weight: 800; } .fw9-m { font-weight: 900; } } @media screen and (min-width: 60em) { .normal-l { font-weight: normal; } .b-l { font-weight: bold; } .fw1-l { font-weight: 100; } .fw2-l { font-weight: 200; } .fw3-l { font-weight: 300; } .fw4-l { font-weight: 400; } .fw5-l { font-weight: 500; } .fw6-l { font-weight: 600; } .fw7-l { font-weight: 700; } .fw8-l { font-weight: 800; } .fw9-l { font-weight: 900; } } /* FORMS */ .input-reset { -webkit-appearance: none; -moz-appearance: none; } .button-reset::-moz-focus-inner, .input-reset::-moz-focus-inner { border: 0; padding: 0; } /* HEIGHTS Docs: http://tachyons.io/docs/layout/heights/ Base: h = height min-h = min-height min-vh = min-height vertical screen height vh = vertical screen height Modifiers 1 = 1st step in height scale 2 = 2nd step in height scale 3 = 3rd step in height scale 4 = 4th step in height scale 5 = 5th step in height scale -25 = literal value 25% -50 = literal value 50% -75 = literal value 75% -100 = literal value 100% -auto = string value of auto -inherit = string value of inherit Media Query Extensions: -ns = not-small -m = medium -l = large */ /* Height Scale */ .h1 { height: 1rem; } .h2 { height: 2rem; } .h3 { height: 4rem; } .h4 { height: 8rem; } .h5 { height: 16rem; } /* Height Percentages - Based off of height of parent */ .h-25 { height: 25%; } .h-50 { height: 50%; } .h-75 { height: 75%; } .h-100 { height: 100%; } .min-h-100 { min-height: 100%; } /* Screen Height Percentage */ .vh-25 { height: 25vh; } .vh-50 { height: 50vh; } .vh-75 { height: 75vh; } .vh-100 { height: 100vh; } .min-vh-100 { min-height: 100vh; } /* String Properties */ .h-auto { height: auto; } .h-inherit { height: inherit; } @media screen and (min-width: 30em) { .h1-ns { height: 1rem; } .h2-ns { height: 2rem; } .h3-ns { height: 4rem; } .h4-ns { height: 8rem; } .h5-ns { height: 16rem; } .h-25-ns { height: 25%; } .h-50-ns { height: 50%; } .h-75-ns { height: 75%; } .h-100-ns { height: 100%; } .min-h-100-ns { min-height: 100%; } .vh-25-ns { height: 25vh; } .vh-50-ns { height: 50vh; } .vh-75-ns { height: 75vh; } .vh-100-ns { height: 100vh; } .min-vh-100-ns { min-height: 100vh; } .h-auto-ns { height: auto; } .h-inherit-ns { height: inherit; } } @media screen and (min-width: 30em) and (max-width: 60em) { .h1-m { height: 1rem; } .h2-m { height: 2rem; } .h3-m { height: 4rem; } .h4-m { height: 8rem; } .h5-m { height: 16rem; } .h-25-m { height: 25%; } .h-50-m { height: 50%; } .h-75-m { height: 75%; } .h-100-m { height: 100%; } .min-h-100-m { min-height: 100%; } .vh-25-m { height: 25vh; } .vh-50-m { height: 50vh; } .vh-75-m { height: 75vh; } .vh-100-m { height: 100vh; } .min-vh-100-m { min-height: 100vh; } .h-auto-m { height: auto; } .h-inherit-m { height: inherit; } } @media screen and (min-width: 60em) { .h1-l { height: 1rem; } .h2-l { height: 2rem; } .h3-l { height: 4rem; } .h4-l { height: 8rem; } .h5-l { height: 16rem; } .h-25-l { height: 25%; } .h-50-l { height: 50%; } .h-75-l { height: 75%; } .h-100-l { height: 100%; } .min-h-100-l { min-height: 100%; } .vh-25-l { height: 25vh; } .vh-50-l { height: 50vh; } .vh-75-l { height: 75vh; } .vh-100-l { height: 100vh; } .min-vh-100-l { min-height: 100vh; } .h-auto-l { height: auto; } .h-inherit-l { height: inherit; } } /* LETTER SPACING Docs: http://tachyons.io/docs/typography/tracking/ Media Query Extensions: -ns = not-small -m = medium -l = large */ .tracked { letter-spacing: .1em; } .tracked-tight { letter-spacing: -.05em; } .tracked-mega { letter-spacing: .25em; } @media screen and (min-width: 30em) { .tracked-ns { letter-spacing: .1em; } .tracked-tight-ns { letter-spacing: -.05em; } .tracked-mega-ns { letter-spacing: .25em; } } @media screen and (min-width: 30em) and (max-width: 60em) { .tracked-m { letter-spacing: .1em; } .tracked-tight-m { letter-spacing: -.05em; } .tracked-mega-m { letter-spacing: .25em; } } @media screen and (min-width: 60em) { .tracked-l { letter-spacing: .1em; } .tracked-tight-l { letter-spacing: -.05em; } .tracked-mega-l { letter-spacing: .25em; } } /* LINE HEIGHT / LEADING Docs: http://tachyons.io/docs/typography/line-height Media Query Extensions: -ns = not-small -m = medium -l = large */ .lh-solid { line-height: 1; } .lh-title { line-height: 1.25; } .lh-copy { line-height: 1.5; } @media screen and (min-width: 30em) { .lh-solid-ns { line-height: 1; } .lh-title-ns { line-height: 1.25; } .lh-copy-ns { line-height: 1.5; } } @media screen and (min-width: 30em) and (max-width: 60em) { .lh-solid-m { line-height: 1; } .lh-title-m { line-height: 1.25; } .lh-copy-m { line-height: 1.5; } } @media screen and (min-width: 60em) { .lh-solid-l { line-height: 1; } .lh-title-l { line-height: 1.25; } .lh-copy-l { line-height: 1.5; } } /* LINKS Docs: http://tachyons.io/docs/elements/links/ */ .link { text-decoration: none; -webkit-transition: color .15s ease-in; transition: color .15s ease-in; } .link:link, .link:visited { -webkit-transition: color .15s ease-in; transition: color .15s ease-in; } .link:hover { -webkit-transition: color .15s ease-in; transition: color .15s ease-in; } .link:active { -webkit-transition: color .15s ease-in; transition: color .15s ease-in; } .link:focus { -webkit-transition: color .15s ease-in; transition: color .15s ease-in; outline: 1px dotted currentColor; } /* LISTS http://tachyons.io/docs/elements/lists/ */ .list { list-style-type: none; } /* MAX WIDTHS Docs: http://tachyons.io/docs/layout/max-widths/ Base: mw = max-width Modifiers 1 = 1st step in width scale 2 = 2nd step in width scale 3 = 3rd step in width scale 4 = 4th step in width scale 5 = 5th step in width scale 6 = 6st step in width scale 7 = 7nd step in width scale 8 = 8rd step in width scale 9 = 9th step in width scale -100 = literal value 100% -none = string value none Media Query Extensions: -ns = not-small -m = medium -l = large */ /* Max Width Percentages */ .mw-100 { max-width: 100%; } /* Max Width Scale */ .mw1 { max-width: 1rem; } .mw2 { max-width: 2rem; } .mw3 { max-width: 4rem; } .mw4 { max-width: 8rem; } .mw5 { max-width: 16rem; } .mw6 { max-width: 32rem; } .mw7 { max-width: 48rem; } .mw8 { max-width: 64rem; } .mw9 { max-width: 96rem; } /* Max Width String Properties */ .mw-none { max-width: none; } @media screen and (min-width: 30em) { .mw-100-ns { max-width: 100%; } .mw1-ns { max-width: 1rem; } .mw2-ns { max-width: 2rem; } .mw3-ns { max-width: 4rem; } .mw4-ns { max-width: 8rem; } .mw5-ns { max-width: 16rem; } .mw6-ns { max-width: 32rem; } .mw7-ns { max-width: 48rem; } .mw8-ns { max-width: 64rem; } .mw9-ns { max-width: 96rem; } .mw-none-ns { max-width: none; } } @media screen and (min-width: 30em) and (max-width: 60em) { .mw-100-m { max-width: 100%; } .mw1-m { max-width: 1rem; } .mw2-m { max-width: 2rem; } .mw3-m { max-width: 4rem; } .mw4-m { max-width: 8rem; } .mw5-m { max-width: 16rem; } .mw6-m { max-width: 32rem; } .mw7-m { max-width: 48rem; } .mw8-m { max-width: 64rem; } .mw9-m { max-width: 96rem; } .mw-none-m { max-width: none; } } @media screen and (min-width: 60em) { .mw-100-l { max-width: 100%; } .mw1-l { max-width: 1rem; } .mw2-l { max-width: 2rem; } .mw3-l { max-width: 4rem; } .mw4-l { max-width: 8rem; } .mw5-l { max-width: 16rem; } .mw6-l { max-width: 32rem; } .mw7-l { max-width: 48rem; } .mw8-l { max-width: 64rem; } .mw9-l { max-width: 96rem; } .mw-none-l { max-width: none; } } /* WIDTHS Docs: http://tachyons.io/docs/layout/widths/ Base: w = width Modifiers 1 = 1st step in width scale 2 = 2nd step in width scale 3 = 3rd step in width scale 4 = 4th step in width scale 5 = 5th step in width scale -10 = literal value 10% -20 = literal value 20% -25 = literal value 25% -30 = literal value 30% -33 = literal value 33% -34 = literal value 34% -40 = literal value 40% -50 = literal value 50% -60 = literal value 60% -70 = literal value 70% -75 = literal value 75% -80 = literal value 80% -90 = literal value 90% -100 = literal value 100% -third = 100% / 3 (Not supported in opera mini or IE8) -two-thirds = 100% / 1.5 (Not supported in opera mini or IE8) -auto = string value auto Media Query Extensions: -ns = not-small -m = medium -l = large */ /* Width Scale */ .w1 { width: 1rem; } .w2 { width: 2rem; } .w3 { width: 4rem; } .w4 { width: 8rem; } .w5 { width: 16rem; } .w-10 { width: 10%; } .w-20 { width: 20%; } .w-25 { width: 25%; } .w-30 { width: 30%; } .w-33 { width: 33%; } .w-34 { width: 34%; } .w-40 { width: 40%; } .w-50 { width: 50%; } .w-60 { width: 60%; } .w-70 { width: 70%; } .w-75 { width: 75%; } .w-80 { width: 80%; } .w-90 { width: 90%; } .w-100 { width: 100%; } .w-third { width: 33.33333%; } .w-two-thirds { width: 66.66667%; } .w-auto { width: auto; } @media screen and (min-width: 30em) { .w1-ns { width: 1rem; } .w2-ns { width: 2rem; } .w3-ns { width: 4rem; } .w4-ns { width: 8rem; } .w5-ns { width: 16rem; } .w-10-ns { width: 10%; } .w-20-ns { width: 20%; } .w-25-ns { width: 25%; } .w-30-ns { width: 30%; } .w-33-ns { width: 33%; } .w-34-ns { width: 34%; } .w-40-ns { width: 40%; } .w-50-ns { width: 50%; } .w-60-ns { width: 60%; } .w-70-ns { width: 70%; } .w-75-ns { width: 75%; } .w-80-ns { width: 80%; } .w-90-ns { width: 90%; } .w-100-ns { width: 100%; } .w-third-ns { width: 33.33333%; } .w-two-thirds-ns { width: 66.66667%; } .w-auto-ns { width: auto; } } @media screen and (min-width: 30em) and (max-width: 60em) { .w1-m { width: 1rem; } .w2-m { width: 2rem; } .w3-m { width: 4rem; } .w4-m { width: 8rem; } .w5-m { width: 16rem; } .w-10-m { width: 10%; } .w-20-m { width: 20%; } .w-25-m { width: 25%; } .w-30-m { width: 30%; } .w-33-m { width: 33%; } .w-34-m { width: 34%; } .w-40-m { width: 40%; } .w-50-m { width: 50%; } .w-60-m { width: 60%; } .w-70-m { width: 70%; } .w-75-m { width: 75%; } .w-80-m { width: 80%; } .w-90-m { width: 90%; } .w-100-m { width: 100%; } .w-third-m { width: 33.33333%; } .w-two-thirds-m { width: 66.66667%; } .w-auto-m { width: auto; } } @media screen and (min-width: 60em) { .w1-l { width: 1rem; } .w2-l { width: 2rem; } .w3-l { width: 4rem; } .w4-l { width: 8rem; } .w5-l { width: 16rem; } .w-10-l { width: 10%; } .w-20-l { width: 20%; } .w-25-l { width: 25%; } .w-30-l { width: 30%; } .w-33-l { width: 33%; } .w-34-l { width: 34%; } .w-40-l { width: 40%; } .w-50-l { width: 50%; } .w-60-l { width: 60%; } .w-70-l { width: 70%; } .w-75-l { width: 75%; } .w-80-l { width: 80%; } .w-90-l { width: 90%; } .w-100-l { width: 100%; } .w-third-l { width: 33.33333%; } .w-two-thirds-l { width: 66.66667%; } .w-auto-l { width: auto; } } /* OVERFLOW Media Query Extensions: -ns = not-small -m = medium -l = large */ .overflow-visible { overflow: visible; } .overflow-hidden { overflow: hidden; } .overflow-scroll { overflow: scroll; } .overflow-auto { overflow: auto; } .overflow-x-visible { overflow-x: visible; } .overflow-x-hidden { overflow-x: hidden; } .overflow-x-scroll { overflow-x: scroll; } .overflow-x-auto { overflow-x: auto; } .overflow-y-visible { overflow-y: visible; } .overflow-y-hidden { overflow-y: hidden; } .overflow-y-scroll { overflow-y: scroll; } .overflow-y-auto { overflow-y: auto; } @media screen and (min-width: 30em) { .overflow-visible-ns { overflow: visible; } .overflow-hidden-ns { overflow: hidden; } .overflow-scroll-ns { overflow: scroll; } .overflow-auto-ns { overflow: auto; } .overflow-x-visible-ns { overflow-x: visible; } .overflow-x-hidden-ns { overflow-x: hidden; } .overflow-x-scroll-ns { overflow-x: scroll; } .overflow-x-auto-ns { overflow-x: auto; } .overflow-y-visible-ns { overflow-y: visible; } .overflow-y-hidden-ns { overflow-y: hidden; } .overflow-y-scroll-ns { overflow-y: scroll; } .overflow-y-auto-ns { overflow-y: auto; } } @media screen and (min-width: 30em) and (max-width: 60em) { .overflow-visible-m { overflow: visible; } .overflow-hidden-m { overflow: hidden; } .overflow-scroll-m { overflow: scroll; } .overflow-auto-m { overflow: auto; } .overflow-x-visible-m { overflow-x: visible; } .overflow-x-hidden-m { overflow-x: hidden; } .overflow-x-scroll-m { overflow-x: scroll; } .overflow-x-auto-m { overflow-x: auto; } .overflow-y-visible-m { overflow-y: visible; } .overflow-y-hidden-m { overflow-y: hidden; } .overflow-y-scroll-m { overflow-y: scroll; } .overflow-y-auto-m { overflow-y: auto; } } @media screen and (min-width: 60em) { .overflow-visible-l { overflow: visible; } .overflow-hidden-l { overflow: hidden; } .overflow-scroll-l { overflow: scroll; } .overflow-auto-l { overflow: auto; } .overflow-x-visible-l { overflow-x: visible; } .overflow-x-hidden-l { overflow-x: hidden; } .overflow-x-scroll-l { overflow-x: scroll; } .overflow-x-auto-l { overflow-x: auto; } .overflow-y-visible-l { overflow-y: visible; } .overflow-y-hidden-l { overflow-y: hidden; } .overflow-y-scroll-l { overflow-y: scroll; } .overflow-y-auto-l { overflow-y: auto; } } /* POSITIONING Docs: http://tachyons.io/docs/layout/position/ Media Query Extensions: -ns = not-small -m = medium -l = large */ .static { position: static; } .relative { position: relative; } .absolute { position: absolute; } .fixed { position: fixed; } @media screen and (min-width: 30em) { .static-ns { position: static; } .relative-ns { position: relative; } .absolute-ns { position: absolute; } .fixed-ns { position: fixed; } } @media screen and (min-width: 30em) and (max-width: 60em) { .static-m { position: static; } .relative-m { position: relative; } .absolute-m { position: absolute; } .fixed-m { position: fixed; } } @media screen and (min-width: 60em) { .static-l { position: static; } .relative-l { position: relative; } .absolute-l { position: absolute; } .fixed-l { position: fixed; } } /* OPACITY Docs: http://tachyons.io/docs/themes/opacity/ */ .o-100 { opacity: 1; } .o-90 { opacity: .9; } .o-80 { opacity: .8; } .o-70 { opacity: .7; } .o-60 { opacity: .6; } .o-50 { opacity: .5; } .o-40 { opacity: .4; } .o-30 { opacity: .3; } .o-20 { opacity: .2; } .o-10 { opacity: .1; } .o-05 { opacity: .05; } .o-025 { opacity: .025; } .o-0 { opacity: 0; } /*@import 'tachyons/src/_rotations';*/ /* SKINS Docs: http://tachyons.io/docs/themes/skins/ Classes for setting foreground and background colors on elements. If you haven't declared a border color, but set border on an element, it will be set to the current text color. */ /* Text colors */ .black-90 { color: rgba(0, 0, 0, .9); } .black-80 { color: rgba(0, 0, 0, .8); } .black-70 { color: rgba(0, 0, 0, .7); } .black-60 { color: rgba(0, 0, 0, .6); } .black-50 { color: rgba(0, 0, 0, .5); } .black-40 { color: rgba(0, 0, 0, .4); } .black-30 { color: rgba(0, 0, 0, .3); } .black-20 { color: rgba(0, 0, 0, .2); } .black-10 { color: rgba(0, 0, 0, .1); } .black-05 { color: rgba(0, 0, 0, .05); } .white-90 { color: rgba(255, 255, 255, .9); } .white-80 { color: rgba(255, 255, 255, .8); } .white-70 { color: rgba(255, 255, 255, .7); } .white-60 { color: rgba(255, 255, 255, .6); } .white-50 { color: rgba(255, 255, 255, .5); } .white-40 { color: rgba(255, 255, 255, .4); } .white-30 { color: rgba(255, 255, 255, .3); } .white-20 { color: rgba(255, 255, 255, .2); } .white-10 { color: rgba(255, 255, 255, .1); } .black { color: #000; } .near-black { color: #111; } .dark-gray { color: #333; } .mid-gray { color: #555; } .gray { color: #777; } .silver { color: #999; } .light-silver { color: #aaa; } .moon-gray { color: #ccc; } .light-gray { color: #eee; } .near-white { color: #f4f4f4; } .white { color: #fff; } .dark-red { color: #e7040f; } .red { color: #ff4136; } .light-red { color: #ff725c; } .orange { color: #ff6300; } .gold { color: #ffb700; } .yellow { color: #ffd700; } .light-yellow { color: #fbf1a9; } .purple { color: #5e2ca5; } .light-purple { color: #a463f2; } .dark-pink { color: #d5008f; } .hot-pink { color: #ff41b4; } .pink { color: #ff80cc; } .light-pink { color: #ffa3d7; } .dark-green { color: #137752; } .green { color: #19a974; } .light-green { color: #9eebcf; } .navy { color: #001b44; } .dark-blue { color: #00449e; } .blue { color: #0594CB; } .light-blue { color: #96ccff; } .lightest-blue { color: #cdecff; } .washed-blue { color: #f6fffe; } .washed-green { color: #e8fdf5; } .washed-yellow { color: #fffceb; } .washed-red { color: #ffdfdf; } .color-inherit { color: inherit; } .bg-black-90 { background-color: rgba(0, 0, 0, .9); } .bg-black-80 { background-color: rgba(0, 0, 0, .8); } .bg-black-70 { background-color: rgba(0, 0, 0, .7); } .bg-black-60 { background-color: rgba(0, 0, 0, .6); } .bg-black-50 { background-color: rgba(0, 0, 0, .5); } .bg-black-40 { background-color: rgba(0, 0, 0, .4); } .bg-black-30 { background-color: rgba(0, 0, 0, .3); } .bg-black-20 { background-color: rgba(0, 0, 0, .2); } .bg-black-10 { background-color: rgba(0, 0, 0, .1); } .bg-black-05 { background-color: rgba(0, 0, 0, .05); } .bg-white-90 { background-color: rgba(255, 255, 255, .9); } .bg-white-80 { background-color: rgba(255, 255, 255, .8); } .bg-white-70 { background-color: rgba(255, 255, 255, .7); } .bg-white-60 { background-color: rgba(255, 255, 255, .6); } .bg-white-50 { background-color: rgba(255, 255, 255, .5); } .bg-white-40 { background-color: rgba(255, 255, 255, .4); } .bg-white-30 { background-color: rgba(255, 255, 255, .3); } .bg-white-20 { background-color: rgba(255, 255, 255, .2); } .bg-white-10 { background-color: rgba(255, 255, 255, .1); } /* Background colors */ .bg-black { background-color: #000; } .bg-near-black { background-color: #111; } .bg-dark-gray { background-color: #333; } .bg-mid-gray { background-color: #555; } .bg-gray { background-color: #777; } .bg-silver { background-color: #999; } .bg-light-silver { background-color: #aaa; } .bg-moon-gray { background-color: #ccc; } .bg-light-gray { background-color: #eee; } .bg-near-white { background-color: #f4f4f4; } .bg-white { background-color: #fff; } .bg-transparent { background-color: transparent; } .bg-dark-red { background-color: #e7040f; } .bg-red { background-color: #ff4136; } .bg-light-red { background-color: #ff725c; } .bg-orange { background-color: #ff6300; } .bg-gold { background-color: #ffb700; } .bg-yellow { background-color: #ffd700; } .bg-light-yellow { background-color: #fbf1a9; } .bg-purple { background-color: #5e2ca5; } .bg-light-purple { background-color: #a463f2; } .bg-dark-pink { background-color: #d5008f; } .bg-hot-pink { background-color: #ff41b4; } .bg-pink { background-color: #ff80cc; } .bg-light-pink { background-color: #ffa3d7; } .bg-dark-green { background-color: #137752; } .bg-green { background-color: #19a974; } .bg-light-green { background-color: #9eebcf; } .bg-navy { background-color: #001b44; } .bg-dark-blue { background-color: #00449e; } .bg-blue { background-color: #0594CB; } .bg-light-blue { background-color: #96ccff; } .bg-lightest-blue { background-color: #cdecff; } .bg-washed-blue { background-color: #f6fffe; } .bg-washed-green { background-color: #e8fdf5; } .bg-washed-yellow { background-color: #fffceb; } .bg-washed-red { background-color: #ffdfdf; } .bg-inherit { background-color: inherit; } /* SKINS:PSEUDO Customize the color of an element when it is focused or hovered over. */ .hover-black:hover, .hover-black:focus { color: #000; } .hover-near-black:hover, .hover-near-black:focus { color: #111; } .hover-dark-gray:hover, .hover-dark-gray:focus { color: #333; } .hover-mid-gray:hover, .hover-mid-gray:focus { color: #555; } .hover-gray:hover, .hover-gray:focus { color: #777; } .hover-silver:hover, .hover-silver:focus { color: #999; } .hover-light-silver:hover, .hover-light-silver:focus { color: #aaa; } .hover-moon-gray:hover, .hover-moon-gray:focus { color: #ccc; } .hover-light-gray:hover, .hover-light-gray:focus { color: #eee; } .hover-near-white:hover, .hover-near-white:focus { color: #f4f4f4; } .hover-white:hover, .hover-white:focus { color: #fff; } .hover-black-90:hover, .hover-black-90:focus { color: rgba(0, 0, 0, .9); } .hover-black-80:hover, .hover-black-80:focus { color: rgba(0, 0, 0, .8); } .hover-black-70:hover, .hover-black-70:focus { color: rgba(0, 0, 0, .7); } .hover-black-60:hover, .hover-black-60:focus { color: rgba(0, 0, 0, .6); } .hover-black-50:hover, .hover-black-50:focus { color: rgba(0, 0, 0, .5); } .hover-black-40:hover, .hover-black-40:focus { color: rgba(0, 0, 0, .4); } .hover-black-30:hover, .hover-black-30:focus { color: rgba(0, 0, 0, .3); } .hover-black-20:hover, .hover-black-20:focus { color: rgba(0, 0, 0, .2); } .hover-black-10:hover, .hover-black-10:focus { color: rgba(0, 0, 0, .1); } .hover-white-90:hover, .hover-white-90:focus { color: rgba(255, 255, 255, .9); } .hover-white-80:hover, .hover-white-80:focus { color: rgba(255, 255, 255, .8); } .hover-white-70:hover, .hover-white-70:focus { color: rgba(255, 255, 255, .7); } .hover-white-60:hover, .hover-white-60:focus { color: rgba(255, 255, 255, .6); } .hover-white-50:hover, .hover-white-50:focus { color: rgba(255, 255, 255, .5); } .hover-white-40:hover, .hover-white-40:focus { color: rgba(255, 255, 255, .4); } .hover-white-30:hover, .hover-white-30:focus { color: rgba(255, 255, 255, .3); } .hover-white-20:hover, .hover-white-20:focus { color: rgba(255, 255, 255, .2); } .hover-white-10:hover, .hover-white-10:focus { color: rgba(255, 255, 255, .1); } .hover-inherit:hover, .hover-inherit:focus { color: inherit; } .hover-bg-black:hover, .hover-bg-black:focus { background-color: #000; } .hover-bg-near-black:hover, .hover-bg-near-black:focus { background-color: #111; } .hover-bg-dark-gray:hover, .hover-bg-dark-gray:focus { background-color: #333; } .hover-bg-mid-gray:hover, .hover-bg-mid-gray:focus { background-color: #555; } .hover-bg-gray:hover, .hover-bg-gray:focus { background-color: #777; } .hover-bg-silver:hover, .hover-bg-silver:focus { background-color: #999; } .hover-bg-light-silver:hover, .hover-bg-light-silver:focus { background-color: #aaa; } .hover-bg-moon-gray:hover, .hover-bg-moon-gray:focus { background-color: #ccc; } .hover-bg-light-gray:hover, .hover-bg-light-gray:focus { background-color: #eee; } .hover-bg-near-white:hover, .hover-bg-near-white:focus { background-color: #f4f4f4; } .hover-bg-white:hover, .hover-bg-white:focus { background-color: #fff; } .hover-bg-transparent:hover, .hover-bg-transparent:focus { background-color: transparent; } .hover-bg-black-90:hover, .hover-bg-black-90:focus { background-color: rgba(0, 0, 0, .9); } .hover-bg-black-80:hover, .hover-bg-black-80:focus { background-color: rgba(0, 0, 0, .8); } .hover-bg-black-70:hover, .hover-bg-black-70:focus { background-color: rgba(0, 0, 0, .7); } .hover-bg-black-60:hover, .hover-bg-black-60:focus { background-color: rgba(0, 0, 0, .6); } .hover-bg-black-50:hover, .hover-bg-black-50:focus { background-color: rgba(0, 0, 0, .5); } .hover-bg-black-40:hover, .hover-bg-black-40:focus { background-color: rgba(0, 0, 0, .4); } .hover-bg-black-30:hover, .hover-bg-black-30:focus { background-color: rgba(0, 0, 0, .3); } .hover-bg-black-20:hover, .hover-bg-black-20:focus { background-color: rgba(0, 0, 0, .2); } .hover-bg-black-10:hover, .hover-bg-black-10:focus { background-color: rgba(0, 0, 0, .1); } .hover-bg-white-90:hover, .hover-bg-white-90:focus { background-color: rgba(255, 255, 255, .9); } .hover-bg-white-80:hover, .hover-bg-white-80:focus { background-color: rgba(255, 255, 255, .8); } .hover-bg-white-70:hover, .hover-bg-white-70:focus { background-color: rgba(255, 255, 255, .7); } .hover-bg-white-60:hover, .hover-bg-white-60:focus { background-color: rgba(255, 255, 255, .6); } .hover-bg-white-50:hover, .hover-bg-white-50:focus { background-color: rgba(255, 255, 255, .5); } .hover-bg-white-40:hover, .hover-bg-white-40:focus { background-color: rgba(255, 255, 255, .4); } .hover-bg-white-30:hover, .hover-bg-white-30:focus { background-color: rgba(255, 255, 255, .3); } .hover-bg-white-20:hover, .hover-bg-white-20:focus { background-color: rgba(255, 255, 255, .2); } .hover-bg-white-10:hover, .hover-bg-white-10:focus { background-color: rgba(255, 255, 255, .1); } .hover-dark-red:hover, .hover-dark-red:focus { color: #e7040f; } .hover-red:hover, .hover-red:focus { color: #ff4136; } .hover-light-red:hover, .hover-light-red:focus { color: #ff725c; } .hover-orange:hover, .hover-orange:focus { color: #ff6300; } .hover-gold:hover, .hover-gold:focus { color: #ffb700; } .hover-yellow:hover, .hover-yellow:focus { color: #ffd700; } .hover-light-yellow:hover, .hover-light-yellow:focus { color: #fbf1a9; } .hover-purple:hover, .hover-purple:focus { color: #5e2ca5; } .hover-light-purple:hover, .hover-light-purple:focus { color: #a463f2; } .hover-dark-pink:hover, .hover-dark-pink:focus { color: #d5008f; } .hover-hot-pink:hover, .hover-hot-pink:focus { color: #ff41b4; } .hover-pink:hover, .hover-pink:focus { color: #ff80cc; } .hover-light-pink:hover, .hover-light-pink:focus { color: #ffa3d7; } .hover-dark-green:hover, .hover-dark-green:focus { color: #137752; } .hover-green:hover, .hover-green:focus { color: #19a974; } .hover-light-green:hover, .hover-light-green:focus { color: #9eebcf; } .hover-navy:hover, .hover-navy:focus { color: #001b44; } .hover-dark-blue:hover, .hover-dark-blue:focus { color: #00449e; } .hover-blue:hover, .hover-blue:focus { color: #0594CB; } .hover-light-blue:hover, .hover-light-blue:focus { color: #96ccff; } .hover-lightest-blue:hover, .hover-lightest-blue:focus { color: #cdecff; } .hover-washed-blue:hover, .hover-washed-blue:focus { color: #f6fffe; } .hover-washed-green:hover, .hover-washed-green:focus { color: #e8fdf5; } .hover-washed-yellow:hover, .hover-washed-yellow:focus { color: #fffceb; } .hover-washed-red:hover, .hover-washed-red:focus { color: #ffdfdf; } .hover-bg-dark-red:hover, .hover-bg-dark-red:focus { background-color: #e7040f; } .hover-bg-red:hover, .hover-bg-red:focus { background-color: #ff4136; } .hover-bg-light-red:hover, .hover-bg-light-red:focus { background-color: #ff725c; } .hover-bg-orange:hover, .hover-bg-orange:focus { background-color: #ff6300; } .hover-bg-gold:hover, .hover-bg-gold:focus { background-color: #ffb700; } .hover-bg-yellow:hover, .hover-bg-yellow:focus { background-color: #ffd700; } .hover-bg-light-yellow:hover, .hover-bg-light-yellow:focus { background-color: #fbf1a9; } .hover-bg-purple:hover, .hover-bg-purple:focus { background-color: #5e2ca5; } .hover-bg-light-purple:hover, .hover-bg-light-purple:focus { background-color: #a463f2; } .hover-bg-dark-pink:hover, .hover-bg-dark-pink:focus { background-color: #d5008f; } .hover-bg-hot-pink:hover, .hover-bg-hot-pink:focus { background-color: #ff41b4; } .hover-bg-pink:hover, .hover-bg-pink:focus { background-color: #ff80cc; } .hover-bg-light-pink:hover, .hover-bg-light-pink:focus { background-color: #ffa3d7; } .hover-bg-dark-green:hover, .hover-bg-dark-green:focus { background-color: #137752; } .hover-bg-green:hover, .hover-bg-green:focus { background-color: #19a974; } .hover-bg-light-green:hover, .hover-bg-light-green:focus { background-color: #9eebcf; } .hover-bg-navy:hover, .hover-bg-navy:focus { background-color: #001b44; } .hover-bg-dark-blue:hover, .hover-bg-dark-blue:focus { background-color: #00449e; } .hover-bg-blue:hover, .hover-bg-blue:focus { background-color: #0594CB; } .hover-bg-light-blue:hover, .hover-bg-light-blue:focus { background-color: #96ccff; } .hover-bg-lightest-blue:hover, .hover-bg-lightest-blue:focus { background-color: #cdecff; } .hover-bg-washed-blue:hover, .hover-bg-washed-blue:focus { background-color: #f6fffe; } .hover-bg-washed-green:hover, .hover-bg-washed-green:focus { background-color: #e8fdf5; } .hover-bg-washed-yellow:hover, .hover-bg-washed-yellow:focus { background-color: #fffceb; } .hover-bg-washed-red:hover, .hover-bg-washed-red:focus { background-color: #ffdfdf; } .hover-bg-inherit:hover, .hover-bg-inherit:focus { background-color: inherit; } /* Variables */ /* SPACING Docs: http://tachyons.io/docs/layout/spacing/ An eight step powers of two scale ranging from 0 to 16rem. Base: p = padding m = margin Modifiers: a = all h = horizontal v = vertical t = top r = right b = bottom l = left 0 = none 1 = 1st step in spacing scale 2 = 2nd step in spacing scale 3 = 3rd step in spacing scale 4 = 4th step in spacing scale 5 = 5th step in spacing scale 6 = 6th step in spacing scale 7 = 7th step in spacing scale Media Query Extensions: -ns = not-small -m = medium -l = large */ .pa0 { padding: 0; } .pa1 { padding: .25rem; } .pa2 { padding: .5rem; } .pa3 { padding: 1rem; } .pa4 { padding: 2rem; } .pa5 { padding: 4rem; } .pa6 { padding: 8rem; } .pa7 { padding: 16rem; } .pl0 { padding-left: 0; } .pl1 { padding-left: .25rem; } .pl2 { padding-left: .5rem; } .pl3 { padding-left: 1rem; } .pl4 { padding-left: 2rem; } .pl5 { padding-left: 4rem; } .pl6 { padding-left: 8rem; } .pl7 { padding-left: 16rem; } .pr0 { padding-right: 0; } .pr1 { padding-right: .25rem; } .pr2 { padding-right: .5rem; } .pr3 { padding-right: 1rem; } .pr4 { padding-right: 2rem; } .pr5 { padding-right: 4rem; } .pr6 { padding-right: 8rem; } .pr7 { padding-right: 16rem; } .pb0 { padding-bottom: 0; } .pb1 { padding-bottom: .25rem; } .pb2 { padding-bottom: .5rem; } .pb3 { padding-bottom: 1rem; } .pb4 { padding-bottom: 2rem; } .pb5 { padding-bottom: 4rem; } .pb6 { padding-bottom: 8rem; } .pb7 { padding-bottom: 16rem; } .pt0 { padding-top: 0; } .pt1 { padding-top: .25rem; } .pt2 { padding-top: .5rem; } .pt3 { padding-top: 1rem; } .pt4 { padding-top: 2rem; } .pt5 { padding-top: 4rem; } .pt6 { padding-top: 8rem; } .pt7 { padding-top: 16rem; } .pv0 { padding-top: 0; padding-bottom: 0; } .pv1 { padding-top: .25rem; padding-bottom: .25rem; } .pv2 { padding-top: .5rem; padding-bottom: .5rem; } .pv3 { padding-top: 1rem; padding-bottom: 1rem; } .pv4 { padding-top: 2rem; padding-bottom: 2rem; } .pv5 { padding-top: 4rem; padding-bottom: 4rem; } .pv6 { padding-top: 8rem; padding-bottom: 8rem; } .pv7 { padding-top: 16rem; padding-bottom: 16rem; } .ph0 { padding-left: 0; padding-right: 0; } .ph1 { padding-left: .25rem; padding-right: .25rem; } .ph2 { padding-left: .5rem; padding-right: .5rem; } .ph3 { padding-left: 1rem; padding-right: 1rem; } .ph4 { padding-left: 2rem; padding-right: 2rem; } .ph5 { padding-left: 4rem; padding-right: 4rem; } .ph6 { padding-left: 8rem; padding-right: 8rem; } .ph7 { padding-left: 16rem; padding-right: 16rem; } .ma0 { margin: 0; } .ma1 { margin: .25rem; } .ma2 { margin: .5rem; } .ma3 { margin: 1rem; } .ma4 { margin: 2rem; } .ma5 { margin: 4rem; } .ma6 { margin: 8rem; } .ma7 { margin: 16rem; } .ml0 { margin-left: 0; } .ml1 { margin-left: .25rem; } .ml2 { margin-left: .5rem; } .ml3 { margin-left: 1rem; } .ml4 { margin-left: 2rem; } .ml5 { margin-left: 4rem; } .ml6 { margin-left: 8rem; } .ml7 { margin-left: 16rem; } .mr0 { margin-right: 0; } .mr1 { margin-right: .25rem; } .mr2 { margin-right: .5rem; } .mr3 { margin-right: 1rem; } .mr4 { margin-right: 2rem; } .mr5 { margin-right: 4rem; } .mr6 { margin-right: 8rem; } .mr7 { margin-right: 16rem; } .mb0 { margin-bottom: 0; } .mb1 { margin-bottom: .25rem; } .mb2 { margin-bottom: .5rem; } .mb3 { margin-bottom: 1rem; } .mb4 { margin-bottom: 2rem; } .mb5 { margin-bottom: 4rem; } .mb6 { margin-bottom: 8rem; } .mb7 { margin-bottom: 16rem; } .mt0 { margin-top: 0; } .mt1 { margin-top: .25rem; } .mt2 { margin-top: .5rem; } .mt3 { margin-top: 1rem; } .mt4 { margin-top: 2rem; } .mt5 { margin-top: 4rem; } .mt6 { margin-top: 8rem; } .mt7 { margin-top: 16rem; } .mv0 { margin-top: 0; margin-bottom: 0; } .mv1 { margin-top: .25rem; margin-bottom: .25rem; } .mv2 { margin-top: .5rem; margin-bottom: .5rem; } .mv3 { margin-top: 1rem; margin-bottom: 1rem; } .mv4 { margin-top: 2rem; margin-bottom: 2rem; } .mv5 { margin-top: 4rem; margin-bottom: 4rem; } .mv6 { margin-top: 8rem; margin-bottom: 8rem; } .mv7 { margin-top: 16rem; margin-bottom: 16rem; } .mh0 { margin-left: 0; margin-right: 0; } .mh1 { margin-left: .25rem; margin-right: .25rem; } .mh2 { margin-left: .5rem; margin-right: .5rem; } .mh3 { margin-left: 1rem; margin-right: 1rem; } .mh4 { margin-left: 2rem; margin-right: 2rem; } .mh5 { margin-left: 4rem; margin-right: 4rem; } .mh6 { margin-left: 8rem; margin-right: 8rem; } .mh7 { margin-left: 16rem; margin-right: 16rem; } @media screen and (min-width: 30em) { .pa0-ns { padding: 0; } .pa1-ns { padding: .25rem; } .pa2-ns { padding: .5rem; } .pa3-ns { padding: 1rem; } .pa4-ns { padding: 2rem; } .pa5-ns { padding: 4rem; } .pa6-ns { padding: 8rem; } .pa7-ns { padding: 16rem; } .pl0-ns { padding-left: 0; } .pl1-ns { padding-left: .25rem; } .pl2-ns { padding-left: .5rem; } .pl3-ns { padding-left: 1rem; } .pl4-ns { padding-left: 2rem; } .pl5-ns { padding-left: 4rem; } .pl6-ns { padding-left: 8rem; } .pl7-ns { padding-left: 16rem; } .pr0-ns { padding-right: 0; } .pr1-ns { padding-right: .25rem; } .pr2-ns { padding-right: .5rem; } .pr3-ns { padding-right: 1rem; } .pr4-ns { padding-right: 2rem; } .pr5-ns { padding-right: 4rem; } .pr6-ns { padding-right: 8rem; } .pr7-ns { padding-right: 16rem; } .pb0-ns { padding-bottom: 0; } .pb1-ns { padding-bottom: .25rem; } .pb2-ns { padding-bottom: .5rem; } .pb3-ns { padding-bottom: 1rem; } .pb4-ns { padding-bottom: 2rem; } .pb5-ns { padding-bottom: 4rem; } .pb6-ns { padding-bottom: 8rem; } .pb7-ns { padding-bottom: 16rem; } .pt0-ns { padding-top: 0; } .pt1-ns { padding-top: .25rem; } .pt2-ns { padding-top: .5rem; } .pt3-ns { padding-top: 1rem; } .pt4-ns { padding-top: 2rem; } .pt5-ns { padding-top: 4rem; } .pt6-ns { padding-top: 8rem; } .pt7-ns { padding-top: 16rem; } .pv0-ns { padding-top: 0; padding-bottom: 0; } .pv1-ns { padding-top: .25rem; padding-bottom: .25rem; } .pv2-ns { padding-top: .5rem; padding-bottom: .5rem; } .pv3-ns { padding-top: 1rem; padding-bottom: 1rem; } .pv4-ns { padding-top: 2rem; padding-bottom: 2rem; } .pv5-ns { padding-top: 4rem; padding-bottom: 4rem; } .pv6-ns { padding-top: 8rem; padding-bottom: 8rem; } .pv7-ns { padding-top: 16rem; padding-bottom: 16rem; } .ph0-ns { padding-left: 0; padding-right: 0; } .ph1-ns { padding-left: .25rem; padding-right: .25rem; } .ph2-ns { padding-left: .5rem; padding-right: .5rem; } .ph3-ns { padding-left: 1rem; padding-right: 1rem; } .ph4-ns { padding-left: 2rem; padding-right: 2rem; } .ph5-ns { padding-left: 4rem; padding-right: 4rem; } .ph6-ns { padding-left: 8rem; padding-right: 8rem; } .ph7-ns { padding-left: 16rem; padding-right: 16rem; } .ma0-ns { margin: 0; } .ma1-ns { margin: .25rem; } .ma2-ns { margin: .5rem; } .ma3-ns { margin: 1rem; } .ma4-ns { margin: 2rem; } .ma5-ns { margin: 4rem; } .ma6-ns { margin: 8rem; } .ma7-ns { margin: 16rem; } .ml0-ns { margin-left: 0; } .ml1-ns { margin-left: .25rem; } .ml2-ns { margin-left: .5rem; } .ml3-ns { margin-left: 1rem; } .ml4-ns { margin-left: 2rem; } .ml5-ns { margin-left: 4rem; } .ml6-ns { margin-left: 8rem; } .ml7-ns { margin-left: 16rem; } .mr0-ns { margin-right: 0; } .mr1-ns { margin-right: .25rem; } .mr2-ns { margin-right: .5rem; } .mr3-ns { margin-right: 1rem; } .mr4-ns { margin-right: 2rem; } .mr5-ns { margin-right: 4rem; } .mr6-ns { margin-right: 8rem; } .mr7-ns { margin-right: 16rem; } .mb0-ns { margin-bottom: 0; } .mb1-ns { margin-bottom: .25rem; } .mb2-ns { margin-bottom: .5rem; } .mb3-ns { margin-bottom: 1rem; } .mb4-ns { margin-bottom: 2rem; } .mb5-ns { margin-bottom: 4rem; } .mb6-ns { margin-bottom: 8rem; } .mb7-ns { margin-bottom: 16rem; } .mt0-ns { margin-top: 0; } .mt1-ns { margin-top: .25rem; } .mt2-ns { margin-top: .5rem; } .mt3-ns { margin-top: 1rem; } .mt4-ns { margin-top: 2rem; } .mt5-ns { margin-top: 4rem; } .mt6-ns { margin-top: 8rem; } .mt7-ns { margin-top: 16rem; } .mv0-ns { margin-top: 0; margin-bottom: 0; } .mv1-ns { margin-top: .25rem; margin-bottom: .25rem; } .mv2-ns { margin-top: .5rem; margin-bottom: .5rem; } .mv3-ns { margin-top: 1rem; margin-bottom: 1rem; } .mv4-ns { margin-top: 2rem; margin-bottom: 2rem; } .mv5-ns { margin-top: 4rem; margin-bottom: 4rem; } .mv6-ns { margin-top: 8rem; margin-bottom: 8rem; } .mv7-ns { margin-top: 16rem; margin-bottom: 16rem; } .mh0-ns { margin-left: 0; margin-right: 0; } .mh1-ns { margin-left: .25rem; margin-right: .25rem; } .mh2-ns { margin-left: .5rem; margin-right: .5rem; } .mh3-ns { margin-left: 1rem; margin-right: 1rem; } .mh4-ns { margin-left: 2rem; margin-right: 2rem; } .mh5-ns { margin-left: 4rem; margin-right: 4rem; } .mh6-ns { margin-left: 8rem; margin-right: 8rem; } .mh7-ns { margin-left: 16rem; margin-right: 16rem; } } @media screen and (min-width: 30em) and (max-width: 60em) { .pa0-m { padding: 0; } .pa1-m { padding: .25rem; } .pa2-m { padding: .5rem; } .pa3-m { padding: 1rem; } .pa4-m { padding: 2rem; } .pa5-m { padding: 4rem; } .pa6-m { padding: 8rem; } .pa7-m { padding: 16rem; } .pl0-m { padding-left: 0; } .pl1-m { padding-left: .25rem; } .pl2-m { padding-left: .5rem; } .pl3-m { padding-left: 1rem; } .pl4-m { padding-left: 2rem; } .pl5-m { padding-left: 4rem; } .pl6-m { padding-left: 8rem; } .pl7-m { padding-left: 16rem; } .pr0-m { padding-right: 0; } .pr1-m { padding-right: .25rem; } .pr2-m { padding-right: .5rem; } .pr3-m { padding-right: 1rem; } .pr4-m { padding-right: 2rem; } .pr5-m { padding-right: 4rem; } .pr6-m { padding-right: 8rem; } .pr7-m { padding-right: 16rem; } .pb0-m { padding-bottom: 0; } .pb1-m { padding-bottom: .25rem; } .pb2-m { padding-bottom: .5rem; } .pb3-m { padding-bottom: 1rem; } .pb4-m { padding-bottom: 2rem; } .pb5-m { padding-bottom: 4rem; } .pb6-m { padding-bottom: 8rem; } .pb7-m { padding-bottom: 16rem; } .pt0-m { padding-top: 0; } .pt1-m { padding-top: .25rem; } .pt2-m { padding-top: .5rem; } .pt3-m { padding-top: 1rem; } .pt4-m { padding-top: 2rem; } .pt5-m { padding-top: 4rem; } .pt6-m { padding-top: 8rem; } .pt7-m { padding-top: 16rem; } .pv0-m { padding-top: 0; padding-bottom: 0; } .pv1-m { padding-top: .25rem; padding-bottom: .25rem; } .pv2-m { padding-top: .5rem; padding-bottom: .5rem; } .pv3-m { padding-top: 1rem; padding-bottom: 1rem; } .pv4-m { padding-top: 2rem; padding-bottom: 2rem; } .pv5-m { padding-top: 4rem; padding-bottom: 4rem; } .pv6-m { padding-top: 8rem; padding-bottom: 8rem; } .pv7-m { padding-top: 16rem; padding-bottom: 16rem; } .ph0-m { padding-left: 0; padding-right: 0; } .ph1-m { padding-left: .25rem; padding-right: .25rem; } .ph2-m { padding-left: .5rem; padding-right: .5rem; } .ph3-m { padding-left: 1rem; padding-right: 1rem; } .ph4-m { padding-left: 2rem; padding-right: 2rem; } .ph5-m { padding-left: 4rem; padding-right: 4rem; } .ph6-m { padding-left: 8rem; padding-right: 8rem; } .ph7-m { padding-left: 16rem; padding-right: 16rem; } .ma0-m { margin: 0; } .ma1-m { margin: .25rem; } .ma2-m { margin: .5rem; } .ma3-m { margin: 1rem; } .ma4-m { margin: 2rem; } .ma5-m { margin: 4rem; } .ma6-m { margin: 8rem; } .ma7-m { margin: 16rem; } .ml0-m { margin-left: 0; } .ml1-m { margin-left: .25rem; } .ml2-m { margin-left: .5rem; } .ml3-m { margin-left: 1rem; } .ml4-m { margin-left: 2rem; } .ml5-m { margin-left: 4rem; } .ml6-m { margin-left: 8rem; } .ml7-m { margin-left: 16rem; } .mr0-m { margin-right: 0; } .mr1-m { margin-right: .25rem; } .mr2-m { margin-right: .5rem; } .mr3-m { margin-right: 1rem; } .mr4-m { margin-right: 2rem; } .mr5-m { margin-right: 4rem; } .mr6-m { margin-right: 8rem; } .mr7-m { margin-right: 16rem; } .mb0-m { margin-bottom: 0; } .mb1-m { margin-bottom: .25rem; } .mb2-m { margin-bottom: .5rem; } .mb3-m { margin-bottom: 1rem; } .mb4-m { margin-bottom: 2rem; } .mb5-m { margin-bottom: 4rem; } .mb6-m { margin-bottom: 8rem; } .mb7-m { margin-bottom: 16rem; } .mt0-m { margin-top: 0; } .mt1-m { margin-top: .25rem; } .mt2-m { margin-top: .5rem; } .mt3-m { margin-top: 1rem; } .mt4-m { margin-top: 2rem; } .mt5-m { margin-top: 4rem; } .mt6-m { margin-top: 8rem; } .mt7-m { margin-top: 16rem; } .mv0-m { margin-top: 0; margin-bottom: 0; } .mv1-m { margin-top: .25rem; margin-bottom: .25rem; } .mv2-m { margin-top: .5rem; margin-bottom: .5rem; } .mv3-m { margin-top: 1rem; margin-bottom: 1rem; } .mv4-m { margin-top: 2rem; margin-bottom: 2rem; } .mv5-m { margin-top: 4rem; margin-bottom: 4rem; } .mv6-m { margin-top: 8rem; margin-bottom: 8rem; } .mv7-m { margin-top: 16rem; margin-bottom: 16rem; } .mh0-m { margin-left: 0; margin-right: 0; } .mh1-m { margin-left: .25rem; margin-right: .25rem; } .mh2-m { margin-left: .5rem; margin-right: .5rem; } .mh3-m { margin-left: 1rem; margin-right: 1rem; } .mh4-m { margin-left: 2rem; margin-right: 2rem; } .mh5-m { margin-left: 4rem; margin-right: 4rem; } .mh6-m { margin-left: 8rem; margin-right: 8rem; } .mh7-m { margin-left: 16rem; margin-right: 16rem; } } @media screen and (min-width: 60em) { .pa0-l { padding: 0; } .pa1-l { padding: .25rem; } .pa2-l { padding: .5rem; } .pa3-l { padding: 1rem; } .pa4-l { padding: 2rem; } .pa5-l { padding: 4rem; } .pa6-l { padding: 8rem; } .pa7-l { padding: 16rem; } .pl0-l { padding-left: 0; } .pl1-l { padding-left: .25rem; } .pl2-l { padding-left: .5rem; } .pl3-l { padding-left: 1rem; } .pl4-l { padding-left: 2rem; } .pl5-l { padding-left: 4rem; } .pl6-l { padding-left: 8rem; } .pl7-l { padding-left: 16rem; } .pr0-l { padding-right: 0; } .pr1-l { padding-right: .25rem; } .pr2-l { padding-right: .5rem; } .pr3-l { padding-right: 1rem; } .pr4-l { padding-right: 2rem; } .pr5-l { padding-right: 4rem; } .pr6-l { padding-right: 8rem; } .pr7-l { padding-right: 16rem; } .pb0-l { padding-bottom: 0; } .pb1-l { padding-bottom: .25rem; } .pb2-l { padding-bottom: .5rem; } .pb3-l { padding-bottom: 1rem; } .pb4-l { padding-bottom: 2rem; } .pb5-l { padding-bottom: 4rem; } .pb6-l { padding-bottom: 8rem; } .pb7-l { padding-bottom: 16rem; } .pt0-l { padding-top: 0; } .pt1-l { padding-top: .25rem; } .pt2-l { padding-top: .5rem; } .pt3-l { padding-top: 1rem; } .pt4-l { padding-top: 2rem; } .pt5-l { padding-top: 4rem; } .pt6-l { padding-top: 8rem; } .pt7-l { padding-top: 16rem; } .pv0-l { padding-top: 0; padding-bottom: 0; } .pv1-l { padding-top: .25rem; padding-bottom: .25rem; } .pv2-l { padding-top: .5rem; padding-bottom: .5rem; } .pv3-l { padding-top: 1rem; padding-bottom: 1rem; } .pv4-l { padding-top: 2rem; padding-bottom: 2rem; } .pv5-l { padding-top: 4rem; padding-bottom: 4rem; } .pv6-l { padding-top: 8rem; padding-bottom: 8rem; } .pv7-l { padding-top: 16rem; padding-bottom: 16rem; } .ph0-l { padding-left: 0; padding-right: 0; } .ph1-l { padding-left: .25rem; padding-right: .25rem; } .ph2-l { padding-left: .5rem; padding-right: .5rem; } .ph3-l { padding-left: 1rem; padding-right: 1rem; } .ph4-l { padding-left: 2rem; padding-right: 2rem; } .ph5-l { padding-left: 4rem; padding-right: 4rem; } .ph6-l { padding-left: 8rem; padding-right: 8rem; } .ph7-l { padding-left: 16rem; padding-right: 16rem; } .ma0-l { margin: 0; } .ma1-l { margin: .25rem; } .ma2-l { margin: .5rem; } .ma3-l { margin: 1rem; } .ma4-l { margin: 2rem; } .ma5-l { margin: 4rem; } .ma6-l { margin: 8rem; } .ma7-l { margin: 16rem; } .ml0-l { margin-left: 0; } .ml1-l { margin-left: .25rem; } .ml2-l { margin-left: .5rem; } .ml3-l { margin-left: 1rem; } .ml4-l { margin-left: 2rem; } .ml5-l { margin-left: 4rem; } .ml6-l { margin-left: 8rem; } .ml7-l { margin-left: 16rem; } .mr0-l { margin-right: 0; } .mr1-l { margin-right: .25rem; } .mr2-l { margin-right: .5rem; } .mr3-l { margin-right: 1rem; } .mr4-l { margin-right: 2rem; } .mr5-l { margin-right: 4rem; } .mr6-l { margin-right: 8rem; } .mr7-l { margin-right: 16rem; } .mb0-l { margin-bottom: 0; } .mb1-l { margin-bottom: .25rem; } .mb2-l { margin-bottom: .5rem; } .mb3-l { margin-bottom: 1rem; } .mb4-l { margin-bottom: 2rem; } .mb5-l { margin-bottom: 4rem; } .mb6-l { margin-bottom: 8rem; } .mb7-l { margin-bottom: 16rem; } .mt0-l { margin-top: 0; } .mt1-l { margin-top: .25rem; } .mt2-l { margin-top: .5rem; } .mt3-l { margin-top: 1rem; } .mt4-l { margin-top: 2rem; } .mt5-l { margin-top: 4rem; } .mt6-l { margin-top: 8rem; } .mt7-l { margin-top: 16rem; } .mv0-l { margin-top: 0; margin-bottom: 0; } .mv1-l { margin-top: .25rem; margin-bottom: .25rem; } .mv2-l { margin-top: .5rem; margin-bottom: .5rem; } .mv3-l { margin-top: 1rem; margin-bottom: 1rem; } .mv4-l { margin-top: 2rem; margin-bottom: 2rem; } .mv5-l { margin-top: 4rem; margin-bottom: 4rem; } .mv6-l { margin-top: 8rem; margin-bottom: 8rem; } .mv7-l { margin-top: 16rem; margin-bottom: 16rem; } .mh0-l { margin-left: 0; margin-right: 0; } .mh1-l { margin-left: .25rem; margin-right: .25rem; } .mh2-l { margin-left: .5rem; margin-right: .5rem; } .mh3-l { margin-left: 1rem; margin-right: 1rem; } .mh4-l { margin-left: 2rem; margin-right: 2rem; } .mh5-l { margin-left: 4rem; margin-right: 4rem; } .mh6-l { margin-left: 8rem; margin-right: 8rem; } .mh7-l { margin-left: 16rem; margin-right: 16rem; } } /* NEGATIVE MARGINS Base: n = negative Modifiers: a = all t = top r = right b = bottom l = left 1 = 1st step in spacing scale 2 = 2nd step in spacing scale 3 = 3rd step in spacing scale 4 = 4th step in spacing scale 5 = 5th step in spacing scale 6 = 6th step in spacing scale 7 = 7th step in spacing scale Media Query Extensions: -ns = not-small -m = medium -l = large */ .na1 { margin: -0.25rem; } .na2 { margin: -0.5rem; } .na3 { margin: -1rem; } .na4 { margin: -2rem; } .na5 { margin: -4rem; } .na6 { margin: -8rem; } .na7 { margin: -16rem; } .nl1 { margin-left: -0.25rem; } .nl2 { margin-left: -0.5rem; } .nl3 { margin-left: -1rem; } .nl4 { margin-left: -2rem; } .nl5 { margin-left: -4rem; } .nl6 { margin-left: -8rem; } .nl7 { margin-left: -16rem; } .nr1 { margin-right: -0.25rem; } .nr2 { margin-right: -0.5rem; } .nr3 { margin-right: -1rem; } .nr4 { margin-right: -2rem; } .nr5 { margin-right: -4rem; } .nr6 { margin-right: -8rem; } .nr7 { margin-right: -16rem; } .nb1 { margin-bottom: -0.25rem; } .nb2 { margin-bottom: -0.5rem; } .nb3 { margin-bottom: -1rem; } .nb4 { margin-bottom: -2rem; } .nb5 { margin-bottom: -4rem; } .nb6 { margin-bottom: -8rem; } .nb7 { margin-bottom: -16rem; } .nt1 { margin-top: -0.25rem; } .nt2 { margin-top: -0.5rem; } .nt3 { margin-top: -1rem; } .nt4 { margin-top: -2rem; } .nt5 { margin-top: -4rem; } .nt6 { margin-top: -8rem; } .nt7 { margin-top: -16rem; } @media screen and (min-width: 30em) { .na1-ns { margin: -0.25rem; } .na2-ns { margin: -0.5rem; } .na3-ns { margin: -1rem; } .na4-ns { margin: -2rem; } .na5-ns { margin: -4rem; } .na6-ns { margin: -8rem; } .na7-ns { margin: -16rem; } .nl1-ns { margin-left: -0.25rem; } .nl2-ns { margin-left: -0.5rem; } .nl3-ns { margin-left: -1rem; } .nl4-ns { margin-left: -2rem; } .nl5-ns { margin-left: -4rem; } .nl6-ns { margin-left: -8rem; } .nl7-ns { margin-left: -16rem; } .nr1-ns { margin-right: -0.25rem; } .nr2-ns { margin-right: -0.5rem; } .nr3-ns { margin-right: -1rem; } .nr4-ns { margin-right: -2rem; } .nr5-ns { margin-right: -4rem; } .nr6-ns { margin-right: -8rem; } .nr7-ns { margin-right: -16rem; } .nb1-ns { margin-bottom: -0.25rem; } .nb2-ns { margin-bottom: -0.5rem; } .nb3-ns { margin-bottom: -1rem; } .nb4-ns { margin-bottom: -2rem; } .nb5-ns { margin-bottom: -4rem; } .nb6-ns { margin-bottom: -8rem; } .nb7-ns { margin-bottom: -16rem; } .nt1-ns { margin-top: -0.25rem; } .nt2-ns { margin-top: -0.5rem; } .nt3-ns { margin-top: -1rem; } .nt4-ns { margin-top: -2rem; } .nt5-ns { margin-top: -4rem; } .nt6-ns { margin-top: -8rem; } .nt7-ns { margin-top: -16rem; } } @media screen and (min-width: 30em) and (max-width: 60em) { .na1-m { margin: -0.25rem; } .na2-m { margin: -0.5rem; } .na3-m { margin: -1rem; } .na4-m { margin: -2rem; } .na5-m { margin: -4rem; } .na6-m { margin: -8rem; } .na7-m { margin: -16rem; } .nl1-m { margin-left: -0.25rem; } .nl2-m { margin-left: -0.5rem; } .nl3-m { margin-left: -1rem; } .nl4-m { margin-left: -2rem; } .nl5-m { margin-left: -4rem; } .nl6-m { margin-left: -8rem; } .nl7-m { margin-left: -16rem; } .nr1-m { margin-right: -0.25rem; } .nr2-m { margin-right: -0.5rem; } .nr3-m { margin-right: -1rem; } .nr4-m { margin-right: -2rem; } .nr5-m { margin-right: -4rem; } .nr6-m { margin-right: -8rem; } .nr7-m { margin-right: -16rem; } .nb1-m { margin-bottom: -0.25rem; } .nb2-m { margin-bottom: -0.5rem; } .nb3-m { margin-bottom: -1rem; } .nb4-m { margin-bottom: -2rem; } .nb5-m { margin-bottom: -4rem; } .nb6-m { margin-bottom: -8rem; } .nb7-m { margin-bottom: -16rem; } .nt1-m { margin-top: -0.25rem; } .nt2-m { margin-top: -0.5rem; } .nt3-m { margin-top: -1rem; } .nt4-m { margin-top: -2rem; } .nt5-m { margin-top: -4rem; } .nt6-m { margin-top: -8rem; } .nt7-m { margin-top: -16rem; } } @media screen and (min-width: 60em) { .na1-l { margin: -0.25rem; } .na2-l { margin: -0.5rem; } .na3-l { margin: -1rem; } .na4-l { margin: -2rem; } .na5-l { margin: -4rem; } .na6-l { margin: -8rem; } .na7-l { margin: -16rem; } .nl1-l { margin-left: -0.25rem; } .nl2-l { margin-left: -0.5rem; } .nl3-l { margin-left: -1rem; } .nl4-l { margin-left: -2rem; } .nl5-l { margin-left: -4rem; } .nl6-l { margin-left: -8rem; } .nl7-l { margin-left: -16rem; } .nr1-l { margin-right: -0.25rem; } .nr2-l { margin-right: -0.5rem; } .nr3-l { margin-right: -1rem; } .nr4-l { margin-right: -2rem; } .nr5-l { margin-right: -4rem; } .nr6-l { margin-right: -8rem; } .nr7-l { margin-right: -16rem; } .nb1-l { margin-bottom: -0.25rem; } .nb2-l { margin-bottom: -0.5rem; } .nb3-l { margin-bottom: -1rem; } .nb4-l { margin-bottom: -2rem; } .nb5-l { margin-bottom: -4rem; } .nb6-l { margin-bottom: -8rem; } .nb7-l { margin-bottom: -16rem; } .nt1-l { margin-top: -0.25rem; } .nt2-l { margin-top: -0.5rem; } .nt3-l { margin-top: -1rem; } .nt4-l { margin-top: -2rem; } .nt5-l { margin-top: -4rem; } .nt6-l { margin-top: -8rem; } .nt7-l { margin-top: -16rem; } } /* TABLES Docs: http://tachyons.io/docs/elements/tables/ */ .collapse { border-collapse: collapse; border-spacing: 0; } .striped--light-silver:nth-child(odd) { background-color: #aaa; } .striped--moon-gray:nth-child(odd) { background-color: #ccc; } .striped--light-gray:nth-child(odd) { background-color: #eee; } .striped--near-white:nth-child(odd) { background-color: #f4f4f4; } .stripe-light:nth-child(odd) { background-color: rgba(255, 255, 255, .1); } .stripe-dark:nth-child(odd) { background-color: rgba(0, 0, 0, .1); } /* TEXT DECORATION Docs: http://tachyons.io/docs/typography/text-decoration/ Media Query Extensions: -ns = not-small -m = medium -l = large */ .strike { text-decoration: line-through; } .underline { text-decoration: underline; } .no-underline { text-decoration: none; } @media screen and (min-width: 30em) { .strike-ns { text-decoration: line-through; } .underline-ns { text-decoration: underline; } .no-underline-ns { text-decoration: none; } } @media screen and (min-width: 30em) and (max-width: 60em) { .strike-m { text-decoration: line-through; } .underline-m { text-decoration: underline; } .no-underline-m { text-decoration: none; } } @media screen and (min-width: 60em) { .strike-l { text-decoration: line-through; } .underline-l { text-decoration: underline; } .no-underline-l { text-decoration: none; } } /* TEXT ALIGN Docs: http://tachyons.io/docs/typography/text-align/ Base t = text-align Modifiers l = left r = right c = center j = justify Media Query Extensions: -ns = not-small -m = medium -l = large */ .tl { text-align: left; } .tr { text-align: right; } .tc { text-align: center; } .tj { text-align: justify; } @media screen and (min-width: 30em) { .tl-ns { text-align: left; } .tr-ns { text-align: right; } .tc-ns { text-align: center; } .tj-ns { text-align: justify; } } @media screen and (min-width: 30em) and (max-width: 60em) { .tl-m { text-align: left; } .tr-m { text-align: right; } .tc-m { text-align: center; } .tj-m { text-align: justify; } } @media screen and (min-width: 60em) { .tl-l { text-align: left; } .tr-l { text-align: right; } .tc-l { text-align: center; } .tj-l { text-align: justify; } } /* TEXT TRANSFORM Docs: http://tachyons.io/docs/typography/text-transform/ Base: tt = text-transform Modifiers c = capitalize l = lowercase u = uppercase n = none Media Query Extensions: -ns = not-small -m = medium -l = large */ .ttc { text-transform: capitalize; } .ttl { text-transform: lowercase; } .ttu { text-transform: uppercase; } .ttn { text-transform: none; } @media screen and (min-width: 30em) { .ttc-ns { text-transform: capitalize; } .ttl-ns { text-transform: lowercase; } .ttu-ns { text-transform: uppercase; } .ttn-ns { text-transform: none; } } @media screen and (min-width: 30em) and (max-width: 60em) { .ttc-m { text-transform: capitalize; } .ttl-m { text-transform: lowercase; } .ttu-m { text-transform: uppercase; } .ttn-m { text-transform: none; } } @media screen and (min-width: 60em) { .ttc-l { text-transform: capitalize; } .ttl-l { text-transform: lowercase; } .ttu-l { text-transform: uppercase; } .ttn-l { text-transform: none; } } /* TYPE SCALE Docs: http://tachyons.io/docs/typography/scale/ Base: f = font-size Modifiers 1 = 1st step in size scale 2 = 2nd step in size scale 3 = 3rd step in size scale 4 = 4th step in size scale 5 = 5th step in size scale 6 = 6th step in size scale 7 = 7th step in size scale Media Query Extensions: -ns = not-small -m = medium -l = large */ /* * For Hero/Marketing Titles * * These generally are too large for mobile * so be careful using them on smaller screens. * */ .f-6, .f-headline { font-size: 6rem; } .f-5, .f-subheadline { font-size: 5rem; } /* Type Scale */ .f1 { font-size: 3rem; } .f2 { font-size: 2.25rem; } .f3 { font-size: 1.5rem; } .f4 { font-size: 1.25rem; } .f5 { font-size: 1rem; } .f6 { font-size: .875rem; } .f7 { font-size: .75rem; } /* Small and hard to read for many people so use with extreme caution */ @media screen and (min-width: 30em){ .f-6-ns, .f-headline-ns { font-size: 6rem; } .f-5-ns, .f-subheadline-ns { font-size: 5rem; } .f1-ns { font-size: 3rem; } .f2-ns { font-size: 2.25rem; } .f3-ns { font-size: 1.5rem; } .f4-ns { font-size: 1.25rem; } .f5-ns { font-size: 1rem; } .f6-ns { font-size: .875rem; } .f7-ns { font-size: .75rem; } } @media screen and (min-width: 30em) and (max-width: 60em) { .f-6-m, .f-headline-m { font-size: 6rem; } .f-5-m, .f-subheadline-m { font-size: 5rem; } .f1-m { font-size: 3rem; } .f2-m { font-size: 2.25rem; } .f3-m { font-size: 1.5rem; } .f4-m { font-size: 1.25rem; } .f5-m { font-size: 1rem; } .f6-m { font-size: .875rem; } .f7-m { font-size: .75rem; } } @media screen and (min-width: 60em) { .f-6-l, .f-headline-l { font-size: 6rem; } .f-5-l, .f-subheadline-l { font-size: 5rem; } .f1-l { font-size: 3rem; } .f2-l { font-size: 2.25rem; } .f3-l { font-size: 1.5rem; } .f4-l { font-size: 1.25rem; } .f5-l { font-size: 1rem; } .f6-l { font-size: .875rem; } .f7-l { font-size: .75rem; } } /* TYPOGRAPHY http://tachyons.io/docs/typography/measure/ Media Query Extensions: -ns = not-small -m = medium -l = large */ /* Measure is limited to ~66 characters */ .measure { max-width: 30em; } /* Measure is limited to ~80 characters */ .measure-wide { max-width: 34em; } /* Measure is limited to ~45 characters */ .measure-narrow { max-width: 20em; } /* Book paragraph style - paragraphs are indented with no vertical spacing. */ .indent { text-indent: 1em; margin-top: 0; margin-bottom: 0; } .small-caps { -webkit-font-feature-settings: "c2sc"; font-feature-settings: "c2sc"; font-variant: small-caps; } /* Combine this class with a width to truncate text (or just leave as is to truncate at width of containing element. */ .truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } @media screen and (min-width: 30em) { .measure-ns { max-width: 30em; } .measure-wide-ns { max-width: 34em; } .measure-narrow-ns { max-width: 20em; } .indent-ns { text-indent: 1em; margin-top: 0; margin-bottom: 0; } .small-caps-ns { -webkit-font-feature-settings: "c2sc"; font-feature-settings: "c2sc"; font-variant: small-caps; } .truncate-ns { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } } @media screen and (min-width: 30em) and (max-width: 60em) { .measure-m { max-width: 30em; } .measure-wide-m { max-width: 34em; } .measure-narrow-m { max-width: 20em; } .indent-m { text-indent: 1em; margin-top: 0; margin-bottom: 0; } .small-caps-m { -webkit-font-feature-settings: "c2sc"; font-feature-settings: "c2sc"; font-variant: small-caps; } .truncate-m { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } } @media screen and (min-width: 60em) { .measure-l { max-width: 30em; } .measure-wide-l { max-width: 34em; } .measure-narrow-l { max-width: 20em; } .indent-l { text-indent: 1em; margin-top: 0; margin-bottom: 0; } .small-caps-l { -webkit-font-feature-settings: "c2sc"; font-feature-settings: "c2sc"; font-variant: small-caps; } .truncate-l { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } } /* UTILITIES Media Query Extensions: -ns = not-small -m = medium -l = large */ /* Equivalent to .overflow-y-scroll */ .overflow-container { overflow-y: scroll; } .center { margin-right: auto; margin-left: auto; } .mr-auto { margin-right: auto; } .ml-auto { margin-left: auto; } @media screen and (min-width: 30em){ .center-ns { margin-right: auto; margin-left: auto; } .mr-auto-ns { margin-right: auto; } .ml-auto-ns { margin-left: auto; } } @media screen and (min-width: 30em) and (max-width: 60em){ .center-m { margin-right: auto; margin-left: auto; } .mr-auto-m { margin-right: auto; } .ml-auto-m { margin-left: auto; } } @media screen and (min-width: 60em){ .center-l { margin-right: auto; margin-left: auto; } .mr-auto-l { margin-right: auto; } .ml-auto-l { margin-left: auto; } } /* VISIBILITY Media Query Extensions: -ns = not-small -m = medium -l = large */ /* Text that is hidden but accessible Ref: http://snook.ca/archives/html_and_css/hiding-content-for-accessibility */ .clip { position: fixed !important; _position: absolute !important; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ clip: rect(1px, 1px, 1px, 1px); } @media screen and (min-width: 30em) { .clip-ns { position: fixed !important; _position: absolute !important; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ clip: rect(1px, 1px, 1px, 1px); } } @media screen and (min-width: 30em) and (max-width: 60em) { .clip-m { position: fixed !important; _position: absolute !important; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ clip: rect(1px, 1px, 1px, 1px); } } @media screen and (min-width: 60em) { .clip-l { position: fixed !important; _position: absolute !important; clip: rect(1px 1px 1px 1px); /* IE6, IE7 */ clip: rect(1px, 1px, 1px, 1px); } } /* WHITE SPACE Media Query Extensions: -ns = not-small -m = medium -l = large */ .ws-normal { white-space: normal; } .nowrap { white-space: nowrap; } .pre { white-space: pre; } @media screen and (min-width: 30em) { .ws-normal-ns { white-space: normal; } .nowrap-ns { white-space: nowrap; } .pre-ns { white-space: pre; } } @media screen and (min-width: 30em) and (max-width: 60em) { .ws-normal-m { white-space: normal; } .nowrap-m { white-space: nowrap; } .pre-m { white-space: pre; } } @media screen and (min-width: 60em) { .ws-normal-l { white-space: normal; } .nowrap-l { white-space: nowrap; } .pre-l { white-space: pre; } } /* VERTICAL ALIGN Media Query Extensions: -ns = not-small -m = medium -l = large */ .v-base { vertical-align: baseline; } .v-mid { vertical-align: middle; } .v-top { vertical-align: top; } .v-btm { vertical-align: bottom; } @media screen and (min-width: 30em) { .v-base-ns { vertical-align: baseline; } .v-mid-ns { vertical-align: middle; } .v-top-ns { vertical-align: top; } .v-btm-ns { vertical-align: bottom; } } @media screen and (min-width: 30em) and (max-width: 60em) { .v-base-m { vertical-align: baseline; } .v-mid-m { vertical-align: middle; } .v-top-m { vertical-align: top; } .v-btm-m { vertical-align: bottom; } } @media screen and (min-width: 60em) { .v-base-l { vertical-align: baseline; } .v-mid-l { vertical-align: middle; } .v-top-l { vertical-align: top; } .v-btm-l { vertical-align: bottom; } } /* HOVER EFFECTS Docs: http://tachyons.io/docs/themes/hovers/ - Dim - Glow - Hide Child - Underline text - Grow - Pointer - Shadow */ /* Dim element on hover by adding the dim class. */ .dim { opacity: 1; -webkit-transition: opacity .15s ease-in; transition: opacity .15s ease-in; } .dim:hover, .dim:focus { opacity: .5; -webkit-transition: opacity .15s ease-in; transition: opacity .15s ease-in; } .dim:active { opacity: .8; -webkit-transition: opacity .15s ease-out; transition: opacity .15s ease-out; } /* Animate opacity to 100% on hover by adding the glow class. */ .glow { -webkit-transition: opacity .15s ease-in; transition: opacity .15s ease-in; } .glow:hover, .glow:focus { opacity: 1; -webkit-transition: opacity .15s ease-in; transition: opacity .15s ease-in; } /* Hide child & reveal on hover: Put the hide-child class on a parent element and any nested element with the child class will be hidden and displayed on hover or focus.
Hidden until hover or focus
Hidden until hover or focus
Hidden until hover or focus
Hidden until hover or focus
*/ .hide-child .child { opacity: 0; -webkit-transition: opacity .15s ease-in; transition: opacity .15s ease-in; } .hide-child:hover .child, .hide-child:focus .child, .hide-child:active .child { opacity: 1; -webkit-transition: opacity .15s ease-in; transition: opacity .15s ease-in; } .underline-hover:hover, .underline-hover:focus { text-decoration: underline; } /* Can combine this with overflow-hidden to make background images grow on hover * even if you are using background-size: cover */ .grow { -moz-osx-font-smoothing: grayscale; -webkit-backface-visibility: hidden; backface-visibility: hidden; -webkit-transform: translateZ(0); transform: translateZ(0); -webkit-transition: -webkit-transform 0.25s ease-out; transition: -webkit-transform 0.25s ease-out; transition: transform 0.25s ease-out; transition: transform 0.25s ease-out, -webkit-transform 0.25s ease-out; } .grow:hover, .grow:focus { -webkit-transform: scale(1.05); transform: scale(1.05); } .grow:active { -webkit-transform: scale(.90); transform: scale(.90); } .grow-large { -moz-osx-font-smoothing: grayscale; -webkit-backface-visibility: hidden; backface-visibility: hidden; -webkit-transform: translateZ(0); transform: translateZ(0); -webkit-transition: -webkit-transform .25s ease-in-out; transition: -webkit-transform .25s ease-in-out; transition: transform .25s ease-in-out; transition: transform .25s ease-in-out, -webkit-transform .25s ease-in-out; } .grow-large:hover, .grow-large:focus { -webkit-transform: scale(1.2); transform: scale(1.2); } .grow-large:active { -webkit-transform: scale(.95); transform: scale(.95); } /* Add pointer on hover */ .pointer:hover { cursor: pointer; } /* Add shadow on hover. Performant box-shadow animation pattern from http://tobiasahlin.com/blog/how-to-animate-box-shadow/ */ .shadow-hover { cursor: pointer; position: relative; -webkit-transition: all 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); transition: all 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); } .shadow-hover::after { content: ''; -webkit-box-shadow: 0px 0px 16px 2px rgba(0, 0, 0, .2); box-shadow: 0px 0px 16px 2px rgba(0, 0, 0, .2); border-radius: inherit; opacity: 0; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; -webkit-transition: opacity 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); transition: opacity 0.5s cubic-bezier(0.165, 0.84, 0.44, 1); } .shadow-hover:hover::after, .shadow-hover:focus::after { opacity: 1; } /* Combine with classes in skins and skins-pseudo for * many different transition possibilities. */ .bg-animate, .bg-animate:hover, .bg-animate:focus { -webkit-transition: background-color .15s ease-in-out; transition: background-color .15s ease-in-out; } /* Z-INDEX Base z = z-index Modifiers -0 = literal value 0 -1 = literal value 1 -2 = literal value 2 -3 = literal value 3 -4 = literal value 4 -5 = literal value 5 -999 = literal value 999 -9999 = literal value 9999 -max = largest accepted z-index value as integer -inherit = string value inherit -initial = string value initial -unset = string value unset MDN: https://developer.mozilla.org/en/docs/Web/CSS/z-index Spec: http://www.w3.org/TR/CSS2/zindex.html Articles: https://philipwalton.com/articles/what-no-one-told-you-about-z-index/ Tips on extending: There might be a time worth using negative z-index values. Or if you are using tachyons with another project, you might need to adjust these values to suit your needs. */ .z-0 { z-index: 0; } .z-1 { z-index: 1; } .z-2 { z-index: 2; } .z-3 { z-index: 3; } .z-4 { z-index: 4; } .z-5 { z-index: 5; } .z-999 { z-index: 999; } .z-9999 { z-index: 9999; } .z-max { z-index: 2147483647; } .z-inherit { z-index: inherit; } .z-initial { z-index: auto; z-index: initial; } .z-unset { z-index: unset; } /* NESTED Tachyons module for styling nested elements that are generated by a cms. */ .nested-copy-line-height p, .nested-copy-line-height ul, .nested-copy-line-height ol { line-height: 1.5; } .nested-headline-line-height h1, .nested-headline-line-height h2, .nested-headline-line-height h3, .nested-headline-line-height h4, .nested-headline-line-height h5, .nested-headline-line-height h6 { line-height: 1.25; } .nested-list-reset ul, .nested-list-reset ol { padding-left: 0; margin-left: 0; list-style-type: none; } .nested-copy-indent p+p { text-indent: 1em; margin-top: 0; margin-bottom: 0; } .nested-copy-separator p+p { margin-top: 1.5em; } .nested-img img { width: 100%; max-width: 100%; display: block; } .nested-links a { color: #0594CB; -webkit-transition: color .15s ease-in; transition: color .15s ease-in; } .nested-links a:hover, .nested-links a:focus { color: #96ccff; -webkit-transition: color .15s ease-in; transition: color .15s ease-in; } /*@import 'tachyons/src/_styles';*/ /* Variables */ /* Importing here will allow you to override any variables in the modules */ /* Tachyons COLOR VARIABLES Grayscale - Solids - Transparencies Colors */ /* CUSTOM MEDIA QUERIES Media query values can be changed to fit your own content. There are no magic bullets when it comes to media query width values. They should be declared in em units - and they should be set to meet the needs of your content. You can also add additional media queries, or remove some of the existing ones. These media queries can be referenced like so: @media (--breakpoint-not-small) { .medium-and-larger-specific-style { background-color: red; } } @media (--breakpoint-medium) { .medium-screen-specific-style { background-color: red; } } @media (--breakpoint-large) { .large-and-larger-screen-specific-style { background-color: red; } } */ /* Media Queries */ /* Debugging */ /*@import 'tachyons/src/_debug-children'; @import 'tachyons/src/_debug-grid';*/ /* Uncomment out the line below to help debug layout issues */ /* @import 'tachyons/src/_debug'; */ /* purgecss start ignore */ .header-link:after { position: relative; left: 0.5em; opacity: 0; font-size: 0.8em; -moz-transition: opacity 0.2s ease-in-out 0.1s; -ms-transition: opacity 0.2s ease-in-out 0.1s; } h2:hover .header-link, h3:hover .header-link, h4:hover .header-link, h5:hover .header-link, h6:hover .header-link { opacity: 1; } .animated { -webkit-animation-duration: .5s; animation-duration: .5s; -webkit-animation-fill-mode: forwards; animation-fill-mode: forwards; -webkit-animation-timing-function: ease-in-out; animation-timing-function: ease-in-out; } @-webkit-keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .fadeIn { -webkit-animation-name: fadeIn; animation-name: fadeIn; } .animated-delay-1 { -webkit-animation-delay: 0.5s; animation-delay: 0.5s; } .note, .warning { border-left-width: 4px; border-left-style: solid; position: relative; border-color: #0594CB; display: block; } .note #exclamation-icon, .warning #exclamation-icon { fill: #0594CB; position: absolute; top: 35%; left: -12px; /*background-color: white;*/ } .admonition-content { display: block; margin: 0px; padding: .125em 1em; /*margin-left: 1em;*/ margin-top: 2em; margin-bottom: 2em; overflow-x: auto; /*font-size: .9375em;*/ background-color: rgba(0, 0, 0, .05); } .hide-child-menu .child-menu { display: none; } .hide-child-menu:hover .child-menu, .hide-child-menu:focus .child-menu, .hide-child-menu:active .child-menu { display: block; } /*documentation-copy headings exaggerate spacing and size to chunk content */ .documentation-copy h2 { margin-top: 3em } .documentation-copy h2.minor { font-size: inherit; margin-top: inherit; border-bottom: none; } .searchbox{display:inline-block;position:relative;width:200px;height:32px!important;white-space:nowrap;-webkit-box-sizing:border-box;box-sizing:border-box;visibility:visible!important} .searchbox .algolia-autocomplete{display:block;width:100%;height:100%} .searchbox__wrapper{width:100%;height:100%;z-index:999;position:relative} .searchbox__input{display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-transition:background .4s ease,-webkit-box-shadow .4s ease;transition:background .4s ease,-webkit-box-shadow .4s ease;transition:box-shadow .4s ease,background .4s ease;transition:box-shadow .4s ease,background .4s ease,-webkit-box-shadow .4s ease;border:0;border-radius:16px;-webkit-box-shadow:inset 0 0 0 1px #ccc;box-shadow:inset 0 0 0 1px #ccc;background:#fff!important;padding:0 26px 0 32px;width:100%;height:100%;vertical-align:middle;white-space:normal;font-size:12px;-webkit-appearance:none;-moz-appearance:none;appearance:none} .searchbox__input::-webkit-search-cancel-button,.searchbox__input::-webkit-search-decoration,.searchbox__input::-webkit-search-results-button,.searchbox__input::-webkit-search-results-decoration{display:none} .searchbox__input:hover{-webkit-box-shadow:inset 0 0 0 1px #b3b3b3;box-shadow:inset 0 0 0 1px #b3b3b3} .searchbox__input:active,.searchbox__input:focus{outline:0;-webkit-box-shadow:inset 0 0 0 1px #aaa;box-shadow:inset 0 0 0 1px #aaa;background:#fff} .searchbox__input::-webkit-input-placeholder{color:#aaa} .searchbox__input:-ms-input-placeholder{color:#aaa} .searchbox__input::-ms-input-placeholder{color:#aaa} .searchbox__input::placeholder{color:#aaa} .searchbox__submit{position:absolute;top:0;margin:0;border:0;border-radius:16px 0 0 16px;background-color:rgba(69, 142, 225, 0);padding:0;width:32px;height:100%;vertical-align:middle;text-align:center;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;right:inherit;left:0} .searchbox__submit:before{display:inline-block;margin-right:-4px;height:100%;vertical-align:middle;content:""} .searchbox__submit:active,.searchbox__submit:hover{cursor:pointer} .searchbox__submit:focus{outline:0} .searchbox__submit svg{width:14px;height:14px;vertical-align:middle;fill:#6d7e96} .searchbox__reset{display:block;position:absolute;top:8px;right:8px;margin:0;border:0;background:none;cursor:pointer;padding:0;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;fill:rgba(0, 0, 0, .5)} .searchbox__reset.hide{display:none} .searchbox__reset:focus{outline:0} .searchbox__reset svg{display:block;margin:4px;width:8px;height:8px} .searchbox__input:valid~.searchbox__reset{display:block;-webkit-animation-name:sbx-reset-in;animation-name:sbx-reset-in;-webkit-animation-duration:.15s;animation-duration:.15s} @-webkit-keyframes sbx-reset-in{0%{-webkit-transform:translate3d(-20%,0,0);transform:translate3d(-20%,0,0);opacity:0}to{-webkit-transform:none;transform:none;opacity:1}} @keyframes sbx-reset-in{0%{-webkit-transform:translate3d(-20%,0,0);transform:translate3d(-20%,0,0);opacity:0}to{-webkit-transform:none;transform:none;opacity:1}} .algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu{right:0!important;left:inherit!important} .algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu:before{right:48px} .algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu{left:0!important;right:inherit!important} .algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu:before{left:48px} .algolia-autocomplete .ds-dropdown-menu{top:-6px;border-radius:4px;margin:6px 0 0;padding:0;text-align:left;height:auto;position:relative;background:transparent;border:none;z-index:999;max-width:600px;min-width:500px;-webkit-box-shadow:0 1px 0 0 rgba(0, 0, 0, .2),0 2px 3px 0 rgba(0, 0, 0, .1);box-shadow:0 1px 0 0 rgba(0, 0, 0, .2),0 2px 3px 0 rgba(0, 0, 0, .1)} .algolia-autocomplete .ds-dropdown-menu:before{display:block;position:absolute;content:"";width:14px;height:14px;background:#fff;z-index:1000;top:-7px;border-top:1px solid #d9d9d9;border-right:1px solid #d9d9d9;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);border-radius:2px} .algolia-autocomplete .ds-dropdown-menu .ds-suggestions{position:relative;z-index:1000;margin-top:8px} .algolia-autocomplete .ds-dropdown-menu .ds-suggestions a:hover{text-decoration:none} .algolia-autocomplete .ds-dropdown-menu .ds-suggestion{cursor:pointer} .algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion.suggestion-layout-simple,.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion:not(.suggestion-layout-simple) .algolia-docsearch-suggestion--content{background-color:rgba(69, 142, 225, .05)} .algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{position:relative;border:1px solid #d9d9d9;background:#fff;border-radius:4px;overflow:auto;padding:0 8px 8px} .algolia-autocomplete .ds-dropdown-menu *{-webkit-box-sizing:border-box;box-sizing:border-box} .algolia-autocomplete .algolia-docsearch-suggestion{display:block;position:relative;padding:0 8px;background:#fff;color:#02060c;overflow:hidden} .algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#174d8c;background:rgba(143, 187, 237, .1);padding:.1em .05em} .algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl0 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl1 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{padding:0 0 1px;background:inherit;-webkit-box-shadow:inset 0 -2px 0 0 rgba(69, 142, 225, .8);box-shadow:inset 0 -2px 0 0 rgba(69, 142, 225, .8);color:inherit} .algolia-autocomplete .algolia-docsearch-suggestion--content{display:block;float:right;width:70%;position:relative;padding:5.33333px 0 5.33333px 10.66667px;cursor:pointer} .algolia-autocomplete .algolia-docsearch-suggestion--content:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;left:-1px} .algolia-autocomplete .algolia-docsearch-suggestion--category-header{position:relative;border-bottom:1px solid #ddd;display:none;margin-top:8px;padding:4px 0;font-size:1em;color:#33363d} .algolia-autocomplete .algolia-docsearch-suggestion--wrapper{width:100%;float:left;padding:8px 0 0} .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{float:left;width:30%;text-align:right;position:relative;padding:5.33333px 10.66667px;color:#a4a7ae;font-size:.9em;word-wrap:break-word} .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;right:0} .algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline{display:none} .algolia-autocomplete .algolia-docsearch-suggestion--title{margin-bottom:4px;color:#02060c;font-size:.9em;font-weight:700} .algolia-autocomplete .algolia-docsearch-suggestion--text{display:block;line-height:1.2em;font-size:.85em;color:#63676d} .algolia-autocomplete .algolia-docsearch-suggestion--no-results{width:100%;padding:8px 0;text-align:center;font-size:1.2em} .algolia-autocomplete .algolia-docsearch-suggestion--no-results:before{display:none} .algolia-autocomplete .algolia-docsearch-suggestion code{padding:1px 5px;font-size:90%;border:none;color:#222;background-color:#ebebeb;border-radius:3px;font-family:Menlo,Monaco,Consolas,Courier New,monospace} .algolia-autocomplete .algolia-docsearch-suggestion code .algolia-docsearch-suggestion--highlight{background:none} .algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--category-header,.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__secondary{display:block} @media (min-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:block}} @media (max-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:inline-block;width:auto;float:left;padding:0;color:#02060c;font-size:.9em;font-weight:700;text-align:left;opacity:.5}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{content:"|"}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{display:inline-block;width:auto;text-align:left;float:left;padding:0}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content:before{display:none}} .algolia-autocomplete .suggestion-layout-simple.algolia-docsearch-suggestion{border-bottom:1px solid #eee;padding:8px;margin:0} .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content{width:100%;padding:0} .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content:before{display:none} .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header{margin:0;padding:0;display:block;width:100%;border:none} .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl0,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1{opacity:.6;font-size:.85em} .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1:before{background-image:url('data:image/svg+xml;utf8,');content:"";width:10px;height:10px;display:inline-block} .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--wrapper{width:100%;float:left;margin:0;padding:0} .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--duplicate-content,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--subcategory-inline{display:none!important} .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title{margin:0;color:#458ee1;font-size:.9em;font-weight:400} .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title:before{content:"#";font-weight:700;color:#458ee1;display:inline-block} .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text{margin:4px 0 0;display:block;line-height:1.4em;padding:5.33333px 8px;background:#f8f8f8;font-size:.85em;opacity:.8} .algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{color:#3f4145;font-weight:700;-webkit-box-shadow:none;box-shadow:none} .algolia-autocomplete .algolia-docsearch-footer{width:134px;height:20px;z-index:2000;margin-top:10.66667px;float:right;font-size:0;line-height:0} .algolia-autocomplete .algolia-docsearch-footer--logo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='168' height='24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath d='M78.988.938h16.594a2.968 2.968 0 0 1 2.966 2.966V20.5a2.967 2.967 0 0 1-2.966 2.964H78.988a2.967 2.967 0 0 1-2.966-2.964V3.897A2.961 2.961 0 0 1 78.988.938zm41.937 17.866c-4.386.02-4.386-3.54-4.386-4.106l-.007-13.336 2.675-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-10.846-2.18c.821 0 1.43-.047 1.855-.129v-2.719a6.334 6.334 0 0 0-1.574-.199 5.7 5.7 0 0 0-.897.069 2.699 2.699 0 0 0-.814.24c-.24.116-.439.28-.582.491-.15.212-.219.335-.219.656 0 .628.219.991.616 1.23s.938.362 1.615.362zm-.233-9.7c.883 0 1.629.109 2.231.328.602.218 1.088.525 1.444.915.363.396.609.922.76 1.483.157.56.232 1.175.232 1.85v6.874a32.5 32.5 0 0 1-1.868.314c-.834.123-1.772.185-2.813.185-.69 0-1.327-.069-1.895-.198a4.001 4.001 0 0 1-1.471-.636 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.803 0-.656.13-1.073.384-1.525a3.24 3.24 0 0 1 1.047-1.106c.445-.287.95-.492 1.532-.615a8.8 8.8 0 0 1 1.82-.185 8.404 8.404 0 0 1 1.972.24v-.438c0-.307-.035-.6-.11-.874a1.88 1.88 0 0 0-.384-.73 1.784 1.784 0 0 0-.724-.493 3.164 3.164 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.735 7.735 0 0 0-1.26.307l-.321-2.192c.335-.117.834-.233 1.478-.349a10.98 10.98 0 0 1 2.073-.178zm52.842 9.626c.822 0 1.43-.048 1.854-.13V13.7a6.347 6.347 0 0 0-1.574-.199c-.294 0-.595.021-.896.069a2.7 2.7 0 0 0-.814.24 1.46 1.46 0 0 0-.582.491c-.15.212-.218.335-.218.656 0 .628.218.991.615 1.23.404.245.938.362 1.615.362zm-.226-9.694c.883 0 1.629.108 2.231.327.602.219 1.088.526 1.444.915.355.39.609.923.759 1.483a6.8 6.8 0 0 1 .233 1.852v6.873c-.41.088-1.034.19-1.868.314-.834.123-1.772.184-2.813.184-.69 0-1.327-.068-1.895-.198a4.001 4.001 0 0 1-1.471-.635 3.085 3.085 0 0 1-.951-1.134c-.226-.465-.343-1.12-.343-1.804 0-.656.13-1.073.384-1.524.26-.45.608-.82 1.047-1.107.445-.286.95-.491 1.532-.614a8.803 8.803 0 0 1 2.751-.13c.329.034.671.096 1.04.185v-.437a3.3 3.3 0 0 0-.109-.875 1.873 1.873 0 0 0-.384-.731 1.784 1.784 0 0 0-.724-.492 3.165 3.165 0 0 0-1.143-.205c-.616 0-1.177.075-1.69.164a7.75 7.75 0 0 0-1.26.307l-.321-2.193c.335-.116.834-.232 1.478-.348a11.633 11.633 0 0 1 2.073-.177zm-8.034-1.271a1.626 1.626 0 0 1-1.628-1.62c0-.895.725-1.62 1.628-1.62.904 0 1.63.725 1.63 1.62 0 .895-.733 1.62-1.63 1.62zm1.348 13.22h-2.689V7.27l2.69-.423v11.956zm-4.714 0c-4.386.02-4.386-3.54-4.386-4.107l-.008-13.336 2.676-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-8.698-5.903c0-1.156-.253-2.119-.746-2.788-.493-.677-1.183-1.01-2.067-1.01-.882 0-1.574.333-2.065 1.01-.493.676-.733 1.632-.733 2.788 0 1.168.246 1.953.74 2.63.492.683 1.183 1.018 2.066 1.018.882 0 1.574-.342 2.067-1.019.492-.683.738-1.46.738-2.63zm2.737-.007c0 .902-.13 1.584-.397 2.33a5.52 5.52 0 0 1-1.128 1.906 4.986 4.986 0 0 1-1.752 1.223c-.685.286-1.739.45-2.265.45-.528-.006-1.574-.157-2.252-.45a5.096 5.096 0 0 1-1.744-1.223c-.487-.527-.863-1.162-1.137-1.906a6.345 6.345 0 0 1-.41-2.33c0-.902.123-1.77.397-2.508a5.554 5.554 0 0 1 1.15-1.892 5.133 5.133 0 0 1 1.75-1.216c.679-.287 1.425-.423 2.232-.423.808 0 1.553.142 2.237.423a4.88 4.88 0 0 1 1.753 1.216 5.644 5.644 0 0 1 1.135 1.892c.287.738.431 1.606.431 2.508zm-20.138 0c0 1.12.246 2.363.738 2.882.493.52 1.13.78 1.91.78.424 0 .828-.062 1.204-.178.377-.116.677-.253.917-.417V9.33a10.476 10.476 0 0 0-1.766-.226c-.971-.028-1.71.37-2.23 1.004-.513.636-.773 1.75-.773 2.788zm7.438 5.274c0 1.824-.466 3.156-1.404 4.004-.936.846-2.367 1.27-4.296 1.27-.705 0-2.17-.137-3.34-.396l.431-2.118c.98.205 2.272.26 2.95.26 1.074 0 1.84-.219 2.299-.656.459-.437.684-1.086.684-1.948v-.437a8.07 8.07 0 0 1-1.047.397c-.43.13-.93.198-1.492.198-.739 0-1.41-.116-2.018-.349a4.206 4.206 0 0 1-1.567-1.025c-.431-.45-.774-1.017-1.013-1.694-.24-.677-.363-1.885-.363-2.773 0-.834.13-1.88.384-2.577.26-.696.629-1.298 1.129-1.796.493-.498 1.095-.881 1.8-1.162a6.605 6.605 0 0 1 2.428-.457c.87 0 1.67.109 2.45.24.78.129 1.444.265 1.985.415V18.17z' fill='%235468FF'/%3E%3Cpath d='M6.972 6.677v1.627c-.712-.446-1.52-.67-2.425-.67-.585 0-1.045.13-1.38.391a1.24 1.24 0 0 0-.502 1.03c0 .425.164.765.494 1.02.33.256.835.532 1.516.83.447.192.795.356 1.045.495.25.138.537.332.862.582.324.25.563.548.718.894.154.345.23.741.23 1.188 0 .947-.334 1.691-1.004 2.234-.67.542-1.537.814-2.601.814-1.18 0-2.16-.229-2.936-.686v-1.708c.84.628 1.814.942 2.92.942.585 0 1.048-.136 1.388-.407.34-.271.51-.646.51-1.125 0-.287-.1-.55-.302-.79-.203-.24-.42-.42-.655-.542-.234-.123-.585-.29-1.053-.503a61.27 61.27 0 0 1-.582-.271 13.67 13.67 0 0 1-.55-.287 4.275 4.275 0 0 1-.567-.351 6.92 6.92 0 0 1-.455-.4c-.18-.17-.31-.34-.39-.51-.08-.17-.155-.37-.224-.598a2.553 2.553 0 0 1-.104-.742c0-.915.333-1.638.998-2.17.664-.532 1.523-.798 2.576-.798.968 0 1.793.17 2.473.51zm7.468 5.696v-.287c-.022-.607-.187-1.088-.495-1.444-.309-.357-.75-.535-1.324-.535-.532 0-.99.194-1.373.583-.382.388-.622.949-.717 1.683h3.909zm1.005 2.792v1.404c-.596.34-1.383.51-2.362.51-1.255 0-2.255-.377-3-1.132-.744-.755-1.116-1.744-1.116-2.968 0-1.297.34-2.316 1.021-3.055.68-.74 1.548-1.11 2.6-1.11 1.033 0 1.852.323 2.458.966.606.644.91 1.572.91 2.784 0 .33-.033.676-.096 1.038h-5.314c.107.702.405 1.239.894 1.611.49.372 1.106.558 1.85.558.862 0 1.58-.202 2.155-.606zm6.605-1.77h-1.212c-.596 0-1.045.116-1.349.35-.303.234-.454.532-.454.894 0 .372.117.664.35.877.235.213.575.32 1.022.32.51 0 .912-.142 1.204-.424.293-.281.44-.651.44-1.108v-.91zm-4.068-2.554V9.325c.627-.361 1.457-.542 2.489-.542 2.116 0 3.175 1.026 3.175 3.08V17h-1.548v-.957c-.415.68-1.143 1.02-2.186 1.02-.766 0-1.38-.22-1.843-.661-.462-.442-.694-1.003-.694-1.684 0-.776.293-1.38.878-1.81.585-.431 1.404-.647 2.457-.647h1.34V11.8c0-.554-.133-.971-.399-1.253-.266-.282-.707-.423-1.324-.423a4.07 4.07 0 0 0-2.345.718zm9.333-1.93v1.42c.394-1 1.101-1.5 2.123-1.5.148 0 .313.016.494.048v1.531a1.885 1.885 0 0 0-.75-.143c-.542 0-.989.24-1.34.718-.351.479-.527 1.048-.527 1.707V17h-1.563V8.91h1.563zm5.01 4.084c.022.82.272 1.492.75 2.019.479.526 1.15.79 2.01.79.639 0 1.235-.176 1.788-.527v1.404c-.521.319-1.186.479-1.995.479-1.265 0-2.276-.4-3.031-1.197-.755-.798-1.133-1.792-1.133-2.984 0-1.16.38-2.151 1.14-2.975.761-.825 1.79-1.237 3.088-1.237.702 0 1.346.149 1.93.447v1.436a3.242 3.242 0 0 0-1.77-.495c-.84 0-1.513.266-2.019.798-.505.532-.758 1.213-.758 2.042zM40.24 5.72v4.579c.458-1 1.293-1.5 2.505-1.5.787 0 1.42.245 1.899.734.479.49.718 1.17.718 2.042V17h-1.564v-5.106c0-.553-.14-.98-.422-1.284-.282-.303-.652-.455-1.11-.455-.531 0-1.002.202-1.411.606-.41.405-.615 1.022-.615 1.851V17h-1.563V5.72h1.563zm14.966 10.02c.596 0 1.096-.253 1.5-.758.404-.506.606-1.157.606-1.955 0-.915-.202-1.62-.606-2.114-.404-.495-.92-.742-1.548-.742-.553 0-1.05.224-1.491.67-.442.447-.662 1.133-.662 2.058 0 .958.212 1.67.638 2.138.425.469.946.703 1.563.703zM53.004 5.72v4.42c.574-.894 1.388-1.341 2.44-1.341 1.022 0 1.857.383 2.506 1.149.649.766.973 1.781.973 3.047 0 1.138-.309 2.109-.925 2.912-.617.803-1.463 1.205-2.537 1.205-1.075 0-1.894-.447-2.457-1.34V17h-1.58V5.72h1.58zm9.908 11.104l-3.223-7.913h1.739l1.005 2.632 1.26 3.415c.096-.32.48-1.458 1.15-3.415l.909-2.632h1.66l-2.92 7.866c-.777 2.074-1.963 3.11-3.559 3.11a2.92 2.92 0 0 1-.734-.079v-1.34c.17.042.351.064.543.064 1.032 0 1.755-.57 2.17-1.708z' fill='%235D6494'/%3E%3Cpath d='M89.632 5.967v-.772a.978.978 0 0 0-.978-.977h-2.28a.978.978 0 0 0-.978.977v.793c0 .088.082.15.171.13a7.127 7.127 0 0 1 1.984-.28c.65 0 1.295.088 1.917.259.082.02.164-.04.164-.13m-6.248 1.01l-.39-.389a.977.977 0 0 0-1.382 0l-.465.465a.973.973 0 0 0 0 1.38l.383.383c.062.061.15.047.205-.014.226-.307.472-.601.746-.874.281-.28.568-.526.883-.751.068-.042.075-.137.02-.2m4.16 2.453v3.341c0 .096.104.165.192.117l2.97-1.537c.068-.034.089-.117.055-.184a3.695 3.695 0 0 0-3.08-1.866c-.068 0-.136.054-.136.13m0 8.048a4.489 4.489 0 0 1-4.49-4.482 4.488 4.488 0 0 1 4.49-4.482 4.488 4.488 0 0 1 4.489 4.482 4.484 4.484 0 0 1-4.49 4.482m0-10.85a6.363 6.363 0 1 0 0 12.729 6.37 6.37 0 0 0 6.372-6.368 6.358 6.358 0 0 0-6.371-6.36' fill='%23FFF'/%3E%3C/g%3E%3C/svg%3E");background-repeat:no-repeat;background-position:50%;background-size:100%;overflow:hidden;text-indent:-9000px;padding:0!important;width:100%;height:100%;display:block} /* These styles enhance the home page carousel, located here: themes/gohugoioTheme/layouts/partials/home-page-sections/showcase.html */ .overflow-x-scroll{ -webkit-overflow-scrolling: touch; } .row { -webkit-transition: 450ms -webkit-transform; transition: 450ms -webkit-transform; transition: 450ms transform; transition: 450ms transform, 450ms -webkit-transform; font-size: 0; } .tile { -webkit-transition: 450ms all; transition: 450ms all; } .details { background: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, .9)), to(rgba(0, 0, 0, 0))); background: linear-gradient(to top, rgba(0, 0, 0, .9) 0%, rgba(0, 0, 0, 0) 100%); -webkit-transition: 450ms opacity; transition: 450ms opacity; } .tile:hover .details { opacity: 1; } .row:hover .tile { opacity: 0.3; } .row:hover .tile:hover { opacity: 1; } .chroma .lntable pre { padding: 0; margin: 0; border: 0; } .chroma .lntable pre code { padding: 0; margin: 0; } pre, .pre { overflow-x: auto; overflow-y: hidden; overflow: scroll; } code { padding: 0.2em; margin: 0; font-size: 85%; background-color: rgba(27, 31, 35, .05); border-radius: 3px; } pre code { display: block; padding: 1.5em 1.5em; font-size: .875rem; line-height: 2; overflow-x: auto; } pre { background-color: #fff; color: #333; white-space: pre; -webkit-hyphens: none; -ms-hyphens: none; hyphens: none; position: relative; border-width: 1px; border-color: #ccc; border-style: solid; } /* The Pygments highlighter comes with its own styles. */ .highlight pre { background-color: inherit; color: inherit; padding: 0.5em; font-size: .875rem; } /*We are adding the copy button content here so we can change it with javascript. See the "Clipboard scripts"*/ .copy:after { content: "Copy" } .copied:after { content: "Copied" } @media screen and (min-width: 60em) { .full-width, pre.expand:hover { /*width: 100vw; position: relative; left: 50%; right: 50%; margin-left: -50vw; margin-right: -50vw;*/ /*width: 60vw;*/ /*position: relative; left: 50%; right: 50%;*/ /*margin-left: -30vw;*/ margin-right: -30vw; max-width: 100vw; } } .code-block .line-numbers-rows { background: #2f3a46; border: none; bottom: -50px; color: #98a4b3; left: -178px; padding: 50px 0; top: -50px; width: 138px } .code-block .line-numbers-rows>span:before { color: inherit; padding-right: 30px } .tab-button{ margin-bottom:1px; position: relative; z-index: 1; color:#333; border-color:#ccc; outline: none; background-color:white; } .tab-pane code{ background:#f1f2f2; border-radius:0; } .tab-pane .chroma{ background:none; padding:0; } .tab-button.active{ border-bottom-color:#f1f2f2; background-color: #f1f2f2; } .tab-content .tab-pane{ display: none; } .tab-content .tab-pane.active{ display: block; } /* Treatment of copy buttons inside a tab module */ .tab-content .copy, .tab-content .copied{ display: none; } .tab-content .tab-pane.active + .copy, .tab-content .tab-pane.active + .copied{ display: block; } .primary-color {color: #0594CB} .bg-primary-color {background-color: #0594CB} .hover-bg-primary-color:hover {background-color: #0594CB} .primary-color-dark {color: #0A1922} .bg-primary-color-dark {background-color: #0A1922} .hover-bg-primary-color-dark:hover {background-color: #0A1922} .primary-color-light {color: #f9f9f9} .bg-primary-color-light {background-color: #f9f9f9} .hover-bg-primary-color-light:hover {background-color: #f9f9f9} .accent-color {color: #EBB951} .bg-accent-color {background-color: #EBB951} .hover-bg-accent-color:hover {background-color: #EBB951} .accent-color-light {color: #FF4088} .hover-accent-color-light:hover {color: #FF4088} .bg-accent-color-light {background-color: #FF4088} .hover-bg-accent-color-light:hover {background-color: #FF4088} .accent-color-dark {color: #33ba91} .bg-accent-color-dark {background-color: #33ba91} .hover-bg-accent-color-dark:hover {background-color: #33ba91} .text-color-primary {color: #373737} .text-on-primary-color {color: #fff} .text-color-secondary {color: #ccc} .text-color-disabled {color: #F7f7f7} .divider-color {color: #f6f6f6} .warn-color {color: red} .nested-links a { color: #0594CB; text-decoration: none; } .column-count-2 {-webkit-column-count: 1;column-count: 1} .column-gap-1 {-webkit-column-gap: 0;column-gap: 0} .break-inside-avoid {-webkit-column-break-inside: auto;break-inside: auto} @media screen and (min-width: 60em) { .column-count-3-l {-webkit-column-count: 3;column-count: 3} .column-count-2-l {-webkit-column-count: 2;column-count: 2} .column-gap-1-l {-webkit-column-gap: 1;column-gap: 1} .break-inside-avoid-l {-webkit-column-break-inside: avoid;break-inside: avoid} } .prose ul, .prose ol { margin-bottom: 2em; } .prose ul li, .prose ol li { margin-bottom: .5em; } .prose li:hover { background-color: #eee } .prose ::selection { background: #0594CB; /* WebKit/Blink Browsers */ color: white; } body { line-height: 1.45; } p {margin-bottom: 1.3em;} h1, h2, h3, h4 { margin: 1.414em 0 0.5em; line-height: 1.2; } h1 { margin-top: 0; font-size: 2.441em; } h2 {font-size: 1.953em;} h3 {font-size: 1.563em;} h4 {font-size: 1.25em;} small, .font_small {font-size: 0.8em;} .prose table { width: 100%; margin-bottom: 3em; border-collapse: collapse; border-spacing: 0; font-size: 1em; border: 1px solid #eee } .prose table th { background-color: #0594CB; border-bottom: 1px solid #0594CB; color: white; font-weight: 400; text-align: left; padding: .375em .5em; } .prose table td, .prose table tc { padding: .75em .5em; text-align: left; border-right: 1px solid #eee; } .prose table tr:nth-child(even) { background-color: #eee; } dl dt { font-weight: bold; font-size: 1.125rem; } dd { margin: .5em 0 2em 0; padding: 0; } .f2-fluid { font-size: 2.25rem; } @media screen and (min-width: 60em) { .f2-fluid { font-size: 1.25rem; font-size: calc(0.70833rem + 0.83333vw); } } /* From http://cssfontstack.com */ code, .code, pre code, .highlight pre { font-family: 'inconsolata',Menlo,Monaco,'Courier New',monospace; } .sans-serif { font-family: 'Muli', avenir, 'helvetica neue', helvetica, ubuntu, roboto, noto, 'segoe ui', arial, sans-serif; } .serif { font-family: Palatino,"Palatino Linotype","Palatino LT STD","Book Antiqua",Georgia,serif; } /* Monospaced Typefaces (for code) */ .courier { font-family: 'Courier Next', courier, monospace; } /* Sans-Serif Typefaces */ .helvetica { font-family: 'helvetica neue', helvetica, sans-serif; } .avenir { font-family: 'avenir next', avenir, sans-serif; } /* Serif Typefaces */ .athelas { font-family: athelas, georgia, serif; } .georgia { font-family: georgia, serif; } .times { font-family: times, serif; } .bodoni { font-family: "Bodoni MT", serif; } .calisto { font-family: "Calisto MT", serif; } .garamond { font-family: garamond, serif; } .baskerville { font-family: baskerville, serif; } /* pagination.html: https://github.com/gohugoio/hugo/blob/master/tpl/tplimpl/template_embedded.go#L117 */ .pagination { margin: 3rem 0; } .pagination li { display: inline-block; margin-right: .375rem; font-size: .875rem; margin-bottom: 2.5em; } .pagination li a { padding: .5rem .625rem; background-color: white; color: #333; border: 1px solid #ddd; border-radius: 3px; text-decoration: none; } .pagination li.disabled { display: none; } .pagination li.active a:link, .pagination li.active a:active, .pagination li.active a:visited { background-color: #ddd; } /* Hides non-meaningful TOC items*/ #TableOfContents ul li ul li ul li{ display: none; } #TableOfContents ul li { color: black; display: block; margin-bottom: .375em; line-height: 1.375; } #TableOfContents ul li a{ width: 100%; padding: .25em .375em; margin-left: -.375em; } #TableOfContents ul li a:hover { background-color: #999; color: white; } .no-js .needs-js { opacity: 0 } .js .needs-js { opacity: 1; -webkit-transition: opacity .15s ease-in; transition: opacity .15s ease-in; } .facebook, .twitter, .instagram, .youtube { fill: #BABABA; } .facebook:hover { fill: #3b5998; } .twitter { fill: #55acee; } .twitter:hover { fill: #BABABA; } .instagram:hover { fill: #e95950; } .youtube:hover { fill: #bb0000; } @media (min-width: 75em) { [data-scrolldir="down"] .sticky { position: fixed; top:100px; right:0; } [data-scrolldir="up"] .sticky { position: fixed; top:100px; right:0; } } .fill-current { fill: currentColor; } /* Background */ .chroma { background-color: #ffffff } /* Error */ .chroma .err { color: #a61717; background-color: #e3d2d2 } /* LineTableTD */ .chroma .lntd { vertical-align: top; padding: 0; margin: 0; border: 0; } /* LineTable */ .chroma .lntable { border-spacing: 0; padding: 0; margin: 0; border: 0; width: auto; overflow: auto; display: block; } /* LineHighlight */ .chroma .hl { display: block; width: 100%;background-color: #ffffcc } /* LineNumbersTable */ .chroma .lnt { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; } /* LineNumbers */ .chroma .ln { margin-right: 0.4em; padding: 0 0.4em 0 0.4em; } /* Keyword */ .chroma .k { font-weight: bold } /* KeywordConstant */ .chroma .kc { font-weight: bold } /* KeywordDeclaration */ .chroma .kd { font-weight: bold } /* KeywordNamespace */ .chroma .kn { font-weight: bold } /* KeywordPseudo */ .chroma .kp { font-weight: bold } /* KeywordReserved */ .chroma .kr { font-weight: bold } /* KeywordType */ .chroma .kt { color: #445588; font-weight: bold } /* NameAttribute */ .chroma .na { color: #008080 } /* NameBuiltin */ .chroma .nb { color: #999999 } /* NameClass */ .chroma .nc { color: #445588; font-weight: bold } /* NameConstant */ .chroma .no { color: #008080 } /* NameEntity */ .chroma .ni { color: #800080 } /* NameException */ .chroma .ne { color: #990000; font-weight: bold } /* NameFunction */ .chroma .nf { color: #990000; font-weight: bold } /* NameNamespace */ .chroma .nn { color: #555555 } /* NameTag */ .chroma .nt { color: #000080 } /* NameVariable */ .chroma .nv { color: #008080 } /* LiteralString */ .chroma .s { color: #bb8844 } /* LiteralStringAffix */ .chroma .sa { color: #bb8844 } /* LiteralStringBacktick */ .chroma .sb { color: #bb8844 } /* LiteralStringChar */ .chroma .sc { color: #bb8844 } /* LiteralStringDelimiter */ .chroma .dl { color: #bb8844 } /* LiteralStringDoc */ .chroma .sd { color: #bb8844 } /* LiteralStringDouble */ .chroma .s2 { color: #bb8844 } /* LiteralStringEscape */ .chroma .se { color: #bb8844 } /* LiteralStringHeredoc */ .chroma .sh { color: #bb8844 } /* LiteralStringInterpol */ .chroma .si { color: #bb8844 } /* LiteralStringOther */ .chroma .sx { color: #bb8844 } /* LiteralStringRegex */ .chroma .sr { color: #808000 } /* LiteralStringSingle */ .chroma .s1 { color: #bb8844 } /* LiteralStringSymbol */ .chroma .ss { color: #bb8844 } /* LiteralNumber */ .chroma .m { color: #009999 } /* LiteralNumberBin */ .chroma .mb { color: #009999 } /* LiteralNumberFloat */ .chroma .mf { color: #009999 } /* LiteralNumberHex */ .chroma .mh { color: #009999 } /* LiteralNumberInteger */ .chroma .mi { color: #009999 } /* LiteralNumberIntegerLong */ .chroma .il { color: #009999 } /* LiteralNumberOct */ .chroma .mo { color: #009999 } /* Operator */ .chroma .o { font-weight: bold } /* OperatorWord */ .chroma .ow { font-weight: bold } /* Comment */ .chroma .c { color: #999988; font-style: italic } /* CommentHashbang */ .chroma .ch { color: #999988; font-style: italic } /* CommentMultiline */ .chroma .cm { color: #999988; font-style: italic } /* CommentSingle */ .chroma .c1 { color: #999988; font-style: italic } /* CommentSpecial */ .chroma .cs { color: #999999; font-weight: bold; font-style: italic } /* CommentPreproc */ .chroma .cp { color: #999999; font-weight: bold } /* CommentPreprocFile */ .chroma .cpf { color: #999999; font-weight: bold } /* GenericDeleted */ .chroma .gd { color: #000000; background-color: #ffdddd } /* GenericEmph */ .chroma .ge { font-style: italic } /* GenericError */ .chroma .gr { color: #aa0000 } /* GenericHeading */ .chroma .gh { color: #999999 } /* GenericInserted */ .chroma .gi { color: #000000; background-color: #ddffdd } /* GenericOutput */ .chroma .go { color: #888888 } /* GenericPrompt */ .chroma .gp { color: #555555 } /* GenericStrong */ .chroma .gs { font-weight: bold } /* GenericSubheading */ .chroma .gu { color: #aaaaaa } /* GenericTraceback */ .chroma .gt { color: #aa0000 } /* TextWhitespace */ .chroma .w { color: #bbbbbb } .nested-blockquote blockquote { border-left: 4px solid #0594CB; padding-left: 1em; /*margin: 0;*/ } .mw-90 { max-width:90%; } /* purgecss end ignore */ hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/output/js/000077500000000000000000000000001363637351300271105ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/assets/output/js/app.js000066400000000000000000004734541363637351300302470ustar00rootroot00000000000000!function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e,t,n){!function(t,n){var r=function(e,t){"use strict";if(!t.getElementsByClassName)return;var n,r,i=t.documentElement,s=e.Date,o=e.HTMLPictureElement,a=e.addEventListener,c=e.setTimeout,u=e.requestAnimationFrame||c,l=e.requestIdleCallback,h=/^picture$/i,d=["load","error","lazyincluded","_lazyloaded"],f={},p=Array.prototype.forEach,g=function(e,t){return f[t]||(f[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")),f[t].test(e.getAttribute("class")||"")&&f[t]},m=function(e,t){g(e,t)||e.setAttribute("class",(e.getAttribute("class")||"").trim()+" "+t)},v=function(e,t){var n;(n=g(e,t))&&e.setAttribute("class",(e.getAttribute("class")||"").replace(n," "))},y=function(e,t,n){var r=n?"addEventListener":"removeEventListener";n&&y(e,t),d.forEach(function(n){e[r](n,t)})},b=function(e,r,i,s,o){var a=t.createEvent("Event");return i||(i={}),i.instance=n,a.initEvent(r,!s,!o),a.detail=i,e.dispatchEvent(a),a},w=function(t,n){var i;!o&&(i=e.picturefill||r.pf)?(n&&n.src&&!t.getAttribute("srcset")&&t.setAttribute("srcset",n.src),i({reevaluate:!0,elements:[t]})):n&&n.src&&(t.src=n.src)},_=function(e,t){return(getComputedStyle(e,null)||{})[t]},E=function(e,t,n){for(n=n||e.offsetWidth;n0)&&"visible"!=_(s,"overflow")&&(r=s.getBoundingClientRect(),o=R>r.left&&kr.top-1&&T500&&i.clientWidth>500?500:370),L=r.expand,I=L*r.expFactor),H2&&f>2&&!t.hidden?(H=I,q=0):H=f>1&&q>1&&B<6?L:0;for(;s=d&&(T=a.top)<=O&&(R=a.right)>=d*D&&(k=a.left)<=A&&(M||R||k||T)&&(r.loadHidden||"hidden"!=_(m[s],"visibility"))&&(u&&B<3&&!p&&(f<3||q<4)||F(m[s],h))){if(X(m[s]),l=!0,B>9)break}else!l&&u&&!c&&B<4&&q<4&&f>2&&(o[0]||r.preloadAfterLoad)&&(o[0]||!p&&(M||R||k||T||"auto"!=m[s].getAttribute(r.sizesAttr)))&&(c=o[0]||m[s]);else X(m[s]);c&&!l&&X(c)}},K=function(e){var t,n=0,i=r.throttleDelay,o=r.ricTimeout,a=function(){t=!1,n=s.now(),e()},u=l&&o>49?function(){l(a,{timeout:o}),o!==r.ricTimeout&&(o=r.ricTimeout)}:S(function(){c(a)},!0);return function(e){var r;(e=!0===e)&&(o=33),t||(t=!0,(r=i-(s.now()-n))<0&&(r=0),e||r<9?u():c(u,r))}}(U),V=function(e){m(e.target,r.loadedClass),v(e.target,r.loadingClass),y(e.target,W),b(e.target,"lazyloaded")},J=S(V),W=function(e){J({target:e.target})},G=function(e){var t,n=e.getAttribute(r.srcsetAttr);(t=r.customMedia[e.getAttribute("data-media")||e.getAttribute("media")])&&e.setAttribute("media",t),n&&e.setAttribute("srcset",n)},Q=S(function(e,t,n,i,s){var o,a,u,l,f,g;(f=b(e,"lazybeforeunveil",t)).defaultPrevented||(i&&(n?m(e,r.autosizesClass):e.setAttribute("sizes",i)),a=e.getAttribute(r.srcsetAttr),o=e.getAttribute(r.srcAttr),s&&(u=e.parentNode,l=u&&h.test(u.nodeName||"")),g=t.firesLoad||"src"in e&&(a||o||l),f={target:e},g&&(y(e,z,!0),clearTimeout(d),d=c(z,2500),m(e,r.loadingClass),y(e,W,!0)),l&&p.call(u.getElementsByTagName("source"),G),a?e.setAttribute("srcset",a):o&&!l&&(j.test(e.nodeName)?function(e,t){try{e.contentWindow.location.replace(t)}catch(n){e.src=t}}(e,o):e.src=o),s&&(a||l)&&w(e,{src:o})),e._lazyRace&&delete e._lazyRace,v(e,r.lazyClass),x(function(){(!g||e.complete&&e.naturalWidth>1)&&(g?z(f):B--,V(f))},!0)}),X=function(e){var t,n=P.test(e.nodeName),i=n&&(e.getAttribute(r.sizesAttr)||e.getAttribute("sizes")),s="auto"==i;(!s&&u||!n||!e.getAttribute("src")&&!e.srcset||e.complete||g(e,r.errorClass)||!g(e,r.lazyClass))&&(t=b(e,"lazyunveilread").detail,s&&N.updateElem(e,!0,e.offsetWidth),e._lazyRace=!0,B++,Q(e,t,s,i,n))},Z=function(){if(!u)if(s.now()-E<999)c(Z,999);else{var e=C(function(){r.loadMode=3,K()});u=!0,r.loadMode=3,K(),a("scroll",function(){3==r.loadMode&&(r.loadMode=2),e()},!0)}};return{_:function(){E=s.now(),n.elements=t.getElementsByClassName(r.lazyClass),o=t.getElementsByClassName(r.lazyClass+" "+r.preloadClass),D=r.hFac,a("scroll",K,!0),a("resize",K,!0),e.MutationObserver?new MutationObserver(K).observe(i,{childList:!0,subtree:!0,attributes:!0}):(i.addEventListener("DOMNodeInserted",K,!0),i.addEventListener("DOMAttrModified",K,!0),setInterval(K,999)),a("hashchange",K,!0),["focus","mouseover","click","load","transitionend","animationend","webkitAnimationEnd"].forEach(function(e){t.addEventListener(e,K,!0)}),/d$|^c/.test(t.readyState)?Z():(a("load",Z),t.addEventListener("DOMContentLoaded",K),c(Z,2e4)),n.elements.length?(U(),x._lsFlush()):K()},checkElems:K,unveil:X}}(),N=function(){var e,n=S(function(e,t,n,r){var i,s,o;if(e._lazysizesWidth=r,r+="px",e.setAttribute("sizes",r),h.test(t.nodeName||""))for(i=t.getElementsByTagName("source"),s=0,o=i.length;s0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText,this.container="object"===r(e.container)?e.container:document.body}},{key:"listenClick",value:function(e){var t=this;this.listener=(0,a.default)(e,"click",function(e){return t.onClick(e)})}},{key:"onClick",value:function(e){var t=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new s.default({action:this.action(t),target:this.target(t),text:this.text(t),container:this.container,trigger:t,emitter:this})}},{key:"defaultAction",value:function(e){return l("action",e)}},{key:"defaultTarget",value:function(e){var t=l("target",e);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(e){return l("text",e)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"==typeof e?[e]:e,n=!!document.queryCommandSupported;return t.forEach(function(e){n=n&&!!document.queryCommandSupported(e)}),n}}]),t}();function l(e,t){var n="data-clipboard-"+e;if(t.hasAttribute(n))return t.getAttribute(n)}e.exports=u},function(e,t,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action=e.action,this.container=e.container,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var e=this,t="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[t?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,s.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,s.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function(e){this.emitter.emit(e?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(e){if(void 0!==e){if(!e||"object"!==(void 0===e?"undefined":r(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function(){return this._target}}]),e}();e.exports=o},function(e,t){e.exports=function(e){var t;if("SELECT"===e.nodeName)e.focus(),t=e.value;else if("INPUT"===e.nodeName||"TEXTAREA"===e.nodeName){var n=e.hasAttribute("readonly");n||e.setAttribute("readonly",""),e.select(),e.setSelectionRange(0,e.value.length),n||e.removeAttribute("readonly"),t=e.value}else{e.hasAttribute("contenteditable")&&e.focus();var r=window.getSelection(),i=document.createRange();i.selectNodeContents(e),r.removeAllRanges(),r.addRange(i),t=r.toString()}return t}},function(e,t){function n(){}n.prototype={on:function(e,t,n){var r=this.e||(this.e={});return(r[e]||(r[e]=[])).push({fn:t,ctx:n}),this},once:function(e,t,n){var r=this;function i(){r.off(e,i),t.apply(n,arguments)}return i._=t,this.on(e,i,n)},emit:function(e){for(var t=[].slice.call(arguments,1),n=((this.e||(this.e={}))[e]||[]).slice(),r=0,i=n.length;r0&&n.parentNode.classList.add("expand")}}},function(e,t,n){n(9)({apiKey:"167e7998590aebda7f9fedcf86bc4a55",indexName:"hugodocs",inputSelector:"#search-input",debug:!0})},function(e,t,n){ /*! docsearch 2.6.1 | © Algolia | github.com/algolia/docsearch */ !function(t,n){e.exports=n()}("undefined"!=typeof self&&self,function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=22)}([function(e,t,n){"use strict";var r=n(1);function i(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}e.exports={isArray:null,isFunction:null,isObject:null,bind:null,each:null,map:null,mixin:null,isMsie:function(e){if(void 0===e&&(e=navigator.userAgent),/(msie|trident)/i.test(e)){var t=e.match(/(msie |rv:)(\d+(.\d+)?)/i);if(t)return t[2]}return!1},escapeRegExChars:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isNumber:function(e){return"number"==typeof e},toStr:function(e){return void 0===e||null===e?"":e+""},cloneDeep:function(e){var t=this.mixin({},e),n=this;return this.each(t,function(e,r){e&&(n.isArray(e)?t[r]=[].concat(e):n.isObject(e)&&(t[r]=n.cloneDeep(e)))}),t},error:function(e){throw new Error(e)},every:function(e,t){var n=!0;return e?(this.each(e,function(r,i){if(!(n=t.call(null,r,i,e)))return!1}),!!n):n},any:function(e,t){var n=!1;return e?(this.each(e,function(r,i){if(t.call(null,r,i,e))return n=!0,!1}),n):n},getUniqueId:function(){var e=0;return function(){return e++}}(),templatify:function(e){if(this.isFunction(e))return e;var t=r.element(e);return"SCRIPT"===t.prop("tagName")?function(){return t.text()}:function(){return String(e)}},defer:function(e){setTimeout(e,0)},noop:function(){},formatPrefix:function(e,t){return t?"":e+"-"},className:function(e,t,n){return(n?"":".")+e+t},escapeHighlightedString:function(e,t,n){t=t||"";var r=document.createElement("div");r.appendChild(document.createTextNode(t)),n=n||"";var s=document.createElement("div");s.appendChild(document.createTextNode(n));var o=document.createElement("div");return o.appendChild(document.createTextNode(e)),o.innerHTML.replace(RegExp(i(r.innerHTML),"g"),t).replace(RegExp(i(s.innerHTML),"g"),n)}}},function(e,t,n){"use strict";e.exports={element:null}},function(e,t){var n=Object.prototype.hasOwnProperty,r=Object.prototype.toString;e.exports=function(e,t,i){if("[object Function]"!==r.call(t))throw new TypeError("iterator must be a function");var s=e.length;if(s===+s)for(var o=0;o was loaded but did not call our provided callback"),JSONPScriptError:s("JSONPScriptError"," {{ end }}hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/head-additions.html000066400000000000000000000000161363637351300327110ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/hero.html000066400000000000000000000012521363637351300307740ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/home-page-sections/000077500000000000000000000000001363637351300326405ustar00rootroot00000000000000features-icons.html000066400000000000000000000026051363637351300364010ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/home-page-sections
{{ if .Params.features }}
{{ $features := .Params.features }} {{ range $i, $e := $features }} {{ $features_count := $e | len }}
{{ with .image_path }} icon depicting {{ $e.heading }} {{ end }}

{{ .heading }}

{{.tagline}}

{{ .copy }}
{{ end }}
{{ end }}
features-single.html000066400000000000000000000021061363637351300365430ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/home-page-sections{{ if .Params.sections }} {{ range .Params.sections }} {{ $.Scratch.Add "i" 1 }}{{ $i := $.Scratch.Get "i" }}
{{ end }} {{ end }} installation.html000066400000000000000000000034011363637351300361460ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/home-page-sections

Install in seconds, build in milliseconds.

Hugo works on macOS, Windows, Linux, FreeBSD, and others.

Host on any server or your favorite CDN.

Hugo Gopher

Mac OS

$ brew install hugo

Windows

$ choco install hugo -confirm

Linux

$ snap install hugo
open-source-involvement.html000066400000000000000000000033331363637351300402540ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/home-page-sections
Github Logo
showcase.html000066400000000000000000000034241363637351300352660ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/home-page-sections

Showcase

{{/* NOTE: transitions for this section are in themes/gohugoioTheme/src/css/_carousel.css */}}
{{ $showcasePages := where .Site.RegularPages "Section" "showcase" }} {{ if $showcasePages }} {{ template "home_showcase_item" (index $showcasePages 0) }} {{ range $p := first 10 ($showcasePages | after 1 | shuffle) }} {{template "home_showcase_item" $p }} {{end}} {{end}}
{{/* END */}}
{{/* using Flex to make the button show up on the right side */}} See All
{{ define "home_showcase_item" }} {{ $img := (.Resources.ByType "image").GetMatch "*featured*" }} {{ with $img }} {{ $big := .Fill "1024x512 top" }} {{ $small := $big.Resize "512x" }} {{with $.Title}}
{{.}} →
{{end}}
{{ end }} {{ end }}sponsors.html000066400000000000000000000034241363637351300353400ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/home-page-sections{{$classes_box := "ba b--light-gray bg-light-gray br3 flex flex-column flex-wrap items-center justify-center ph3 pv4 mb4 w-100 w-30-l "}} {{$gtag := .gtag | default "unknown" }} {{ with .cx.Site.Data.sponsors }}
 

Hugo Sponsors

{{ range .banners }} {{ $banner := . }} {{if .logo}}
{{with .link -}} {{ $url := printf "%s?%s" . (querify "utm_source" "homepage" "utm_medium" "banner" "utm_campaign" "hugosponsor") | safeURL }} {{ if eq (getenv "HUGO_ENV") "production" | or (eq $.cx.Site.Params.env "production") }} {{ $gtagID := printf "Sponsor %s %s" $banner.name $gtag | title }} {{ else }} {{ end }} {{- end}} Logo for {{ .name }} {{with .link}}{{end}} {{with .copy}}

{{- . -}}

{{end}}
{{else}}

Your Logo Here

{{end}} {{end}}
{{end}} tweets.html000066400000000000000000000016131363637351300347630ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/home-page-sections
{{ $interior_classes := $.Site.Params.flex_box_interior_classes }}

See what others are saying about Hugo…

{{ range first 4 (sort $.Site.Data.homepagetweets.tweet "date" "desc" ) }} {{ end }}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/icon-link.html000066400000000000000000000006441363637351300317260ustar00rootroot00000000000000 nav-links-docs-mobile.html000066400000000000000000000010031363637351300340470ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials{{ $currentPage := . }} {{ $menu := .Site.Menus.docs.ByWeight }}
    {{ range $menu }}{{ $post := printf "%s" .Post }}
  • {{ .Name }}
  • {{end}}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/nav-links-docs.html000066400000000000000000000022411363637351300326660ustar00rootroot00000000000000{{ $currentPage := . }} nav-links-global-mobile.html000066400000000000000000000006621363637351300343710ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials{{ $currentPage := . }} {{ $menu := .Site.Menus.global }} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/nav-links.html000066400000000000000000000030151363637351300317400ustar00rootroot00000000000000{{ $currentPage := . }} {{ $.Scratch.Add "listlinkClasses" "f6 link primary-color-dark hover-white db brand-font ma0 w-100 pv3 ph4" }} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/nav-mobile.html000066400000000000000000000011721363637351300320710ustar00rootroot00000000000000
{{ partial "nav-links-docs-mobile.html" . }}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/nav-top.html000066400000000000000000000010701363637351300314210ustar00rootroot00000000000000{{ $currentPage := . }}
{{ partial "nav-links" .}}
{{ partial "nav-button-open" .}}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/page-edit.html000066400000000000000000000002721363637351300316770ustar00rootroot00000000000000Improve this page hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/page-header.html000066400000000000000000000014471363637351300322070ustar00rootroot00000000000000{{ $currentPage := . }} {{ $currentURL := .RelPermalink }}
  • News:
  • {{ range $name, $taxonomy := .Site.Taxonomies.categories }} {{ $link := $name | printf "%s%s" "/categories/" | printf "%s/" }}
  • {{ $name | humanize }}
  • {{ end }}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/pagelayout.html000066400000000000000000000021471363637351300322150ustar00rootroot00000000000000{{ $section_to_display := .section_to_display }}
{{ partial "nav-links-docs.html" .context }}
{{ $interior_classes := .context.Site.Params.flex_box_interior_classes }}
{{ range $section_to_display }} {{ partial "boxes-section-summaries" (dict "context" . "classes" $interior_classes "fullcontent" true) }} {{ end }}
previous-next-links-in-section-with-title.html000066400000000000000000000013261363637351300400660ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials{{ if or .PrevInSection .NextInSection }} {{/* this div holds these a tags as a unit for flex-box display */}} {{ end }} previous-next-links-in-section.html000066400000000000000000000012351363637351300357750ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials{{ if or .PrevInSection .NextInSection }} {{/* this div holds these a tags as a unit for flex-box display */}} {{ end }} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/previous-next-links.html000066400000000000000000000015251363637351300340100ustar00rootroot00000000000000{{if .Prev }} {{ partial "svg/ic_chevron_left_black_24px.svg" (dict "size" "30px") }} {{ .Prev.Title }} {{end}} {{if .Next }} {{ .Next.Title }} {{ partial "svg/ic_chevron_right_black_24px.svg" (dict "size" "30px") }} {{end}} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/related.html000066400000000000000000000003061363637351300314560ustar00rootroot00000000000000{{ $related := .Site.RegularPages.Related . | first 5 }} {{ with $related }}

See Also

{{ end }}hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/site-footer.html000066400000000000000000000045111363637351300323000ustar00rootroot00000000000000
Hugo Logo
{{ with getenv "REPOSITORY_URL" -}}

Netlify badge

{{- end }}
  {{ partial "home-page-sections/sponsors.html" (dict "cx" . "gtag" "footer" "classes_section" "pb3 w-100" "classes_copy" "f7 w-90-ns") }}
 

The Hugo logos are copyright © Steve Francia 2013–{{ now.Year }}.

The Hugo Gopher is based on an original work by Renée French.

{{- partial "nav-mobile.html" . -}}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/site-manifest.html000066400000000000000000000005771363637351300326200ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/site-nav.html000066400000000000000000000024701363637351300315700ustar00rootroot00000000000000{{ $currentPage := . }} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/site-scripts.html000066400000000000000000000012461363637351300324730ustar00rootroot00000000000000 {{ $scripts := resources.Get "output/js/app.js" }} {{ $isDev := eq hugo.Environment "development" }} {{ if not $isDev }} {{ $scripts = $scripts | fingerprint }} {{ end }} {{ with $scripts }} {{ if $isDev }} {{ else }} {{ end }} {{ $.Scratch.Set "scripts" . }} {{end}} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/site-search.html000066400000000000000000000006671363637351300322570ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/social-follow.html000066400000000000000000000010311363637351300326040ustar00rootroot00000000000000 {{ with .Site.Social.twitter }} {{ end }} Star hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/summary.html000066400000000000000000000006361363637351300315410ustar00rootroot00000000000000
{{ humanize .Section }}

{{ .Title }}

hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/000077500000000000000000000000001363637351300277505ustar00rootroot00000000000000Twitter_Logo_Blue.svg000066400000000000000000000014271363637351300340070ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svgTwitter_Logo_Blue hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/apple.svg000066400000000000000000000010661363637351300315750ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/clipboard.svg000066400000000000000000000010071363637351300324260ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/clippy.svg000066400000000000000000000010071363637351300317670ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/cloud.svg000066400000000000000000000036771363637351300316140ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/content.svg000066400000000000000000000050401363637351300321420ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/design.svg000066400000000000000000000013031363637351300317370ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/exclamation.svg000066400000000000000000000000001363637351300327630ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/facebook.svg000066400000000000000000000007651363637351300322520ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/focus.svg000066400000000000000000000026231363637351300316130ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/freebsd.svg000066400000000000000000000015521363637351300321060ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/functions.svg000066400000000000000000000046061363637351300325070ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/github-corner.svg000066400000000000000000000030011363637351300332330ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/github-squared.svg000066400000000000000000000036241363637351300334220ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/gitter.svg000066400000000000000000000106411363637351300317710ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/gme.svg000066400000000000000000005270721363637351300312560ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/godoc-icon.html000066400000000000000000000076531363637351300326720ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/gopher-2.svg000066400000000000000000000042251363637351300321170ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/gopher-front.svg000066400000000000000000000045751363637351300331160ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/gopher-homepage.svg000066400000000000000000000157711363637351300335530ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/gopher-side_path.svg000066400000000000000000000071261363637351300337210ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/gopher-small.svg000066400000000000000000000127171363637351300330730ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/gopher.svg000066400000000000000000000127241363637351300317630ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/hugo-h-only.svg000066400000000000000000002015721363637351300326460ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/hugo.svg000066400000000000000000000021521363637351300314330ustar00rootroot00000000000000 ic_arrow_drop_down.svg000066400000000000000000000002711363637351300342720ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/ic_arrow_drop_up.svg000066400000000000000000000002711363637351300340260ustar00rootroot00000000000000 ic_chevron_left_black_24px.svg000066400000000000000000000003521363637351300355540ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg ic_chevron_right_black_24px.svg000066400000000000000000000003531363637351300357400ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/idea.svg000066400000000000000000000374061363637351300314050ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/instagram.svg000066400000000000000000000033301363637351300324550ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/javascript.svg000066400000000000000000000044561363637351300326500ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/json.svg000066400000000000000000000074651363637351300314560ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/link-ext.svg000066400000000000000000000016161363637351300322300ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/link-permalink.svg000066400000000000000000000006211363637351300334050ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/md.svg000066400000000000000000000004701363637351300310720ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/mdsolid.svg000066400000000000000000000014771363637351300321350ustar00rootroot00000000000000 Svg Vector Icons : http://www.onlinewebfonts.com/icon hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/newlogo.svg000066400000000000000000000415141363637351300321500ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/sass.svg000066400000000000000000000054261363637351300314510ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/search.svg000066400000000000000000000022011363637351300317310ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/twitter.svg000066400000000000000000000026221363637351300321750ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/website.svg000066400000000000000000000120241363637351300321320ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/windows.svg000066400000000000000000000003121363637351300321570ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/svg/yaml.svg000066400000000000000000000022741363637351300314400ustar00rootroot00000000000000iconhugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/tags.html000066400000000000000000000020001363637351300307650ustar00rootroot00000000000000{{ $currentPageUrl := .RelPermalink }} {{ if and .Params.tags .Site.Taxonomies.tags }} {{ $name := index .Params.tags 0 }} {{ $name := $name | urlize }} {{ $tags := index .Site.Taxonomies.tags $name }}
{{end}} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/partials/toc.html000066400000000000000000000010641363637351300306250ustar00rootroot00000000000000 hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/robots.txt000066400000000000000000000003161363637351300274030ustar00rootroot00000000000000User-agent: * # robotstxt.org - if ENV production variable is false robots will be disallowed. {{ if eq (getenv "HUGO_ENV") "production" }} Disallow: admin/ Disallow: {{ else }} Disallow: / {{ end }} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/000077500000000000000000000000001363637351300275075ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/articlelist.html000066400000000000000000000006471363637351300327230ustar00rootroot00000000000000 {{ range $ind, $art := $.Site.Data.articles.article }} {{ end }}
Title Author Date
{{$art.title | markdownify }} {{ $art.author | markdownify }} {{ $art.date }}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/code-toggle.html000066400000000000000000000022571363637351300325740ustar00rootroot00000000000000{{ $langs := (slice "yaml" "toml" "json") }}
{{- with .Get "file" -}}
{{ . }}.
{{- end -}} {{ range $langs }}   {{ end }}
{{ range $langs }}
{{ highlight ($.Inner | transform.Remarshal . | safeHTML) . ""}}
{{ if ne ($.Get "copy") "false" }} {{/* Functionality located within filesaver.js The copy here is located in the css with .copy class so it can be replaced with JS on success */}} {{end}} {{ end }}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/code.html000066400000000000000000000013451363637351300313120ustar00rootroot00000000000000
{{- with .Get "file" -}}
{{.}}
{{- end -}} {{ if ne (.Get "copy") "false" }} {{/* Functionality located within filesaver.js The copy here is located in the css with .copy class so it can be replaced with JS on success */}} {{end}}
{{- .Inner -}}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/datatable.html000066400000000000000000000006461363637351300323240ustar00rootroot00000000000000 {{ range $ind, $art := $.Site.Data.articles.article }} {{ end }}
Title Author Date
{{$art.title | markdownify }} {{ $art.author | markdownify }} {{ $art.date }}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/directoryindex.html000066400000000000000000000005141363637351300334310ustar00rootroot00000000000000{{- $pathURL := .Get "pathURL" -}} {{- $path := .Get "path" -}} {{- $files := readDir $path -}} {{- range $files }} {{- end }}
Size in bytes Name
{{ .Size }} {{ .Name }}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/docfile.html000066400000000000000000000011701363637351300320010ustar00rootroot00000000000000{{ $file := .Get 0}} {{ $filepath := $file }} {{ $syntax := index (split $file ".") 1 }} {{ $syntaxoverride := eq (len .Params) 2 }}
{{$filepath}}
{{- readFile $file -}}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/exfile.html000066400000000000000000000016331363637351300316540ustar00rootroot00000000000000{{ $file := .Get 0}} {{ $filepath := replace $file "static/" ""}} {{ $syntax := index (split $file ".") 1 }} {{ $syntaxoverride := eq (len .Params) 2 }}
{{$filepath}}
{{- readFile $file -}}
Source
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/exfm.html000066400000000000000000000016451363637351300313420ustar00rootroot00000000000000 {{ $file := .Get 0}} {{ $filepath := replace $file "static/" ""}} {{ $syntax := index (split $file ".") 1 }} {{ $syntaxoverride := eq (len .Params) 2 }}
{{$filepath}}
{{- readFile $file -}}
Source
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/gh.html000066400000000000000000000005141363637351300307730ustar00rootroot00000000000000{{ range .Params }} {{ if eq (substr . 0 1) "@" }} {{ . }} {{ else if eq (substr . 0 2) "0x" }} {{ substr . 2 6 }} {{ else }} #{{ . }} {{ end }} {{ end }}hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/ghrepo.html000066400000000000000000000001101363637351300316510ustar00rootroot00000000000000GitHub repositoryhugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/nohighlight.html000066400000000000000000000000711363637351300326770ustar00rootroot00000000000000
{{ .Inner }}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/note.html000066400000000000000000000006021363637351300313400ustar00rootroot00000000000000{{ $_hugo_config := `{ "version": 1 }` }} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/output.html000066400000000000000000000004761363637351300317440ustar00rootroot00000000000000{{$file := .Get "file"}} {{$icon := index (split $file ".") 1 }}
{{$file}}
{{- .Inner -}}
hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/readfile.html000066400000000000000000000002431363637351300321470ustar00rootroot00000000000000{{$file := .Get "file"}} {{- if eq (.Get "markdown") "true" -}} {{- $file | readFile | markdownify -}} {{- else -}} {{ $file | readFile | safeHTML }} {{- end -}}hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/tip.html000066400000000000000000000005501363637351300311710ustar00rootroot00000000000000{{ $_hugo_config := `{ "version": 1 }` }} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/warning.html000066400000000000000000000005771363637351300320530ustar00rootroot00000000000000{{ $_hugo_config := `{ "version": 1 }` }} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/shortcodes/yt.html000066400000000000000000000010641363637351300310320ustar00rootroot00000000000000
{{if (.Get "thumbnail")}}
{{else}}
{{end}}
{{ if (.Get "description") }}
{{ .Get "description" | markdownify }}
{{ end }}hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/showcase/000077500000000000000000000000001363637351300271465ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/showcase/list.html000066400000000000000000000043011363637351300310050ustar00rootroot00000000000000{{ define "main" }}

{{ .Title }}

{{ .Content }}
{{ range (.Paginate (.Pages | shuffle ) 20).Pages }} {{template "showcase_items" .}} {{ end }}
The Showcase articles are copyright the content authors. Any open source license will be attached.
{{ end }} {{define "showcase_items"}}
{{ $img := (.Resources.ByType "image").GetMatch "*featured*" }} {{ with $img }} {{ $big := .Fill "1024x512 top" }} {{ $small := $big.Resize "512x" }} {{end}}
{{/* the margin aligns to the bottom */}}

{{- .Title -}}

{{end}} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/layouts/showcase/single.html000066400000000000000000000064451363637351300313260ustar00rootroot00000000000000{{ define "title" }} Showcase: {{ .Title }} {{ end }} {{ define "main" }}
{{template "sc-details" .}}
{{template "sc-main-column" .}}
{{/* bottom row */}} Last Update: {{ .Lastmod.Format "January 2, 2006" }}
{{ partial "page-edit.html" . }}
The Showcase articles are copyright the content authors. Any open source license will be attached.
{{ end }} {{define "sc-main-column"}} {{ $img := (.Resources.ByType "image").GetMatch "*featured*" }} {{ with $img }} {{ $big := .Fill "1024x512 top" }} {{ $small := $big.Resize "512x" }} {{ $img.Title }} {{ end }} {{end}} {{define "sc-details"}} {{end}} {{define "sc-navigation"}} {{$section := where .Site.RegularPages "Section" .Section}} {{$number_of_entries := $section | len}} {{end}} hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/static/000077500000000000000000000000001363637351300251215ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/static/android-chrome-144x144.png000066400000000000000000000166741363637351300314670ustar00rootroot00000000000000PNG  IHDRFgAMA a cHRMz&u0`:pQ<bKGDtIME]]IDATxYpyHWM[^3=3In%g*˭8=x_Sc[y/qblj]S+\ۙxZJWHq  ($@wXjO?lٲW"{=l<b'>## Pp75` 7G#v`:mF-DGaXtH47i=@m`C{Ɇ.q)(OS'h@ftЀ#ҡh c8:8N.gQ צV< 5}PmR\ϟ>5W)2 G$C 6'Ý=ZQNh,dHcQCN vS kt s ?8z8DVO#F4њ?:ush+OF ^$Sd.R"K.ޫڧ_̕frHk:Hh9, "~z#o-F^wR. />]x[H m5cpA:stpt>u8"GJ3_w_ԖԱA:iz{%v5rIT>_MtjKa;7/~(~pU){?wm# P/mD?};saCEYXC(܂H,`d=8E2r5 ԫUXr,~GJ}|QyBiȮka9][Ț/2sʊ Ӊ£pt :2%Ӑ$ɪi?;a7gz&"Cb z:86tLsW(Nc`YP<>>+Gb xlZ5*nWK? 3yj @͂pm^|Qmkմ!:C òփhB6T;^\qiE,6 יǩs?_f CAyc#E#p8]@$dSidIk5P8-?x8]ޓY9ZWwm2z-?Dސ;Lf$U@(Fxl 4GK%ZL|t,[Vrw.W==Aw* $gk]k7=^טw@ˊi90 @HAPMCXB*@1,lkgoݼV#Z1u]6ҕJ[3<.;h$`DW@UU2YqT-,PּO|઼КRk佶YL>f&>i$N!֕F1<,?WpE$YYMA׭+pM:(뭙ҿ,OkpHϣ"t*? :|+)7\"3C90"c1^O ]MTmE5(E*+Q_])8JhoR4&<ƍEʪ<7* U>;,? z+?W5"|x|2R =(}z{e@{Qy=Gw_*q$d~ZNB{凡08;ഋ(\z DJylާ?>$?&,NG=A趀ggdBYϝ2s2{;QP8].F"嶰_Ez$4$ѲMrh/3!o~?Mh1D;ygWNn޾]+˱B  @mvu WT;,YD6"Rxlb,ҜUrweD֗WJ?+F;vڝ 궧y0>qx+D~Xo7|?6}.wSv 9$"B@o qH o# <~{<(rH(Fhc^ZG߼}_tHRx* PUr^ UFc^Fw0*r dm#( T/ofZi[z\>+PJ~OAAX0N Jw;.JxL<  XJ0V??"fmm:5;C҉!mÆaaY?ֲH}O]s"ĻJb=ﷆP7)l7aHϫ.ލB#Q86 E)XA(w(l2jba5"ve^]ר`zZ!,p$x n12N#H$MA-jt~C6D!J)҃y&@tl 㓇LkǃɩS$߬t%T{ѷ-miYl׾ހщ1A6щ1xuc#OW  `3ݽ"ulY+JhveuE X\5^XwiU=JQ a@mj/8=›l -SeJ6@LȖ)2% [dd˔ll -SeJG gL@I'Z ky::,i +.9`'@.^hy [Ȗ)2% [dd˔ll -SeJ6@LȖ)RFLyZb0jM@eRqpoi8.g{}FT Xl:]Sq*YH5&}&D2% [dd˔ll -SeJ6@LȖ)2% [dd˔ll -SeJ6@LȖ)2Dkn?Qo8@B?["TuH42kд>NcEy{H@O5m V ^C>ÿ{S=C) V^F5#a,kgETUE.Akh>t 5^D =G!Et{ !6HfE(( H(f󠚆^i-{;(\ JdQ.F~Ej*2$4YnR~_t"5ZEe>J@ R+q9cE#p86H݊Ȓl*LbZ T-VZY;wJmţ-AVʋȯ!:?vjb.Jb Ҿih+BQh0;KҚPfOdw%~ @rZp<>sobΏZ7}NXB:@a- UUMEơ ^كd4e{8]s{-TIPhl*rP4\{3D@U~!@MJ`!R(0ZzA:2IdS)Hd~iţ.߹PNfѸ(It(6T̊wAv+cΫN̔-Hs "Q#`MaP 7Z3.B2r5U+ ! Ζcu\}=o-߄4??9~ψqc0e??;QQȫ:Lfe |rv0m?m7˸(Z"!(E1ʋWȬ&!KU 1UJ7* tG K9BMw'sg:/.* PˣZ*c((+B+ SOIw%k)ȣPHR  = 5Y -I'Kz- U&d6j| FtlH2$h 8 ZlbKulT~ۗ1X7zRE7ש%2q\,/0 \n7P~XyLZ ;Sѣ Ҽ( F7? ؀@FM@:DOLH @)h y|="`$IVs:tAe!B@)P*+ HCPr2,/ݼ\/JA<6S< %[)CR1CѠ:P{2#U^_,}&\+Qa-J`$H,m55j*҉r :S*G_<8/ޮ{h4~$]E=uB-℘WoF_傜¸M]&HR|p`}GB K҉U_D1̭"@rӓ_׻8#/(NdMQ8ңN;<뾧8~㏍z}ӧ\sspp< cf%]g9ͶRPB!0O"MSX!OR2_~>h|`P7c=NOc}HƵ!A $VOO9qht蠠`YPѱ<~޴xln`j(CLP~hv[Sq#8Fs^+՗")\刔Q/&j(PW!0Cиqj\,v5VwKQ(N.A2*`*2^ɢjte,OziMHUZFĥEEx m#ֲj 2UjUKҊ|7 Q NWfvHk,6Қ71uhevSP0𯷍0 cHQ .rH,9AL姷ϕ?_>%/Qѥ}vXe2@{'c c譇΋OEnh!˱nEǜ?jjtGc+XqP}oiyz@VE#`8[+}tvI>Tbf"((8`8plQMCZC&\f`}JTGw^|zaɴs؍?ңt:4]Zsr}3C~P\nx>܍JXR(A떀À/&\ l?-Zԋ:iJE<Шo"Xu!= .젵pavcKVjO{ ogf r&Oh QAt3Ӛwuo _X\9FA hɫ&y|vG2 Ni9۟>e$Ư]?dUYmĻ.ȏ`>GUz܇ڦ,NGCTxM]y{/9.$@ᨘ(oϔn9vpӕc4)?X}R&" C O= $,(tCB@Yw|ɴIX!߳ڷ,bLki&y,W_zTa+"ZhkOT\<_ :^U;龎:~@d, 7g&/-z=w_pHy_vIGԡ9Hk} .hs}voDG%tEXtdate:create2017-02-21T08:06:30+01:00pn%tEXtdate:modify2017-02-21T08:06:30+01:0038WzTXtRaw profile type iptcx qV((OIR# .c #K D4d#T ˀHJ.tB5IENDB`hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/static/android-chrome-192x192.png000066400000000000000000000240301363637351300314560ustar00rootroot00000000000000PNG  IHDRRlgAMA a cHRMz&u0`:pQ<bKGDtIME]&IDATxwם翷ADQ,JԾyi;I'$ӝg潏Ϝ3O/:O4/st$vH.JBR\@RC"RR HOB۲{{0 ` d/0;E?n?}] %0X_fhK0t&o=<h;?3=&.LlFfb(gB&ioiM+o @w˿{$ȏ8PP.0] Mv |A/A{wYE;A(l0& Z>>es]aA.Zd<ߜj}_NƝ?rKEP)*er{9R|B0fVtC9vPWTӼM޿{v"6`FZ6a{mlDc+O۾)PP% & ~yDK*2t!`A0 |zc;vww?FD-ljag򿉝>0ah yß YWQ^ӝꍹ{/g4 l+ͳy1 L&(p5IqRz~T~op$H3كkW]0"C洈Py9ݱO#/a('~!shO%B˿99 X}/=Fc`,`_O'?rӔRQ'!J٦>\{xF0>( anX{lkn;BI^Ʃ-W{ uW7BTvj=+O7gn&+@QlP3_`5γgo_* uT&޿srOtAj! J{7sGgw1ځx^<8ZPO~喰-2 Z/8|Z]g f_W IH+㘭bs:Ĵ4_q3ǁ:9hP̺O'>ly0[ERZ/PYsϟt7~\@6e>! qkͩu=Uiecnw(&RB& I7aݯ~P):[K|r)j؞^pu~?ˎ7ynkRP0Bp8S MKH#JAKElM3 WߗJ?s|G  @ E#rW>|臑;B&)(G o(CMӐd#͂jr!,Մ_3ɟϋOEVq GϷGaIێ7 t.FG ΁!eDʥ2@Bm*Wmj҇Xl`^?84@[J |Q+*U';aG0FhtvG-~r==*U$cH'U% e'|%}0Vɗ  YR[Ł@+L=wK C?)ٿNT [֤y cp{= J)J"kQRiڋRG̿#s"#-:𶊾@kO&sG5 F Z~K!^;6- `_O?PΑL?}tpn1CaB( kQEDŕʿZQ}7Z_*UIe 7fzU=Ϸ]Vvl{~#VǑ!U=irʍHმWJ!*ElE9w~yv%/&Q8ݮ56JH#JC*8+& ݻ$ݬyH̾U\TUu_:ywz`_x^qxۥ^yP堩Z/ڦPm}Wϟ<_A*z&VOY /[M/P?}:((!p]"n;Я&#J!]GT[M!lo^*:1I,@mM߸ډ-OExRjvD Á`$6 aVZ#O@V{6%H%œbcqGmSK.5ךN ?tK9jBo v!4:p] F8YI$\_GTַkZ=#N)ٕ{aw9`VivMv/HwHn[u@*ѨmM݆pB*UŐI$Pjp )f'*u l:V 8gof=?/ Z~ʚ;y~b>:L$-nX=^嶊nQ[?#T;wl27E{׋(| a(|:* EۦrJMԖC}:UBxn/2;Aw;Z廾ŷ}xRXnS&.'B##m Ro֤2r@owb/mA[w$zqumI Cfy~'Jz DJlC.V>=yozCpm8m41mJMv_:=px X<?c#P5tE|iUڝ.muQ?v"jv;(wyܺ}axMR+3~7n +oooL{Q.vQPwB u%Op$jVj(al: tԧ1os)%hHxoY.F~__fMv6} ndHH␤*)ڶ&{GsoV"h)jg6fc8'X Fhl.O[<NN k:WvG !LAQ;NQp럖T5#py<T&7Goz!@Ec7!ip JkGD,(np$.'`tByG ő![`!L| 0~t D][y~aǎnET!Dx}`[}V`N6,nB<^"c 7OYcp0N u VAQpqhMK@@C-οUt <6`$ fR،h &vՅ__F|cm&vyV_ AN)7@0 !z ul^mX dh ca` 4L 100&@h ca` 4L 100&@h ca` 4L 100>@1;wh J|MF!RhWIjRm/cjR 5I_$ ln9$ dx@4b1T+ Z AӴq%C@P.Y3@e/\,uk(xtt2 #GtGCSB@TJ%ĖWI=1:T HǓ(`(ag"8*!H ToЉ.-Rsy&!PUt(ʅ4vocn3ۤ]?Rr_ PQ) <6 BiJ<(,TEKc#~w9rBIVsh$RX|4稖"V(K\s,>G&h]h\PB=$wm33>\ӹuc%n}* Bcal/Zl2dtr’B8-WsbZNPTV>Jy_jv;, @Jg ȥR7`~R,(fPgx>LЬ7>'ŏfjc< -`#Tr^vj㏀@UTbqr9#a tԯp%($ $3}_. AZ"!OV]6MCZ}˥S;PV$j Ry3K(Ԫb˫gA(A@?u> T=jJgA4f"+$HP)@iۚ;~,QKm}~%/YPslhyRoxp4 cxtuY*4Kqwhv2Z\?t(NzԐhB.ZlN#<8ZqjمgKFq((C zQCW!_qƁfƠ[(~$>tD>pZQ"ΠT,"0<(\/AvƻT4{_b :ܓtGQY WNWt|@zy0ꀖi)=q^z7hH)YYt7ml2z |<_Gn9prW R>?ѿhq6f'X"0$";Q~>Q[YKKDwXtS-!"D !(E1k Ӛ>ɡTo~r_J7c3BЃݟVGT蹿QЋc;g^,{!kɧ̵GW#)%N۫ȍPP6!FGpv]WKe$c$k5 \)\?l23<ڗu7X;14Y$}7'r>DSKե(g Bۥfbacpy\ư\: Ԕ_^jo_^+)5N#Y}lA#3^C D賁1#:5f7ы=׎-/JBXm3x|^۵aSNeFQA<8JbqRulzaF?hY/a3W|;J{^W4 uo oRsxIQLHjs*lVB_$I(dUl"D]M2b ' 6l|˹?_.oG M=?~}]a60@ਿOI nFolq,~z-l`6lNPx1L\~vly QxڍFTUC!Erm\o 7gG eoiyA1ձ$7OEEv4O< ɳ]L]x.k"] Fhl.GwGE$1d)(ba RcpMHw]#i,p- k&S}`8-ReS>yK/T).f2Z>xA} `k6xR=5gr犷,)8@8ǫfm[@nS .%hxifqy4{+^PBh\?0f !h.sH~^#^E "4:Y۴,HǐKd1SkGg7Y*7~_@365ZZ`}Ҽ`bbvm*.gtRlzaS& P*gώKbfA냂:;xfP^ըj}}v!46PM|rMO_R*t#_ޟ-V|{kk}6lF%- Ņه+/-.;|*xivmGM6OY-߇ y~šNoΝ~(dt4V؃œXPU󆟓/_O5EZ  a8._@U5TKed)di=/6ZZH>O l,p{j_s8`tV+cǙ󏽯,UlDM_I( d3x逺td9e^yTg_4E1,ښ~~ɁA-m`L^28om^ꝯf_ ښ}m_&^@Wl i2M,/{~u2<)pT!p PDTÕN>[=>}Ey~ɡ.mfy[斴‰g}hҶi7!(Gx@Zzz\q|g<߼v=γ:t>0ҢڦnJǓΫg%m U7M<,ܼr8!YۚF7pҝa`ǴU:u(oEd;-,U}uEv,};ٮCb6ofǶ(M^2OsN9n[NߕU[H/֕! ez&#w!̴i03Dg8/.shzpDҍ57Ic{<>nmS7/3Nx/ܐfi8ZviGśf+7;)B0c 7^!.y_=sjv́fCie:wL]ݫ}aٚvXl9ґrKV*v5xG}=[9:WJLmy~fƵwc`g3-ڦ+G||~B/)c4+n: &mfg>z>/x+BӮyp(8t֙(Vs)k&&y]l&5?\8~mO_h 濚Tk0`,Y,Ϸ&.b0Pl߫eXw"='[%tEXtdate:create2017-02-21T08:06:30+01:00pn%tEXtdate:modify2017-02-21T08:06:30+01:0038WzTXtRaw profile type iptcx qV((OIR# .c #K D4d#T ˀHJ.tB5IENDB`hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/static/android-chrome-256x256.png000066400000000000000000000353601363637351300314700ustar00rootroot00000000000000PNG  IHDR\rfgAMA a cHRMz&u0`:pQ<bKGDtIME]9IDATxYwcǕ8#rdLKJ dU\.U]]^ G}ݫv.]nٖ풥T*I )> D$H?#)y8;v@0{I߀`|L&7y? l.c 1Bp00la.Bo /f `0 i"}_ A3l^C273|UA8=Nߟm"0"gxH[z9y7|Ik$ s(M)k'C҆k66Ġ_D5^\8ʑIݰ< 7־H8C<0N`srIo\GO`7;+ݩ%Q {bY0e(CTwKwOK X)l57XG?X9c?bA@ !cw֗j[|_[ Hw-awGAO%[?T(ʊ܆+^ 5x!au WZ;wY7ɦ˲C6؞?`@-b}!~rgA/6x!݈+}'?WߜnI cO 2ڊh=FZ^!.@0A61|`OhS1#C2| @jo|©L;}Gs F#2Crr-|ǿz'Q( !A>uK<VR]hBBA@ yh'r\]0fvk 5tXXd4нbPpjϿiWB Ҋ'1]}ވ._վ uƜ oQpJzM3in70>ҁ / Vc1u6~n=Ҋ!cC $6YoM}~ /?[4r?`ɧ_ :&l- Owz\|y <2ݍݶ/7\>=ͤUφpPk-`e]mcp!_vS޵޸w'ѯ~/ơKC(bp93rAK)ky&ʙDr+Ϟ~zD㾝R+x9ېDlzF.t_F_~ ٱ< KZ-;*X0${IuG[z׾ho1 :c`zz>@8D.!P91~W/0mT %Q9Smh2{v)󓵷(2LĶ&̬LE4Y.ſCM>/H̥K%|=1B)Ga= 7 Axx3V/fu j[.0s] s%L|m:e$< 2iC!H3sogta j Lbm{"HtJKgWϗǗ*DZx/vKJ6}f.c /$9 Mz>pycQPYpBgYlR *8*IRKk%rӑ/;iů ]fv;=^ }[qq|XاC,1~:B`&J˲@SuZyyJ:Vrq<󩍒=:\gه奧cA!B(R Fà!1U2Upl3*HRZ_ ?X9owN4o6$]}LO1{[4BWBKs+-۞~>?(|s/)2&aH)vh5`tY\ g\_ uO;J#b/XmSnXbaS]6`{bl>MK&KCONABq=R>L4ȼ7k?*Ly79knpF[ʻwv}(p{p,|pA)hV(gQ-`&ܷ2G@!QY*{'Okӌ&=4WwsɌT]␸>|ɲ`$x:p<I? pl&PT`6^lM [/Ư/"f4 M݁n>z^^]ҍؿ?O.<<` Ra>|H? R _0`8 UU02 +kY5JkNI^WUUܻ<0݊'s=z^뱲WC9DWC,@4?p0oEgYoˣT(jyjY@iW4F)j<{9hu͌]}\!pKyGbڞwQDTp-ӝvR8fb.rF1Ƞp(Ud韯f\PKx@f4߆!z3>ف WK[[_|Em=JǢSF#PT[Q-LrlRsz{Iߕܗώ,? {{!}΂CYIA[MM8u_8yQvt n1|1Gkiε?<^C}uzu @eӤ'^gߝk wA1$A۟(gJuTeX 3f2G/']qr-iFw_r۹Z˷פ>ш%nˆS$S{nqPD1CVcyX.@Ͽ?_ Uӌ!#Mfͺl:s*߈UoDM{ Jt]^,0msry4u0A‘HFd ؇l}*gĚڻ! 3O;~( EP^{&j2j sAP&[v8` !f}-~f鷑vݫww`OZ{g~=/^VXUG;>/vBRsbPwp^OI '8ӧeHS6"* QS45dbh|$!#/!O8#0UxYeAHwo'lv@jv5@u$iRv\{# Q:Sp'?xC][p=NڝYQRF(Pfa/;స[ȵb{g}w{jѮ0nїG[ٹNCR$X:wsGCusonj EPsNsGc$ҐTogyvtlT'M-%*iȤ2`R(4}lE"H̥FE޾`t& _0C'#ERcB9 (mSa ]{A^@O?W((ӕeBaR 1BP.Q\uVvL\[ ^^KU ( lkēIDSIh>0|Č$YBb.`8r.b>f/e[ ׌H_:sH=ޝuh4@0B0|x!}ʹ<ʅV/\?U ^c<;mDb1$ݮgX̽_6 /C4+nÁ,'}'!ecHSV)+CI'R# J0zDP a3` 0BF@0f! #@ a3` 0BF@0f! #@ a3`=Ntr22.Zl6v-uRhw#!^X?{;zNϧLB%LFi \jB5*0οt`$ tZ i3` 0BF@0f! #@ a3` 0BF@0f! #@ a3` 0BF@0f! #@ a3` 0BF@0f! #@ aF8瓾`(Yma!`09 mONfjL[-!Bڭ,˜ iWg`0^4ILUTBm,!QMTK%0`:<թFzvR@sh듾16y8C!C1S_`ͣ?ΩNCٞ 062Osx:IK /c(fsXߜ:;۫w!0Z-=yVx:(J)DPP *ʅ,z6 `PXZjDTZ" FR.R!9ͶF%}74zFZx:h2YQIJ@0::mY( (fshj`7:Wlj$(=M^ctk ZMw&N#JbY #WB6Z۴` jKmwctQWtY!#1?(й; v@gYYGTi?wl۶0&ؑ?,8s RQP t! zCsnvP 0yCn=mlRZ0 gݔQc9V`x' 08bm}r{9̿N PTl4ŐZw  !`Y"ATc 벹jvШVϬZ,ɭ_=>BckS^HvFU U$չY@+~ye۷/+G%:(W'SЃH"@ׁ[^Ep jZ<6r':{'09팥<,Mߝn#v1j=|ǧk\uml@n8w?}'J(4: 0H5Xuȓ|Ʉ Z62)z;Kö\CrB/ (rh5KA{ؾqBz*=u lxNt=K!8~G ]:clvf rN6i$,IwOBNظ;?ZB6z 8+=PJYSw*OҭW֮G\co%@`WO˗[ou=!~gjyY)Lט0>5nѨTNB!k*0頓c;j2ϟ#A<7~HX33g=r^/b&UBHkpgyЋ{{zwLK,Uf=o6/>>D=8+63wUh6 bb$|(;22V֩+h;:5|7XOl3R^ƌ7tp/`+st^_tVSLM0 AwYZہ*5uCP-ֱ칛cYu _!+DՏ^vi ^{g5W^2h;uEF՟y%OsƂd~?=9y~i*RhS(FVH! o`P ۲P)QPv'PՕ'[+[O%U5fk5A9{&u_{glW.*QesL-4B23Ao}c16&$I ل `V.#)uMp;dg}B W.6JϩLxu3ߞf` qg ,TɨYy=iVYm:p&$t:h7W BV5QlN(ڍVڋf#|DeOO+zBaTyofk^vFbKͼ[=Ww)ZƝ]^_>ܷ-? ^66nqfF4B<8tLMYϡjvzO>w@z.]9Vqdv9׹LzgVmwmwG٨uzow{IpG4P<]~>ιO5I(!gnk[ LlmAWL \tˎ)˂AcnjzMAay{z9ji*B}off^Q&"Z/f/ycuKr6WMIő\G eǻpѨՑ_͠R*±L) 3_>W䘹 J6~6=BП+ ^o`3!R\u'ooD_ 5g&,MՐO#>x'tv, , l큀P8STsM;,}ioݔ~4.cIo *Y 8vt..̍dyy%ɇlFVCR!תp龛+`u18ZJJ{`K$P 3aTM*^5׽ ˬ6Sp!{jeteUv7$H᠓4FF9dE(np 6֞ H,jok?=8m~]ߓf˂m;|yUi_[ ziY 2B0‰vsnPB1CZuȬ@B[g{VYϨ${L iŀO xgY@@8Eb~Hx:u4*U2먖˰,0| Y꣇'Gǭ0:R:+&l. ^2>G4h6wWPU'{leM3Y m3mPDTdޫYR?oߪLs' C, =A˂Aل/ydtQM-ŅGCm9lA$ ߏb7@)lD1Ga=V ,>mYիG72gp37s\ݮ<[U ozV貋]KmNe7n^_Nf~n9kNL?CY vVL8|j#~;KJChpȲh"<O;ۮ7[ˠ\xcxBD{k=|i8Vʜ9}wPGީqդo` $a(e;~;q=Rv >$ӈSP5me2]@i=zv #j= 7nk]rmgA ßuc6Ō)eG8ƍәIMfԥ( CH.#A AFμ# 0CW/6h4pK=p;8xf9oމ^C{eY);Htˎ=t3^2452Eϔ麷H]/^yxx@e/o70JƔV/:wWBc5%%PPv p0phx-;~Y%h7(es(f0̶ GU YK6nҐZĶǴR{_$#&kGe-'tuN7VPp*e]_"~~+]vVmTٶՆN ys%-It&{ȩK@UU1c1$Eqp]}DznP-P-`'~[eRy~x3m ж^oATI?l9>^{>sv~1Ǒ(|E{ћqXeMѐ@@%^5ndrdz3ߊ6˂ۖo[5Ň 39i]\y^(S^ CK;9Wlw wGɤlj`jC@xtĊvZϐ&!pOmiNB%v0lWsb?$3,0xmiU;H=yabQ?BlxX3 Z:ѸmaQ2eiŃN3ұQ_0# Krr!98W8~_D3_zBuY@@ IԮExקVOKw[>^!;MW6؂]n?r}UėnH{qb%ESvwe S|x2 "ȰL?B`i/x0/܈^:Ob~&{^ BO>P< WHncO{VUZ+0Cr;7%bSsӎ=Mr[fz|gk'Ch0"}w Fcf^pIx_)ɡ); ĬfܼܸBn:ۀ` ϸFa; QHa%>[iǃ Tr*AH*|5Zp l~!<=_ٶ{D^t^=kӠnݖ٤ӥ?gdY.o3x:"xW܃铏EaڤҊeP8 1Vgo^;YO{#w!#f/}_ .=*s:͈@mgwi:_ӟ'!ӊSkMJ| E3SE:fP_jPP ׮\|{ٸnIßۿŷY&pfno'|dz!GݖL4[+Nnm?&*Bf}ZqǗKG* #ԁW@`$ϞkBAX{, 쭶 VBl['F>i2I#RZw@#2/ܧgZcG^7w7] 3Cvܿ[!:%-#,/_x>Ih nzxڼYǪ[o}o_oCFcVi/Ds {B]~pwَ8!,OG-~V:JBkY;.QqL1w/0I88)DPr-KE=j̝"[^%I;Hߝbxu+$ݯ{=6mս3|}w !F\v{u\V 6 @2~!迺?#cCL r{ _lM!B<KKޓ>_[: q6H+3$e@'os?v-4}~@`'5?2 :Do7? q+W_"` `{!5zsițu1aӈ)f~A^#plnb?!Š%tEXtdate:create2017-02-21T08:06:30+01:00pn%tEXtdate:modify2017-02-21T08:06:30+01:0038WzTXtRaw profile type iptcx qV((OIR# .c #K D4d#T ˀHJ.tB5IENDB`hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/static/android-chrome-36x36.png000066400000000000000000000030701363637351300313110ustar00rootroot00000000000000PNG  IHDR$$hgAMA a cHRMz&u0`:pQ<4PLTEfffffffff+q x{Gkwz{ffffffuz{z"s y{{5o wz{~Mjvz{)qy{fffz{fff z{fff#y#yfff#w{Dlx{ffffffm_g+r y{ffffffySj tzffffffDmvzDlffffffhdf5px{ffffffo\h(r y{(rfffffffffLkvzufffffffffzz| { $95>=}-:<{)ZyvOVxR("8;:~,;w49}BE~DG9~-%:+aS\X~//7 ':|AWtRNSj D,vW=R cgh`-+h $;(HH,Z!3oo %@0PbKGDjtIME];IDAT8c`fV66VfF|-<> &:3:<4}1B|KMXBJw2!H% $s|?T3&{B`Z& i{懍WwfU̍ a~\T۾nģ%bD _lXLj@7mHfA6H.jm>_;] mhuI=~/ UUߗ"0B OFpV&K;Ӡv^J()%rŕU'\FRP? nG3V& `ȳ%£8½)@0<+y2irmT> N.K; UGx֞)q4s?AJ:H,P$B.aine:^uЁF%Tl5߷$&yJh$&<ߙk}mz7ȁe{t0=9\'{?X߀D(Es䬕(B A V{zhP^qJJen7 @2>Ƙw0ȧ'^e6c48@at=@=48jM3;CHv=ep2uw{\%TddKP6dCH7I 8!LC{zhPmU94% ŷ<<P|) A\Xdm9P­;H)LaؖE!B]~I˶ Ys +% ǻ% KdWHbH˲- 2{u3Ry2kzm,bDX2%RoK>H:,z+KFrkߺ)%_@F:e4]ˁ_}yid)%G4 n/ΠnB3W = +,E.i f)l]=Qtʜ.U@- iqLC/ʾ_Q1M a;{B&IP 3@TBJ隫X 76ߘY׀|7a?(_ҁ0i'.JN:s[CۓݺVJ;50BGӵo-%OE`(uu~8"@TH~eע9 u36 :@m!?z]F%Z#Zld̏fO_p󂭒@޹.oMVFSǮ.GDuk ۗd$:_}0iXOS\_;x}vN+pFLgVUiFD$zbwu%K( E"'R ht#mrDfnrq㚍^uyڛ&;AJV}w=5cWЮE~VV#۰rzݙ`@'qӥU?TkާN\ 4M)K=jxDW7h-e.n\7f+r׮=|3-Wlg9jOqMO}?6TQҽ0 9% "4J5Εn]Lz@2ۉ:˪xqĺ^l۟>g1l6LggNxF.jN9ٶmߊwS"?xK)|^3kٔӱ]35Y]ߛv1`gJ8>;]Ի?a {' ^)[(D̫Wv{)L'~ޭpC)TVNMߏjʄ?I] s75}qՐ}gV*XnX`5,c@"Ă):e+sӵ3 ZLg^}î\O~;!?OI܈9;3Y?@Muv|ɺm NT5pQ{>oy^m 0U3;P(gDi㌘]y˞#g%tEXtdate:create2017-02-21T08:06:30+01:00pn%tEXtdate:modify2017-02-21T08:06:30+01:0038WzTXtRaw profile type iptcx qV((OIR# .c #K D4d#T ˀHJ.tB5IENDB`hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/static/android-chrome-96x96.png000066400000000000000000000112131363637351300313230ustar00rootroot00000000000000PNG  IHDR``w8gAMA a cHRMz&u0`:pQ<bKGDtIME],IDATx]koWz~p83)Ȳ_e;786n l|跢c 4@"@AM4ms٤ĖDJH:3pp$eDQ"`9y3 裏>H'`o5WR3 更s'*Lelj0I0'g 30pTjQI"z:g` !=}o\ E㛻_yRD($º2z"|kp';_^ ?$R5Zh4޽t@~>.@&:V =A@[r@% Lh륑5g/cFa ">E.av%މKo_7m燎@n 4Nu=3&TTp=``0Z BX^J"Aƅ#[gTcRGhP>(±=w=yRPN'a  nE%E$(eA!xԯ4汚4lAYc(HW]~L;-!gY ‘Hn[|Pģ1u6:G~?.߾q@mkmЪ|2.^I8"$m\>XxB>/F# 0Lo}rQ3YPjoDCuP->1؂Ɔ h<*g]O=2'\Twd A c 4h?u(kKHDʲS"g>{FkeiSaC4+@Co^x텝C ) |"DlxZ@YqD12:Tְu:rSo8vN]qup{HV, o`<B.U$PJQ!Z@KMߙ9XI>LYؐ,Bp8 Y) \`3 hܡ}H.ıh$4, (_F} (.'G\I涒00D(2%,y#; ưޢ(.EQrX}.QJyЦ[LǍ];2:.ܳ bC~ 0۔FuڄrcǞ s3 PN `Ǟ JW(c dU v}3n. `MV̪_"^V^'o"1SC@ؽ]fT־Y"6o촱vjS7}9 2t}>]F.ðݞ|k6SG^bon`s@'e 2t}ކRm:̗zMK=4yq,'`S +>]F.O@'e 2t}nnfs;HmGlҢIQToǏ4AQQI[|^,^M~Cdݾ JejAn [8I& FpG| :Dr1J ~ui\TѻI&t SXE!娢圦iծ) шju]Ks~EӌN&3( n#mJ&#jS(E<E&)|RK9떿\Si%A:̟ګ秕Orh[yn`9D>E }.6؜AC ƴ#O+†M \rID͞U w}? % sȤF \˗mY}iH!_B"f C=3YΎγT3g˟:\$,WvgYfo܊9/"p| Ej%!4_񗞏mƑ7O_;- Hb_@M!/Tᶈ𦙑#3;/̰] KarFq\}uPY2bwvxqJ߬߈U>_ 6Cm"̫c12ힺ$=?|`ĕ8 TDIg-ȲiHnǀҟg˧ccXۮuqJ*"|L{o8&\3:)Pge BKH.vcEU݈ b19Ptiޭe[Wyc`"BIe;n?i*@ud)cg&N(TT% %7v00_bFHs2a;3eqz5U>]$ހC.LyZ5ttj+]TJ;S Nk^֨&s8*ea^? [@*ؐjفB3vn4uZڊ& {aue5^w=b 8@ jF?VdH.7j;+f-^HaoKhS+Kk'Kɉ;sC"3?0J C߈wn?4:_-7G:$XX'5apydFzvGHl(N|)~rqJhiH:&[V'¿cUc-[MZA稼8t@~ބvQ_緽v2uM7+ϲ{/y(rګ~Wy~Dfo} Sr[_ch-f~TϓaFψOOuɌӂdDoR?4|rQ]ݕHl5Vp?2#=7tٱ5å/L.Dw^7]>$"`햼 k $wTj"XpyeʬyKnzvOIբ&?8e]ps[xER1E}nvǔϊbK=A`a?aJ<`3=Ƽ=C:DpXII;* Uջ #BjpX}cQ56U&.,T `5xHoJcL,o%tEXtdate:create2017-02-21T08:06:30+01:00pn%tEXtdate:modify2017-02-21T08:06:30+01:0038WzTXtRaw profile type iptcx qV((OIR# .c #K D4d#T ˀHJ.tB5IENDB`hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/static/apple-touch-icon.png000066400000000000000000000141361363637351300310030ustar00rootroot00000000000000PNG  IHDRegAMA a cHRMz&u0`:pQ<bKGDtIME7 IDATxٓ}cf0\K\xKRv,(ǎ*ʖd;D< )W^ R$ZۡeGdr;M9x-IAܹ0`ptNQA<0gE70@ j /D+D+D+D+D+D+D+D+D+D+D+̠0x얥N^,4$wFӷѾ}B~*nQʡ[תv-C#tK•V~t L;'EQܺTC)a QaT낼ǰ03gJ _ZA,,9U;qMRZVJOo mYD-Bdȁqx)cMEG614)(DRg9۴\fnCZع9@,41Ԍ\T%Gku/,*|a|e[9imYX^oƯPƉ)>S.t)sej([?1 ؠeM~v~lcy1whNwo߷ t1m%e/.V[!_++c w/Xz9_:g:Xv ;=Vz|[.DF[~t湢0DMC}>a9zS3b-/€)D,Cєc;i9h >DܳU*6ꄑ1mekYi"шEQ^KUEmۋ"_]9%n[:rȈɁ1/i+U/( !?TضS-zOs Y*F!c3RYfhOT7NcwHrR:K&Xnz2[r(gM]ASSoIVèbc^5<؈$%2![] h6b6Weeze gÿ`p,[=yx9?d)0EQB,ȄD!s;BZ-feq<ժC_CܹEܴbj9eӭe* Bt$fZ|V!۲*rq6{+D[>Y eC)W5N-r) x*;FjF)_( f-woIEwm޿} S=|I{T%8 aH,rhWЙ ƻ0BIG8òFLSKr674E"m^\aعaV+;UǴ<#>/JJ 117\\(YbwmRǴo].=Ӵ%'2pkAc٬Z*{Y!ݷ"{pײA;\yazmcFS!!MFmTz" RQxx}UR ȡKoמ;{Ç1 JT4`{]^LT E95 xYޅ}p=ajFgt%&R&qAwkr6]ݹ{J{ }q )wشk'^}oGn~)4M H"3 1b6[-W"8[["C\.:  Mf)W( u;Zٳ5v4M,VEpfKd2U 12(ư:ߞ?=fX8WI3ڹ{QVJe &o?Eѝȯ}U:BPe'< )ÛE˳!⃻՛7cCHc/ W+eKv &)-3<C4ς=)Hq^,gsMM︔znR^vAMg;[`K&L*qce!rh:kYH1,b3jI/os+&}!$ O`^ѿhzx 4M>Or @} afcwApApApApApApApApApApApApApApApel1XNOD:0rP&.@ߘ.*ViI}WWWWWWWWWWW4mhy̠ `x2/Ʒ0 0*w90Yr0h@!`.tH )H 99999999999999999999sӃE qsM]wȇ=`VUTCq鵊ڟ_߷f:C)fF9n߲Gbڬmďymۅ|?f@C:7DB@? BFVVJ%lw%,6.uO%?Af˗Ŗa @}3#<[ #w媪(R: ?>Bi*rIzc<ijE]tq|V_mhjȄ#"EQDgMg84_3C~ duNo2aeQE$)Is!ezQ*lVZNUQj%*yx=tx)6m9x̕a,е B-\x9MU PW%< #EQ'Zyg7e%1b4C|-Z8s`z4c M0Vٖ])YV祿{b#ܥ1\T.k?:*5`M Hb"/w1*|\r Nf1@+s}P'E05ZVcw>Z&3^vMJi4u1`F ) P`ۙ~4+0k>]dG@chj+Ţ2iLgi|v+蠯+]mZwG=%'rR:K&Y-w2[fPsyCk?E Sm $lfƅBtg|?q)B!AHd2B,Bh+mղR*vK#vlW&QȞ6+#/ZiZF8woZq6ʶvn m_B=I{(GaT^H󍫶iz,D|~_,)?DM9/ -屼Y6pm⽷3[VhӼVQ)0mS% B2g?wG4͊\9^ w&boZXy#`ǩϫOδru;W(DFF4wGqR)fx+/|:͡)9ØӏM6aV޸T{Lϋfq&*4 QNkb6%۲<#,b2{k崟_?,G+?=_\?z6-/€@<~~ dF9W( ޷l,m[9j6+MsF)txeB.D"Y./(d4w6z}a(`۩>7YSܥ(ꏹ>.wq<.SY)ZM=E\>sVr) aXB2z ސrdSpD>s˄=[_t)= GCW^>W}vZ;5k[^rwA.Jœ FT({,/f7OMEXB=i|7⽷ȤPqMUtI]y^G";6ž7! fh8NlNεr:wG|p5'5q-/n&G۰]P~yr9x>kK+i87eѦU*W׎g vyJGwm}u5 aAF@.<|PutX6Q|`Mlf~4D+ """""""""""- ۝?v%tEXtdate:create2017-02-21T08:06:29+01:00)\%tEXtdate:modify2017-02-21T08:06:29+01:00XXuWzTXtRaw profile type iptcx qV((OIR# .c #K D4d#T ˀHJ.tB5IENDB`hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/static/browserconfig.xml000066400000000000000000000005171363637351300305170ustar00rootroot00000000000000 #2d89ef hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/static/dist/000077500000000000000000000000001363637351300260645ustar00rootroot00000000000000hugo-0.68.3/docs/_vendor/github.com/gohugoio/gohugoioTheme/static/dist/app.bundle.js000066400000000000000000004125641363637351300304660ustar00rootroot00000000000000!function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var n={};e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=11)}([function(t,e,n){"use strict";var r=function(t){var e=document.createElement("a");return e.className="header-link",e.href="#"+t,e.innerHTML=' ',e},i=function(t,e){for(var n=e.getElementsByTagName("h"+t),i=0;i0&&p.parentNode.classList.add("expand")}}catch(t){a=!0,u=t}finally{try{!s&&l.return&&l.return()}finally{if(a)throw u}}}},function(t,e,n){"use strict";n(13)({apiKey:"167e7998590aebda7f9fedcf86bc4a55",indexName:"hugodocs",inputSelector:"#search-input",debug:!0})},function(t,e,n){"use strict";n(14),n(15)},function(t,e,n){"use strict";function r(){for(var t=this.dataset.target.split(" "),e=document.querySelector(".mobilemenu:not(.dn)"),n=document.querySelector(".desktopmenu:not(.dn)"),r=document.querySelector(".desktopmenu:not(.dn)"),i=0;i=0?function(){var t=window.pageYOffset;(t>=i-s||window.innerHeight+t>=document.body.offsetHeight)&&clearInterval(u)}:function(){window.pageYOffset<=(i||0)&&clearInterval(u)};var u=setInterval(a,16)},e=document.querySelectorAll("#TableOfContents ul li a");[].forEach.call(e,function(e){e.addEventListener("click",function(n){n.preventDefault();var r=e.getAttribute("href"),i=document.querySelector(r),o=e.getAttribute("data-speed");i&&t(i,o||500)},!1)})}}()},function(t,e,n){"use strict";function r(t){if(t.target){t.preventDefault();var e=t.currentTarget,n=e.getAttribute("data-toggle-tab")}else var n=t;window.localStorage&&window.localStorage.setItem("configLangPref",n);for(var r=document.querySelectorAll("[data-toggle-tab='"+n+"']"),i=document.querySelectorAll("[data-pane='"+n+"']"),a=0;a0&&void 0!==arguments[0]?arguments[0]:{};this.action=t.action,this.container=t.container,this.emitter=t.emitter,this.target=t.target,this.text=t.text,this.trigger=t.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var t=this,e="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return t.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[e?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,r.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,r.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var t=void 0;try{t=document.execCommand(this.action)}catch(e){t=!1}this.handleResult(t)}},{key:"handleResult",value:function(t){this.emitter.emit(t?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=t,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(t){if(void 0!==t){if(!t||"object"!==(void 0===t?"undefined":i(t))||1!==t.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&t.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(t.hasAttribute("readonly")||t.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=t}},get:function(){return this._target}}]),t}();t.exports=s})},{select:5}],8:[function(e,n,r){!function(i,o){if("function"==typeof t&&t.amd)t(["module","./clipboard-action","tiny-emitter","good-listener"],o);else if(void 0!==r)o(n,e("./clipboard-action"),e("tiny-emitter"),e("good-listener"));else{var s={exports:{}};o(s,i.clipboardAction,i.tinyEmitter,i.goodListener),i.clipboard=s.exports}}(this,function(t,e,n,r){"use strict";function i(t){return t&&t.__esModule?t:{default:t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function s(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function a(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function u(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}var c=i(e),l=i(n),h=i(r),f="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},p=function(){function t(t,e){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof t.action?t.action:this.defaultAction,this.target="function"==typeof t.target?t.target:this.defaultTarget,this.text="function"==typeof t.text?t.text:this.defaultText,this.container="object"===f(t.container)?t.container:document.body}},{key:"listenClick",value:function(t){var e=this;this.listener=(0,h.default)(t,"click",function(t){return e.onClick(t)})}},{key:"onClick",value:function(t){var e=t.delegateTarget||t.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new c.default({action:this.action(e),target:this.target(e),text:this.text(e),container:this.container,trigger:e,emitter:this})}},{key:"defaultAction",value:function(t){return u("action",t)}},{key:"defaultTarget",value:function(t){var e=u("target",t);if(e)return document.querySelector(e)}},{key:"defaultText",value:function(t){return u("text",t)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],e="string"==typeof t?[t]:t,n=!!document.queryCommandSupported;return e.forEach(function(t){n=n&&!!document.queryCommandSupported(t)}),n}}]),e}(l.default);t.exports=d})},{"./clipboard-action":7,"good-listener":4,"tiny-emitter":6}]},{},[8])(8)})},function(t,e,n){/*! docsearch 2.4.1 | © Algolia | github.com/algolia/docsearch */ !function(e,n){t.exports=n()}(0,function(){return function(t){function e(r){if(n[r])return n[r].exports;var i=n[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var n={};return e.m=t,e.c=n,e.i=function(t){return t},e.d=function(t,n,r){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:r})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=46)}([function(t,e,n){"use strict";function r(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}var i=n(1);t.exports={isArray:null,isFunction:null,isObject:null,bind:null,each:null,map:null,mixin:null,isMsie:function(){return!!/(msie|trident)/i.test(navigator.userAgent)&&navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2]},escapeRegExChars:function(t){return t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isNumber:function(t){return"number"==typeof t},toStr:function(t){return void 0===t||null===t?"":t+""},cloneDeep:function(t){var e=this.mixin({},t),n=this;return this.each(e,function(t,r){t&&(n.isArray(t)?e[r]=[].concat(t):n.isObject(t)&&(e[r]=n.cloneDeep(t)))}),e},error:function(t){throw new Error(t)},every:function(t,e){var n=!0;return t?(this.each(t,function(r,i){if(!(n=e.call(null,r,i,t)))return!1}),!!n):n},any:function(t,e){var n=!1;return t?(this.each(t,function(r,i){if(e.call(null,r,i,t))return n=!0,!1}),n):n},getUniqueId:function(){var t=0;return function(){return t++}}(),templatify:function(t){if(this.isFunction(t))return t;var e=i.element(t);return"SCRIPT"===e.prop("tagName")?function(){return e.text()}:function(){return String(t)}},defer:function(t){setTimeout(t,0)},noop:function(){},formatPrefix:function(t,e){return e?"":t+"-"},className:function(t,e,n){return(n?"":".")+t+e},escapeHighlightedString:function(t,e,n){e=e||"";var i=document.createElement("div");i.appendChild(document.createTextNode(e)),n=n||"";var o=document.createElement("div");o.appendChild(document.createTextNode(n));var s=document.createElement("div");return s.appendChild(document.createTextNode(t)),s.innerHTML.replace(RegExp(r(i.innerHTML),"g"),e).replace(RegExp(r(o.innerHTML),"g"),n)}}},function(t,e,n){"use strict";t.exports={element:null}},function(t,e){var n=Object.prototype.hasOwnProperty,r=Object.prototype.toString;t.exports=function(t,e,i){if("[object Function]"!==r.call(e))throw new TypeError("iterator must be a function");var o=t.length;if(o===+o)for(var s=0;s was loaded but did not call our provided callback"),JSONPScriptError:i("JSONPScriptError","` or ``. MediaType : The MIME type of the resource, such as `image/jpeg`. MediaType.MainType : The main type of the resource's MIME type. For example, a file of MIME type `application/pdf` has for MainType `application`. MediaType.SubType : The subtype of the resource's MIME type. For example, a file of MIME type `application/pdf` has for SubType `pdf`. Note that this is not the same as the file extension - PowerPoint files have a subtype of `vnd.mspowerpoint`. MediaType.Suffixes : A slice of possible suffixes for the resource's MIME type. ## Methods ByType : Returns the page resources of the given type. ```go {{ .Resources.ByType "image" }} ``` Match : Returns all the page resources (as a slice) whose `Name` matches the given Glob pattern ([examples](https://github.com/gobwas/glob/blob/master/readme.md)). The matching is case-insensitive. ```go {{ .Resources.Match "images/*" }} ``` GetMatch : Same as `Match` but will return the first match. ### Pattern Matching ```go // Using Match/GetMatch to find this images/sunset.jpg ? .Resources.Match "images/sun*" ✅ .Resources.Match "**/sunset.jpg" ✅ .Resources.Match "images/*.jpg" ✅ .Resources.Match "**.jpg" ✅ .Resources.Match "*" 🚫 .Resources.Match "sunset.jpg" 🚫 .Resources.Match "*sunset.jpg" 🚫 ``` ## Page Resources Metadata The page resources' metadata is managed from the corresponding page's front matter with an array/table parameter named `resources`. You can batch assign values using [wildcards](http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm). {{% note %}} Resources of type `page` get `Title` etc. from their own front matter. {{% /note %}} name : Sets the value returned in `Name`. {{% warning %}} The methods `Match` and `GetMatch` use `Name` to match the resources. {{%/ warning %}} title : Sets the value returned in `Title` params : A map of custom key/values. ### Resources metadata example {{< code-toggle copy="false">}} title: Application date : 2018-01-25 resources : - src : "images/sunset.jpg" name : "header" - src : "documents/photo_specs.pdf" title : "Photo Specifications" params: icon : "photo" - src : "documents/guide.pdf" title : "Instruction Guide" - src : "documents/checklist.pdf" title : "Document Checklist" - src : "documents/payment.docx" title : "Proof of Payment" - src : "**.pdf" name : "pdf-file-:counter" params : icon : "pdf" - src : "**.docx" params : icon : "word" {{}} From the example above: - `sunset.jpg` will receive a new `Name` and can now be found with `.GetMatch "header"`. - `documents/photo_specs.pdf` will get the `photo` icon. - `documents/checklist.pdf`, `documents/guide.pdf` and `documents/payment.docx` will get `Title` as set by `title`. - Every `PDF` in the bundle except `documents/photo_specs.pdf` will get the `pdf` icon. - All `PDF` files will get a new `Name`. The `name` parameter contains a special placeholder [`:counter`](#the-counter-placeholder-in-name-and-title), so the `Name` will be `pdf-file-1`, `pdf-file-2`, `pdf-file-3`. - Every docx in the bundle will receive the `word` icon. {{% warning %}} The __order matters__ --- Only the **first set** values of the `title`, `name` and `params`-**keys** will be used. Consecutive parameters will be set only for the ones not already set. In the above example, `.Params.icon` is first set to `"photo"` in `src = "documents/photo_specs.pdf"`. So that would not get overridden to `"pdf"` by the later set `src = "**.pdf"` rule. {{%/ warning %}} ### The `:counter` placeholder in `name` and `title` The `:counter` is a special placeholder recognized in `name` and `title` parameters `resources`. The counter starts at 1 the first time they are used in either `name` or `title`. For example, if a bundle has the resources `photo_specs.pdf`, `other_specs.pdf`, `guide.pdf` and `checklist.pdf`, and the front matter has specified the `resources` as: {{< code-toggle copy="false">}} [[resources]] src = "*specs.pdf" title = "Specification #:counter" [[resources]] src = "**.pdf" name = "pdf-file-:counter" {{}} the `Name` and `Title` will be assigned to the resource files as follows: | Resource file | `Name` | `Title` | |-------------------|-------------------|-----------------------| | checklist.pdf | `"pdf-file-1.pdf` | `"checklist.pdf"` | | guide.pdf | `"pdf-file-2.pdf` | `"guide.pdf"` | | other\_specs.pdf | `"pdf-file-3.pdf` | `"Specification #1"` | | photo\_specs.pdf | `"pdf-file-4.pdf` | `"Specification #2"` | hugo-0.68.3/docs/content/en/content-management/related.md000066400000000000000000000130141363637351300233150ustar00rootroot00000000000000--- title: Related Content description: List related content in "See Also" sections. date: 2017-09-05 categories: [content management] keywords: [content] menu: docs: parent: "content-management" weight: 40 weight: 30 draft: false aliases: [/content/related/,/related/] toc: true --- Hugo uses a set of factors to identify a page's related content based on Front Matter parameters. This can be tuned to the desired set of indices and parameters or left to Hugo's default [Related Content configuration](#configure-related-content). ## List Related Content To list up to 5 related pages (which share the same _date_ or _keyword_ parameters) is as simple as including something similar to this partial in your single page template: {{< code file="layouts/partials/related.html" >}} {{ $related := .Site.RegularPages.Related . | first 5 }} {{ with $related }}

See Also

{{ end }} {{< /code >}} ### Methods Here is the list of "Related" methods available on a page collection such `.RegularPages`. #### .Related PAGE Returns a collection of pages related the given one. ``` {{ $related := .Site.RegularPages.Related . }} ``` #### .RelatedIndices PAGE INDICE1 [INDICE2 ...] Returns a collection of pages related to a given one restricted to a list of indices. ``` {{ $related := .Site.RegularPages.RelatedIndices . "tags" "date" }} ``` #### .RelatedTo KEYVALS [KEYVALS2 ...] Returns a collection of pages related together by a set of indices and their match. In order to build those set and pass them as argument, one must use the `keyVals` function where the first argument would be the `indice` and the consecutive ones its potential `matches`. ``` {{ $related := .Site.RegularPages.RelatedTo ( keyVals "tags" "hugo" "rocks") ( keyVals "date" .Date ) }} ``` {{% note %}} Read [this blog article](https://regisphilibert.com/blog/2018/04/hugo-optmized-relashionships-with-related-content/) for a great explanation of more advanced usage of this feature. {{% /note %}} ## Configure Related Content Hugo provides a sensible default configuration of Related Content, but you can fine-tune this in your configuration, on the global or language level if needed. ### Default configuration Without any `related` configuration set on the project, Hugo's Related Content methods will use the following. ```yaml related: threshold: 80 includeNewer: false toLower: false indices: - name: keywords weight: 100 - name: date weight: 10 ``` Custom configuration should be set using the same syntax. {{% note %}} If you add a `related` config section, you need to add a complete configuration. It is not possible to just set, say, `includeNewer` and use the rest from the Hugo defaults. {{% /note %}} ### Top Level Config Options threshold : A value between 0-100. Lower value will give more, but maybe not so relevant, matches. includeNewer : Set to true to include **pages newer than the current page** in the related content listing. This will mean that the output for older posts may change as new related content gets added. toLower : Set to true to lower case keywords in both the indexes and the queries. This may give more accurate results at a slight performance penalty. Note that this can also be set per index. ### Config Options per Index name : The index name. This value maps directly to a page param. Hugo supports string values (`author` in the example) and lists (`tags`, `keywords` etc.) and time and date objects. weight : An integer weight that indicates _how important_ this parameter is relative to the other parameters. It can be 0, which has the effect of turning this index off, or even negative. Test with different values to see what fits your content best. pattern : This is currently only relevant for dates. When listing related content, we may want to list content that is also close in time. Setting "2006" (default value for date indexes) as the pattern for a date index will add weight to pages published in the same year. For busier blogs, "200601" (year and month) may be a better default. toLower : See above. ## Performance Considerations **Fast is Hugo's middle name** and we would not have released this feature had it not been blistering fast. This feature has been in the back log and requested by many for a long time. The development got this recent kick start from this Twitter thread: {{< tweet 898398437527363585 >}} Scott S. Lowe removed the "Related Content" section built using the `intersect` template function on tags, and the build time dropped from 30 seconds to less than 2 seconds on his 1700 content page sized blog. He should now be able to add an improved version of that "Related Content" section without giving up the fast live-reloads. But it's worth noting that: * If you don't use any of the `Related` methods, you will not use the Relate Content feature, and performance will be the same as before. * Calling `.RegularPages.Related` etc. will create one inverted index, also sometimes named posting list, that will be reused for any lookups in that same page collection. Doing that in addition to, as an example, calling `.Pages.Related` will work as expected, but will create one additional inverted index. This should still be very fast, but worth having in mind, especially for bigger sites. {{% note %}} We currently do not index **Page content**. We thought we would release something that will make most people happy before we start solving [Sherlock's last case](https://github.com/joearms/sherlock). {{% /note %}} hugo-0.68.3/docs/content/en/content-management/sections.md000066400000000000000000000072301363637351300235270ustar00rootroot00000000000000--- title: Content Sections linktitle: Sections description: "Hugo generates a **section tree** that matches your content." date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [content management] keywords: [lists,sections,content types,organization] menu: docs: parent: "content-management" weight: 50 weight: 50 #rem draft: false aliases: [/content/sections/] toc: true --- A **Section** is a collection of pages that gets defined based on the organization structure under the `content/` directory. By default, all the **first-level** directories under `content/` form their own sections (**root sections**). If a user needs to define a section `foo` at a deeper level, they need to create a directory named `foo` with an `_index.md` file (see [Branch Bundles][branch bundles] for more information). {{% note %}} A **section** cannot be defined or overridden by a front matter parameter -- it is strictly derived from the content organization structure. {{% /note %}} ## Nested Sections The sections can be nested as deeply as you need. ```bash content └── blog <-- Section, because first-level dir under content/ ├── funny-cats │   ├── mypost.md │   └── kittens <-- Section, because contains _index.md │   └── _index.md └── tech <-- Section, because contains _index.md └── _index.md ``` **The important part to understand is, that to make the section tree fully navigational, at least the lower-most section needs a content file. (e.g. `_index.md`).** {{% note %}} When we talk about a **section** in correlation with template selection, it is currently always the *root section* only (`/blog/funny-cats/mypost/ => blog`). If you need a specific template for a sub-section, you need to adjust either the `type` or `layout` in front matter. {{% /note %}} ## Example: Breadcrumb Navigation With the available [section variables and methods](#section-page-variables-and-methods) you can build powerful navigation. One common example would be a partial to show Breadcrumb navigation: {{< code file="layouts/partials/breadcrumb.html" download="breadcrumb.html" >}} {{ define "breadcrumbnav" }} {{ if .p1.Parent }} {{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) }} {{ else if not .p1.IsHome }} {{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) }} {{ end }} {{ .p1.Title }} {{ end }} {{< /code >}} ## Section Page Variables and Methods Also see [Page Variables](/variables/page/). {{< readfile file="/content/en/readfiles/sectionvars.md" markdown="true" >}} ## Content Section Lists Hugo will automatically create pages for each *root section* that list all of the content in that section. See the documentation on [section templates][] for details on customizing the way these pages are rendered. ## Content *Section* vs Content *Type* By default, everything created within a section will use the [content `type`][content type] that matches the *root section* name. For example, Hugo will assume that `posts/post-1.md` has a `posts` content `type`. If you are using an [archetype][] for your `posts` section, Hugo will generate front matter according to what it finds in `archetypes/posts.md`. [archetype]: /content-management/archetypes/ [content type]: /content-management/types/ [directory structure]: /getting-started/directory-structure/ [section templates]: /templates/section-templates/ [branch bundles]: /content-management/page-bundles/#branch-bundles hugo-0.68.3/docs/content/en/content-management/shortcodes.md000066400000000000000000000355751363637351300240720ustar00rootroot00000000000000--- title: Shortcodes linktitle: description: Shortcodes are simple snippets inside your content files calling built-in or custom templates. godocref: date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2019-11-07 menu: docs: parent: "content-management" weight: 35 weight: 35 #rem categories: [content management] keywords: [markdown,content,shortcodes] draft: false aliases: [/extras/shortcodes/] testparam: "Hugo Rocks!" toc: true --- ## What a Shortcode is Hugo loves Markdown because of its simple content format, but there are times when Markdown falls short. Often, content authors are forced to add raw HTML (e.g., video ``) to Markdown content. We think this contradicts the beautiful simplicity of Markdown's syntax. Hugo created **shortcodes** to circumvent these limitations. A shortcode is a simple snippet inside a content file that Hugo will render using a predefined template. Note that shortcodes will not work in template files. If you need the type of drop-in functionality that shortcodes provide but in a template, you most likely want a [partial template][partials] instead. In addition to cleaner Markdown, shortcodes can be updated any time to reflect new classes, techniques, or standards. At the point of site generation, Hugo shortcodes will easily merge in your changes. You avoid a possibly complicated search and replace operation. ## Use Shortcodes {{< youtube 2xkNJL4gJ9E >}} In your content files, a shortcode can be called by calling `{{%/* shortcodename parameters */%}}`. Shortcode parameters are space delimited, and parameters with internal spaces can be quoted. The first word in the shortcode declaration is always the name of the shortcode. Parameters follow the name. Depending upon how the shortcode is defined, the parameters may be named, positional, or both, although you can't mix parameter types in a single call. The format for named parameters models that of HTML with the format `name="value"`. Some shortcodes use or require closing shortcodes. Again like HTML, the opening and closing shortcodes match (name only) with the closing declaration, which is prepended with a slash. Here are two examples of paired shortcodes: ``` {{%/* mdshortcode */%}}Stuff to `process` in the *center*.{{%/* /mdshortcode */%}} ``` ``` {{}} A bunch of code here {{}} ``` The examples above use two different delimiters, the difference being the `%` character in the first and the `<>` characters in the second. ### Shortcodes with raw string parameters {{< new-in "0.64.1" >}} You can pass multiple lines as parameters to a shortcode by using raw string literals: ``` {{HTML, and a new line with a "quoted string".` */>}} ``` ### Shortcodes with Markdown In Hugo `0.55` we changed how the `%` delimiter works. Shortcodes using the `%` as the outer-most delimiter will now be fully rendered when sent to the content renderer (e.g. Blackfriday for Markdown), meaning they can be part of the generated table of contents, footnotes, etc. If you want the old behavior, you can put the following line in the start of your shortcode template: ``` {{ $_hugo_config := `{ "version": 1 }` }} ``` ### Shortcodes Without Markdown The `<` character indicates that the shortcode's inner content does *not* need further rendering. Often shortcodes without markdown include internal HTML: ``` {{}}

Hello World!

{{}} ``` ### Nested Shortcodes You can call shortcodes within other shortcodes by creating your own templates that leverage the `.Parent` variable. `.Parent` allows you to check the context in which the shortcode is being called. See [Shortcode templates][sctemps]. ## Use Hugo's Built-in Shortcodes Hugo ships with a set of predefined shortcodes that represent very common usage. These shortcodes are provided for author convenience and to keep your markdown content clean. ### `figure` `figure` is an extension of the image syntax in markdown, which does not provide a shorthand for the more semantic [HTML5 `
` element][figureelement]. The `figure` shortcode can use the following named parameters: src : URL of the image to be displayed. link : If the image needs to be hyperlinked, URL of the destination. target : Optional `target` attribute for the URL if `link` parameter is set. rel : Optional `rel` attribute for the URL if `link` parameter is set. alt : Alternate text for the image if the image cannot be displayed. title : Image title. caption : Image caption. Markdown within the value of `caption` will be rendered. class : `class` attribute of the HTML `figure` tag. height : `height` attribute of the image. width : `width` attribute of the image. attr : Image attribution text. Markdown within the value of `attr` will be rendered. attrlink : If the attribution text needs to be hyperlinked, URL of the destination. #### Example `figure` Input {{< code file="figure-input-example.md" >}} {{}} {{< /code >}} #### Example `figure` Output {{< output file="figure-output-example.html" >}}

Steve Francia

{{< /output >}} ### `gist` Bloggers often want to include GitHub gists when writing posts. Let's suppose we want to use the [gist at the following url][examplegist]: ``` https://gist.github.com/spf13/7896402 ``` We can embed the gist in our content via username and gist ID pulled from the URL: ``` {{}} ``` #### Example `gist` Input If the gist contains several files and you want to quote just one of them, you can pass the filename (quoted) as an optional third argument: {{< code file="gist-input.md" >}} {{}} {{< /code >}} #### Example `gist` Output {{< output file="gist-output.html" >}} {{< gist spf13 7896402 >}} {{< /output >}} #### Example `gist` Display To demonstrate the remarkably efficiency of Hugo's shortcode feature, we have embedded the `spf13` `gist` example in this page. The following simulates the experience for visitors to your website. Naturally, the final display will be contingent on your stylesheets and surrounding markup. {{< gist spf13 7896402 >}} ### `highlight` This shortcode will convert the source code provided into syntax-highlighted HTML. Read more on [highlighting](/tools/syntax-highlighting/). `highlight` takes exactly one required `language` parameter and requires a closing shortcode. #### Example `highlight` Input {{< code file="content/tutorials/learn-html.md" >}} {{}}

{{ .Title }}

{{ range .Pages }} {{ .Render "summary"}} {{ end }}
{{}} {{< /code >}} #### Example `highlight` Output The `highlight` shortcode example above would produce the following HTML when the site is rendered: {{< output file="tutorials/learn-html/index.html" >}} <section id="main"> <div> <h1 id="title">{{ .Title }}</h1> {{ range .Pages }} {{ .Render "summary"}} {{ end }} </div> </section> {{< /output >}} {{% note "More on Syntax Highlighting" %}} To see even more options for adding syntax-highlighted code blocks to your website, see [Syntax Highlighting in Developer Tools](/tools/syntax-highlighting/). {{% /note %}} ### `instagram` If you'd like to embed a photo from [Instagram][], you only need the photo's ID. You can discern an Instagram photo ID from the URL: ``` https://www.instagram.com/p/BWNjjyYFxVx/ ``` #### Example `instagram` Input {{< code file="instagram-input.md" >}} {{}} {{< /code >}} You also have the option to hide the caption: {{< code file="instagram-input-hide-caption.md" >}} {{}} {{< /code >}} #### Example `instagram` Output By adding the preceding `hidecaption` example, the following HTML will be added to your rendered website's markup: {{< output file="instagram-hide-caption-output.html" >}} {{< instagram BWNjjyYFxVx hidecaption >}} {{< /output >}} #### Example `instagram` Display Using the preceding `instagram` with `hidecaption` example above, the following simulates the displayed experience for visitors to your website. Naturally, the final display will be contingent on your stylesheets and surrounding markup. {{< instagram BWNjjyYFxVx hidecaption >}} ### `param` Gets a value from the current `Page's` params set in front matter, with a fall back to the site param value. It will log an `ERROR` if the param with the given key could not be found in either. ```bash {{}} ``` Since `testparam` is a param defined in front matter of this page with the value `Hugo Rocks!`, the above will print: {{< param testparam >}} To access deeply nested params, use "dot syntax", e.g: ```bash {{}} ``` ### `ref` and `relref` These shortcodes will look up the pages by their relative path (e.g., `blog/post.md`) or their logical name (`post.md`) and return the permalink (`ref`) or relative permalink (`relref`) for the found page. `ref` and `relref` also make it possible to make fragmentary links that work for the header links generated by Hugo. {{% note "More on Cross References" %}} Read a more extensive description of `ref` and `relref` in the [cross references](/content-management/cross-references/) documentation. {{% /note %}} `ref` and `relref` take exactly one required parameter of _reference_, quoted and in position `0`. #### Example `ref` and `relref` Input ``` [Neat]({{}}) [Who]({{}}) ``` #### Example `ref` and `relref` Output Assuming that standard Hugo pretty URLs are turned on. ``` Neat Who ``` ### `tweet` You want to include a single tweet into your blog post? Everything you need is the URL of the tweet: ``` https://twitter.com/spf13/status/877500564405444608 ``` #### Example `tweet` Input Pass the tweet's ID from the URL as a parameter to the `tweet` shortcode: {{< code file="example-tweet-input.md" >}} {{}} {{< /code >}} #### Example `tweet` Output Using the preceding `tweet` example, the following HTML will be added to your rendered website's markup: {{< output file="example-tweet-output.html" >}} {{< tweet 877500564405444608 >}} {{< /output >}} #### Example `tweet` Display Using the preceding `tweet` example, the following simulates the displayed experience for visitors to your website. Naturally, the final display will be contingent on your stylesheets and surrounding markup. {{< tweet 877500564405444608 >}} ### `vimeo` Adding a video from [Vimeo][] is equivalent to the [YouTube Input shortcode][]. ``` https://vimeo.com/channels/staffpicks/146022717 ``` #### Example `vimeo` Input Extract the ID from the video's URL and pass it to the `vimeo` shortcode: {{< code file="example-vimeo-input.md" >}} {{}} {{< /code >}} #### Example `vimeo` Output Using the preceding `vimeo` example, the following HTML will be added to your rendered website's markup: {{< output file="example-vimeo-output.html" >}} {{< vimeo 146022717 >}} {{< /output >}} {{% tip %}} If you want to further customize the visual styling of the YouTube or Vimeo output, add a `class` named parameter when calling the shortcode. The new `class` will be added to the `
` that wraps the `
{{< /code >}} {{< code file="youtube-embed.html" copy="false" >}}
{{< /code >}} ### Single Named Example: `image` Let's say you want to create your own `img` shortcode rather than use Hugo's built-in [`figure` shortcode][figure]. Your goal is to be able to call the shortcode as follows in your content files: {{< code file="content-image.md" >}} {{}} {{< /code >}} You have created the shortcode at `/layouts/shortcodes/img.html`, which loads the following shortcode template: {{< code file="/layouts/shortcodes/img.html" >}}
{{ with .Get "link"}}{{ end }} {{ if .Get "link"}}{{ end }} {{ if or (or (.Get "title") (.Get "caption")) (.Get "attr")}}
{{ if isset .Params "title" }}

{{ .Get "title" }}

{{ end }} {{ if or (.Get "caption") (.Get "attr")}}

{{ .Get "caption" }} {{ with .Get "attrlink"}} {{ end }} {{ .Get "attr" }} {{ if .Get "attrlink"}} {{ end }}

{{ end }}
{{ end }}
{{< /code >}} Would be rendered as: {{< code file="img-output.html" copy="false" >}}

Steve Francia

{{< /code >}} ### Single Flexible Example: `vimeo` ``` {{}} {{}} ``` Would load the template found at `/layouts/shortcodes/vimeo.html`: {{< code file="/layouts/shortcodes/vimeo.html" >}} {{ if .IsNamedParams }}
{{ else }}
{{ end }} {{< /code >}} Would be rendered as: {{< code file="vimeo-iframes.html" copy="false" >}}
{{< /code >}} ### Paired Example: `highlight` The following is taken from `highlight`, which is a [built-in shortcode][] that ships with Hugo. {{< code file="highlight-example.md" >}} {{}} This HTML {{}} {{< /code >}} The template for the `highlight` shortcode uses the following code, which is already included in Hugo: ``` {{ .Get 0 | highlight .Inner }} ``` The rendered output of the HTML example code block will be as follows: {{< code file="syntax-highlighted.html" copy="false" >}}
<html>
    <body> This HTML </body>
</html>
{{< /code >}} ### Nested Shortcode: Image Gallery Hugo's [`.Parent` shortcode variable][parent] returns a boolean value depending on whether the shortcode in question is called within the context of a *parent* shortcode. This provides an inheritance model for common shortcode parameters. The following example is contrived but demonstrates the concept. Assume you have a `gallery` shortcode that expects one named `class` parameter: {{< code file="layouts/shortcodes/gallery.html" >}}
{{.Inner}}
{{< /code >}} You also have an `img` shortcode with a single named `src` parameter that you want to call inside of `gallery` and other shortcodes, so that the parent defines the context of each `img`: {{< code file="layouts/shortcodes/img.html" >}} {{- $src := .Get "src" -}} {{- with .Parent -}} {{- else -}} {{- end }} {{< /code >}} You can then call your shortcode in your content as follows: ``` {{}} {{}} {{}} {{}} {{}} ``` This will output the following HTML. Note how the first two `img` shortcodes inherit the `class` value of `content-gallery` set with the call to the parent `gallery`, whereas the third `img` only uses `src`: ``` ``` ## Error Handling in Shortcodes Use the [errorf](/functions/errorf) template func and [.Position](/variables/shortcodes/) variable to get useful error messages in shortcodes: ```bash {{ with .Get "name" }} {{ else }} {{ errorf "missing value for param 'name': %s" .Position }} {{ end }} ``` When the above fails, you will see an `ERROR` log similar to the below: ```bash ERROR 2018/11/07 10:05:55 missing value for param name: "/Users/bep/dev/go/gohugoio/hugo/docs/content/en/variables/shortcodes.md:32:1" ``` ## More Shortcode Examples More shortcode examples can be found in the [shortcodes directory for spf13.com][spfscs] and the [shortcodes directory for the Hugo docs][docsshortcodes]. ## Inline Shortcodes Since Hugo 0.52, you can implement your shortcodes inline -- e.g. where you use them in the content file. This can be useful for scripting that you only need in one place. This feature is disabled by default, but can be enabled in your site config: {{< code-toggle file="config">}} enableInlineShortcodes = true {{< /code-toggle >}} It is disabled by default for security reasons. The security model used by Hugo's template handling assumes that template authors are trusted, but that the content files are not, so the templates are injection-safe from malformed input data. But in most situations you have full control over the content, too, and then `enableInlineShortcodes = true` would be considered safe. But it's something to be aware of: It allows ad-hoc [Go Text templates](https://golang.org/pkg/text/template/) to be executed from the content files. And once enabled, you can do this in your content files: ```go-text-template {{}}{{ now }}{{}} ``` The above will print the current date and time. Note that an inline shortcode's inner content is parsed and executed as a Go text template with the same context as a regular shortcode template. This means that the current page can be accessed via `.Page.Title` etc. This also means that there are no concept of "nested inline shortcodes". The same inline shortcode can be reused later in the same content file, with different params if needed, using the self-closing syntax: ```go-text-template {{}} ``` [basic content files]: /content-management/formats/ "See how Hugo leverages markdown--and other supported formats--to create content for your website." [built-in shortcode]: /content-management/shortcodes/ [config]: /getting-started/configuration/ "Learn more about Hugo's built-in configuration variables as well as how to us your site's configuration file to include global key-values that can be used throughout your rendered website." [Content Management: Shortcodes]: /content-management/shortcodes/#using-hugo-s-built-in-shortcodes "Check this section if you are not familiar with the definition of what a shortcode is or if you are unfamiliar with how to use Hugo's built-in shortcodes in your content files." [source organization]: /getting-started/directory-structure/#directory-structure-explained "Learn how Hugo scaffolds new sites and what it expects to find in each of your directories." [docsshortcodes]: https://github.com/gohugoio/hugo/tree/master/docs/layouts/shortcodes "See the shortcode source directory for the documentation site you're currently reading." [figure]: /content-management/shortcodes/#figure [hugosc]: /content-management/shortcodes/#using-hugo-s-built-in-shortcodes [lookup order]: /templates/lookup-order/ "See the order in which Hugo traverses your template files to decide where and how to render your content at build time" [pagevars]: /variables/page/ "See which variables you can leverage in your templating for page vs list templates." [parent]: /variables/shortcodes/ [shortcodesvars]: /variables/shortcodes/ "Certain variables are specific to shortcodes, although most .Page variables can be accessed within your shortcode template." [spfscs]: https://github.com/spf13/spf13.com/tree/master/layouts/shortcodes "See more examples of shortcodes by visiting the shortcode directory of the source for spf13.com, the blog of Hugo's creator, Steve Francia." [templates]: /templates/ "The templates section of the Hugo docs." [vimeoexample]: #single-flexible-example-vimeo [youtubeshortcode]: /content-management/shortcodes/#youtube "See how to use Hugo's built-in YouTube shortcode." hugo-0.68.3/docs/content/en/templates/single-page-templates.md000066400000000000000000000057011363637351300243020ustar00rootroot00000000000000--- title: Single Page Templates linktitle: description: The primary view of content in Hugo is the single view. Hugo will render every Markdown file provided with a corresponding single template. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-04-06 categories: [templates] keywords: [page,templates] menu: docs: parent: "templates" weight: 60 weight: 60 sections_weight: 60 draft: false aliases: [/layout/content/] toc: true --- ## Single Page Template Lookup Order See [Template Lookup](/templates/lookup-order/). ## Example Single Page Templates Content pages are of the type `page` and will therefore have all the [page variables][pagevars] and [site variables][] available to use in their templates. ### `posts/single.html` This single page template makes use of Hugo [base templates][], the [`.Format` function][] for dates, the [`.WordCount` page variable][pagevars], and ranges through the single content's specific [taxonomies][pagetaxonomy]. [`with`][] is also used to check whether the taxonomies are set in the front matter. {{< code file="layouts/posts/single.html" download="single.html" >}} {{ define "main" }}

{{ .Title }}

{{ .Content }}
{{ end }} {{< /code >}} To easily generate new instances of a content type (e.g., new `.md` files in a section like `project/`) with preconfigured front matter, use [content archetypes][archetypes]. [archetypes]: /content-management/archetypes/ [base templates]: /templates/base/ [config]: /getting-started/configuration/ [content type]: /content-management/types/ [directory structure]: /getting-started/directory-structure/ [dry]: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself [`.Format` function]: /functions/format/ [front matter]: /content-management/front-matter/ [pagetaxonomy]: /templates/taxonomy-templates/#displaying-a-single-piece-of-content-s-taxonomies [pagevars]: /variables/page/ [partials]: /templates/partials/ [section]: /content-management/sections/ [site variables]: /variables/site/ [spf13]: https://spf13.com/ [`with`]: /functions/with/ hugo-0.68.3/docs/content/en/templates/sitemap-template.md000066400000000000000000000066171363637351300233750ustar00rootroot00000000000000--- title: Sitemap Template # linktitle: Sitemap description: Hugo ships with a built-in template file observing the v0.9 of the Sitemap Protocol, but you can override this template if needed. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [templates] keywords: [sitemap, xml, templates] menu: docs: parent: "templates" weight: 160 weight: 160 sections_weight: 160 draft: false aliases: [/layout/sitemap/,/templates/sitemap/] toc: false --- A single Sitemap template is used to generate the `sitemap.xml` file. Hugo automatically comes with this template file. *No work is needed on the users' part unless they want to customize `sitemap.xml`.* A sitemap is a `Page` and therefore has all the [page variables][pagevars] available to use in this template along with Sitemap-specific ones: `.Sitemap.ChangeFreq` : The page change frequency `.Sitemap.Priority` : The priority of the page `.Sitemap.Filename` : The sitemap filename If provided, Hugo will use `/layouts/sitemap.xml` instead of the internal `sitemap.xml` template that ships with Hugo. ## Sitemap Templates Hugo has built-on Sitemap templates, but you can provide your own if needed, in either `layouts/sitemap.xml` or `layouts/_default/sitemap.xml`. For multilingual sites, we also create a Sitemap index. You can provide a custom layout for that in either `layouts/sitemapindex.xml` or `layouts/_default/sitemapindex.xml`. ## Hugo’s sitemap.xml This template respects the version 0.9 of the [Sitemap Protocol](http://www.sitemaps.org/protocol.html). ```xml {{ printf "" | safeHTML }} {{ range .Data.Pages }} {{ .Permalink }}{{ if not .Lastmod.IsZero }} {{ safeHTML ( .Lastmod.Format "2006-01-02T15:04:05-07:00" ) }}{{ end }}{{ with .Sitemap.ChangeFreq }} {{ . }}{{ end }}{{ if ge .Sitemap.Priority 0.0 }} {{ .Sitemap.Priority }}{{ end }}{{ if .IsTranslated }}{{ range .Translations }} {{ end }} {{ end }} {{ end }} ``` ## Hugo's sitemapindex.xml This is used to create a Sitemap index in multilingual mode: ```xml {{ printf "" | safeHTML }} {{ range . }} {{ .SitemapAbsURL }} {{ if not .LastChange.IsZero }} {{ .LastChange.Format "2006-01-02T15:04:05-07:00" | safeHTML }} {{ end }} {{ end }} ``` ## Configure `sitemap.xml` Defaults for ``, `` and `filename` values can be set in the site's config file, e.g.: {{< code-toggle file="config" >}} [sitemap] changefreq = "monthly" priority = 0.5 filename = "sitemap.xml" {{}} The same fields can be specified in an individual content file's front matter in order to override the value assigned to that piece of content at render time. [pagevars]: /variables/page/ hugo-0.68.3/docs/content/en/templates/taxonomy-templates.md000066400000000000000000000320161363637351300237640ustar00rootroot00000000000000--- title: Taxonomy Templates # linktitle: description: Taxonomy templating includes taxonomy list pages, taxonomy terms pages, and using taxonomies in your single page templates. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [templates] keywords: [taxonomies,metadata,front matter,terms,templates] menu: docs: parent: "templates" weight: 50 weight: 50 sections_weight: 50 draft: false aliases: [/taxonomies/displaying/,/templates/terms/,/indexes/displaying/,/taxonomies/templates/,/indexes/ordering/, /templates/taxonomies/, /templates/taxonomy/] toc: true --- Hugo includes support for user-defined groupings of content called **taxonomies**. Taxonomies are classifications that demonstrate logical relationships between content. See [Taxonomies under Content Management](/content-management/taxonomies) if you are unfamiliar with how Hugo leverages this powerful feature. Hugo provides multiple ways to use taxonomies throughout your project templates: * Order the way content associated with a taxonomy term is displayed in a [taxonomy list template](#taxonomy-list-template) * Order the way the terms for a taxonomy are displayed in a [taxonomy terms template](#taxonomy-terms-template) * List a single content's taxonomy terms within a [single page template][] ## Taxonomy List Templates Taxonomy list page templates are lists and therefore have all the variables and methods available to [list pages][lists]. ### Taxonomy List Template Lookup Order See [Template Lookup](/templates/lookup-order/). ## Taxonomy Terms Template ### Taxonomy Terms Templates Lookup Order See [Template Lookup](/templates/lookup-order/). ### Taxonomy Methods A Taxonomy is a `map[string]WeightedPages`. .Get(term) : Returns the WeightedPages for a term. .Count(term) : The number of pieces of content assigned to this term. .Alphabetical : Returns an OrderedTaxonomy (slice) ordered by Term. .ByCount : Returns an OrderedTaxonomy (slice) ordered by number of entries. .Reverse : Returns an OrderedTaxonomy (slice) in reverse order. Must be used with an OrderedTaxonomy. ### OrderedTaxonomy Since Maps are unordered, an OrderedTaxonomy is a special structure that has a defined order. ```go []struct { Name string WeightedPages WeightedPages } ``` Each element of the slice has: .Term : The Term used. .WeightedPages : A slice of Weighted Pages. .Count : The number of pieces of content assigned to this term. .Pages : All Pages assigned to this term. All [list methods][renderlists] are available to this. ## WeightedPages WeightedPages is simply a slice of WeightedPage. ```go type WeightedPages []WeightedPage ``` .Count(term) : The number of pieces of content assigned to this term. .Pages : Returns a slice of pages, which then can be ordered using any of the [list methods][renderlists]. ## Displaying custom metadata in Taxonomy Terms Templates If you need to display custom metadata for each taxonomy term, you will need to create a page for that term at `/content///_index.md` and add your metadata in its front matter, [as explained in the taxonomies documentation](/content-management/taxonomies/#add-custom-meta-data-to-a-taxonomy-term). Based on the Actors taxonomy example shown there, within your taxonomy terms template, you may access your custom fields by iterating through the variable `.Pages` as such: ```go-html-template
    {{ range .Pages }}
  • {{ .Title }} {{ .Params.wikipedia }}
  • {{ end }}
``` ## Order Taxonomies Taxonomies can be ordered by either alphabetical key or by the number of content pieces assigned to that key. ### Order Alphabetically Example In Hugo 0.55 and later you can do: ```go-html-template ``` Before that you would have to do something like: ```go-html-template
    {{ $type := .Type }} {{ range $key, $value := .Data.Terms.Alphabetical }} {{ $name := .Name }} {{ $count := .Count }} {{ with $.Site.GetPage (printf "/%s/%s" $type $name) }}
  • {{ $name }} {{ $count }}
  • {{ end }} {{ end }}
``` ## Order Content within Taxonomies Hugo uses both `date` and `weight` to order content within taxonomies. Each piece of content in Hugo can optionally be assigned a date. It can also be assigned a weight for each taxonomy it is assigned to. When iterating over content within taxonomies, the default sort is the same as that used for [section and list pages]() first by weight then by date. This means that if the weights for two pieces of content are the same, than the more recent content will be displayed first. The default weight for any piece of content is 0. ### Assign Weight Content can be assigned weight for each taxonomy that it's assigned to. ``` +++ tags = [ "a", "b", "c" ] tags_weight = 22 categories = ["d"] title = "foo" categories_weight = 44 +++ Front Matter with weighted tags and categories ``` The convention is `taxonomyname_weight`. In the above example, this piece of content has a weight of 22 which applies to the sorting when rendering the pages assigned to the "a", "b" and "c" values of the 'tag' taxonomy. It has also been assigned the weight of 44 when rendering the 'd' category. With this the same piece of content can appear in different positions in different taxonomies. Currently taxonomies only support the default ordering of content which is weight -> date. There are two different templates that the use of taxonomies will require you to provide. Both templates are covered in detail in the templates section. A [list template](/templates/list/) is any template that will be used to render multiple pieces of content in a single html page. This template will be used to generate all the automatically created taxonomy pages. A [taxonomy terms template](/templates/terms/) is a template used to generate the list of terms for a given template. There are four common ways you can display the data in your taxonomies in addition to the automatic taxonomy pages created by hugo using the [list templates](/templates/list/): 1. For a given piece of content, you can list the terms attached 2. For a given piece of content, you can list other content with the same term 3. You can list all terms for a taxonomy 4. You can list all taxonomies (with their terms) ## Display a Single Piece of Content's Taxonomies Within your content templates, you may wish to display the taxonomies that piece of content is assigned to. Because we are leveraging the front matter system to define taxonomies for content, the taxonomies assigned to each content piece are located in the usual place (i.e., `.Params.`). ### Example: List Tags in a Single Page Template {{< new-in "0.65.0" >}} ```go-html-template ``` Before Hugo 0.65.0 you needed to do something like this: ```go-html-template {{ $taxo := "tags" }}
    {{ range .Param $taxo }} {{ $name := . }} {{ with $.Site.GetPage (printf "/%s/%s" $taxo ($name | urlize)) }}
  • {{ $name }}
  • {{ end }} {{ end }}
``` If you want to list taxonomies inline, you will have to take care of optional plural endings in the title (if multiple taxonomies), as well as commas. Let's say we have a taxonomy "directors" such as `directors: [ "Joel Coen", "Ethan Coen" ]` in the TOML-format front matter. To list such taxonomies, use the following: ### Example: Comma-delimit Tags in a Single Page Template ```go-html-template {{ $taxo := "directors" }} {{ with .Param $taxo }} Director{{ if gt (len .) 1 }}s{{ end }}: {{ range $index, $director := . }} {{- if gt $index 0 }}, {{ end -}} {{ with $.Site.GetPage (printf "/%s/%s" $taxo $director) -}} {{ $director }} {{- end -}} {{- end -}} {{ end }} ``` Alternatively, you may use the [delimit template function][delimit] as a shortcut if the taxonomies should just be listed with a separator. See {{< gh 2143 >}} on GitHub for discussion. ## List Content with the Same Taxonomy Term If you are using a taxonomy for something like a series of posts, you can list individual pages associated with the same taxonomy. This is also a quick and dirty method for showing related content: ### Example: Showing Content in Same Series ```go-html-template ``` ## List All content in a Given taxonomy This would be very useful in a sidebar as “featured content”. You could even have different sections of “featured content” by assigning different terms to the content. ### Example: Grouping "Featured" Content ```go-html-template ``` ## Render a Site's Taxonomies If you wish to display the list of all keys for your site's taxonomy, you can retrieve them from the [`.Site` variable][sitevars] available on every page. This may take the form of a tag cloud, a menu, or simply a list. The following example displays all terms in a site's tags taxonomy: ### Example: List All Site Tags {#example-list-all-site-tags} In Hugo 0.55 and later you can simply do: ```go-html-template ``` Before that you would do something like this: {{< todo >}}Clean up rest of the taxonomy examples re Hugo 0.55.{{< /todo >}} ```go-html-template
    {{ range $name, $taxonomy := .Site.Taxonomies.tags }} {{ with $.Site.GetPage (printf "/tags/%s" $name) }}
  • {{ $name }}
  • {{ end }} {{ end }}
``` ### Example: List All Taxonomies, Terms, and Assigned Content This example will list all taxonomies and their terms, as well as all the content assigned to each of the terms. {{< code file="layouts/partials/all-taxonomies.html" download="all-taxonomies.html" download="all-taxonomies.html" >}}
    {{ range $taxonomy_term, $taxonomy := .Site.Taxonomies }} {{ with $.Site.GetPage (printf "/%s" $taxonomy_term) }}
  • {{ $taxonomy_term }}
      {{ range $key, $value := $taxonomy }}
    • {{ $key }}
    • {{ end }}
  • {{ end }} {{ end }}
{{< /code >}} ## `.Site.GetPage` for Taxonomies Because taxonomies are lists, the [`.GetPage` function][getpage] can be used to get all the pages associated with a particular taxonomy term using a terse syntax. The following ranges over the full list of tags on your site and links to each of the individual taxonomy pages for each term without having to use the more fragile URL construction of the ["List All Site Tags" example above]({{< relref "#example-list-all-site-tags" >}}): {{< code file="links-to-all-tags.html" >}} {{ $taxo := "tags" }}
    {{ with ($.Site.GetPage (printf "/%s" $taxo)) }} {{ range .Pages }}
  • {{ .Title}}
  • {{ end }} {{ end }}
{{< /code >}} [delimit]: /functions/delimit/ [getpage]: /functions/getpage/ [lists]: /templates/lists/ [renderlists]: /templates/lists/ [single page template]: /templates/single-page-templates/ [sitevars]: /variables/site/ hugo-0.68.3/docs/content/en/templates/template-debugging.md000066400000000000000000000041261363637351300236570ustar00rootroot00000000000000--- title: Template Debugging # linktitle: Template Debugging description: You can use Go templates' `printf` function to debug your Hugo templates. These snippets provide a quick and easy visualization of the variables available to you in different contexts. godocref: https://golang.org/pkg/fmt/ date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [templates] keywords: [debugging,troubleshooting] menu: docs: parent: "templates" weight: 180 weight: 180 sections_weight: 180 draft: false aliases: [] toc: false --- Here are some snippets you can add to your template to answer some common questions. These snippets use the `printf` function available in all Go templates. This function is an alias to the Go function, [fmt.Printf](https://golang.org/pkg/fmt/). ## What Variables are Available in this Context? You can use the template syntax, `$.`, to get the top-level template context from anywhere in your template. This will print out all the values under, `.Site`. ``` {{ printf "%#v" $.Site }} ``` This will print out the value of `.Permalink`: ``` {{ printf "%#v" .Permalink }} ``` This will print out a list of all the variables scoped to the current context (`.`, aka ["the dot"][tempintro]). ``` {{ printf "%#v" . }} ``` When developing a [homepage][], what does one of the pages you're looping through look like? ``` {{ range .Pages }} {{/* The context, ".", is now each one of the pages as it goes through the loop */}} {{ printf "%#v" . }} {{ end }} ``` ## Why Am I Showing No Defined Variables? Check that you are passing variables in the `partial` function: ``` {{ partial "header" }} ``` This example will render the header partial, but the header partial will not have access to any contextual variables. You need to pass variables explicitly. For example, note the addition of ["the dot"][tempintro]. ``` {{ partial "header" . }} ``` The dot (`.`) is considered fundamental to understanding Hugo templating. For more information, see [Introduction to Hugo Templating][tempintro]. [homepage]: /templates/homepage/ [tempintro]: /templates/introduction/ hugo-0.68.3/docs/content/en/templates/views.md000066400000000000000000000105341363637351300212500ustar00rootroot00000000000000--- title: Content View Templates # linktitle: Content Views description: Hugo can render alternative views of your content, which is especially useful in list and summary views. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [templates] keywords: [views] menu: docs: parent: "templates" weight: 70 weight: 70 sections_weight: 70 draft: false aliases: [] toc: true --- These alternative **content views** are especially useful in [list templates][lists]. The following are common use cases for content views: * You want content of every type to be shown on the homepage but only with limited [summary views][summaries]. * You only want a bulleted list of your content on a [taxonomy list page][taxonomylists]. Views make this very straightforward by delegating the rendering of each different type of content to the content itself. ## Create a Content View To create a new view, create a template in each of your different content type directories with the view name. The following example contains an "li" view and a "summary" view for the `posts` and `project` content types. As you can see, these sit next to the [single content view][single] template, `single.html`. You can even provide a specific view for a given type and continue to use the `_default/single.html` for the primary view. ``` ▾ layouts/ ▾ posts/ li.html single.html summary.html ▾ project/ li.html single.html summary.html ``` Hugo also has support for a default content template to be used in the event that a specific content view template has not been provided for that type. Content views can also be defined in the `_default` directory and will work the same as list and single templates who eventually trickle down to the `_default` directory as a matter of the lookup order. ``` ▾ layouts/ ▾ _default/ li.html single.html summary.html ``` ## Which Template Will be Rendered? The following is the [lookup order][lookup] for content views: 1. `/layouts//.html` 2. `/layouts/_default/.html` 3. `/themes//layouts//.html` 4. `/themes//layouts/_default/.html` ## Example: Content View Inside a List The following example demonstrates how to use content views inside of your [list templates][lists]. ### `list.html` In this example, `.Render` is passed into the template to call the [render function][render]. `.Render` is a special function that instructs content to render itself with the view template provided as the first argument. In this case, the template is going to render the `summary.html` view that follows: {{< code file="layouts/_default/list.html" download="list.html" >}}

{{ .Title }}

{{ range .Pages }} {{ .Render "summary"}} {{ end }}
{{< /code >}} ### `summary.html` Hugo will pass the entire page object to the following `summary.html` view template. (See [Page Variables][pagevars] for a complete list.) {{< code file="layouts/_default/summary.html" download="summary.html" >}} {{< /code >}} ### `li.html` Continuing on the previous example, we can change our render function to use a smaller `li.html` view by changing the argument in the call to the `.Render` function (i.e., `{{ .Render "li" }}`). {{< code file="layouts/_default/li.html" download="li.html" >}}
  • {{ .Title }}
    {{ .Date.Format "Mon, Jan 2, 2006" }}
  • {{< /code >}} [lists]: /templates/lists/ [lookup]: /templates/lookup-order/ [pagevars]: /variables/page/ [render]: /functions/render/ [single]: /templates/single-page-templates/ [spf]: https://spf13.com [spfsourceli]: https://github.com/spf13/spf13.com/blob/master/layouts/_default/li.html [spfsourcesection]: https://github.com/spf13/spf13.com/blob/master/layouts/_default/section.html [spfsourcesummary]: https://github.com/spf13/spf13.com/blob/master/layouts/_default/summary.html [summaries]: /content-management/summaries/ [taxonomylists]: /templates/taxonomy-templates/ hugo-0.68.3/docs/content/en/tools/000077500000000000000000000000001363637351300167305ustar00rootroot00000000000000hugo-0.68.3/docs/content/en/tools/_index.md000066400000000000000000000016371363637351300205270ustar00rootroot00000000000000--- title: Developer Tools linktitle: Developer Tools Overview description: In addition to Hugo's powerful CLI, there is a large number of community-developed tool chains for Hugo developers. date: 2016-12-05 publishdate: 2016-12-05 lastmod: 2017-02-26 categories: [developer tools] keywords: [] menu: docs: parent: "tools" weight: 01 weight: 01 sections_weight: 01 draft: false --- One of Hugo's greatest strengths is its passionate---and always evolving---developer community. With the exception of the `highlight` shortcode mentioned in [Syntax Highlighting][syntax], the tools and other projects featured in this section are offerings from both commercial services and open-source projects, many of which are developed by Hugo developers just like you. [See the popularity of Hugo compared with other static site generators.][staticgen] [staticgen]: https://staticgen.com [syntax]: /tools/syntax-highlighting/ hugo-0.68.3/docs/content/en/tools/editors.md000066400000000000000000000051471363637351300207320ustar00rootroot00000000000000--- title: Editor Plug-ins for Hugo linktitle: Editor Plug-ins description: The Hugo community uses a wide range of preferred tools and has developed plug-ins for some of the most popular text editors to help automate parts of your workflow. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [developer tools] keywords: [editor, plug-ins] menu: docs: parent: "tools" weight: 50 weight: 50 sections_weight: 50 draft: false aliases: [] toc: false --- The Hugo community uses a wide range of preferred tools and has developed plug-ins for some of the most popular text editors to help automate parts of your workflow. ## Sublime Text * [Hugofy](https://github.com/akmittal/Hugofy). Hugofy is a plugin for Sublime Text 3 to make life easier to use Hugo static site generator. ## Visual Studio Code * [Hugofy](https://marketplace.visualstudio.com/items?itemName=akmittal.hugofy). Hugofy is a plugin for Visual Studio Code to "make life easier" when developing with Hugo. The source code can be found [here](https://github.com/akmittal/hugofy-vscode). * [Hugo Helper](https://marketplace.visualstudio.com/items?itemName=rusnasonov.vscode-hugo). Hugo Helper is a plugin for Visual Studio Code that has some useful commands for Hugo. The source code can be found [here](https://github.com/rusnasonov/vscode-hugo). * [Hugo Language and Syntax Support](https://marketplace.visualstudio.com/items?itemName=budparr.language-hugo-vscode). Hugo Language and Syntax Support is a Visual Studio Code plugin for Hugo syntax highlighting and snippets. The source code can be found [here](https://github.com/budparr/language-hugo-vscode). ## Emacs * [emacs-easy-hugo](https://github.com/masasam/emacs-easy-hugo). Emacs major mode for managing hugo blogs. Note that Hugo also supports [Org-mode][formats]. * [ox-hugo.el](https://ox-hugo.scripter.co). Native Org-mode exporter that exports to Blackfriday Markdown with Hugo front-matter. `ox-hugo` supports two common Org blogging flows --- exporting multiple Org sub-trees in a single file to multiple Hugo posts, and exporting a single Org file to a single Hugo post. It also leverages the Org tag and property inheritance features. See [*Why ox-hugo?*](https://ox-hugo.scripter.co/doc/why-ox-hugo/) for more. ## Vim * [Vim Hugo Helper](https://github.com/robertbasic/vim-hugo-helper). A small Vim plugin to help me with writing posts with Hugo. ## Atom * [Hugofy](https://atom.io/packages/hugofy). A Hugo Static Website Generator package for Atom. * [language-hugo](https://atom.io/packages/language-hugo). Adds syntax highlighting to Hugo files. [formats]: /content-management/formats/ hugo-0.68.3/docs/content/en/tools/frontends.md000066400000000000000000000062111363637351300212540ustar00rootroot00000000000000--- title: Frontend Interfaces with Hugo linktitle: Frontends description: Do you prefer a graphical user interface over a text editor? Give these frontends a try. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [developer tools] keywords: [frontend,gui] menu: docs: parent: "tools" weight: 40 weight: 40 sections_weight: 40 draft: false aliases: [] toc: false --- * [enwrite](https://github.com/zzamboni/enwrite). Enwrite enables evernote-powered, statically generated blogs and websites. Now posting to your blog or updating your website is as easy as writing a new note in Evernote! * [Lipi](https://github.com/SohanChy/Lipi). Lipi is a native GUI frontend written in Java to manage your Hugo websites. * [Netlify CMS](https://netlifycms.org). Netlify CMS is an open source, serverless solution for managing Git based content in static sites, and it works on any platform that can host static sites. A [Hugo/Netlify CMS starter](https://github.com/netlify-templates/one-click-hugo-cms) is available to get new projects running quickly. * [Hokus CMS](https://github.com/julianoappelklein/hokus). Hokus CMS is an open source, multiplatform, easy to use, desktop application for Hugo. Build from simple to complex user interfaces for Hugo websites by choosing from a dozen ready-to-use components — all for free, with no vendor lock-in. ## Commercial Services * [Appernetic.io](https://appernetic.io) is a Hugo Static Site Generator as a Service that is easy to use for non-technical users. * **Features:** inline PageDown editor, visual tree view, image upload and digital asset management with Cloudinary, site preview, continuous integration with GitHub, atomic deploy and hosting, Git and Hugo integration, autosave, custom domain, project syncing, theme cloning and management. Developers have complete control over the source code and can manage it with GitHub’s deceptively simple workflow. * [DATOCMS](https://www.datocms.com) DatoCMS is a fully customizable administrative area for your static websites. Use your favorite website generator, let your clients publish new content independently, and the host the site anywhere you like. * [Forestry.io](https://forestry.io/). Forestry is a git-backed CMS for Hugo, Gatsby, Jekyll and VuePress websites with support for GitHub, GitLab, Bitbucket and Azure Devops. Forestry provides a nice user interface to edit and model content for non technical editors. It supports S3, Cloudinary and Netlify Large Media integrations for storing media. Every time an update is made via the CMS, Forestry will commit changes back to your repo and vice-versa. * [Netlify.com](https://www.netlify.com). Netlify builds, deploys, and hosts your static website or app (Hugo, Jekyll, etc). Netlify offers a drag-and-drop interface and automatic deployments from GitHub or Bitbucket. * **Features:** global CDN, atomic deploys, ultra-fast DNS, instant cache invalidation, high availability, automated hosting, Git integration, form submission hooks, authentication providers, and custom domains. Developers have complete control over the source code and can manage it with GitHub or Bitbucket's deceptively simple workflow. hugo-0.68.3/docs/content/en/tools/migrations.md000066400000000000000000000135241363637351300214330ustar00rootroot00000000000000--- title: Migrate to Hugo linktitle: Migrations description: A list of community-developed tools for migrating from your existing static site generator or content management system to Hugo. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 keywords: [migrations,jekyll,wordpress,drupal,ghost,contentful] menu: docs: parent: "tools" weight: 10 weight: 10 sections_weight: 10 draft: false aliases: [/developer-tools/migrations/,/developer-tools/migrated/] toc: true --- This section highlights some projects around Hugo that are independently developed. These tools try to extend the functionality of our static site generator or help you to get started. {{% note %}} Do you know or maintain a similar project around Hugo? Feel free to open a [pull request](https://github.com/gohugoio/hugo/pulls) on GitHub if you think it should be added. {{% /note %}} Take a look at this list of migration tools if you currently use other blogging tools like Jekyll or WordPress but intend to switch to Hugo instead. They'll take care to export your content into Hugo-friendly formats. ## Jekyll Alternatively, you can use the new [Jekyll import command](/commands/hugo_import_jekyll/). - [JekyllToHugo](https://github.com/SenjinDarashiva/JekyllToHugo) - A Small script for converting Jekyll blog posts to a Hugo site. - [ConvertToHugo](https://github.com/coderzh/ConvertToHugo) - Convert your blog from Jekyll to Hugo. ## Ghost - [ghostToHugo](https://github.com/jbarone/ghostToHugo) - Convert Ghost blog posts and export them to Hugo. ## Octopress - [octohug](https://github.com/codebrane/octohug) - Octopress to Hugo migrator. ## DokuWiki - [dokuwiki-to-hugo](https://github.com/wgroeneveld/dokuwiki-to-hugo) - Migrates your dokuwiki source pages from [DokuWiki syntax](https://www.dokuwiki.org/wiki:syntax) to Hugo Markdown syntax. Includes extra's like the TODO plugin. Written with extensibility in mind using python 3. Also generates a TOML header for each page. Designed to copypaste the wiki directory into your /content directory. ## WordPress - [wordpress-to-hugo-exporter](https://github.com/SchumacherFM/wordpress-to-hugo-exporter) - A one-click WordPress plugin that converts all posts, pages, taxonomies, metadata, and settings to Markdown and YAML which can be dropped into Hugo. (Note: If you have trouble using this plugin, you can [export your site for Jekyll](https://wordpress.org/plugins/jekyll-exporter/) and use Hugo's built in Jekyll converter listed above.) - [exitwp-for-hugo](https://github.com/wooni005/exitwp-for-hugo) - A python script which works with the xml export from Wordpress and converts Wordpress pages and posts to Markdown and YAML for hugo. - [blog2md](https://github.com/palaniraja/blog2md) - Works with [exported xml](https://en.support.wordpress.com/export/) file of your free YOUR-TLD.wordpress.com website. It also saves approved comments to `YOUR-POST-NAME-comments.md` file along with posts. - [wordhugopress](https://github.com/nantipov/wordhugopress) - A small utility written in Java, exports the entire WordPress site from the database and resource (e.g. images) files stored locally or remotelly. Therefore, migration from the backup files is possible. Supports merging of the multiple WordPress sites into a single Hugo one. ## Medium - [medium2md](https://github.com/gautamdhameja/medium-2-md) - A simple Medium to Hugo exporter able to import stories in one command, including Front Matter. - [medium-to-hugo](https://github.com/bgadrian/medium-to-hugo) - CLI tool written in Go to export medium posts into a Hugo compatible Markdown format. Tags and images are included. All images will be downloaded locally and linked appropriately. ## Tumblr - [tumblr-importr](https://github.com/carlmjohnson/tumblr-importr) - An importer that uses the Tumblr API to create a Hugo static site. - [tumblr2hugomarkdown](https://github.com/Wysie/tumblr2hugomarkdown) - Export all your Tumblr content to Hugo Markdown files with preserved original formatting. - [Tumblr to Hugo](https://github.com/jipiboily/tumblr-to-hugo) - A migration tool that converts each of your Tumblr posts to a content file with a proper title and path. Furthermore, "Tumblr to Hugo" creates a CSV file with the original URL and the new path on Hugo, to help you setup the redirections. ## Drupal - [drupal2hugo](https://github.com/danapsimer/drupal2hugo) - Convert a Drupal site to Hugo. ## Joomla - [hugojoomla](https://github.com/davetcc/hugojoomla) - This utility written in Java takes a Joomla database and converts all the content into Markdown files. It changes any URLs that are in Joomla's internal format and converts them to a suitable form. ## Blogger - [blogimport](https://github.com/natefinch/blogimport) - A tool to import from Blogger posts to Hugo. - [blogger-to-hugo](https://bitbucket.org/petraszd/blogger-to-hugo) - Another tool to import Blogger posts to Hugo. It also downloads embedded images so they will be stored locally. - [blog2md](https://github.com/palaniraja/blog2md) - Works with [exported xml](https://support.google.com/blogger/answer/41387?hl=en) file of your YOUR-TLD.blogspot.com website. It also saves comments to `YOUR-POST-NAME-comments.md` file along with posts. - [BloggerToHugo](https://github.com/huanlin/blogger-to-hugo) - Yet another tool to import Blogger posts to Hugo. For Windows platform only, and .NET Framework 4.5 is required. See README.md before using this tool. ## Contentful - [contentful2hugo](https://github.com/ArnoNuyts/contentful2hugo) - A tool to create content-files for Hugo from content on [Contentful](https://www.contentful.com/). ## BlogML - [BlogML2Hugo](https://github.com/jijiechen/BlogML2Hugo) - A tool that helps you convert BlogML xml file to Hugo markdown files. Users need to take care of links to attachments and images by themselves. This helps the blogs that export BlogML files (e.g. BlogEngine.NET) tramsform to hugo sites easily. hugo-0.68.3/docs/content/en/tools/other.md000066400000000000000000000031251363637351300203740ustar00rootroot00000000000000--- title: Other Hugo Community Projects linktitle: Other Projects description: Some interesting projects developed by the Hugo community that don't quite fit into our other developer tool categories. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [developer tools] keywords: [frontend,gui] menu: docs: parent: "tools" weight: 70 weight: 70 sections_weight: 70 draft: false aliases: [] toc: false --- And for all the other small things around Hugo: * [hugo-gallery](https://github.com/icecreammatt/hugo-gallery) lets you create an image gallery for Hugo sites. * [flickr-hugo-embed](https://github.com/nikhilm/flickr-hugo-embed) prints shortcodes to embed a set of images from an album on Flickr into Hugo. * [hugo-openapispec-shortcode](https://github.com/tenfourty/hugo-openapispec-shortcode) A shortcode that allows you to include [Open API Spec](https://openapis.org) (formerly known as Swagger Spec) in a page. * [HugoPhotoSwipe](https://github.com/GjjvdBurg/HugoPhotoSwipe) makes it easy to create image galleries using PhotoSwipe. * [Hugo SFTP Upload](https://github.com/thomasmey/HugoSftpUpload) Syncs the local build of your Hugo website with your remote webserver via SFTP. * [Emacs Easy Hugo](https://github.com/masasam/emacs-easy-hugo) Emacs package for writing blog posts in markdown or org-mode and building your site with Hugo. * [JAMStack Themes](https://jamstackthemes.dev/ssg/hugo/). JAMStack themes is a collection of site themes filterable by static site generator and supported CMS to help build CMS-connected sites using Hugo (linking to Hugo-specific themes). hugo-0.68.3/docs/content/en/tools/search.md000066400000000000000000000062721363637351300205260ustar00rootroot00000000000000--- title: Search for your Hugo Website linktitle: Search description: See some of the open-source and commercial search options for your newly created Hugo website. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-26 categories: [developer tools] keywords: [search,tools] menu: docs: parent: "tools" weight: 60 weight: 60 sections_weight: 60 draft: false aliases: [] toc: true --- A static website with a dynamic search function? Yes, Hugo provides an alternative to embeddable scripts from Google or other search engines for static websites. Hugo allows you to provide your visitors with a custom search function by indexing your content files directly. * [GitHub Gist for Hugo Workflow](https://gist.github.com/sebz/efddfc8fdcb6b480f567). This gist contains a simple workflow to create a search index for your static website. It uses a simple Grunt script to index all your content files and [lunr.js](https://lunrjs.com/) to serve the search results. * [hugo-elasticsearch](https://www.npmjs.com/package/hugo-elasticsearch). Generate [Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html) indexes for Hugo static sites by parsing front matter. Hugo-Elasticsearch will generate a newline delimited JSON (NDJSON) file that can be bulk uploaded into Elasticsearch using any one of the available [clients](https://www.elastic.co/guide/en/elasticsearch/client/index.html). * [hugo-lunr](https://www.npmjs.com/package/hugo-lunr). A simple way to add site search to your static Hugo site using [lunr.js](https://lunrjs.com/). Hugo-lunr will create an index file of any html and markdown documents in your Hugo project. * [hugo-lunr-zh](https://www.npmjs.com/package/hugo-lunr-zh). A bit like Hugo-lunr, but Hugo-lunr-zh can help you separate the Chinese keywords. * [Github Gist for Fuse.js integration](https://gist.github.com/eddiewebb/735feb48f50f0ddd65ae5606a1cb41ae). This gist demonstrates how to leverage Hugo's existing build time processing to generate a searchable JSON index used by [Fuse.js](https://fusejs.io/) on the client side. Although this gist uses Fuse.js for fuzzy matching, any client side search tool capable of reading JSON indexes will work. Does not require npm, grunt or other build-time tools except Hugo! * [hugo-search-index](https://www.npmjs.com/package/hugo-search-index). A library containing Gulp tasks and a prebuilt browser script that implements search. Gulp generates a search index from project markdown files. ## Commercial Search Services * [Algolia](https://www.algolia.com/)'s Search API makes it easy to deliver a great search experience in your apps and websites. Algolia Search provides hosted full-text, numerical, faceted, and geolocalized search. * [Bonsai](https://www.bonsai.io) is a fully-managed hosted Elasticsearch service that is fast, reliable, and simple to set up. Easily ingest your docs from Hugo into Elasticsearch following [this guide from the docs](https://docs.bonsai.io/docs/hugo). * [ExpertRec](https://www.expertrec.com/) is a hosted search-as-a-service solution that is fast and scalable. Set-up and integration is extremely easy and takes only a few minutes. The search settings can be modified without coding using a dashboard. hugo-0.68.3/docs/content/en/tools/starter-kits.md000066400000000000000000000052371363637351300217150ustar00rootroot00000000000000--- title: Starter Kits linktitle: Starter Kits description: A list of community-developed projects designed to help you get up and running with Hugo. date: 2017-02-22 publishdate: 2017-02-01 lastmod: 2018-08-11 keywords: [starters,assets,pipeline] menu: docs: parent: "tools" weight: 30 weight: 30 sections_weight: 30 draft: false aliases: [/developer-tools/migrations/,/developer-tools/migrated/] toc: false --- Know of a Hugo-related starter kit that isn't mentioned here? [Please add it to the list.][addkit] {{% note "Starter Kits are Not Maintained by the Hugo Team"%}} The following starter kits are developed by active members of the Hugo community. If you find yourself having issues with any of the projects, it's best to file an issue directly with the project's maintainer(s). {{% /note %}} * [Hugo Wrapper][hugow]. Hugo Wrapper is a POSIX-style shell script which acts as a wrapper to download and run Hugo binary for your platform. It can be executed in variety of [Operating Systems][hugow-test] and [Command Shells][hugow-test]. * [Victor Hugo][]. Victor Hugo is a Hugo boilerplate for creating truly epic websites using Webpack as an asset pipeline. Victor Hugo uses post-css and Babel for CSS and JavaScript, respectively, and is actively maintained. * [GOHUGO AMP][]. GoHugo AMP is a starter theme that aims to make it easy to adopt [Google's AMP Project][amp]. The starter kit comes with 40+ shortcodes and partials plus automatic structured data. The project also includes a [separate site with extensive documentation][gohugodocs]. * [Blaupause][]. Blaupause is a developer-friendly Hugo starter kit based on Gulp tasks. It comes ES6-ready with several helpers for SVG and fonts and basic structure for HTML, SCSS, and JavaScript. * [hugulp][]. hugulp is a tool to optimize the assets of a Hugo website. The main idea is to recreate the famous Ruby on Rails Asset Pipeline, which minifies, concatenates and fingerprints the assets used in your website. * [Atlas][]. Atlas is a Hugo boilerplate designed to speed up development with support for Netlify, Hugo Pipes, SCSS & more. It's actively maintained and contributions are always welcome. [addkit]: https://github.com/gohugoio/hugo/edit/master/docs/content/en/tools/starter-kits.md [amp]: https://www.ampproject.org/ [Blaupause]: https://github.com/fspoettel/blaupause [GOHUGO AMP]: https://github.com/wildhaber/gohugo-amp [gohugodocs]: https://gohugo-amp.gohugohq.com/ [hugow]: https://github.com/khos2ow/hugo-wrapper [hugow-test]: https://github.com/khos2ow/hugo-wrapper#tested-on [hugulp]: https://github.com/jbrodriguez/hugulp [Victor Hugo]: https://github.com/netlify/victor-hugo [Atlas]: https://github.com/indigotree/atlas hugo-0.68.3/docs/content/en/troubleshooting/000077500000000000000000000000001363637351300210175ustar00rootroot00000000000000hugo-0.68.3/docs/content/en/troubleshooting/_index.md000066400000000000000000000010611363637351300226050ustar00rootroot00000000000000--- title: Troubleshoot linktitle: Troubleshoot description: Frequently asked questions and known issues pulled from the Hugo Discuss forum. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 menu: docs: parent: "troubleshooting" weight: 1 weight: 1 draft: false hidesectioncontents: false slug: aliases: [/troubleshooting/faqs/,/faqs/] toc: false notesforauthors: --- The Troubleshooting section includes known issues, recent workarounds, and FAQs pulled from the [Hugo Discussion Forum][forum]. [forum]: https://discourse.gohugo.io hugo-0.68.3/docs/content/en/troubleshooting/build-performance.md000066400000000000000000000074041363637351300247440ustar00rootroot00000000000000--- title: Build Performance linktitle: Build Performance description: An overview of features used for diagnosing and improving performance issues in site builds. date: 2017-03-12 publishdate: 2017-03-12 lastmod: 2017-03-12 keywords: [performance, build] categories: [troubleshooting] menu: docs: parent: "troubleshooting" weight: 3 slug: aliases: [] toc: true --- {{% note %}} The example site used below is from https://github.com/gohugoio/hugo/tree/master/examples/blog {{% /note %}} ## Template Metrics Hugo is a very fast static site generator, but it is possible to write inefficient templates. Hugo's *template metrics* feature is extremely helpful in pinpointing which templates are executed most often and how long those executions take **in terms of CPU time**. | Metric Name | Description | |---------------------|-------------| | cumulative duration | The cumulative time spent executing a given template. | | average duration | The average time spent executing a given template. | | maximum duration | The maximum time a single execution took for a given template. | | count | The number of times a template was executed. | | template | The template name. | ``` ▶ hugo --templateMetrics Started building sites ... Built site for language en: 0 draft content 0 future content 0 expired content 2 regular pages created 22 other pages created 0 non-page files copied 0 paginator pages created 4 tags created 3 categories created total in 18 ms Template Metrics: cumulative average maximum duration duration duration count template ---------- -------- -------- ----- -------- 6.419663ms 583.605µs 994.374µs 11 _internal/_default/rss.xml 4.718511ms 1.572837ms 3.880742ms 3 indexes/category.html 4.642666ms 2.321333ms 3.282842ms 2 posts/single.html 4.364445ms 396.767µs 2.451372ms 11 partials/header.html 2.346069ms 586.517µs 903.343µs 4 indexes/tag.html 2.330919ms 211.901µs 2.281342ms 11 partials/header.includes.html 1.238976ms 103.248µs 446.084µs 12 posts/li.html 972.16µs 972.16µs 972.16µs 1 _internal/_default/sitemap.xml 953.597µs 953.597µs 953.597µs 1 index.html 822.263µs 822.263µs 822.263µs 1 indexes/post.html 567.498µs 51.59µs 112.205µs 11 partials/navbar.html 348.22µs 31.656µs 88.249µs 11 partials/meta.html 346.782µs 173.391µs 276.176µs 2 posts/summary.html 235.184µs 21.38µs 124.383µs 11 partials/footer.copyright.html 132.003µs 12µs 117.999µs 11 partials/menu.html 72.547µs 6.595µs 63.764µs 11 partials/footer.html ``` {{% note %}} **A Note About Parallelism** Hugo builds pages in parallel where multiple pages are generated simultaneously. Because of this parallelism, the sum of "cumulative duration" values is usually greater than the actual time it takes to build a site. {{% /note %}} ## Cached Partials Some `partial` templates such as sidebars or menus are executed many times during a site build. Depending on the content within the `partial` template and the desired output, the template may benefit from caching to reduce the number of executions. The [`partialCached`][partialCached] template function provides caching capabilities for `partial` templates. {{% tip %}} Note that you can create cached variants of each `partial` by passing additional parameters to `partialCached` beyond the initial context. See the `partialCached` documentation for more details. {{% /tip %}} [partialCached]:{{< ref "/functions/partialCached.md" >}} hugo-0.68.3/docs/content/en/troubleshooting/faq.md000066400000000000000000000047561363637351300221240ustar00rootroot00000000000000--- title: Frequently Asked Questions linktitle: FAQ description: Solutions to some common Hugo problems. date: 2018-02-10 categories: [troubleshooting] menu: docs: parent: "troubleshooting" keywords: [faqs] weight: 2 toc: true aliases: [/faq/] --- {{% note %}} **Note:** The answers/solutions presented below are short, and may not be enough to solve your problem. Visit [Hugo Discourse](https://discourse.gohugo.io/) and use the search. It that does not help, start a new topic and ask your questions. {{% /note %}} ## I can't see my content! Is your markdown file [in draft mode](https://gohugo.io/content-management/front-matter/#front-matter-variables)? When testing, run `hugo server` with the `-D` or `--buildDrafts` [switch](https://gohugo.io/getting-started/usage/#draft-future-and-expired-content). ## Can I set configuration variables via OS environment? Yes you can! See [Configure with Environment Variables](/getting-started/configuration/#configure-with-environment-variables). ## How do I schedule posts? 1. Set `publishDate` in the page [Front Matter](/content-management/front-matter/) to a date in the future. 2. Build and publish at intervals. How to automate the "publish at intervals" part depends on your situation: * If you deploy from your own PC/server, you can automate with [Cron](https://en.wikipedia.org/wiki/Cron) or similar. * If your site is hosted on a service similar to [Netlify](https://www.netlify.com/) you can use a service such as [ifttt](https://ifttt.com/date_and_time) to schedule the updates. Also see this Twitter thread: {{< tweet 962380712027590657 >}} ## Can I use the latest Hugo version on Netlify? Yes you can! Read [this](/hosting-and-deployment/hosting-on-netlify/#configure-hugo-version-in-netlify). ## I get "TOCSS ... this feature is not available in your current Hugo version" If you process `SCSS` or `SASS` to `CSS` in your Hugo project, you need the Hugo `extended` version, or else you may see this error message: ```bash error: failed to transform resource: TOCSS: failed to transform "scss/main.scss" (text/x-scss): this feature is not available in your current Hugo version ``` We release two set of binaries for technical reasons. The extended version is not what you get by default for some installation methods. On the [release page](https://github.com/gohugoio/hugo/releases), look for archives with `extended` in the name. To build `hugo-extended`, use `go install --tags extended` To confirm, run `hugo version` and look for the word `extended`. hugo-0.68.3/docs/content/en/variables/000077500000000000000000000000001363637351300175405ustar00rootroot00000000000000hugo-0.68.3/docs/content/en/variables/_index.md000066400000000000000000000013231363637351300213270ustar00rootroot00000000000000--- title: Variables and Params linktitle: Variables Overview description: Page-, file-, taxonomy-, and site-level variables and parameters available in templates. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [variables and params] keywords: [variables,params,values,globals] draft: false menu: docs: parent: "variables" weight: 1 weight: 01 #rem sections_weight: 01 aliases: [/templates/variables/] toc: false --- Hugo's templates are context aware and make a large number of values available to you as you're creating views for your website. [Go templates]: /templates/introduction/ "Understand context in Go templates by learning the language's fundamental templating functions." hugo-0.68.3/docs/content/en/variables/files.md000066400000000000000000000033041363637351300211640ustar00rootroot00000000000000--- title: File Variables linktitle: description: "You can access filesystem-related data for a content file in the `.File` variable." date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [variables and params] keywords: [files] draft: false menu: docs: parent: "variables" weight: 40 weight: 40 sections_weight: 40 aliases: [/variables/file-variables/] toc: false --- {{% note "Rendering Local Files" %}} For information on creating shortcodes and templates that tap into Hugo's file-related feature set, see [Local File Templates](/templates/files/). {{% /note %}} The `.File` object contains the following fields: .File.Path : the original relative path of the page, relative to the content dir (e.g., `posts/foo.en.md`) .File.LogicalName : the name of the content file that represents a page (e.g., `foo.en.md`) .File.TranslationBaseName : the filename without extension or optional language identifier (e.g., `foo`) .File.ContentBaseName : is a either TranslationBaseName or name of containing folder if file is a leaf bundle. .File.BaseFileName : the filename without extension (e.g., `foo.en`) .File.Ext : the file extension of the content file (e.g., `md`); this can also be called using `.File.Extension` as well. Note that it is *only* the extension without `.`. .File.Lang : the language associated with the given file if Hugo's [Multilingual features][multilingual] are enabled (e.g., `en`) .File.Dir : given the path `content/posts/dir1/dir2/`, the relative directory path of the content file will be returned (e.g., `posts/dir1/dir2/`). Note that the path separator (`\` or `/`) could be dependent on the operating system. [Multilingual]: /content-management/multilingual/ hugo-0.68.3/docs/content/en/variables/git.md000066400000000000000000000033011363637351300206420ustar00rootroot00000000000000--- title: Git Info Variables linktitle: Git Variables description: Get the last Git revision information for every content file. date: 2017-03-12 publishdate: 2017-03-12 lastmod: 2017-03-12 categories: [variables and params] keywords: [git] draft: false menu: docs: parent: "variables" weight: 70 weight: 70 sections_weight: 70 aliases: [/extras/gitinfo/] toc: false wip: false --- {{% note "`.GitInfo` Performance Considerations" %}} Hugo's Git integrations should be fairly performant but *can* increase your build time. This will depend on the size of your Git history. {{% /note %}} ## `.GitInfo` Prerequisites 1. The Hugo site must be in a Git-enabled directory. 2. The Git executable must be installed and in your system `PATH`. 3. The `.GitInfo` feature must be enabled in your Hugo project by passing `--enableGitInfo` flag on the command line or by setting `enableGitInfo` to `true` in your [site's configuration file][configuration]. ## The `.GitInfo` Object The `GitInfo` object contains the following fields: .AbbreviatedHash : the abbreviated commit hash (e.g., `866cbcc`) .AuthorName : the author's name, respecting `.mailmap` .AuthorEmail : the author's email address, respecting `.mailmap` .AuthorDate : the author date .Hash : the commit hash (e.g., `866cbccdab588b9908887ffd3b4f2667e94090c3`) .Subject : commit message subject (e.g., `tpl: Add custom index function`) ## `.Lastmod` If the `.GitInfo` feature is enabled, `.Lastmod` (on `Page`) is fetched from Git i.e. `.GitInfo.AuthorDate`. This behaviour can be changed by adding your own [front matter configuration for dates](/getting-started/configuration/#configure-front-matter). [configuration]: /getting-started/configuration/ hugo-0.68.3/docs/content/en/variables/hugo.md000066400000000000000000000030171363637351300210250ustar00rootroot00000000000000--- title: Hugo-specific Variables linktitle: Hugo Variables description: The `.Hugo` variable provides easy access to Hugo-related data. date: 2017-03-12 publishdate: 2017-03-12 lastmod: 2017-03-12 categories: [variables and params] keywords: [hugo,generator] draft: false menu: docs: parent: "variables" weight: 60 weight: 60 sections_weight: 60 aliases: [] toc: false wip: false --- {{% warning "Deprecated" %}} Page's `.Hugo` is deprecated and will be removed in a future release. Use the global `hugo` function. For example: `hugo.Generator`. {{% /warning %}} It contains the following fields: .Hugo.Generator : `` tag for the version of Hugo that generated the site. `.Hugo.Generator` outputs a *complete* HTML tag; e.g. `` .Hugo.Version : the current version of the Hugo binary you are using e.g. `0.13-DEV`
    .Hugo.Environment : the current running environment as defined through the `--environment` cli tag. .Hugo.CommitHash : the git commit hash of the current Hugo binary e.g. `0e8bed9ccffba0df554728b46c5bbf6d78ae5247` .Hugo.BuildDate : the compile date of the current Hugo binary formatted with RFC 3339 e.g. `2002-10-02T10:00:00-05:00`
    {{% note "Use the Hugo Generator Tag" %}} We highly recommend using `.Hugo.Generator` in your website's ``. `.Hugo.Generator` is included by default in all themes hosted on [themes.gohugo.io](https://themes.gohugo.io). The generator tag allows the Hugo team to track the usage and popularity of Hugo. {{% /note %}} hugo-0.68.3/docs/content/en/variables/menus.md000066400000000000000000000072201363637351300212120ustar00rootroot00000000000000--- title: Menu Entry Properties linktitle: Menu Entry Properties description: A menu entry in a menu-template has specific variables and functions to make menu management easier. date: 2017-03-12 publishdate: 2017-03-12 lastmod: 2017-03-12 categories: [variables and params] keywords: [menus] draft: false menu: docs: title: "variables defined by a menu entry" parent: "variables" weight: 50 weight: 50 sections_weight: 50 aliases: [/variables/menu/] toc: false --- A **menu entry** has the following properties available that can be used in a [menu template][menu-template]. ## Menu Entry Variables .Menu : _string_
    Name of the **menu** that contains this **menu entry**. .URL : _string_
    URL that the menu entry points to. The `url` key, if set for the menu entry, sets this value. If that key is not set, and if the menu entry is set in a page front-matter, this value defaults to the page's `.RelPermalink`. .Page : _\*Page_
    Reference to the [page object][page-object] associated with the menu entry. This will be non-nil if the menu entry is set via a page's front-matter and not via the site config. .Name : _string_
    Name of the menu entry. The `name` key, if set for the menu entry, sets this value. If that key is not set, and if the menu entry is set in a page front-matter, this value defaults to the page's `.LinkTitle`. .Identifier : _string_
    Value of the `identifier` key if set for the menu entry. This value must be unique for each menu entry. **It is necessary to set a unique identifier manually if two or more menu entries have the same `.Name`.** .Pre : _template.HTML_
    Value of the `pre` key if set for the menu entry. This value typically contains a string representing HTML. .Post : _template.HTML_
    Value of the `post` key if set for the menu entry. This value typically contains a string representing HTML. .Weight : _int_
    Value of the `weight` key if set for the menu entry. If that key is not set, and if the menu entry is set in a page front-matter, this value defaults to the page's `.Weight`. .Parent : _string_
    Name (or Identifier if present) of this menu entry's parent **menu entry**. The `parent` key, if set for the menu entry, sets this value. If this key is set, this menu entry nests under that parent entry, else it nests directly under the `.Menu`. .Children : _Menu_
    This value is auto-populated by Hugo. It is a collection of children menu entries, if any, under the current menu entry. ## Menu Entry Functions Menus also have the following functions available: .HasChildren : _boolean_
    Returns `true` if `.Children` is non-nil. .KeyName : _string_
    Returns the `.Identifier` if present, else returns the `.Name`. .IsEqual : _boolean_
    Returns `true` if the two compared menu entries represent the same menu entry. .IsSameResource : _boolean_
    Returns `true` if the two compared menu entries have the same `.URL`. .Title : _string_
    Link title, meant to be used in the `title` attribute of a menu entry's ``-tags. Returns the menu entry's `title` key if set. Else, if the menu entry was created through a page's front-matter, it returns the page's `.LinkTitle`. Else, it just returns an empty string. ## Other Menu-related Functions Additionally, here are some relevant methods available to menus on a page: .IsMenuCurrent : _(menu string, menuEntry *MenuEntry ) boolean_
    See [`.IsMenuCurrent` method](/functions/ismenucurrent/). .HasMenuCurrent : _(menu string, menuEntry *MenuEntry) boolean_
    See [`.HasMenuCurrent` method](/functions/hasmenucurrent/). [menu-template]: /templates/menu-templates/ [page-object]: /variables/page/ hugo-0.68.3/docs/content/en/variables/page.md000066400000000000000000000265071363637351300210100ustar00rootroot00000000000000--- title: Page Variables linktitle: description: Page-level variables are defined in a content file's front matter, derived from the content's file location, or extracted from the content body itself. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [variables and params] keywords: [pages] draft: false menu: docs: title: "variables defined by a page" parent: "variables" weight: 20 weight: 20 sections_weight: 20 aliases: [] toc: true --- The following is a list of page-level variables. Many of these will be defined in the front matter, derived from file location, or extracted from the content itself. {{% note "`.Scratch`" %}} See [`.Scratch`](/functions/scratch/) for page-scoped, writable variables. {{% /note %}} ## Page Variables .AlternativeOutputFormats : contains all alternative formats for a given page; this variable is especially useful `link rel` list in your site's ``. (See [Output Formats](/templates/output-formats/).) .Aliases : aliases of this page .Content : the content itself, defined below the front matter. .Data : the data specific to this type of page. .Date : the date associated with the page; `.Date` pulls from the `date` field in a content's front matter. See also `.ExpiryDate`, `.PublishDate`, and `.Lastmod`. .Description : the description for the page. .Dir : the path of the folder containing this content file. The path is relative to the `content` folder. .Draft : a boolean, `true` if the content is marked as a draft in the front matter. .ExpiryDate : the date on which the content is scheduled to expire; `.ExpiryDate` pulls from the `expirydate` field in a content's front matter. See also `.PublishDate`, `.Date`, and `.Lastmod`. .File : filesystem-related data for this content file. See also [File Variables][]. .FuzzyWordCount : the approximate number of words in the content. .Hugo : see [Hugo Variables](/variables/hugo/). .IsHome : `true` in the context of the [homepage](/templates/homepage/). .IsNode : always `false` for regular content pages. .IsPage : always `true` for regular content pages. .IsTranslated : `true` if there are translations to display. .Keywords : the meta keywords for the content. .Kind : the page's *kind*. Possible return values are `page`, `home`, `section`, `taxonomy`, or `taxonomyTerm`. Note that there are also `RSS`, `sitemap`, `robotsTXT`, and `404` kinds, but these are only available during the rendering of each of these respective page's kind and therefore *not* available in any of the `Pages` collections. .Language : a language object that points to the language's definition in the site `config`. `.Language.Lang` gives you the language code. .Lastmod : the date the content was last modified. `.Lastmod` pulls from the `lastmod` field in a content's front matter. - If `lastmod` is not set, and `.GitInfo` feature is disabled, the front matter `date` field will be used. - If `lastmod` is not set, and `.GitInfo` feature is enabled, `.GitInfo.AuthorDate` will be used instead. See also `.ExpiryDate`, `.Date`, `.PublishDate`, and [`.GitInfo`][gitinfo]. .LinkTitle : access when creating links to the content. If set, Hugo will use the `linktitle` from the front matter before `title`. .Next : Points up to the next [regular page](/variables/site/#site-pages) (sorted by Hugo's [default sort](/templates/lists#default-weight-date-linktitle-filepath)). Example: `{{with .Next}}{{.Permalink}}{{end}}`. Calling `.Next` from the first page returns `nil`. .NextInSection : Points up to the next [regular page](/variables/site/#site-pages) below the same top level section (e.g. in `/blog`)). Pages are sorted by Hugo's [default sort](/templates/lists#default-weight-date-linktitle-filepath). Example: `{{with .NextInSection}}{{.Permalink}}{{end}}`. Calling `.NextInSection` from the first page returns `nil`. .OutputFormats : contains all formats, including the current format, for a given page. Can be combined the with [`.Get` function](/functions/get/) to grab a specific format. (See [Output Formats](/templates/output-formats/).) .Pages : a collection of associated pages. This value will be `nil` within the context of regular content pages. See [`.Pages`](#pages). .Permalink : the Permanent link for this page; see [Permalinks](/content-management/urls/) .Plain : the Page content stripped of HTML tags and presented as a string. .PlainWords : the Page content stripped of HTML as a `[]string` using Go's [`strings.Fields`](https://golang.org/pkg/strings/#Fields) to split `.Plain` into a slice. .Prev : Points down to the previous [regular page](/variables/site/#site-pages) (sorted by Hugo's [default sort](/templates/lists#default-weight-date-linktitle-filepath)). Example: `{{if .PrevPage}}{{.PrevPage.Permalink}}{{end}}`. Calling `.Prev` from the last page returns `nil`. .PrevInSection : Points down to the previous [regular page](/variables/site/#site-pages) below the same top level section (e.g. `/blog`). Pages are sorted by Hugo's [default sort](/templates/lists#default-weight-date-linktitle-filepath). Example: `{{if .PrevInSection}}{{.PrevInSection.Permalink}}{{end}}`. Calling `.PrevInSection` from the last page returns `nil`. .PublishDate : the date on which the content was or will be published; `.Publishdate` pulls from the `publishdate` field in a content's front matter. See also `.ExpiryDate`, `.Date`, and `.Lastmod`. .RSSLink (deprecated) : link to the page's RSS feed. This is deprecated. You should instead do something like this: `{{ with .OutputFormats.Get "RSS" }}{{ .RelPermalink }}{{ end }}`. .RawContent : raw markdown content without the front matter. Useful with [remarkjs.com]( http://remarkjs.com) .ReadingTime : the estimated time, in minutes, it takes to read the content. .Resources : resources such as images and CSS that are associated with this page .Ref : returns the permalink for a given reference (e.g., `.Ref "sample.md"`). `.Ref` does *not* handle in-page fragments correctly. See [Cross References](/content-management/cross-references/). .RelPermalink : the relative permanent link for this page. .RelRef : returns the relative permalink for a given reference (e.g., `RelRef "sample.md"`). `.RelRef` does *not* handle in-page fragments correctly. See [Cross References](/content-management/cross-references/). .Site : see [Site Variables](/variables/site/). .Sites : returns all sites (languages). A typical use case would be to link back to the main language: `
    ...`. .Sites.First : returns the site for the first language. If this is not a multilingual setup, it will return itself. .Summary : a generated summary of the content for easily showing a snippet in a summary view. The breakpoint can be set manually by inserting <!--more--> at the appropriate place in the content page, or the summary can be written independent of the page text. See [Content Summaries](/content-management/summaries/) for more details. .TableOfContents : the rendered [table of contents](/content-management/toc/) for the page. .Title : the title for this page. .Translations : a list of translated versions of the current page. See [Multilingual Mode](/content-management/multilingual/) for more information. .TranslationKey : the key used to map language translations of the current page. See [Multilingual Mode](/content-management/multilingual/) for more information. .Truncated : a boolean, `true` if the `.Summary` is truncated. Useful for showing a "Read more..." link only when necessary. See [Summaries](/content-management/summaries/) for more information. .Type : the [content type](/content-management/types/) of the content (e.g., `posts`). .UniqueID : the MD5-checksum of the content file's path. .Weight : assigned weight (in the front matter) to this content, used in sorting. .WordCount : the number of words in the content. ## Section Variables and Methods Also see [Sections](/content-management/sections/). {{< readfile file="/content/en/readfiles/sectionvars.md" markdown="true" >}} ## The `.Pages` Variable {#pages} `.Pages` is an alias to `.Data.Pages`. It is conventional to use the aliased form `.Pages`. ### `.Pages` compared to `.Site.Pages` {{< readfile file="/content/en/readfiles/pages-vs-site-pages.md" markdown="true" >}} ## Page-level Params Any other value defined in the front matter in a content file, including taxonomies, will be made available as part of the `.Params` variable. ``` --- title: My First Post date: 2017-02-20T15:26:23-06:00 categories: [one] tags: [two,three,four] ``` With the above front matter, the `tags` and `categories` taxonomies are accessible via the following: * `.Params.tags` * `.Params.categories` {{% note "Casing of Params" %}} Page-level `.Params` are *only* accessible in lowercase. {{% /note %}} The `.Params` variable is particularly useful for the introduction of user-defined front matter fields in content files. For example, a Hugo website on book reviews could have the following front matter in `/content/review/book01.md`: ``` --- ... affiliatelink: "http://www.my-book-link.here" recommendedby: "My Mother" ... --- ``` These fields would then be accessible to the `/themes/yourtheme/layouts/review/single.html` template through `.Params.affiliatelink` and `.Params.recommendedby`, respectively. Two common situations where this type of front matter field could be introduced is as a value of a certain attribute like `href=""` or by itself to be displayed as text to the website's visitors. {{< code file="/themes/yourtheme/layouts/review/single.html" >}}

    Buy this book

    It was recommended by {{ .Params.recommendedby }}.

    {{< /code >}} This template would render as follows, assuming you've set [`uglyURLs`](/content-management/urls/) to `false` in your [site `config`](/getting-started/configuration/): {{< output file="yourbaseurl/review/book01/index.html" >}}

    Buy this book

    It was recommended by my Mother.

    {{< /output >}} {{% note %}} See [Archetypes](/content-management/archetypes/) for consistency of `Params` across pieces of content. {{% /note %}} ### The `.Param` Method In Hugo, you can declare params in individual pages and globally for your entire website. A common use case is to have a general value for the site param and a more specific value for some of the pages (i.e., a header image): ``` {{ $.Param "header_image" }} ``` The `.Param` method provides a way to resolve a single value according to it's definition in a page parameter (i.e. in the content's front matter) or a site parameter (i.e., in your `config`). ### Access Nested Fields in Front Matter When front matter contains nested fields like the following: ``` --- author: given_name: John family_name: Feminella display_name: John Feminella --- ``` `.Param` can access these fields by concatenating the field names together with a dot: ``` {{ $.Param "author.display_name" }} ``` If your front matter contains a top-level key that is ambiguous with a nested key, as in the following case: ``` --- favorites.flavor: vanilla favorites: flavor: chocolate --- ``` The top-level key will be preferred. Therefore, the following method, when applied to the previous example, will print `vanilla` and not `chocolate`: ``` {{ $.Param "favorites.flavor" }} => vanilla ``` [gitinfo]: /variables/git/ [File Variables]: /variables/files/ hugo-0.68.3/docs/content/en/variables/pages.md000066400000000000000000000021351363637351300211620ustar00rootroot00000000000000--- title: Pages Methods linktitle: description: Pages is the core page collection in Hugo and has many useful methods. date: 2019-10-20 categories: [variables and params] keywords: [pages] draft: false menu: docs: title: "methods defined on a page collection" parent: "variables" weight: 21 weight: 21 sections_weight: 20 aliases: [/pages] toc: true --- Also see [List templates](/templates/lists) for an overview of sort methods. ## .Next PAGE `.Next` and `.Prev` on `Pages` work similar to the methods with the same names on `.Page`, but are more flexible (and slightly slower) as they can be used on any page collection. `.Next` points **up** to the next page relative to the page sent in as the argument. Example: `{{with .Site.RegularPages.Next . }}{{.RelPermalink}}{{end}}`. Calling `.Next` with the first page in the collection returns `nil`. ## .Prev PAGE `.Prev` points **down** to the previous page relative to the page sent in as the argument. Example: `{{with .Site.RegularPages.Prev . }}{{.RelPermalink}}{{end}}`. Calling `.Prev` with the last page in the collection returns `nil`. hugo-0.68.3/docs/content/en/variables/shortcodes.md000066400000000000000000000033041363637351300222370ustar00rootroot00000000000000--- title: Shortcode Variables linktitle: Shortcode Variables description: Shortcodes can access page variables and also have their own specific built-in variables. date: 2017-03-12 publishdate: 2017-03-12 lastmod: 2017-03-12 categories: [variables and params] keywords: [shortcodes] draft: false menu: docs: parent: "variables" weight: 20 weight: 20 sections_weight: 20 aliases: [] toc: false --- [Shortcodes][shortcodes] have access to parameters delimited in the shortcode declaration via [`.Get`][getfunction], page- and site-level variables, and also the following shortcode-specific fields: .Name : Shortcode name. .Ordinal : Zero-based ordinal in relation to its parent. If the parent is the page itself, this ordinal will represent the position of this shortcode in the page content. .Parent : provides access to the parent shortcode context in nested shortcodes. This can be very useful for inheritance of common shortcode parameters from the root. .Position : Contains [filename and position](https://godoc.org/github.com/gohugoio/hugo/common/text#Position) for the shortcode in a page. Note that this can be relatively expensive to calculate, and is meant for error reporting. See [Error Handling in Shortcodes](/templates/shortcode-templates/#error-handling-in-shortcodes). .IsNamedParams : boolean that returns `true` when the shortcode in question uses [named rather than positional parameters][shortcodes] .Inner : represents the content between the opening and closing shortcode tags when a [closing shortcode][markdownshortcode] is used [getfunction]: /functions/get/ [markdownshortcode]: /content-management/shortcodes/#shortcodes-with-markdown [shortcodes]: /templates/shortcode-templates/ hugo-0.68.3/docs/content/en/variables/site.md000066400000000000000000000111551363637351300210310ustar00rootroot00000000000000--- title: Site Variables linktitle: Site Variables description: Many, but not all, site-wide variables are defined in your site's configuration. However, Hugo provides a number of built-in variables for convenient access to global values in your templates. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [variables and params] keywords: [global,site] draft: false menu: docs: parent: "variables" weight: 10 weight: 10 sections_weight: 10 aliases: [/variables/site-variables/] toc: true --- The following is a list of site-level (aka "global") variables. Many of these variables are defined in your site's [configuration file][config], whereas others are built into Hugo's core for convenient usage in your templates. ## Site Variables List .Site.AllPages : array of all pages, regardless of their translation. .Site.Author : a map of the authors as defined in the site configuration. .Site.BaseURL : the base URL for the site as defined in the site configuration. .Site.BuildDrafts : a boolean (default: `false`) to indicate whether to build drafts as defined in the site configuration. .Site.Copyright : a string representing the copyright of your website as defined in the site configuration. .Site.Data : custom data, see [Data Templates](/templates/data-templates/). .Site.DisqusShortname : a string representing the shortname of the Disqus shortcode as defined in the site configuration. .Site.GoogleAnalytics : a string representing your tracking code for Google Analytics as defined in the site configuration. .Site.Home : reference to the homepage's [page object](https://gohugo.io/variables/page/) .Site.IsMultiLingual : whether there are more than one language in this site. See [Multilingual](/content-management/multilingual/) for more information. .Site.IsServer : a boolean to indicate if the site is being served with Hugo's built-in server. See [`hugo server`](/commands/hugo_server/) for more information. .Site.Language.Lang : the language code of the current locale (e.g., `en`). .Site.Language.LanguageName : the full language name (e.g. `English`). .Site.Language.Weight : the weight that defines the order in the `.Site.Languages` list. .Site.Language : indicates the language currently being used to render the website. This object's attributes are set in site configurations' language definition. .Site.LanguageCode : a string representing the language as defined in the site configuration. This is mostly used to populate the RSS feeds with the right language code. .Site.LanguagePrefix : this can be used to prefix URLs to point to the correct language. It will even work when only one defined language. See also the functions [absLangURL](/functions/abslangurl/) and [relLangURL](/functions/rellangurl). .Site.Languages : an ordered list (ordered by defined weight) of languages. .Site.LastChange : a string representing the date/time of the most recent change to your site. This string is based on the [`date` variable in the front matter](/content-management/front-matter) of your content pages. .Site.Menus : all of the menus in the site. .Site.Pages : array of all content ordered by Date with the newest first. This array contains only the pages in the current language. See [`.Site.Pages`](#site-pages). .Site.RegularPages : a shortcut to the *regular* page collection. `.Site.RegularPages` is equivalent to `where .Site.Pages "Kind" "page"`. See [`.Site.Pages`](#site-pages). .Site.Sections : top-level directories of the site. .Site.Taxonomies : the [taxonomies](/taxonomies/usage/) for the entire site. Replaces the now-obsolete `.Site.Indexes` since v0.11. Also see section [Taxonomies elsewhere](#taxonomies-elsewhere). .Site.Title : a string representing the title of the site. ## The `.Site.Params` Variable `.Site.Params` is a container holding the values from the `params` section of your site configuration. ### Example: `.Site.Params` The following `config.[yaml|toml|json]` defines a site-wide param for `description`: {{< code-toggle file="config" >}} baseURL = "https://yoursite.example.com/" [params] description = "Tesla's Awesome Hugo Site" author = "Nikola Tesla" {{}} You can use `.Site.Params` in a [partial template](/templates/partials/) to call the default site description: {{< code file="layouts/partials/head.html" >}} {{< /code >}} ## The `.Site.Pages` Variable {#site-pages} ### `.Site.Pages` compared to `.Pages` {{< readfile file="/content/en/readfiles/pages-vs-site-pages.md" markdown="true" >}} [config]: /getting-started/configuration/ hugo-0.68.3/docs/content/en/variables/sitemap.md000066400000000000000000000012301363637351300215200ustar00rootroot00000000000000--- title: Sitemap Variables linktitle: Sitemap Variables description: date: 2017-03-12 publishdate: 2017-03-12 lastmod: 2017-03-12 categories: [variables and params] keywords: [sitemap] draft: false menu: docs: parent: "variables" weight: 80 weight: 80 sections_weight: 80 aliases: [] toc: false --- A sitemap is a `Page` and therefore has all the [page variables][pagevars] available to use sitemap templates. They also have the following sitemap-specific variables available to them: .Sitemap.ChangeFreq : the page change frequency .Sitemap.Priority : the priority of the page .Sitemap.Filename : the sitemap filename [pagevars]: /variables/page/hugo-0.68.3/docs/content/en/variables/taxonomy.md000066400000000000000000000054571363637351300217530ustar00rootroot00000000000000--- title: Taxonomy Variables linktitle: description: Taxonomy pages are of type `Page` and have all page-, site-, and list-level variables available to them. However, taxonomy terms templates have additional variables available to their templates. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 categories: [variables and params] keywords: [taxonomies,terms] draft: false menu: docs: parent: "variables" weight: 30 weight: 30 sections_weight: 30 aliases: [] toc: true --- ## Taxonomy Terms Page Variables [Taxonomy terms pages][taxonomytemplates] are of the type `Page` and have the following additional variables. For example, the following fields would be available in `layouts/_defaults/terms.html`, depending on how you organize your [taxonomy templates][taxonomytemplates]: .Data.Singular : The singular name of the taxonomy (e.g., `tags => tag`) .Data.Plural : The plural name of the taxonomy (e.g., `tags => tags`) .Data.Pages : The list of pages in the taxonomy .Data.Terms : The taxonomy itself .Data.Terms.Alphabetical : The taxonomy terms alphabetized .Data.Terms.ByCount : The Terms ordered by popularity Note that `.Data.Terms.Alphabetical` and `.Data.Terms.ByCount` can also be reversed: * `.Data.Terms.Alphabetical.Reverse` * `.Data.Terms.ByCount.Reverse` ## Use `.Site.Taxonomies` Outside of Taxonomy Templates The `.Site.Taxonomies` variable holds all the taxonomies defined site-wide. `.Site.Taxonomies` is a map of the taxonomy name to a list of its values (e.g., `"tags" -> ["tag1", "tag2", "tag3"]`). Each value, though, is not a string but rather a *Taxonomy variable*. ## The `.Taxonomy` Variable The `.Taxonomy` variable, available, for example, as `.Site.Taxonomies.tags`, contains the list of tags (values) and, for each tag, their corresponding content pages. ### Example Usage of `.Site.Taxonomies` The following [partial template][partials] will list all your site's taxonomies, each of their keys, and all the content assigned to each of the keys. For more examples of how to order and render your taxonomies, see [Taxonomy Templates][taxonomytemplates]. {{< code file="all-taxonomies-keys-and-pages.html" download="all-taxonomies-keys-and-pages.html" >}}
      {{ range $taxonomyname, $taxonomy := .Site.Taxonomies }}
    • {{ $taxonomyname }}
        {{ range $key, $value := $taxonomy }}
      • {{ $key }}
      • {{ end }}
    • {{ end }}
    {{< /code >}} [partials]: /templates/partials/ [taxonomytemplates]: /templates/taxonomy-templates/ hugo-0.68.3/docs/content/zh/000077500000000000000000000000001363637351300156075ustar00rootroot00000000000000hugo-0.68.3/docs/content/zh/_index.md000066400000000000000000000052231363637351300174010ustar00rootroot00000000000000--- title: "世界上最快的网站构建框架 The world’s fastest framework for building websites" date: 2017-03-02T12:00:00-05:00 features: - heading: Blistering Speed image_path: /images/icon-fast.svg tagline: What's modern about waiting for your site to build? copy: Hugo is the fastest tool of its kind. At <1 ms per page, the average site builds in less than a second. - heading: Robust Content Management image_path: /images/icon-content-management.svg tagline: Flexibility rules. Hugo is a content strategist's dream. copy: Hugo supports unlimited content types, taxonomies, menus, dynamic API-driven content, and more, all without plugins. - heading: Shortcodes image_path: /images/icon-shortcodes.svg tagline: Hugo's shortcodes are Markdown's hidden superpower. copy: We love the beautiful simplicity of markdown’s syntax, but there are times when we want more flexibility. Hugo shortcodes allow for both beauty and flexibility. - heading: Built-in Templates image_path: /images/icon-built-in-templates.svg tagline: Hugo has common patterns to get your work done quickly. copy: Hugo ships with pre-made templates to make quick work of SEO, commenting, analytics and other functions. One line of code, and you're done. - heading: Multilingual and i18n image_path: /images/icon-multilingual2.svg tagline: Polyglot baked in. copy: Hugo provides full i18n support for multi-language sites with the same straightforward development experience Hugo users love in single-language sites. - heading: Custom Outputs image_path: /images/icon-custom-outputs.svg tagline: HTML not enough? copy: Hugo allows you to output your content in multiple formats, including JSON or AMP, and makes it easy to create your own. sections: - heading: "100s of Themes" cta: Check out the Hugo's themes. link: http://themes.gohugo.io/ color_classes: bg-accent-color white image: /images/homepage-screenshot-hugo-themes.jpg copy: "Hugo provides a robust theming system that is easy to implement but capable of producing even the most complicated websites." - heading: "Capable Templating" cta: Get Started. link: templates/ color_classes: bg-primary-color-light black image: /images/home-page-templating-example.png copy: "Hugo's Go-based templating provides just the right amount of logic to build anything from the simple to complex. If you prefer Jade/Pug-like syntax, you can also use Amber, Ace, or any combination of the three." --- Hugo is one of the most popular open-source static site generators. With its amazing speed and flexibility, Hugo makes building websites fun again. hugo-0.68.3/docs/content/zh/about/000077500000000000000000000000001363637351300167215ustar00rootroot00000000000000hugo-0.68.3/docs/content/zh/about/_index.md000066400000000000000000000005371363637351300205160ustar00rootroot00000000000000--- title: 关于 Hugo linktitle: 概览 description: Hugo 的特色、规划、许可和动力。 date: 2018-04-26 publishdate: 2018-04-26 lastmod: 2018-04-26 categories: [] keywords: [] menu: docs: parent: "about" weight: 1 weight: 1 draft: false aliases: [/about-hugo/,/docs/] toc: false --- Hugo 不是一般的静态网站生成器。 hugo-0.68.3/docs/content/zh/content-management/000077500000000000000000000000001363637351300213735ustar00rootroot00000000000000hugo-0.68.3/docs/content/zh/content-management/_index.md000066400000000000000000000013351363637351300231650ustar00rootroot00000000000000--- title: 内容管理 linktitle: 内容管理概览 description: Hugo 可以管理大型的静态网站,支持骨架、内容类型、菜单、引用、概要等等。 date: 2018-04-23 publishdate: 2018-04-23 lastmod: 2018-04-23 menu: docs: parent: "content-management" weight: 1 keywords: [source, organization] categories: [content management] weight: 01 #rem draft: false aliases: [/content/,/content/organization] toc: false isCJKLanguage: true --- 一个实用的静态网站生成器,需要超越“文件头” (front matter) 和模板的等基本功能,才能兼备可伸缩性和可管理性,满足用户所需。Hugo 不仅是给开发者设计的,也同样适用于内容管理员和写作人员。 hugo-0.68.3/docs/content/zh/documentation.md000066400000000000000000000013101363637351300207750ustar00rootroot00000000000000--- title: Hugo 说明文档 linktitle: Hugo description: Hugo is the world's fastest static website engine. It's written in Go (aka Golang) and developed by bep, spf13 and friends. date: 2017-02-01 publishdate: 2017-02-01 menu: main: parent: "section name" weight: 01 weight: 01 #rem draft: false slug: aliases: [] toc: false layout: documentation-home isCJKLanguage: true --- Hugo 号称**世界上最快的静态网站引擎**。它是以 Go (即 Golang) 编程语言所写成,并由 [bep](https://github.com/bep)、[spf13](https://github.com/spf13) 和[朋友们](https://github.com/gohugoio/hugo/graphs/contributors) 共同开发。 下面是我们说明文档中最常用和实用的章节: hugo-0.68.3/docs/content/zh/news/000077500000000000000000000000001363637351300165635ustar00rootroot00000000000000hugo-0.68.3/docs/content/zh/news/_index.md000066400000000000000000000000701363637351300203500ustar00rootroot00000000000000--- title: "Hugo 新闻" aliases: [/release-notes/] --- hugo-0.68.3/docs/content/zh/templates/000077500000000000000000000000001363637351300176055ustar00rootroot00000000000000hugo-0.68.3/docs/content/zh/templates/_index.md000066400000000000000000000006161363637351300214000ustar00rootroot00000000000000--- title: 模板 Templates linktitle: 模板概览 description: Go templating, template types and lookup order, shortcodes, and data. date: 2017-02-01 publishdate: 2017-02-01 lastmod: 2017-02-01 menu: docs: parent: "templates" weight: 01 weight: 01 #rem categories: [templates] keywords: [] draft: false aliases: [/templates/overview/,/templates/content] toc: false notesforauthors: --- hugo-0.68.3/docs/content/zh/templates/base.md000066400000000000000000000116571363637351300210530ustar00rootroot00000000000000--- title: Base 模板 and Blocks linktitle: description: The base and block constructs allow you to define the outer shell of your master templates (i.e., the chrome of the page). godocref: https://golang.org/pkg/text/template/#example_Template_block date: 2017-02-01 publishdate: 2018-08-11 lastmod: 2017-02-01 categories: [templates,fundamentals] keywords: [blocks,base] menu: docs: parent: "templates" weight: 20 weight: 20 sections_weight: 20 draft: false aliases: [/templates/blocks/,/templates/base-templates-and-blocks/] toc: true --- The `block` keyword allows you to define the outer shell of your pages' one or more master template(s) and then fill in or override portions as necessary. {{< youtube QVOMCYitLEc >}} ## Base Template Lookup Order The [lookup order][lookup] for base templates is as follows: 1. `/layouts/section/-baseof.html` 2. `/themes//layouts/section/-baseof.html` 3. `/layouts//baseof.html` 4. `/themes//layouts//baseof.html` 5. `/layouts/section/baseof.html` 6. `/themes//layouts/section/baseof.html` 7. `/layouts/_default/-baseof.html` 8. `/themes//layouts/_default/-baseof.html` 9. `/layouts/_default/baseof.html` 10. `/themes//layouts/_default/baseof.html` Variables are denoted by capitalized text set within `<>`. Note that Hugo's default behavior is for `type` to inherit from `section` unless otherwise specified. ### Example Base Template Lookup Order As an example, let's assume your site is using a theme called "mytheme" when rendering the section list for a `posts` section. Hugo picks `layout/section/posts.html` as the template for [rendering the section][]. The `{{define}}` block in this template tells Hugo that the template is an extension of a base template. Here is the lookup order for the `posts` base template: 1. `/layouts/section/posts-baseof.html` 2. `/themes/mytheme/layouts/section/posts-baseof.html` 3. `/layouts/posts/baseof.html` 4. `/themes/mytheme/layouts/posts/baseof.html` 5. `/layouts/section/baseof.html` 6. `/themes/mytheme/layouts/section/baseof.html` 7. `/layouts/_default/posts-baseof.html` 8. `/themes/mytheme/layouts/_default/posts-baseof.html` 9. `/layouts/_default/baseof.html` 10. `/themes/mytheme/layouts/_default/baseof.html` ## Define the Base Template The following defines a simple base template at `_default/baseof.html`. As a default template, it is the shell from which all your pages will be rendered unless you specify another `*baseof.html` closer to the beginning of the lookup order. {{< code file="layouts/_default/baseof.html" download="baseof.html" >}} {{ block "title" . }} <!-- Blocks may include default content. --> {{ .Site.Title }} {{ end }} {{ block "main" . }} {{ end }} {{ block "footer" . }} {{ end }} {{< /code >}} ## Override the Base Template From the above base template, you can define a [default list template][hugolists]. The default list template will inherit all of the code defined above and can then implement its own `"main"` block from: {{< code file="layouts/_default/list.html" download="list.html" >}} {{ define "main" }}

    Posts

    {{ range .Pages }}

    {{ .Title }}

    {{ .Content }}
    {{ end }} {{ end }} {{< /code >}} This replaces the contents of our (basically empty) "main" block with something useful for the list template. In this case, we didn't define a `"title"` block, so the contents from our base template remain unchanged in lists. {{% warning %}} Code that you put outside the block definitions *can* break your layout. This even includes HTML comments. For example: ``` {{ define "main" }} ...your code here {{ end }} ``` [See this thread from the Hugo discussion forums.](https://discourse.gohugo.io/t/baseof-html-block-templates-and-list-types-results-in-empty-pages/5612/6) {{% /warning %}} The following shows how you can override both the `"main"` and `"title"` block areas from the base template with code unique to your [default single page template][singletemplate]: {{< code file="layouts/_default/single.html" download="single.html" >}} {{ define "title" }} {{ .Title }} – {{ .Site.Title }} {{ end }} {{ define "main" }}

    {{ .Title }}

    {{ .Content }} {{ end }} {{< /code >}} [hugolists]: /templates/lists [lookup]: /templates/lookup-order/ [rendering the section]: /templates/section-templates/ [singletemplate]: /templates/single-page-templates/ hugo-0.68.3/docs/data/000077500000000000000000000000001363637351300144255ustar00rootroot00000000000000hugo-0.68.3/docs/data/articles.toml000066400000000000000000000545551363637351300171460ustar00rootroot00000000000000[[article]] title = "A visit to the Workshop: Hugo/Unix/Vim integration" url = "https://blog.afoolishmanifesto.com/posts/hugo-unix-vim-integration/" author = "fREW Schmidt" date = "2017-07-22" [[article]] title = "Hugo Easy Gallery - Automagical PhotoSwipe image gallery with a one-line shortcode" url = "https://www.liwen.id.au/heg/" author = "Li-Wen Yip" date = "2017-03-25" [[article]] title = "Automagical Image Gallery in Hugo with PhotoSwipe and jQuery" url = "https://www.liwen.id.au/photoswipe/" author = "Li-Wen Yip" date = "2017-03-04" [[article]] title = "Adding Isso Comments to Hugo" url = "https://stiobhart.net/2017-02-24-isso-comments/" author = "Stíobhart Matulevicz" date = "2017-02-24" [[article]] title = "Hugo Tutorial: How to Build & Host a (Very Fast) Static E-Commerce Site" url = "https://snipcart.com/blog/hugo-tutorial-static-site-ecommerce" author = "Snipcart" date = "2017-02-23" [[article]] title = "How to Password Protect a Hugo Site" url = "https://www.aerobatic.com/blog/password-protect-a-hugo-site/" author = "Aerobatic" date = "2017-02-19" [[article]] title = "Switching from Wordpress to Hugo" url = "http://schnuddelhuddel.de/switching-from-wordpress-to-hugo/" author = "Mario Martelli" date = "2017-02-19" [[article]] title = "Zero to HTTP/2 with AWS and Hugo" url = "https://habd.as/zero-to-http-2-aws-hugo/" author = "Josh Habdas" date = "2017-02-16" [[article]] title = "Deploy a Hugo site to Aerobatic with CircleCI" url = "https://www.aerobatic.com/blog/hugo-github-circleci/" author = "Aerobatic" date = "2017-02-14" [[article]] title = "NPM scripts for building and deploying Hugo site" url = "https://www.aerobatic.com/blog/hugo-npm-buildtool-setup/" author = "Aerobatic" date = "2017-02-12" [[article]] title = "Getting started with Hugo and the plain-blog theme, on NearlyFreeSpeech.Net" url = "https://www.penwatch.net/cms/get_started_plain_blog/" author = "Li-aung “Lewis” Yip" date = "2017-02-12" [[article]] title = "Choose Hugo over Jekyll" url = "https://habd.as/choose-hugo-over-jekyll/" author = "Josh Habdas" date = "2017-02-10" [[article]] title = "Build a Hugo site using Cloud9 IDE and host on App Engine" url = "https://loyall.ch/lab/2017/01/build-a-static-website-with-cloud9-hugo-and-app-engine/" author = "Pascal Aubort" date = "2017-02-05" [[article]] title = "Hugo Continuous Deployment with Bitbucket Pipelines and Aerobatic" url = "https://www.aerobatic.com/blog/hugo-bitbucket-pipelines/" author = "Aerobatic" date = "2017-02-04" [[article]] title = "How to use Firebase to host a Hugo site" url = "https://code.selfmadefighter.com/post/static-site-firebase/" author = "Andrew Cuga" date= "2017-02-04" [[article]] title = "A publishing workflow for teams using static site generators" url = "https://www.keybits.net/post/publishing-workflow-for-teams-using-static-site-generators/" author = "Tom Atkins" date = "2017-01-02" [[article]] title = "How To Dynamically Use Google Fonts In A Hugo Website" url = "https://stoned.io/web-development/hugo/How-To-Dynamically-Use-Google-Fonts-In-A-Hugo-Website/" author = "Hash Borgir" date = "2016-10-27" [[article]] title = "Embedding Facebook In A Hugo Template" url = "https://stoned.io/web-development/hugo/Embedding-Facebook-In-A-Hugo-Template/" author = "Hash Borgir" date = "2016-10-22" [[article]] title = "通过 Gitlab-cl 将 Hugo blog 自动部署至 GitHub (Chinese, Continuous integration)" url = "https://zetaoyang.github.io/post/2016/10/17/gitlab-cl.html" author = "Zetao Yang" date = "2016-10-17" [[article]] title = "A Step-by-Step Guide: Hugo on Netlify" url = "https://www.netlify.com/blog/2016/09/21/a-step-by-step-guide-hugo-on-netlify/" author = "Eli Williamson" date = "2016-09-21" [[article]] title = "Building our site: From Django & Wordpress to a static generator (Part I)" url = "https://tryolabs.com/blog/2016/09/20/building-our-site-django-wordpress-to-static-part-i/" author = "Alan Descoins" date = "2016-09-20" [[article]] title = "Webseitenmaschine - Statische Websites mit Hugo erzeugen (German, $)" url = "http://www.heise.de/ct/ausgabe/2016-12-Statische-Websites-mit-Hugo-erzeugen-3211704.html" author = "Christian Helmbold" date = "2016-05-27" [[article]] title = "Cómo hacer sitios web estáticos con Hugo y Go - Platzi (Video tutorial)" url = "https://www.youtube.com/watch?v=qaXXpdiCHXE" author = "Verónica López" date = "2016-04-06" [[article]] title = "CDNOverview: A CDN comparison site made with Hugo" url = "https://www.cloakfusion.com/cdnoverview-cdn-comparison-site-made-hugo/" author = "Thijs de Zoete" date = "2016-02-23" [[article]] title = "Hugo: A Modern WebSite Engine That Just Works" url = "https://github.com/shekhargulati/52-technologies-in-2016/blob/master/07-hugo/README.md" author = "Shekhar Gulati" date = "2016-02-14" [[article]] title = "Minify Hugo Generated HTML" url = "http://ratson.name/blog/minify-hugo-generated-html/" author = "Ratson" date = "2016-02-02" [[article]] title = "HugoのデプロイをWerckerからCircle CIに変更した - log" url = "http://log.deprode.net/logs/2016-01-17/" author = "Deprode" date = "2016-01-17" [[article]] title = "Static site generators: el futuro de las webs estáticas
    (Hugo, Jekyll, Flask y otros)" url = "http://sitelabs.es/static-site-generators-futuro-las-webs-estaticas/" author = "Eneko Sarasola" date = "2016-01-09" [[article]] title = "Writing a Lambda Function for Hugo" url = "https://blog.jolexa.net/post/writing-a-lambda-function-for-hugo/" author = "Jeremy Olexa" date = "2016-01-01" [[article]] title = "Ein Blog mit Hugo erstellen - Tutorial (Deutsch/German)" url = "http://privat.albicker.org/tags/hugo.html" author = "Bernhard Albicker" date = "2015-12-30" [[article]] title = "How to host Hugo static website generator on AWS Lambda" url = "http://bezdelev.com/post/hugo-aws-lambda-static-website/" author = "Ilya Bezdelev" date = "2015-12-15" [[article]] title = "Migrating from Pelican to Hugo" url = "http://www.softinio.com/post/migrating-from-pelican-to-hugo/" author = "Salar Rahmanian" date = "2015-11-29" [[article]] title = "Static Website Generators Reviewed: Jekyll, Middleman, Roots, Hugo" url = "http://www.smashingmagazine.com/2015/11/static-website-generators-jekyll-middleman-roots-hugo-review/" author = "Mathias Biilmann Christensen" date = "2015-11-16" [[article]] title = "How To Deploy a Hugo Site to Production with Git Hooks on Ubuntu 14.04" url = "https://www.digitalocean.com/community/tutorials/how-to-deploy-a-hugo-site-to-production-with-git-hooks-on-ubuntu-14-04" author = "Justin Ellingwood" date = "2015-11-12" [[article]] title = "How To Install and Use Hugo, a Static Site Generator, on Ubuntu 14.04" url = "https://www.digitalocean.com/community/tutorials/how-to-install-and-use-hugo-a-static-site-generator-on-ubuntu-14-04" author = "Justin Ellingwood" date = "2015-11-09" [[article]] title = "Switching from Wordpress to Hugo" url = "http://justinfx.com/2015/11/08/switching-from-wordpress-to-hugo/" author = "Justin Israel" date = "2015-11-08" [[article]] title = "Hands-on Experience with Hugo as a Static Site Generator" url = "http://usersnap.com/blog/hands-on-experience-with-hugo-static-site-generator/" author = "Thomas Peham" date = "2015-10-15" [[article]] title = "Statische Webseites mit Hugo erstellen/Vortrag mit Foliensatz (deutsch)" url = "http://sfd.koelnerlinuxtreffen.de/2015/HaraldWeidner/" author = "Harald Weidner" date = "2015-09-19" [[article]] title = "Moving from WordPress to Hugo" url = "http://abhipandey.com/2015/09/moving-to-hugo/" author = "Abhishek Pandey" date = "2015-09-15" [[article]] title = "通过webhook将Hugo自动部署至GitHub Pages和GitCafe Pages (Automated deployment)" url = "http://blog.coderzh.com/2015/09/13/use-webhook-automated-deploy-hugo/" author = "CoderZh" date = "2015-09-13" [[article]] title = "使用hugo搭建个人博客站点 (Using Hugo to build a personal blog site)" url = "http://blog.coderzh.com/2015/08/29/hugo/" author = "CoderZh" date = "2015-08-29" [[article]] title = "Good-Bye Wordpress, Hello Hugo! (German)" url = "http://blog.arminhanisch.de/2015/08/blog-migration-zu-hugo/" author = "Armin Hanisch" date = "2015-08-18" [[article]] title = "Générer votre site web statique avec Hugo (Generate your static site with Hugo)" url = "http://www.linux-pratique.com/?p=191" author = "Benoît Benedetti" date = "2015-06-26" [[article]] title = "Hugo向けの新しいテーマを作った (I created a new theme for Hugo)" url = "https://yet.unresolved.xyz/blog/2016/10/03/how-to-make-of-hugo-theme/" author = "Daisuke Tsuji" date = "2015-06-20" [[article]] title = "Hugo - Gerando um site com conteúdo estático. (Portuguese Brazil)" url = "http://blog.ffrizzo.com/posts/hugo/" author = "Fabiano Frizzo" date = "2015-06-02" [[article]] title = "An Introduction to Static Site Generators" url = "http://davidwalsh.name/introduction-static-site-generators" author = "Eduardo Bouças" date = "2015-05-20" [[article]] title = "Hugo Still Rules" url = "http://cheekycoder.com/2015/05/hugo-still-rules/" author = "Cheeky Coder" date = "2015-05-18" [[article]] title = "hugo - Static Site Generator" url = "http://gscacco.github.io/post/hugo/" author = "G Scaccoio" date = "2015-05-04" [[article]] title = "WindowsでHugoを使う" url = "http://ureta.net/2015/05/hugo-on-windows/" author = "うれ太郎" date = "2015-05-01" [[article]] title = "Hugoのshortcodesを用いてサイトにスライドなどを埋め込む" url = "http://blog.yucchiy.com/2015/04/29/hugo-shortcode/" author = "Yucchiy" date = "2015-04-29" [[article]] title = "HugoとCircleCIでGitHub PagesにBlogを公開してみたら超簡単だった" url = "http://hori-ryota.github.io/blog/create-blog-with-hugo-and-circleci/" author = "Hori Ryota" date = "2015-04-17" [[article]] title = "10 Best Static Site Generators" url = "http://beebom.com/2015/04/best-static-site-generators" author = "Aniruddha Mysore" date = "2015-04-06" [[article]] title = "Goodbye WordPress; Hello Hugo" url = "http://willwarren.com/2015/04/05/goodbye-wordpress-hello-hugo/" author = "Will Warren" date = "2015-04-05" [[article]] title = "Static Websites with Hugo on Google Cloud Storage" url = "http://www.moxie.io/post/static-websites-with-hugo-on-google-cloud-storage/" author = "Moxie Input/Output" date = "2015-04-02" [[article]] title = "De nuevo iniciando un blog" url = "https://alvarolizama.net/" author = "Alvaro Lizama" date = "2015-03-29" [[article]] title = "We moved our blog from Posthaven to Hugo after only three posts. Why?" url = "http://blog.hypriot.com/post/moved-from-posthaven-to-hugo/" author = "Hypriot" date = "2015-03-27" [[article]] title = "Top Static Site Generators in 2015" url = "http://superdevresources.com/static-site-generators-2015/" author = "Kanishk Kunal" date = "2015-03-12" [[article]] title = "Moving to Hugo" url = "http://abiosoft.com/moving-to-hugo/" author = "Abiola Ibrahim" date = "2015-03-08" [[article]] title = "Migrating a blog (yes, this one!) from Wordpress to Hugo" url = "http://justindunham.net/migrating-from-wordpress-to-hugo/" author = "Justin Dunham" date = "2015-02-13" [[article]] title = "blogをoctopressからHugoに乗り換えたメモ" url = "http://blog.jigyakkuma.org/2015/02/11/hugo/" author = "jigyakkuma" date = "2015-02-11" [[article]] title = "Hugoでブログをつくった" url = "http://porgy13.github.io/post/new-hugo-blog/" author = "porgy13" date = "2015-02-07" [[article]] title = "Hugoにブログを移行した" url = "http://keichi.net/post/first/" author = "Keichi Takahashi" date = "2015-02-04" [[article]] title = "Hugo静态网站生成器中文教程" url = "http://nanshu.wang/post/2015-01-31/" author = "Nanshu Wang" date = "2015-01-31" [[article]] title = "Hugo + Github Pages + Wercker CI = ¥0(無料)
    でコマンド 1 発(自動化)でサイト
    ・ブログを公開・運営・分析・収益化
    " url = "http://qiita.com/yoheimuta/items/8a619cac356bed89a4c9" author = "Yohei Yoshimuta" date = "2015-01-31" [[article]] title = "Running Hugo websites on anynines" url = "http://blog.anynines.com/running-hugo-websites-on-anynines/" author = "Julian Weber" date = "2015-01-30" [[article]] title = "MiddlemanからHugoへ移行した" url = "http://re-dzine.net/2015/01/hugo/" author = "Haruki Konishi" date = "2015-01-21" [[article]] title = "WordPress から Hugo に乗り換えました" url = "http://rakuishi.com/archives/wordpress-to-hugo/" author = "rakuishi" date = "2015-01-20" [[article]] title = "HUGOを使ってサイトを立ち上げる方法" url = "http://qiita.com/syui/items/869538099551f24acbbf" author = "Syui" date = "2015-01-17" [[article]] title = "Jekyllが許されるのは小学生までだよね" url = "http://t32k.me/mol/log/hugo/" author = "Ishimoto Koji" date = "2015-01-16" [[article]] title = "Getting started with Hugo" url = "http://anthonyfok.org/post/getting-started-with-hugo/" author = "Anthony Fok" date = "2015-01-12" [[article]] title = "把这个博客静态化了 (Migrate to Hugo)" url = "http://lich-eng.com/2015/01/03/migrate-to-hugo/" author = "Li Cheng" date = "2015-01-03" [[article]] title = "Porting my blog with Hugo" url = "http://blog.srackham.com/posts/porting-my-blog-with-hugo/" author = "Stuart Rackham" date = "2014-12-30" [[article]] title = "Hugoを使ってみたときのメモ" url = "http://machortz.github.io/posts/usinghugo/" author = "Machortz" date = "2014-12-29" [[article]] title = "OctopressからHugoへ移行した" url = "http://deeeet.com/writing/2014/12/25/hugo/" author = "Taichi Nakashima" date = "2014-12-25" [[article]] title = "Migrating to Hugo From Octopress" url = "http://nathanleclaire.com/blog/2014/12/22/migrating-to-hugo-from-octopress/" author = "Nathan LeClaire" date = "2014-12-22" [[article]] title = "Dynamic Pages with GoHugo.io" url = "http://cyrillschumacher.com/2014/12/21/dynamic-pages-with-gohugo.io/" author = "Cyrill Schumacher" date = "2014-12-21" [[article]] title = "6 Static Blog Generators That Aren’t Jekyll" url = "http://www.sitepoint.com/6-static-blog-generators-arent-jekyll/" author = "David Turnbull" date = "2014-12-08" [[article]] title = "Travel Blogging Setup" url = "http://www.stou.dk/2014/11/travel-blogging-setup/" author = "Rasmus Stougaard" date = "2014-11-23" [[article]] title = "Hosting A Hugo Website Behind Nginx" url = "http://www.bigbeeconsultants.co.uk/blog/hosting-hugo-website-behind-nginx" author = "Rick Beton" date = "2014-11-20" [[article]] title = "使用Hugo搭建免费个人Blog (How to use Hugo)" url = "http://ulricqin.com/post/how-to-use-hugo/" author = "Ulric Qin 秦晓辉" date = "2014-11-11" [[article]] title = "Built in Speed and Built for Speed by Hugo" url = "http://cheekycoder.com/2014/10/built-for-speed-by-hugo/" author = "Cheeky Coder" date = "2014-10-30" [[article]] title = "Hugo para crear sitios web estáticos" url = "http://www.webbizarro.com/noticias/1076/hugo-para-crear-sitios-web-estaticos/" author = "Web Bizarro" date = "2014-08-19" [[article]] title = "Going with hugo" url = "http://www.markuseliasson.se/article/going-with-hugo/" author = "Markus Eliasson" date = "2014-08-18" [[article]] title = "Benchmarking Jekyll, Hugo and Wintersmith" url = "http://fredrikloch.me/post/2014-08-12-Jekyll-and-its-alternatives-from-a-site-generation-point-of-view/" author = "Fredrik Loch" date = "2014-08-12" [[article]] title = "Goodbye Octopress, Hello Hugo!" url = "http://andreimihu.com/blog/2014/08/11/goodbye-octopress-hello-hugo/" author = "Andrei Mihu" date = "2014-08-11" [[article]] title = "Beautiful sites for Open Source projects" url = "http://beautifulopen.com/2014/08/09/hugo/" author = "Beautiful Open" date = "2014-08-09" [[article]] title = "Hugo: Beyond the Defaults" url = "http://npf.io/2014/08/hugo-beyond-the-defaults/" author = "Nate Finch" date = "2014-08-08" [[article]] title = "First Impressions of Hugo" url = "https://peteraba.com/blog/first-impressions-of-hugo/" author = "Peter Aba" date = "2014-06-06" [[article]] title = "New Site Workflow" url = "http://vurt.co.uk/post/new_website/" author = "Giles Paterson" date = "2014-08-05" [[article]] title = "How I Learned to Stop Worrying and Love the (Static) Web" url = "http://cognition.ca/post/about-hugo/" author = "Joshua McKenty" date = "2014-08-04" [[article]] title = "Hugo - Static Site Generator" url = "http://kenwoo.io/blog/hugo---static-site-generator/" author = "Kenny Woo" date = "2014-08-03" [[article]] title = "Hugo Is Friggin' Awesome" url = "http://npf.io/2014/08/hugo-is-awesome/" author = "Nate Finch" date = "2014-08-01" [[article]] title = "再次搬家 (Move from WordPress to Hugo)" url = "http://www.chingli.com/misc/move-from-wordpress-to-hugo/" author = "青砾 (chingli)" date = "2014-07-12" [[article]] title = "Embedding Gists in Hugo" url = "http://danmux.com/posts/embedded_gists/" author = "Dan Mull" date = "2014-07-05" [[article]] title = "An Introduction To Hugo" url = "http://www.cirrushosting.com/web-hosting-blog/an-introduction-to-hugo/" author = "Dan Silber" date = "2014-07-01" [[article]] title = "Moving to Hugo" url = "http://danmux.com/posts/hugo_based_blog/" author = "Dan Mull" date = "2014-05-29" [[article]] title = "开源之静态站点生成器排行榜
    (Leaderboard of open-source static website generators)" url = "http://code.csdn.net/news/2819909" author = "CSDN.net" date = "2014-05-23" [[article]] title = "Finally, a satisfying and effective blog setup" url = "http://michaelwhatcott.com/now-powered-by-hugo/" author = "Michael Whatcott" date = "2014-05-20" [[article]] title = "Hugo from scratch" url = "http://zackofalltrades.com/notes/2014/05/hugo-from-scratch/" author = "Zack Williams" date = "2014-05-18" [[article]] title = "Why I switched away from Jekyll" url = "http://www.jakejanuzelli.com/why-I-switched-away-from-jekyll/" author = "Jake Januzelli" date = "2014-05-10" [[article]] title = "Welcome our new blog" url = "http://blog.ninya.io/posts/welcome-our-new-blog/" author = "Ninya.io" date = "2014-04-11" [[article]] title = "Mission Not Accomplished" url = "http://johnsto.co.uk/blog/mission-not-accomplished/" author = "Dave Johnston" date = "2014-04-03" [[article]] title = "Hugo - A Static Site Builder in Go" url = "http://deepfriedcode.com/post/hugo/" author = "Deep Fried Code" date = "2014-03-30" [[article]] title = "Adventures in Angular Podcast" url = "http://devchat.tv/adventures-in-angular/003-aia-gdes" author = "Matias Niemela" date = "2014-03-28" [[article]] title = "Hugo" url = "http://bra.am/post/hugo/" author = "bra.am" date = "2014-03-23" [[article]] title = "Converting Blogger To Markdown" url = "http://trishagee.github.io/project/atom-to-hugo/" author = "Trisha Gee" date = "2014-03-20" [[article]] title = "Moving to Hugo Static Web Pages" url = "http://tepid.org/tech/hugo-web/" author = "Tobias Weingartner" date = "2014-03-16" [[article]] title = "New Blog Engine: Hugo" url = "https://blog.afoolishmanifesto.com/posts/hugo/" author = "fREW Schmidt" date = "2014-03-15" [[article]] title = "Hugo + gulp.js = Huggle" url = "http://ktmud.github.io/huggle/en/intro/)" author = "Jesse Yang 杨建超" date = "2014-03-08" [[article]] title = "Powered by Hugo" url = "http://kieranhealy.org/blog/archives/2014/02/24/powered-by-hugo/" author = "Kieran Healy" date = "2014-02-24" [[article]] title = "静的サイトを素早く構築するために
    GoLangで作られたジェネレータHugo
    " url = "http://hamasyou.com/blog/2014/02/21/hugo/" author = "
    Shogo Hamada
    濱田章吾
    " date = "2014-02-21" [[article]] title = "Latest Roundup of Useful Tools For Developers" url = "http://codegeekz.com/latest-roundup-of-useful-tools-for-developers/" author = "CodeGeekz" date = "2014-02-13" [[article]] title = "Hugo: Static Site Generator written in Go" url = "http://www.braveterry.com/2014/02/06/hugo-static-site-generator-written-in-go/" author = "Brave Terry" date = "2014-02-06" [[article]] title = "10 Useful HTML5 Tools for Web Designers and Developers" url = "http://designdizzy.com/10-useful-html5-tools-for-web-designers-and-developers/" author = "Design Dizzy" date = "2014-02-04" [[article]] title = "Hugo – Fast, Flexible Static Site Generator" url = "http://cube3x.com/hugo-fast-flexible-static-site-generator/" author = "Joby Joseph" date = "2014-01-18" [[article]] title = "Hugo: A new way to build static website" url = "http://www.w3update.com/opensource/hugo-a-new-way-to-build-static-website.html" author = "w3update" date = "2014-01-17" [[article]] title = "Xaprb now uses Hugo" url = "http://xaprb.com/blog/2014/01/15/using-hugo/" author = "Baron Schwartz" date = "2014-01-15" [[article]] title = "New jQuery Plugins And Resources That Web Designers Need" url = "http://www.designyourway.net/blog/resources/new-jquery-plugins-and-resources-that-web-designers-need/" author = "Design Your Way" date = "2014-01-01" [[article]] title = "On Blog Construction" url = "http://alexla.sh/post/on-blog-construction/" author = "Alexander Lash" date = "2013-12-27" [[article]] title = "Hugo" url = "http://onethingwell.org/post/69070926608/hugo" author = "One Thing Well" date = "2013-12-05" [[article]] title = "In Praise Of Hugo" url = "http://sound-guru.com/blog/post/hello-world/" author = "sound-guru.com" date = "2013-10-19" [[article]] title = "Hosting a blog on S3 and Cloudfront" url = "http://www.danesparza.net/2013/07/hosting-a-blog-on-s3-and-cloudfront/" author = "Dan Esparza" date = "2013-07-24" hugo-0.68.3/docs/data/docs.json000066400000000000000000003524731363637351300162660ustar00rootroot00000000000000{ "chroma": { "lexers": [ { "Name": "ABAP", "Aliases": [ "ABAP", "abap" ] }, { "Name": "ABNF", "Aliases": [ "abnf" ] }, { "Name": "ANTLR", "Aliases": [ "antlr" ] }, { "Name": "APL", "Aliases": [ "apl" ] }, { "Name": "ActionScript", "Aliases": [ "actionscript", "as" ] }, { "Name": "ActionScript 3", "Aliases": [ "actionscript3", "as", "as3" ] }, { "Name": "Ada", "Aliases": [ "ada", "ada2005", "ada95", "adb", "ads" ] }, { "Name": "Angular2", "Aliases": [ "ng2" ] }, { "Name": "ApacheConf", "Aliases": [ "aconf", "apache", "apacheconf", "conf", "htaccess" ] }, { "Name": "AppleScript", "Aliases": [ "applescript" ] }, { "Name": "Arduino", "Aliases": [ "arduino", "ino" ] }, { "Name": "Awk", "Aliases": [ "awk", "gawk", "mawk", "nawk" ] }, { "Name": "BNF", "Aliases": [ "bnf" ] }, { "Name": "Ballerina", "Aliases": [ "bal", "ballerina" ] }, { "Name": "Base Makefile", "Aliases": [ "*", "bsdmake", "mak", "make", "makefile", "mf", "mk" ] }, { "Name": "Bash", "Aliases": [ "bash", "bash_*", "bashrc", "ebuild", "eclass", "exheres-0", "exlib", "ksh", "sh", "shell", "zsh", "zshrc" ] }, { "Name": "Batchfile", "Aliases": [ "bat", "batch", "cmd", "dosbatch", "winbatch" ] }, { "Name": "BibTeX", "Aliases": [ "bib", "bibtex" ] }, { "Name": "BlitzBasic", "Aliases": [ "b3d", "bb", "blitzbasic", "bplus", "decls" ] }, { "Name": "Brainfuck", "Aliases": [ "b", "bf", "brainfuck" ] }, { "Name": "C", "Aliases": [ "c", "h", "idc" ] }, { "Name": "C#", "Aliases": [ "c#", "cs", "csharp" ] }, { "Name": "C++", "Aliases": [ "C", "CPP", "H", "c++", "cc", "cp", "cpp", "cxx", "h++", "hh", "hpp", "hxx" ] }, { "Name": "CFEngine3", "Aliases": [ "cf", "cf3", "cfengine3" ] }, { "Name": "CMake", "Aliases": [ "cmake", "txt" ] }, { "Name": "COBOL", "Aliases": [ "COB", "CPY", "cob", "cobol", "cpy" ] }, { "Name": "CSS", "Aliases": [ "css" ] }, { "Name": "Cap'n Proto", "Aliases": [ "capnp" ] }, { "Name": "Cassandra CQL", "Aliases": [ "cassandra", "cql" ] }, { "Name": "Ceylon", "Aliases": [ "ceylon" ] }, { "Name": "ChaiScript", "Aliases": [ "chai", "chaiscript" ] }, { "Name": "Cheetah", "Aliases": [ "cheetah", "spitfire", "spt", "tmpl" ] }, { "Name": "Clojure", "Aliases": [ "clj", "clojure" ] }, { "Name": "CoffeeScript", "Aliases": [ "coffee", "coffee-script", "coffeescript" ] }, { "Name": "Common Lisp", "Aliases": [ "cl", "common-lisp", "lisp" ] }, { "Name": "Coq", "Aliases": [ "coq", "v" ] }, { "Name": "Crystal", "Aliases": [ "cr", "crystal" ] }, { "Name": "Cython", "Aliases": [ "cython", "pxd", "pxi", "pyrex", "pyx" ] }, { "Name": "D", "Aliases": [ "d", "di" ] }, { "Name": "DTD", "Aliases": [ "dtd" ] }, { "Name": "Dart", "Aliases": [ "dart" ] }, { "Name": "Diff", "Aliases": [ "diff", "patch", "udiff" ] }, { "Name": "Django/Jinja", "Aliases": [ "django", "jinja" ] }, { "Name": "Docker", "Aliases": [ "docker", "dockerfile" ] }, { "Name": "EBNF", "Aliases": [ "ebnf" ] }, { "Name": "Elixir", "Aliases": [ "elixir", "ex", "exs" ] }, { "Name": "Elm", "Aliases": [ "elm" ] }, { "Name": "EmacsLisp", "Aliases": [ "el", "elisp", "emacs", "emacs-lisp" ] }, { "Name": "Erlang", "Aliases": [ "erl", "erlang", "es", "escript", "hrl" ] }, { "Name": "FSharp", "Aliases": [ "fs", "fsharp", "fsi" ] }, { "Name": "Factor", "Aliases": [ "factor" ] }, { "Name": "Fish", "Aliases": [ "fish", "fishshell", "load" ] }, { "Name": "Forth", "Aliases": [ "forth", "frt", "fs", "fth" ] }, { "Name": "Fortran", "Aliases": [ "F03", "F90", "f03", "f90", "fortran" ] }, { "Name": "GAS", "Aliases": [ "S", "asm", "gas", "s" ] }, { "Name": "GDScript", "Aliases": [ "gd", "gdscript" ] }, { "Name": "GLSL", "Aliases": [ "frag", "geo", "glsl", "vert" ] }, { "Name": "Genshi", "Aliases": [ "genshi", "kid", "xml+genshi", "xml+kid" ] }, { "Name": "Genshi HTML", "Aliases": [ "html+genshi", "html+kid" ] }, { "Name": "Genshi Text", "Aliases": [ "genshitext" ] }, { "Name": "Gnuplot", "Aliases": [ "gnuplot", "plot", "plt" ] }, { "Name": "Go", "Aliases": [ "go", "golang" ] }, { "Name": "Go HTML Template", "Aliases": [ "go-html-template" ] }, { "Name": "Go Text Template", "Aliases": [ "go-text-template" ] }, { "Name": "GraphQL", "Aliases": [ "gql", "graphql", "graphqls" ] }, { "Name": "Groovy", "Aliases": [ "gradle", "groovy" ] }, { "Name": "HCL", "Aliases": [ "hcl" ] }, { "Name": "HTML", "Aliases": [ "htm", "html", "xhtml", "xslt" ] }, { "Name": "HTTP", "Aliases": [ "http" ] }, { "Name": "Handlebars", "Aliases": [ "handlebars" ] }, { "Name": "Haskell", "Aliases": [ "haskell", "hs" ] }, { "Name": "Haxe", "Aliases": [ "haxe", "hx", "hxsl" ] }, { "Name": "Hexdump", "Aliases": [ "hexdump" ] }, { "Name": "Hy", "Aliases": [ "hy", "hylang" ] }, { "Name": "INI", "Aliases": [ "cfg", "dosini", "gitconfig", "inf", "ini" ] }, { "Name": "Idris", "Aliases": [ "idr", "idris" ] }, { "Name": "Igor", "Aliases": [ "igor", "igorpro", "ipf" ] }, { "Name": "Io", "Aliases": [ "io" ] }, { "Name": "J", "Aliases": [ "ijs", "j" ] }, { "Name": "JSON", "Aliases": [ "json" ] }, { "Name": "Java", "Aliases": [ "java" ] }, { "Name": "JavaScript", "Aliases": [ "javascript", "js", "jsm" ] }, { "Name": "Julia", "Aliases": [ "jl", "julia" ] }, { "Name": "Jungle", "Aliases": [ "jungle" ] }, { "Name": "Kotlin", "Aliases": [ "kotlin", "kt" ] }, { "Name": "LLVM", "Aliases": [ "ll", "llvm" ] }, { "Name": "Lighttpd configuration file", "Aliases": [ "lighttpd", "lighty" ] }, { "Name": "Lua", "Aliases": [ "lua", "wlua" ] }, { "Name": "MLIR", "Aliases": [ "mlir" ] }, { "Name": "Mako", "Aliases": [ "mako", "mao" ] }, { "Name": "Mason", "Aliases": [ "m", "mason", "mc", "mhtml", "mi" ] }, { "Name": "Mathematica", "Aliases": [ "cdf", "ma", "mathematica", "mma", "nb", "nbp" ] }, { "Name": "Matlab", "Aliases": [ "m", "matlab" ] }, { "Name": "MiniZinc", "Aliases": [ "MZN", "dzn", "fzn", "minizinc", "mzn" ] }, { "Name": "Modula-2", "Aliases": [ "def", "m2", "mod", "modula2" ] }, { "Name": "MonkeyC", "Aliases": [ "mc", "monkeyc" ] }, { "Name": "MorrowindScript", "Aliases": [ "morrowind", "mwscript" ] }, { "Name": "MySQL", "Aliases": [ "mysql", "sql" ] }, { "Name": "Myghty", "Aliases": [ "myghty", "myt" ] }, { "Name": "NASM", "Aliases": [ "ASM", "asm", "nasm" ] }, { "Name": "Newspeak", "Aliases": [ "newspeak", "ns2" ] }, { "Name": "Nginx configuration file", "Aliases": [ "conf", "nginx" ] }, { "Name": "Nim", "Aliases": [ "nim", "nimrod" ] }, { "Name": "Nix", "Aliases": [ "nix", "nixos" ] }, { "Name": "OCaml", "Aliases": [ "ml", "mli", "mll", "mly", "ocaml" ] }, { "Name": "Objective-C", "Aliases": [ "h", "m", "obj-c", "objc", "objective-c", "objectivec" ] }, { "Name": "Octave", "Aliases": [ "m", "octave" ] }, { "Name": "OpenSCAD", "Aliases": [ "openscad", "scad" ] }, { "Name": "Org Mode", "Aliases": [ "org", "orgmode" ] }, { "Name": "PHP", "Aliases": [ "inc", "php", "php3", "php4", "php5", "php[345]" ] }, { "Name": "PL/pgSQL", "Aliases": [ "plpgsql" ] }, { "Name": "POVRay", "Aliases": [ "inc", "pov" ] }, { "Name": "PacmanConf", "Aliases": [ "conf", "pacmanconf" ] }, { "Name": "Perl", "Aliases": [ "perl", "pl", "pm", "t" ] }, { "Name": "Pig", "Aliases": [ "pig" ] }, { "Name": "PkgConfig", "Aliases": [ "pc", "pkgconfig" ] }, { "Name": "PostScript", "Aliases": [ "eps", "postscr", "postscript", "ps" ] }, { "Name": "PostgreSQL SQL dialect", "Aliases": [ "postgres", "postgresql" ] }, { "Name": "PowerShell", "Aliases": [ "posh", "powershell", "ps1", "psm1" ] }, { "Name": "Prolog", "Aliases": [ "ecl", "pl", "pro", "prolog" ] }, { "Name": "Protocol Buffer", "Aliases": [ "proto", "protobuf" ] }, { "Name": "Puppet", "Aliases": [ "pp", "puppet" ] }, { "Name": "Python", "Aliases": [ "py", "python", "pyw", "sage", "sc", "tac" ] }, { "Name": "Python 3", "Aliases": [ "py3", "python3" ] }, { "Name": "QBasic", "Aliases": [ "BAS", "bas", "basic", "qbasic" ] }, { "Name": "R", "Aliases": [ "R", "Renviron", "Rhistory", "Rprofile", "S", "r", "s", "splus" ] }, { "Name": "Racket", "Aliases": [ "racket", "rkt", "rktd", "rktl" ] }, { "Name": "Ragel", "Aliases": [ "ragel" ] }, { "Name": "Rexx", "Aliases": [ "arexx", "rex", "rexx", "rx" ] }, { "Name": "Ruby", "Aliases": [ "duby", "gemspec", "rake", "rb", "rbw", "rbx", "ruby" ] }, { "Name": "Rust", "Aliases": [ "in", "rs", "rust" ] }, { "Name": "SCSS", "Aliases": [ "scss" ] }, { "Name": "SPARQL", "Aliases": [ "rq", "sparql" ] }, { "Name": "SQL", "Aliases": [ "sql" ] }, { "Name": "SYSTEMD", "Aliases": [ "service", "systemd" ] }, { "Name": "Sass", "Aliases": [ "sass" ] }, { "Name": "Scala", "Aliases": [ "scala" ] }, { "Name": "Scheme", "Aliases": [ "scheme", "scm", "ss" ] }, { "Name": "Scilab", "Aliases": [ "sce", "sci", "scilab", "tst" ] }, { "Name": "Smalltalk", "Aliases": [ "smalltalk", "squeak", "st" ] }, { "Name": "Smarty", "Aliases": [ "smarty", "tpl" ] }, { "Name": "Snobol", "Aliases": [ "snobol" ] }, { "Name": "Solidity", "Aliases": [ "sol", "solidity" ] }, { "Name": "SquidConf", "Aliases": [ "conf", "squid", "squid.conf", "squidconf" ] }, { "Name": "Standard ML", "Aliases": [ "fun", "sig", "sml" ] }, { "Name": "Swift", "Aliases": [ "swift" ] }, { "Name": "TASM", "Aliases": [ "ASM", "asm", "tasm" ] }, { "Name": "TOML", "Aliases": [ "toml" ] }, { "Name": "TableGen", "Aliases": [ "tablegen", "td" ] }, { "Name": "Tcl", "Aliases": [ "rvt", "tcl" ] }, { "Name": "Tcsh", "Aliases": [ "csh", "tcsh" ] }, { "Name": "TeX", "Aliases": [ "aux", "latex", "tex", "toc" ] }, { "Name": "Termcap", "Aliases": [ "src", "termcap" ] }, { "Name": "Terminfo", "Aliases": [ "src", "terminfo" ] }, { "Name": "Terraform", "Aliases": [ "terraform", "tf" ] }, { "Name": "Thrift", "Aliases": [ "thrift" ] }, { "Name": "TradingView", "Aliases": [ "tradingview", "tv" ] }, { "Name": "Transact-SQL", "Aliases": [ "t-sql", "tsql" ] }, { "Name": "Turing", "Aliases": [ "tu", "turing" ] }, { "Name": "Turtle", "Aliases": [ "ttl", "turtle" ] }, { "Name": "Twig", "Aliases": [ "twig" ] }, { "Name": "TypeScript", "Aliases": [ "ts", "tsx", "typescript" ] }, { "Name": "TypoScript", "Aliases": [ "ts", "txt", "typoscript" ] }, { "Name": "TypoScriptCssData", "Aliases": [ "typoscriptcssdata" ] }, { "Name": "TypoScriptHtmlData", "Aliases": [ "typoscripthtmldata" ] }, { "Name": "VB.net", "Aliases": [ "bas", "vb", "vb.net", "vbnet" ] }, { "Name": "VHDL", "Aliases": [ "vhd", "vhdl" ] }, { "Name": "VimL", "Aliases": [ "exrc", "gvimrc", "vim", "vimrc" ] }, { "Name": "WDTE", "Aliases": [ "wdte" ] }, { "Name": "XML", "Aliases": [ "rss", "svg", "wsdl", "wsf", "xml", "xsd", "xsl", "xslt" ] }, { "Name": "Xorg", "Aliases": [ "conf", "xorg.conf" ] }, { "Name": "YAML", "Aliases": [ "yaml", "yml" ] }, { "Name": "cfstatement", "Aliases": [ "cfs" ] }, { "Name": "markdown", "Aliases": [ "markdown", "md", "mkd" ] }, { "Name": "plaintext", "Aliases": [ "no-highlight", "plain", "text", "txt" ] }, { "Name": "reStructuredText", "Aliases": [ "rest", "restructuredtext", "rst" ] }, { "Name": "react", "Aliases": [ "jsx", "react" ] }, { "Name": "reg", "Aliases": [ "reg", "registry" ] }, { "Name": "systemverilog", "Aliases": [ "sv", "svh", "systemverilog" ] }, { "Name": "verilog", "Aliases": [ "v", "verilog" ] }, { "Name": "vue", "Aliases": [ "vue", "vuejs" ] } ] }, "config": { "markup": { "defaultMarkdownHandler": "goldmark", "highlight": { "style": "monokai", "codeFences": true, "noClasses": true, "lineNos": false, "lineNumbersInTable": true, "lineNoStart": 1, "hl_Lines": "", "tabWidth": 4, "guessSyntax": false }, "tableOfContents": { "startLevel": 2, "endLevel": 3, "ordered": false }, "goldmark": { "renderer": { "hardWraps": false, "xhtml": false, "unsafe": false }, "parser": { "autoHeadingID": true, "autoHeadingIDType": "github", "attribute": true }, "extensions": { "typographer": true, "footnote": true, "definitionList": true, "table": true, "strikethrough": true, "linkify": true, "taskList": true } }, "blackFriday": { "smartypants": true, "smartypantsQuotesNBSP": false, "angledQuotes": false, "fractions": true, "hrefTargetBlank": false, "nofollowLinks": false, "noreferrerLinks": false, "smartDashes": true, "latexDashes": true, "taskLists": true, "plainIDAnchors": true, "extensions": null, "extensionsMask": null, "skipHTML": false, "footnoteAnchorPrefix": "", "footnoteReturnLinkContents": "" } }, "minify": { "minifyOutput": false, "disableHTML": false, "disableCSS": false, "disableJS": false, "disableJSON": false, "disableSVG": false, "disableXML": false, "tdewolff": { "html": { "keepConditionalComments": true, "keepDefaultAttrVals": true, "keepDocumentTags": true, "keepEndTags": true, "keepWhitespace": false }, "css": { "decimals": -1, "keepCSS2": true }, "js": {}, "json": {}, "svg": { "decimals": -1 }, "xml": { "keepWhitespace": false } } } }, "media": { "types": [ { "type": "application/javascript", "string": "application/javascript", "mainType": "application", "subType": "javascript", "delimiter": ".", "suffixes": [ "js" ] }, { "type": "application/json", "string": "application/json", "mainType": "application", "subType": "json", "delimiter": ".", "suffixes": [ "json" ] }, { "type": "application/octet-stream", "string": "application/octet-stream", "mainType": "application", "subType": "octet-stream", "delimiter": "", "suffixes": null }, { "type": "application/rss+xml", "string": "application/rss+xml", "mainType": "application", "subType": "rss", "delimiter": ".", "suffixes": [ "xml" ] }, { "type": "application/toml", "string": "application/toml", "mainType": "application", "subType": "toml", "delimiter": ".", "suffixes": [ "toml" ] }, { "type": "application/xml", "string": "application/xml", "mainType": "application", "subType": "xml", "delimiter": ".", "suffixes": [ "xml" ] }, { "type": "application/yaml", "string": "application/yaml", "mainType": "application", "subType": "yaml", "delimiter": ".", "suffixes": [ "yaml", "yml" ] }, { "type": "image/jpeg", "string": "image/jpeg", "mainType": "image", "subType": "jpeg", "delimiter": ".", "suffixes": [ "jpg", "jpeg" ] }, { "type": "image/png", "string": "image/png", "mainType": "image", "subType": "png", "delimiter": ".", "suffixes": [ "png" ] }, { "type": "image/svg+xml", "string": "image/svg+xml", "mainType": "image", "subType": "svg", "delimiter": ".", "suffixes": [ "svg" ] }, { "type": "text/calendar", "string": "text/calendar", "mainType": "text", "subType": "calendar", "delimiter": ".", "suffixes": [ "ics" ] }, { "type": "text/css", "string": "text/css", "mainType": "text", "subType": "css", "delimiter": ".", "suffixes": [ "css" ] }, { "type": "text/csv", "string": "text/csv", "mainType": "text", "subType": "csv", "delimiter": ".", "suffixes": [ "csv" ] }, { "type": "text/html", "string": "text/html", "mainType": "text", "subType": "html", "delimiter": ".", "suffixes": [ "html" ] }, { "type": "text/plain", "string": "text/plain", "mainType": "text", "subType": "plain", "delimiter": ".", "suffixes": [ "txt" ] }, { "type": "text/x-sass", "string": "text/x-sass", "mainType": "text", "subType": "x-sass", "delimiter": ".", "suffixes": [ "sass" ] }, { "type": "text/x-scss", "string": "text/x-scss", "mainType": "text", "subType": "x-scss", "delimiter": ".", "suffixes": [ "scss" ] }, { "type": "video/3gpp", "string": "video/3gpp", "mainType": "video", "subType": "3gpp", "delimiter": ".", "suffixes": [ "3gpp", "3gp" ] }, { "type": "video/mp4", "string": "video/mp4", "mainType": "video", "subType": "mp4", "delimiter": ".", "suffixes": [ "mp4" ] }, { "type": "video/mpeg", "string": "video/mpeg", "mainType": "video", "subType": "mpeg", "delimiter": ".", "suffixes": [ "mpg", "mpeg" ] }, { "type": "video/ogg", "string": "video/ogg", "mainType": "video", "subType": "ogg", "delimiter": ".", "suffixes": [ "ogv" ] }, { "type": "video/webm", "string": "video/webm", "mainType": "video", "subType": "webm", "delimiter": ".", "suffixes": [ "webm" ] }, { "type": "video/x-msvideo", "string": "video/x-msvideo", "mainType": "video", "subType": "x-msvideo", "delimiter": ".", "suffixes": [ "avi" ] } ] }, "output": { "formats": [ { "MediaType": "text/html", "name": "HTML", "mediaType": { "type": "text/html", "string": "text/html", "mainType": "text", "subType": "html", "delimiter": ".", "suffixes": [ "html" ] }, "path": "", "baseName": "index", "rel": "canonical", "protocol": "", "isPlainText": false, "isHTML": true, "noUgly": false, "notAlternative": false, "permalinkable": true, "weight": 10 }, { "MediaType": "text/html", "name": "AMP", "mediaType": { "type": "text/html", "string": "text/html", "mainType": "text", "subType": "html", "delimiter": ".", "suffixes": [ "html" ] }, "path": "amp", "baseName": "index", "rel": "amphtml", "protocol": "", "isPlainText": false, "isHTML": true, "noUgly": false, "notAlternative": false, "permalinkable": true, "weight": 0 }, { "MediaType": "text/css", "name": "CSS", "mediaType": { "type": "text/css", "string": "text/css", "mainType": "text", "subType": "css", "delimiter": ".", "suffixes": [ "css" ] }, "path": "", "baseName": "styles", "rel": "stylesheet", "protocol": "", "isPlainText": true, "isHTML": false, "noUgly": false, "notAlternative": true, "permalinkable": false, "weight": 0 }, { "MediaType": "text/csv", "name": "CSV", "mediaType": { "type": "text/csv", "string": "text/csv", "mainType": "text", "subType": "csv", "delimiter": ".", "suffixes": [ "csv" ] }, "path": "", "baseName": "index", "rel": "alternate", "protocol": "", "isPlainText": true, "isHTML": false, "noUgly": false, "notAlternative": false, "permalinkable": false, "weight": 0 }, { "MediaType": "text/calendar", "name": "Calendar", "mediaType": { "type": "text/calendar", "string": "text/calendar", "mainType": "text", "subType": "calendar", "delimiter": ".", "suffixes": [ "ics" ] }, "path": "", "baseName": "index", "rel": "alternate", "protocol": "webcal://", "isPlainText": true, "isHTML": false, "noUgly": false, "notAlternative": false, "permalinkable": false, "weight": 0 }, { "MediaType": "application/json", "name": "JSON", "mediaType": { "type": "application/json", "string": "application/json", "mainType": "application", "subType": "json", "delimiter": ".", "suffixes": [ "json" ] }, "path": "", "baseName": "index", "rel": "alternate", "protocol": "", "isPlainText": true, "isHTML": false, "noUgly": false, "notAlternative": false, "permalinkable": false, "weight": 0 }, { "MediaType": "text/plain", "name": "ROBOTS", "mediaType": { "type": "text/plain", "string": "text/plain", "mainType": "text", "subType": "plain", "delimiter": ".", "suffixes": [ "txt" ] }, "path": "", "baseName": "robots", "rel": "alternate", "protocol": "", "isPlainText": true, "isHTML": false, "noUgly": false, "notAlternative": false, "permalinkable": false, "weight": 0 }, { "MediaType": "application/rss+xml", "name": "RSS", "mediaType": { "type": "application/rss+xml", "string": "application/rss+xml", "mainType": "application", "subType": "rss", "delimiter": ".", "suffixes": [ "xml" ] }, "path": "", "baseName": "index", "rel": "alternate", "protocol": "", "isPlainText": false, "isHTML": false, "noUgly": true, "notAlternative": false, "permalinkable": false, "weight": 0 }, { "MediaType": "application/xml", "name": "Sitemap", "mediaType": { "type": "application/xml", "string": "application/xml", "mainType": "application", "subType": "xml", "delimiter": ".", "suffixes": [ "xml" ] }, "path": "", "baseName": "sitemap", "rel": "sitemap", "protocol": "", "isPlainText": false, "isHTML": false, "noUgly": true, "notAlternative": false, "permalinkable": false, "weight": 0 } ], "layouts": [ { "Example": "Single page in \"posts\" section", "Kind": "page", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/posts/single.html.html", "layouts/posts/single.html", "layouts/_default/single.html.html", "layouts/_default/single.html" ] }, { "Example": "Base template for single page in \"posts\" section", "Kind": "page", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/posts/single-baseof.html.html", "layouts/posts/baseof.html.html", "layouts/posts/single-baseof.html", "layouts/posts/baseof.html", "layouts/_default/single-baseof.html.html", "layouts/_default/baseof.html.html", "layouts/_default/single-baseof.html", "layouts/_default/baseof.html" ] }, { "Example": "Single page in \"posts\" section with layout set", "Kind": "page", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/posts/demolayout.html.html", "layouts/posts/single.html.html", "layouts/posts/demolayout.html", "layouts/posts/single.html", "layouts/_default/demolayout.html.html", "layouts/_default/single.html.html", "layouts/_default/demolayout.html", "layouts/_default/single.html" ] }, { "Example": "Base template for single page in \"posts\" section with layout set", "Kind": "page", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/posts/demolayout-baseof.html.html", "layouts/posts/single-baseof.html.html", "layouts/posts/baseof.html.html", "layouts/posts/demolayout-baseof.html", "layouts/posts/single-baseof.html", "layouts/posts/baseof.html", "layouts/_default/demolayout-baseof.html.html", "layouts/_default/single-baseof.html.html", "layouts/_default/baseof.html.html", "layouts/_default/demolayout-baseof.html", "layouts/_default/single-baseof.html", "layouts/_default/baseof.html" ] }, { "Example": "AMP single page", "Kind": "page", "OutputFormat": "AMP", "Suffix": "html", "Template Lookup Order": [ "layouts/posts/single.amp.html", "layouts/posts/single.html", "layouts/_default/single.amp.html", "layouts/_default/single.html" ] }, { "Example": "AMP single page, French language", "Kind": "page", "OutputFormat": "AMP", "Suffix": "html", "Template Lookup Order": [ "layouts/posts/single.fr.amp.html", "layouts/posts/single.amp.html", "layouts/posts/single.fr.html", "layouts/posts/single.html", "layouts/_default/single.fr.amp.html", "layouts/_default/single.amp.html", "layouts/_default/single.fr.html", "layouts/_default/single.html" ] }, { "Example": "Home page", "Kind": "home", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/index.html.html", "layouts/home.html.html", "layouts/list.html.html", "layouts/index.html", "layouts/home.html", "layouts/list.html", "layouts/_default/index.html.html", "layouts/_default/home.html.html", "layouts/_default/list.html.html", "layouts/_default/index.html", "layouts/_default/home.html", "layouts/_default/list.html" ] }, { "Example": "Base template for home page", "Kind": "home", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/index-baseof.html.html", "layouts/home-baseof.html.html", "layouts/list-baseof.html.html", "layouts/baseof.html.html", "layouts/index-baseof.html", "layouts/home-baseof.html", "layouts/list-baseof.html", "layouts/baseof.html", "layouts/_default/index-baseof.html.html", "layouts/_default/home-baseof.html.html", "layouts/_default/list-baseof.html.html", "layouts/_default/baseof.html.html", "layouts/_default/index-baseof.html", "layouts/_default/home-baseof.html", "layouts/_default/list-baseof.html", "layouts/_default/baseof.html" ] }, { "Example": "Home page with type set", "Kind": "home", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/demotype/index.html.html", "layouts/demotype/home.html.html", "layouts/demotype/list.html.html", "layouts/demotype/index.html", "layouts/demotype/home.html", "layouts/demotype/list.html", "layouts/index.html.html", "layouts/home.html.html", "layouts/list.html.html", "layouts/index.html", "layouts/home.html", "layouts/list.html", "layouts/_default/index.html.html", "layouts/_default/home.html.html", "layouts/_default/list.html.html", "layouts/_default/index.html", "layouts/_default/home.html", "layouts/_default/list.html" ] }, { "Example": "Base template for home page with type set", "Kind": "home", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/demotype/index-baseof.html.html", "layouts/demotype/home-baseof.html.html", "layouts/demotype/list-baseof.html.html", "layouts/demotype/baseof.html.html", "layouts/demotype/index-baseof.html", "layouts/demotype/home-baseof.html", "layouts/demotype/list-baseof.html", "layouts/demotype/baseof.html", "layouts/index-baseof.html.html", "layouts/home-baseof.html.html", "layouts/list-baseof.html.html", "layouts/baseof.html.html", "layouts/index-baseof.html", "layouts/home-baseof.html", "layouts/list-baseof.html", "layouts/baseof.html", "layouts/_default/index-baseof.html.html", "layouts/_default/home-baseof.html.html", "layouts/_default/list-baseof.html.html", "layouts/_default/baseof.html.html", "layouts/_default/index-baseof.html", "layouts/_default/home-baseof.html", "layouts/_default/list-baseof.html", "layouts/_default/baseof.html" ] }, { "Example": "Home page with layout set", "Kind": "home", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/demolayout.html.html", "layouts/index.html.html", "layouts/home.html.html", "layouts/list.html.html", "layouts/demolayout.html", "layouts/index.html", "layouts/home.html", "layouts/list.html", "layouts/_default/demolayout.html.html", "layouts/_default/index.html.html", "layouts/_default/home.html.html", "layouts/_default/list.html.html", "layouts/_default/demolayout.html", "layouts/_default/index.html", "layouts/_default/home.html", "layouts/_default/list.html" ] }, { "Example": "AMP home, French language\"", "Kind": "home", "OutputFormat": "AMP", "Suffix": "html", "Template Lookup Order": [ "layouts/index.fr.amp.html", "layouts/home.fr.amp.html", "layouts/list.fr.amp.html", "layouts/index.amp.html", "layouts/home.amp.html", "layouts/list.amp.html", "layouts/index.fr.html", "layouts/home.fr.html", "layouts/list.fr.html", "layouts/index.html", "layouts/home.html", "layouts/list.html", "layouts/_default/index.fr.amp.html", "layouts/_default/home.fr.amp.html", "layouts/_default/list.fr.amp.html", "layouts/_default/index.amp.html", "layouts/_default/home.amp.html", "layouts/_default/list.amp.html", "layouts/_default/index.fr.html", "layouts/_default/home.fr.html", "layouts/_default/list.fr.html", "layouts/_default/index.html", "layouts/_default/home.html", "layouts/_default/list.html" ] }, { "Example": "JSON home", "Kind": "home", "OutputFormat": "JSON", "Suffix": "json", "Template Lookup Order": [ "layouts/index.json.json", "layouts/home.json.json", "layouts/list.json.json", "layouts/index.json", "layouts/home.json", "layouts/list.json", "layouts/_default/index.json.json", "layouts/_default/home.json.json", "layouts/_default/list.json.json", "layouts/_default/index.json", "layouts/_default/home.json", "layouts/_default/list.json" ] }, { "Example": "RSS home", "Kind": "home", "OutputFormat": "RSS", "Suffix": "xml", "Template Lookup Order": [ "layouts/index.rss.xml", "layouts/home.rss.xml", "layouts/rss.xml", "layouts/list.rss.xml", "layouts/index.xml", "layouts/home.xml", "layouts/list.xml", "layouts/_default/index.rss.xml", "layouts/_default/home.rss.xml", "layouts/_default/rss.xml", "layouts/_default/list.rss.xml", "layouts/_default/index.xml", "layouts/_default/home.xml", "layouts/_default/list.xml", "layouts/_internal/_default/rss.xml" ] }, { "Example": "RSS section posts", "Kind": "section", "OutputFormat": "RSS", "Suffix": "xml", "Template Lookup Order": [ "layouts/posts/section.rss.xml", "layouts/posts/rss.xml", "layouts/posts/list.rss.xml", "layouts/posts/section.xml", "layouts/posts/list.xml", "layouts/section/section.rss.xml", "layouts/section/rss.xml", "layouts/section/list.rss.xml", "layouts/section/section.xml", "layouts/section/list.xml", "layouts/_default/section.rss.xml", "layouts/_default/rss.xml", "layouts/_default/list.rss.xml", "layouts/_default/section.xml", "layouts/_default/list.xml", "layouts/_internal/_default/rss.xml" ] }, { "Example": "Taxonomy list in categories", "Kind": "taxonomy", "OutputFormat": "RSS", "Suffix": "xml", "Template Lookup Order": [ "layouts/categories/category.rss.xml", "layouts/categories/taxonomy.rss.xml", "layouts/categories/rss.xml", "layouts/categories/list.rss.xml", "layouts/categories/category.xml", "layouts/categories/taxonomy.xml", "layouts/categories/list.xml", "layouts/taxonomy/category.rss.xml", "layouts/taxonomy/taxonomy.rss.xml", "layouts/taxonomy/rss.xml", "layouts/taxonomy/list.rss.xml", "layouts/taxonomy/category.xml", "layouts/taxonomy/taxonomy.xml", "layouts/taxonomy/list.xml", "layouts/category/category.rss.xml", "layouts/category/taxonomy.rss.xml", "layouts/category/rss.xml", "layouts/category/list.rss.xml", "layouts/category/category.xml", "layouts/category/taxonomy.xml", "layouts/category/list.xml", "layouts/_default/category.rss.xml", "layouts/_default/taxonomy.rss.xml", "layouts/_default/rss.xml", "layouts/_default/list.rss.xml", "layouts/_default/category.xml", "layouts/_default/taxonomy.xml", "layouts/_default/list.xml", "layouts/_internal/_default/rss.xml" ] }, { "Example": "Taxonomy terms in categories", "Kind": "taxonomyTerm", "OutputFormat": "RSS", "Suffix": "xml", "Template Lookup Order": [ "layouts/categories/category.terms.rss.xml", "layouts/categories/terms.rss.xml", "layouts/categories/rss.xml", "layouts/categories/list.rss.xml", "layouts/categories/category.terms.xml", "layouts/categories/terms.xml", "layouts/categories/list.xml", "layouts/taxonomy/category.terms.rss.xml", "layouts/taxonomy/terms.rss.xml", "layouts/taxonomy/rss.xml", "layouts/taxonomy/list.rss.xml", "layouts/taxonomy/category.terms.xml", "layouts/taxonomy/terms.xml", "layouts/taxonomy/list.xml", "layouts/category/category.terms.rss.xml", "layouts/category/terms.rss.xml", "layouts/category/rss.xml", "layouts/category/list.rss.xml", "layouts/category/category.terms.xml", "layouts/category/terms.xml", "layouts/category/list.xml", "layouts/_default/category.terms.rss.xml", "layouts/_default/terms.rss.xml", "layouts/_default/rss.xml", "layouts/_default/list.rss.xml", "layouts/_default/category.terms.xml", "layouts/_default/terms.xml", "layouts/_default/list.xml", "layouts/_internal/_default/rss.xml" ] }, { "Example": "Section list for \"posts\" section", "Kind": "section", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/posts/posts.html.html", "layouts/posts/section.html.html", "layouts/posts/list.html.html", "layouts/posts/posts.html", "layouts/posts/section.html", "layouts/posts/list.html", "layouts/section/posts.html.html", "layouts/section/section.html.html", "layouts/section/list.html.html", "layouts/section/posts.html", "layouts/section/section.html", "layouts/section/list.html", "layouts/_default/posts.html.html", "layouts/_default/section.html.html", "layouts/_default/list.html.html", "layouts/_default/posts.html", "layouts/_default/section.html", "layouts/_default/list.html" ] }, { "Example": "Section list for \"posts\" section with type set to \"blog\"", "Kind": "section", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/blog/posts.html.html", "layouts/blog/section.html.html", "layouts/blog/list.html.html", "layouts/blog/posts.html", "layouts/blog/section.html", "layouts/blog/list.html", "layouts/posts/posts.html.html", "layouts/posts/section.html.html", "layouts/posts/list.html.html", "layouts/posts/posts.html", "layouts/posts/section.html", "layouts/posts/list.html", "layouts/section/posts.html.html", "layouts/section/section.html.html", "layouts/section/list.html.html", "layouts/section/posts.html", "layouts/section/section.html", "layouts/section/list.html", "layouts/_default/posts.html.html", "layouts/_default/section.html.html", "layouts/_default/list.html.html", "layouts/_default/posts.html", "layouts/_default/section.html", "layouts/_default/list.html" ] }, { "Example": "Section list for \"posts\" section with layout set to \"demoLayout\"", "Kind": "section", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/posts/demolayout.html.html", "layouts/posts/posts.html.html", "layouts/posts/section.html.html", "layouts/posts/list.html.html", "layouts/posts/demolayout.html", "layouts/posts/posts.html", "layouts/posts/section.html", "layouts/posts/list.html", "layouts/section/demolayout.html.html", "layouts/section/posts.html.html", "layouts/section/section.html.html", "layouts/section/list.html.html", "layouts/section/demolayout.html", "layouts/section/posts.html", "layouts/section/section.html", "layouts/section/list.html", "layouts/_default/demolayout.html.html", "layouts/_default/posts.html.html", "layouts/_default/section.html.html", "layouts/_default/list.html.html", "layouts/_default/demolayout.html", "layouts/_default/posts.html", "layouts/_default/section.html", "layouts/_default/list.html" ] }, { "Example": "Taxonomy list in categories", "Kind": "taxonomy", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/categories/category.html.html", "layouts/categories/taxonomy.html.html", "layouts/categories/list.html.html", "layouts/categories/category.html", "layouts/categories/taxonomy.html", "layouts/categories/list.html", "layouts/taxonomy/category.html.html", "layouts/taxonomy/taxonomy.html.html", "layouts/taxonomy/list.html.html", "layouts/taxonomy/category.html", "layouts/taxonomy/taxonomy.html", "layouts/taxonomy/list.html", "layouts/category/category.html.html", "layouts/category/taxonomy.html.html", "layouts/category/list.html.html", "layouts/category/category.html", "layouts/category/taxonomy.html", "layouts/category/list.html", "layouts/_default/category.html.html", "layouts/_default/taxonomy.html.html", "layouts/_default/list.html.html", "layouts/_default/category.html", "layouts/_default/taxonomy.html", "layouts/_default/list.html" ] }, { "Example": "Taxonomy term in categories", "Kind": "taxonomyTerm", "OutputFormat": "HTML", "Suffix": "html", "Template Lookup Order": [ "layouts/categories/category.terms.html.html", "layouts/categories/terms.html.html", "layouts/categories/list.html.html", "layouts/categories/category.terms.html", "layouts/categories/terms.html", "layouts/categories/list.html", "layouts/taxonomy/category.terms.html.html", "layouts/taxonomy/terms.html.html", "layouts/taxonomy/list.html.html", "layouts/taxonomy/category.terms.html", "layouts/taxonomy/terms.html", "layouts/taxonomy/list.html", "layouts/category/category.terms.html.html", "layouts/category/terms.html.html", "layouts/category/list.html.html", "layouts/category/category.terms.html", "layouts/category/terms.html", "layouts/category/list.html", "layouts/_default/category.terms.html.html", "layouts/_default/terms.html.html", "layouts/_default/list.html.html", "layouts/_default/category.terms.html", "layouts/_default/terms.html", "layouts/_default/list.html" ] } ] }, "tpl": { "funcs": { "cast": { "ToFloat": { "Description": "ToFloat converts the given value to a float.", "Args": [ "v" ], "Aliases": [ "float" ], "Examples": [ [ "{{ \"1234\" | float | printf \"%T\" }}", "float64" ] ] }, "ToInt": { "Description": "ToInt converts the given value to an int.", "Args": [ "v" ], "Aliases": [ "int" ], "Examples": [ [ "{{ \"1234\" | int | printf \"%T\" }}", "int" ] ] }, "ToString": { "Description": "ToString converts the given value to a string.", "Args": [ "v" ], "Aliases": [ "string" ], "Examples": [ [ "{{ 1234 | string | printf \"%T\" }}", "string" ] ] } }, "compare": { "Conditional": { "Description": "Conditional can be used as a ternary operator.\nIt returns a if condition, else b.", "Args": [ "condition", "a", "b" ], "Aliases": [ "cond" ], "Examples": [ [ "{{ cond (eq (add 2 2) 4) \"2+2 is 4\" \"what?\" | safeHTML }}", "2+2 is 4" ] ] }, "Default": { "Description": "Default checks whether a given value is set and returns a default value if it\nis not. \"Set\" in this context means non-zero for numeric types and times;\nnon-zero length for strings, arrays, slices, and maps;\nany boolean or struct value; or non-nil for any other types.", "Args": [ "dflt", "given" ], "Aliases": [ "default" ], "Examples": [ [ "{{ \"Hugo Rocks!\" | default \"Hugo Rules!\" }}", "Hugo Rocks!" ], [ "{{ \"\" | default \"Hugo Rules!\" }}", "Hugo Rules!" ] ] }, "Eq": { "Description": "Eq returns the boolean truth of arg1 == arg2 || arg1 == arg3 || arg1 == arg4.", "Args": [ "first", "others" ], "Aliases": [ "eq" ], "Examples": [ [ "{{ if eq .Section \"blog\" }}current{{ end }}", "current" ] ] }, "Ge": { "Description": "Ge returns the boolean truth of arg1 \u003e= arg2 \u0026\u0026 arg1 \u003e= arg3 \u0026\u0026 arg1 \u003e= arg4.", "Args": [ "first", "others" ], "Aliases": [ "ge" ], "Examples": [ [ "{{ if ge .Hugo.Version \"0.36\" }}Reasonable new Hugo version!{{ end }}", "Reasonable new Hugo version!" ] ] }, "Gt": { "Description": "Gt returns the boolean truth of arg1 \u003e arg2 \u0026\u0026 arg1 \u003e arg3 \u0026\u0026 arg1 \u003e arg4.", "Args": [ "first", "others" ], "Aliases": [ "gt" ], "Examples": [] }, "Le": { "Description": "Le returns the boolean truth of arg1 \u003c= arg2 \u0026\u0026 arg1 \u003c= arg3 \u0026\u0026 arg1 \u003c= arg4.", "Args": [ "first", "others" ], "Aliases": [ "le" ], "Examples": [] }, "Lt": { "Description": "Lt returns the boolean truth of arg1 \u003c arg2 \u0026\u0026 arg1 \u003c arg3 \u0026\u0026 arg1 \u003c arg4.", "Args": [ "first", "others" ], "Aliases": [ "lt" ], "Examples": [] }, "Ne": { "Description": "Ne returns the boolean truth of arg1 != arg2 \u0026\u0026 arg1 != arg3 \u0026\u0026 arg1 != arg4.", "Args": [ "first", "others" ], "Aliases": [ "ne" ], "Examples": [] } }, "collections": { "After": { "Description": "After returns all the items after the first N in a rangeable list.", "Args": [ "index", "seq" ], "Aliases": [ "after" ], "Examples": [] }, "Append": { "Description": "Append appends the arguments up to the last one to the slice in the last argument.\nThis construct allows template constructs like this:\n {{ $pages = $pages | append $p2 $p1 }}\nNote that with 2 arguments where both are slices of the same type,\nthe first slice will be appended to the second:\n {{ $pages = $pages | append .Site.RegularPages }}", "Args": [ "args" ], "Aliases": [ "append" ], "Examples": [] }, "Apply": { "Description": "Apply takes a map, array, or slice and returns a new slice with the function fname applied over it.", "Args": [ "seq", "fname", "args" ], "Aliases": [ "apply" ], "Examples": [] }, "Complement": { "Description": "Complement gives the elements in the last element of seqs that are not in\nany of the others.\nAll elements of seqs must be slices or arrays of comparable types.\n\nThe reasoning behind this rather clumsy API is so we can do this in the templates:\n {{ $c := .Pages | complement $last4 }}", "Args": [ "seqs" ], "Aliases": [ "complement" ], "Examples": [ [ "{{ slice \"a\" \"b\" \"c\" \"d\" \"e\" \"f\" | complement (slice \"b\" \"c\") (slice \"d\" \"e\") }}", "[a f]" ] ] }, "Delimit": { "Description": "Delimit takes a given sequence and returns a delimited HTML string.\nIf last is passed to the function, it will be used as the final delimiter.", "Args": [ "seq", "delimiter", "last" ], "Aliases": [ "delimit" ], "Examples": [ [ "{{ delimit (slice \"A\" \"B\" \"C\") \", \" \" and \" }}", "A, B and C" ] ] }, "Dictionary": { "Description": "Dictionary creates a map[string]interface{} from the given parameters by\nwalking the parameters and treating them as key-value pairs. The number\nof parameters must be even.\nThe keys can be string slices, which will create the needed nested structure.", "Args": [ "values" ], "Aliases": [ "dict" ], "Examples": [] }, "EchoParam": { "Description": "EchoParam returns a given value if it is set; otherwise, it returns an\nempty string.", "Args": [ "a", "key" ], "Aliases": [ "echoParam" ], "Examples": [ [ "{{ echoParam .Params \"langCode\" }}", "en" ] ] }, "First": { "Description": "First returns the first N items in a rangeable list.", "Args": [ "limit", "seq" ], "Aliases": [ "first" ], "Examples": [] }, "Group": { "Description": "Group groups a set of elements by the given key.\nThis is currently only supported for Pages.", "Args": [ "key", "items" ], "Aliases": [ "group" ], "Examples": [] }, "In": { "Description": "In returns whether v is in the set l. l may be an array or slice.", "Args": [ "l", "v" ], "Aliases": [ "in" ], "Examples": [ [ "{{ if in \"this string contains a substring\" \"substring\" }}Substring found!{{ end }}", "Substring found!" ] ] }, "Index": { "Description": "Index returns the result of indexing its first argument by the following\narguments. Thus \"index x 1 2 3\" is, in Go syntax, x[1][2][3]. Each\nindexed item must be a map, slice, or array.\n\nCopied from Go stdlib src/text/template/funcs.go.\n\nWe deviate from the stdlib due to https://github.com/golang/go/issues/14751.\n\nTODO(moorereason): merge upstream changes.", "Args": [ "item", "args" ], "Aliases": [ "index" ], "Examples": [] }, "Intersect": { "Description": "Intersect returns the common elements in the given sets, l1 and l2. l1 and\nl2 must be of the same type and may be either arrays or slices.", "Args": [ "l1", "l2" ], "Aliases": [ "intersect" ], "Examples": [] }, "IsSet": { "Description": "IsSet returns whether a given array, channel, slice, or map has a key\ndefined.", "Args": [ "a", "key" ], "Aliases": [ "isSet", "isset" ], "Examples": [] }, "KeyVals": { "Description": "KeyVals creates a key and values wrapper.", "Args": [ "key", "vals" ], "Aliases": [ "keyVals" ], "Examples": [ [ "{{ keyVals \"key\" \"a\" \"b\" }}", "key: [a b]" ] ] }, "Last": { "Description": "Last returns the last N items in a rangeable list.", "Args": [ "limit", "seq" ], "Aliases": [ "last" ], "Examples": [] }, "Merge": { "Description": "Merge creates a copy of dst and merges src into it.\nCurrently only maps supported. Key handling is case insensitive.", "Args": [ "src", "dst" ], "Aliases": [ "merge" ], "Examples": [ [ "{{ dict \"title\" \"Hugo Rocks!\" | collections.Merge (dict \"title\" \"Default Title\" \"description\" \"Yes, Hugo Rocks!\") | sort }}", "[Yes, Hugo Rocks! Hugo Rocks!]" ], [ "{{ merge (dict \"title\" \"Default Title\" \"description\" \"Yes, Hugo Rocks!\") (dict \"title\" \"Hugo Rocks!\") | sort }}", "[Yes, Hugo Rocks! Hugo Rocks!]" ] ] }, "NewScratch": { "Description": "NewScratch creates a new Scratch which can be used to store values in a\nthread safe way.", "Args": null, "Aliases": [ "newScratch" ], "Examples": [ [ "{{ $scratch := newScratch }}{{ $scratch.Add \"b\" 2 }}{{ $scratch.Add \"b\" 2 }}{{ $scratch.Get \"b\" }}", "4" ] ] }, "Querify": { "Description": "Querify encodes the given parameters in URL-encoded form (\"bar=baz\u0026foo=quux\") sorted by key.", "Args": [ "params" ], "Aliases": [ "querify" ], "Examples": [ [ "{{ (querify \"foo\" 1 \"bar\" 2 \"baz\" \"with spaces\" \"qux\" \"this\u0026that=those\") | safeHTML }}", "bar=2\u0026baz=with+spaces\u0026foo=1\u0026qux=this%26that%3Dthose" ], [ "\u003ca href=\"https://www.google.com?{{ (querify \"q\" \"test\" \"page\" 3) | safeURL }}\"\u003eSearch\u003c/a\u003e", "\u003ca href=\"https://www.google.com?page=3\u0026amp;q=test\"\u003eSearch\u003c/a\u003e" ] ] }, "Reverse": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Seq": { "Description": "Seq creates a sequence of integers. It's named and used as GNU's seq.\n\nExamples:\n 3 =\u003e 1, 2, 3\n 1 2 4 =\u003e 1, 3\n -3 =\u003e -1, -2, -3\n 1 4 =\u003e 1, 2, 3, 4\n 1 -2 =\u003e 1, 0, -1, -2", "Args": [ "args" ], "Aliases": [ "seq" ], "Examples": [ [ "{{ seq 3 }}", "[1 2 3]" ] ] }, "Shuffle": { "Description": "Shuffle returns the given rangeable list in a randomised order.", "Args": [ "seq" ], "Aliases": [ "shuffle" ], "Examples": [] }, "Slice": { "Description": "Slice returns a slice of all passed arguments.", "Args": [ "args" ], "Aliases": [ "slice" ], "Examples": [ [ "{{ slice \"B\" \"C\" \"A\" | sort }}", "[A B C]" ] ] }, "Sort": { "Description": "Sort returns a sorted sequence.", "Args": [ "seq", "args" ], "Aliases": [ "sort" ], "Examples": [] }, "SymDiff": { "Description": "SymDiff returns the symmetric difference of s1 and s2.\nArguments must be either a slice or an array of comparable types.", "Args": [ "s2", "s1" ], "Aliases": [ "symdiff" ], "Examples": [ [ "{{ slice 1 2 3 | symdiff (slice 3 4) }}", "[1 2 4]" ] ] }, "Union": { "Description": "Union returns the union of the given sets, l1 and l2. l1 and\nl2 must be of the same type and may be either arrays or slices.\nIf l1 and l2 aren't of the same type then l1 will be returned.\nIf either l1 or l2 is nil then the non-nil list will be returned.", "Args": [ "l1", "l2" ], "Aliases": [ "union" ], "Examples": [ [ "{{ union (slice 1 2 3) (slice 3 4 5) }}", "[1 2 3 4 5]" ] ] }, "Uniq": { "Description": "Uniq takes in a slice or array and returns a slice with subsequent\nduplicate elements removed.", "Args": [ "seq" ], "Aliases": [ "uniq" ], "Examples": [ [ "{{ slice 1 2 3 2 | uniq }}", "[1 2 3]" ] ] }, "Where": { "Description": "Where returns a filtered subset of a given data type.", "Args": [ "seq", "key", "args" ], "Aliases": [ "where" ], "Examples": [] } }, "crypto": { "MD5": { "Description": "MD5 hashes the given input and returns its MD5 checksum.", "Args": [ "in" ], "Aliases": [ "md5" ], "Examples": [ [ "{{ md5 \"Hello world, gophers!\" }}", "b3029f756f98f79e7f1b7f1d1f0dd53b" ], [ "{{ crypto.MD5 \"Hello world, gophers!\" }}", "b3029f756f98f79e7f1b7f1d1f0dd53b" ] ] }, "SHA1": { "Description": "SHA1 hashes the given input and returns its SHA1 checksum.", "Args": [ "in" ], "Aliases": [ "sha1" ], "Examples": [ [ "{{ sha1 \"Hello world, gophers!\" }}", "c8b5b0e33d408246e30f53e32b8f7627a7a649d4" ] ] }, "SHA256": { "Description": "SHA256 hashes the given input and returns its SHA256 checksum.", "Args": [ "in" ], "Aliases": [ "sha256" ], "Examples": [ [ "{{ sha256 \"Hello world, gophers!\" }}", "6ec43b78da9669f50e4e422575c54bf87536954ccd58280219c393f2ce352b46" ] ] } }, "data": { "GetCSV": { "Description": "GetCSV expects a data separator and one or n-parts of a URL to a resource which\ncan either be a local or a remote one.\nThe data separator can be a comma, semi-colon, pipe, etc, but only one character.\nIf you provide multiple parts for the URL they will be joined together to the final URL.\nGetCSV returns nil or a slice slice to use in a short code.", "Args": [ "sep", "urlParts" ], "Aliases": [ "getCSV" ], "Examples": [] }, "GetJSON": { "Description": "GetJSON expects one or n-parts of a URL to a resource which can either be a local or a remote one.\nIf you provide multiple parts they will be joined together to the final URL.\nGetJSON returns nil or parsed JSON to use in a short code.", "Args": [ "urlParts" ], "Aliases": [ "getJSON" ], "Examples": [] } }, "encoding": { "Base64Decode": { "Description": "Base64Decode returns the base64 decoding of the given content.", "Args": [ "content" ], "Aliases": [ "base64Decode" ], "Examples": [ [ "{{ \"SGVsbG8gd29ybGQ=\" | base64Decode }}", "Hello world" ], [ "{{ 42 | base64Encode | base64Decode }}", "42" ] ] }, "Base64Encode": { "Description": "Base64Encode returns the base64 encoding of the given content.", "Args": [ "content" ], "Aliases": [ "base64Encode" ], "Examples": [ [ "{{ \"Hello world\" | base64Encode }}", "SGVsbG8gd29ybGQ=" ] ] }, "Jsonify": { "Description": "Jsonify encodes a given object to JSON.", "Args": [ "v" ], "Aliases": [ "jsonify" ], "Examples": [ [ "{{ (slice \"A\" \"B\" \"C\") | jsonify }}", "[\"A\",\"B\",\"C\"]" ] ] } }, "fmt": { "Errorf": { "Description": "Errorf formats according to a format specifier and logs an ERROR.\nIt returns an empty string.", "Args": [ "format", "a" ], "Aliases": [ "errorf" ], "Examples": [ [ "{{ errorf \"%s.\" \"failed\" }}", "" ] ] }, "Print": { "Description": "Print returns string representation of the passed arguments.", "Args": [ "a" ], "Aliases": [ "print" ], "Examples": [ [ "{{ print \"works!\" }}", "works!" ] ] }, "Printf": { "Description": "Printf returns a formatted string representation of the passed arguments.", "Args": [ "format", "a" ], "Aliases": [ "printf" ], "Examples": [ [ "{{ printf \"%s!\" \"works\" }}", "works!" ] ] }, "Println": { "Description": "Println returns string representation of the passed arguments ending with a newline.", "Args": [ "a" ], "Aliases": [ "println" ], "Examples": [ [ "{{ println \"works!\" }}", "works!\n" ] ] }, "Warnf": { "Description": "Warnf formats according to a format specifier and logs a WARNING.\nIt returns an empty string.", "Args": [ "format", "a" ], "Aliases": [ "warnf" ], "Examples": [ [ "{{ warnf \"%s.\" \"warning\" }}", "" ] ] } }, "hugo": { "Generator": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "IsProduction": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Version": { "Description": "", "Args": null, "Aliases": null, "Examples": null } }, "images": { "Brightness": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "ColorBalance": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Colorize": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Config": { "Description": "Config returns the image.Config for the specified path relative to the\nworking directory.", "Args": [ "path" ], "Aliases": [ "imageConfig" ], "Examples": [] }, "Contrast": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Filter": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Gamma": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "GaussianBlur": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Grayscale": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Hue": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Invert": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Pixelate": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Saturation": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Sepia": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Sigmoid": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "UnsharpMask": { "Description": "", "Args": null, "Aliases": null, "Examples": null } }, "inflect": { "Humanize": { "Description": "Humanize returns the humanized form of a single parameter.\n\nIf the parameter is either an integer or a string containing an integer\nvalue, the behavior is to add the appropriate ordinal.\n\n Example: \"my-first-post\" -\u003e \"My first post\"\n Example: \"103\" -\u003e \"103rd\"\n Example: 52 -\u003e \"52nd\"", "Args": [ "in" ], "Aliases": [ "humanize" ], "Examples": [ [ "{{ humanize \"my-first-post\" }}", "My first post" ], [ "{{ humanize \"myCamelPost\" }}", "My camel post" ], [ "{{ humanize \"52\" }}", "52nd" ], [ "{{ humanize 103 }}", "103rd" ] ] }, "Pluralize": { "Description": "Pluralize returns the plural form of a single word.", "Args": [ "in" ], "Aliases": [ "pluralize" ], "Examples": [ [ "{{ \"cat\" | pluralize }}", "cats" ] ] }, "Singularize": { "Description": "Singularize returns the singular form of a single word.", "Args": [ "in" ], "Aliases": [ "singularize" ], "Examples": [ [ "{{ \"cats\" | singularize }}", "cat" ] ] } }, "lang": { "Merge": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "NumFmt": { "Description": "NumFmt formats a number with the given precision using the\nnegative, decimal, and grouping options. The `options`\nparameter is a string consisting of `\u003cnegative\u003e \u003cdecimal\u003e \u003cgrouping\u003e`. The\ndefault `options` value is `- . ,`.\n\nNote that numbers are rounded up at 5 or greater.\nSo, with precision set to 0, 1.5 becomes `2`, and 1.4 becomes `1`.", "Args": [ "precision", "number", "options" ], "Aliases": null, "Examples": [ [ "{{ lang.NumFmt 2 12345.6789 }}", "12,345.68" ], [ "{{ lang.NumFmt 2 12345.6789 \"- , .\" }}", "12.345,68" ], [ "{{ lang.NumFmt 6 -12345.6789 \"- .\" }}", "-12345.678900" ], [ "{{ lang.NumFmt 0 -12345.6789 \"- . ,\" }}", "-12,346" ], [ "{{ -98765.4321 | lang.NumFmt 2 }}", "-98,765.43" ] ] }, "Translate": { "Description": "Translate returns a translated string for id.", "Args": [ "id", "args" ], "Aliases": [ "i18n", "T" ], "Examples": [] } }, "math": { "Add": { "Description": "Add adds two numbers.", "Args": [ "a", "b" ], "Aliases": [ "add" ], "Examples": [ [ "{{add 1 2}}", "3" ] ] }, "Ceil": { "Description": "Ceil returns the least integer value greater than or equal to x.", "Args": [ "x" ], "Aliases": null, "Examples": [ [ "{{math.Ceil 2.1}}", "3" ] ] }, "Div": { "Description": "Div divides two numbers.", "Args": [ "a", "b" ], "Aliases": [ "div" ], "Examples": [ [ "{{div 6 3}}", "2" ] ] }, "Floor": { "Description": "Floor returns the greatest integer value less than or equal to x.", "Args": [ "x" ], "Aliases": null, "Examples": [ [ "{{math.Floor 1.9}}", "1" ] ] }, "Log": { "Description": "Log returns the natural logarithm of a number.", "Args": [ "a" ], "Aliases": null, "Examples": [ [ "{{math.Log 1}}", "0" ] ] }, "Mod": { "Description": "Mod returns a % b.", "Args": [ "a", "b" ], "Aliases": [ "mod" ], "Examples": [ [ "{{mod 15 3}}", "0" ] ] }, "ModBool": { "Description": "ModBool returns the boolean of a % b. If a % b == 0, return true.", "Args": [ "a", "b" ], "Aliases": [ "modBool" ], "Examples": [ [ "{{modBool 15 3}}", "true" ] ] }, "Mul": { "Description": "Mul multiplies two numbers.", "Args": [ "a", "b" ], "Aliases": [ "mul" ], "Examples": [ [ "{{mul 2 3}}", "6" ] ] }, "Round": { "Description": "Round returns the nearest integer, rounding half away from zero.", "Args": [ "x" ], "Aliases": null, "Examples": [ [ "{{math.Round 1.5}}", "2" ] ] }, "Sqrt": { "Description": "Sqrt returns the square root of a number.\nNOTE: will return for NaN for negative values of a", "Args": [ "a" ], "Aliases": null, "Examples": [ [ "{{math.Sqrt 81}}", "9" ] ] }, "Sub": { "Description": "Sub subtracts two numbers.", "Args": [ "a", "b" ], "Aliases": [ "sub" ], "Examples": [ [ "{{sub 3 2}}", "1" ] ] } }, "os": { "FileExists": { "Description": "FileExists checks whether a file exists under the given path.", "Args": [ "i" ], "Aliases": [ "fileExists" ], "Examples": [ [ "{{ fileExists \"foo.txt\" }}", "false" ] ] }, "Getenv": { "Description": "Getenv retrieves the value of the environment variable named by the key.\nIt returns the value, which will be empty if the variable is not present.", "Args": [ "key" ], "Aliases": [ "getenv" ], "Examples": [] }, "ReadDir": { "Description": "ReadDir lists the directory contents relative to the configured WorkingDir.", "Args": [ "i" ], "Aliases": [ "readDir" ], "Examples": [ [ "{{ range (readDir \"files\") }}{{ .Name }}{{ end }}", "README.txt" ] ] }, "ReadFile": { "Description": "ReadFile reads the file named by filename relative to the configured WorkingDir.\nIt returns the contents as a string.\nThere is an upper size limit set at 1 megabytes.", "Args": [ "i" ], "Aliases": [ "readFile" ], "Examples": [ [ "{{ readFile \"files/README.txt\" }}", "Hugo Rocks!" ] ] }, "Stat": { "Description": "", "Args": null, "Aliases": null, "Examples": null } }, "partials": { "Include": { "Description": "Include executes the named partial.\nIf the partial contains a return statement, that value will be returned.\nElse, the rendered output will be returned:\nA string if the partial is a text/template, or template.HTML when html/template.", "Args": [ "name", "contextList" ], "Aliases": [ "partial" ], "Examples": [ [ "{{ partial \"header.html\" . }}", "\u003ctitle\u003eHugo Rocks!\u003c/title\u003e" ] ] }, "IncludeCached": { "Description": "IncludeCached executes and caches partial templates. The cache is created with name+variants as the key.", "Args": [ "name", "context", "variants" ], "Aliases": [ "partialCached" ], "Examples": [] } }, "path": { "Base": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Dir": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Ext": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Join": { "Description": "Join joins any number of path elements into a single path, adding a\nseparating slash if necessary. All the input\npath elements are passed into filepath.ToSlash converting any Windows slashes\nto forward slashes.\nThe result is Cleaned; in particular,\nall empty strings are ignored.", "Args": [ "elements" ], "Aliases": null, "Examples": [ [ "{{ slice \"my/path\" \"filename.txt\" | path.Join }}", "my/path/filename.txt" ], [ "{{ path.Join \"my\" \"path\" \"filename.txt\" }}", "my/path/filename.txt" ], [ "{{ \"my/path/filename.txt\" | path.Ext }}", ".txt" ], [ "{{ \"my/path/filename.txt\" | path.Base }}", "filename.txt" ], [ "{{ \"my/path/filename.txt\" | path.Dir }}", "my/path" ] ] }, "Split": { "Description": "Split splits path immediately following the final slash,\nseparating it into a directory and file name component.\nIf there is no slash in path, Split returns an empty dir and\nfile set to path.\nThe input path is passed into filepath.ToSlash converting any Windows slashes\nto forward slashes.\nThe returned values have the property that path = dir+file.", "Args": [ "path" ], "Aliases": null, "Examples": [ [ "{{ \"/my/path/filename.txt\" | path.Split }}", "/my/path/|filename.txt" ], [ "{{ \"/my/path/filename.txt\" | path.Split }}", "/my/path/|filename.txt" ] ] } }, "reflect": { "IsMap": { "Description": "IsMap reports whether v is a map.", "Args": [ "v" ], "Aliases": null, "Examples": [ [ "{{ if reflect.IsMap (dict \"a\" 1) }}Map{{ end }}", "Map" ] ] }, "IsSlice": { "Description": "IsSlice reports whether v is a slice.", "Args": [ "v" ], "Aliases": null, "Examples": [ [ "{{ if reflect.IsSlice (slice 1 2 3) }}Slice{{ end }}", "Slice" ] ] } }, "resources": { "Concat": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "ExecuteAsTemplate": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Fingerprint": { "Description": "Fingerprint transforms the given Resource with a MD5 hash of the content in\nthe RelPermalink and Permalink.", "Args": [ "args" ], "Aliases": [ "fingerprint" ], "Examples": [] }, "FromString": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Get": { "Description": "Get locates the filename given in Hugo's assets filesystem\nand creates a Resource object that can be used for further transformations.", "Args": [ "filename" ], "Aliases": null, "Examples": [] }, "GetMatch": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Match": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Minify": { "Description": "Minify minifies the given Resource using the MediaType to pick the correct\nminifier.", "Args": [ "r" ], "Aliases": [ "minify" ], "Examples": [] }, "PostCSS": { "Description": "PostCSS processes the given Resource with PostCSS", "Args": [ "args" ], "Aliases": [ "postCSS" ], "Examples": [] }, "ToCSS": { "Description": "ToCSS converts the given Resource to CSS. You can optional provide an Options\nobject or a target path (string) as first argument.", "Args": [ "args" ], "Aliases": [ "toCSS" ], "Examples": [] } }, "safe": { "CSS": { "Description": "CSS returns a given string as html/template CSS content.", "Args": [ "a" ], "Aliases": [ "safeCSS" ], "Examples": [ [ "{{ \"Bat\u0026Man\" | safeCSS | safeCSS }}", "Bat\u0026amp;Man" ] ] }, "HTML": { "Description": "HTML returns a given string as html/template HTML content.", "Args": [ "a" ], "Aliases": [ "safeHTML" ], "Examples": [ [ "{{ \"Bat\u0026Man\" | safeHTML | safeHTML }}", "Bat\u0026Man" ], [ "{{ \"Bat\u0026Man\" | safeHTML }}", "Bat\u0026Man" ] ] }, "HTMLAttr": { "Description": "HTMLAttr returns a given string as html/template HTMLAttr content.", "Args": [ "a" ], "Aliases": [ "safeHTMLAttr" ], "Examples": [] }, "JS": { "Description": "JS returns the given string as a html/template JS content.", "Args": [ "a" ], "Aliases": [ "safeJS" ], "Examples": [ [ "{{ \"(1*2)\" | safeJS | safeJS }}", "(1*2)" ] ] }, "JSStr": { "Description": "JSStr returns the given string as a html/template JSStr content.", "Args": [ "a" ], "Aliases": [ "safeJSStr" ], "Examples": [] }, "SanitizeURL": { "Description": "SanitizeURL returns a given string as html/template URL content.", "Args": [ "a" ], "Aliases": [ "sanitizeURL", "sanitizeurl" ], "Examples": [] }, "URL": { "Description": "URL returns a given string as html/template URL content.", "Args": [ "a" ], "Aliases": [ "safeURL" ], "Examples": [ [ "{{ \"http://gohugo.io\" | safeURL | safeURL }}", "http://gohugo.io" ] ] } }, "site": { "BaseURL": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Data": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Hugo": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "IsServer": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Language": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "LastChange": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Menus": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Pages": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Params": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "RegularPages": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "ServerPort": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Sites": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Taxonomies": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Title": { "Description": "", "Args": null, "Aliases": null, "Examples": null } }, "strings": { "Chomp": { "Description": "Chomp returns a copy of s with all trailing newline characters removed.", "Args": [ "s" ], "Aliases": [ "chomp" ], "Examples": [ [ "{{chomp \"\u003cp\u003eBlockhead\u003c/p\u003e\\n\" | safeHTML }}", "\u003cp\u003eBlockhead\u003c/p\u003e" ] ] }, "Contains": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "ContainsAny": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "CountRunes": { "Description": "CountRunes returns the number of runes in s, excluding whitepace.", "Args": [ "s" ], "Aliases": [ "countrunes" ], "Examples": [] }, "CountWords": { "Description": "CountWords returns the approximate word count in s.", "Args": [ "s" ], "Aliases": [ "countwords" ], "Examples": [] }, "FindRE": { "Description": "FindRE returns a list of strings that match the regular expression. By default all matches\nwill be included. The number of matches can be limited with an optional third parameter.", "Args": [ "expr", "content", "limit" ], "Aliases": [ "findRE" ], "Examples": [ [ "{{ findRE \"[G|g]o\" \"Hugo is a static side generator written in Go.\" \"1\" }}", "[go]" ] ] }, "FirstUpper": { "Description": "FirstUpper returns a string with the first character as upper case.", "Args": [ "s" ], "Aliases": null, "Examples": [ [ "{{ \"hugo rocks!\" | strings.FirstUpper }}", "Hugo rocks!" ] ] }, "HasPrefix": { "Description": "HasPrefix tests whether the input s begins with prefix.", "Args": [ "s", "prefix" ], "Aliases": [ "hasPrefix" ], "Examples": [ [ "{{ hasPrefix \"Hugo\" \"Hu\" }}", "true" ], [ "{{ hasPrefix \"Hugo\" \"Fu\" }}", "false" ] ] }, "HasSuffix": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Repeat": { "Description": "Repeat returns a new string consisting of count copies of the string s.", "Args": [ "n", "s" ], "Aliases": null, "Examples": [ [ "{{ \"yo\" | strings.Repeat 4 }}", "yoyoyoyo" ] ] }, "Replace": { "Description": "Replace returns a copy of the string s with all occurrences of old replaced\nwith new.", "Args": [ "s", "old", "new" ], "Aliases": [ "replace" ], "Examples": [ [ "{{ replace \"Batman and Robin\" \"Robin\" \"Catwoman\" }}", "Batman and Catwoman" ] ] }, "ReplaceRE": { "Description": "ReplaceRE returns a copy of s, replacing all matches of the regular\nexpression pattern with the replacement text repl.", "Args": [ "pattern", "repl", "s" ], "Aliases": [ "replaceRE" ], "Examples": [] }, "RuneCount": { "Description": "RuneCount returns the number of runes in s.", "Args": [ "s" ], "Aliases": null, "Examples": [] }, "SliceString": { "Description": "SliceString slices a string by specifying a half-open range with\ntwo indices, start and end. 1 and 4 creates a slice including elements 1 through 3.\nThe end index can be omitted, it defaults to the string's length.", "Args": [ "a", "startEnd" ], "Aliases": [ "slicestr" ], "Examples": [ [ "{{slicestr \"BatMan\" 0 3}}", "Bat" ], [ "{{slicestr \"BatMan\" 3}}", "Man" ] ] }, "Split": { "Description": "Split slices an input string into all substrings separated by delimiter.", "Args": [ "a", "delimiter" ], "Aliases": [ "split" ], "Examples": [] }, "Substr": { "Description": "Substr extracts parts of a string, beginning at the character at the specified\nposition, and returns the specified number of characters.\n\nIt normally takes two parameters: start and length.\nIt can also take one parameter: start, i.e. length is omitted, in which case\nthe substring starting from start until the end of the string will be returned.\n\nTo extract characters from the end of the string, use a negative start number.\n\nIn addition, borrowing from the extended behavior described at http://php.net/substr,\nif length is given and is negative, then that many characters will be omitted from\nthe end of string.", "Args": [ "a", "nums" ], "Aliases": [ "substr" ], "Examples": [ [ "{{substr \"BatMan\" 0 -3}}", "Bat" ], [ "{{substr \"BatMan\" 3 3}}", "Man" ] ] }, "Title": { "Description": "Title returns a copy of the input s with all Unicode letters that begin words\nmapped to their title case.", "Args": [ "s" ], "Aliases": [ "title" ], "Examples": [ [ "{{title \"Bat man\"}}", "Bat Man" ], [ "{{title \"somewhere over the rainbow\"}}", "Somewhere Over the Rainbow" ] ] }, "ToLower": { "Description": "ToLower returns a copy of the input s with all Unicode letters mapped to their\nlower case.", "Args": [ "s" ], "Aliases": [ "lower" ], "Examples": [ [ "{{lower \"BatMan\"}}", "batman" ] ] }, "ToUpper": { "Description": "ToUpper returns a copy of the input s with all Unicode letters mapped to their\nupper case.", "Args": [ "s" ], "Aliases": [ "upper" ], "Examples": [ [ "{{upper \"BatMan\"}}", "BATMAN" ] ] }, "Trim": { "Description": "Trim returns a string with all leading and trailing characters defined\ncontained in cutset removed.", "Args": [ "s", "cutset" ], "Aliases": [ "trim" ], "Examples": [ [ "{{ trim \"++Batman--\" \"+-\" }}", "Batman" ] ] }, "TrimLeft": { "Description": "TrimLeft returns a slice of the string s with all leading characters\ncontained in cutset removed.", "Args": [ "cutset", "s" ], "Aliases": null, "Examples": [ [ "{{ \"aabbaa\" | strings.TrimLeft \"a\" }}", "bbaa" ] ] }, "TrimPrefix": { "Description": "TrimPrefix returns s without the provided leading prefix string. If s doesn't\nstart with prefix, s is returned unchanged.", "Args": [ "prefix", "s" ], "Aliases": null, "Examples": [ [ "{{ \"aabbaa\" | strings.TrimPrefix \"a\" }}", "abbaa" ], [ "{{ \"aabbaa\" | strings.TrimPrefix \"aa\" }}", "bbaa" ] ] }, "TrimRight": { "Description": "TrimRight returns a slice of the string s with all trailing characters\ncontained in cutset removed.", "Args": [ "cutset", "s" ], "Aliases": null, "Examples": [ [ "{{ \"aabbaa\" | strings.TrimRight \"a\" }}", "aabb" ] ] }, "TrimSuffix": { "Description": "TrimSuffix returns s without the provided trailing suffix string. If s\ndoesn't end with suffix, s is returned unchanged.", "Args": [ "suffix", "s" ], "Aliases": null, "Examples": [ [ "{{ \"aabbaa\" | strings.TrimSuffix \"a\" }}", "aabba" ], [ "{{ \"aabbaa\" | strings.TrimSuffix \"aa\" }}", "aabb" ] ] }, "Truncate": { "Description": "Truncate truncates a given string to the specified length.", "Args": [ "a", "options" ], "Aliases": [ "truncate" ], "Examples": [ [ "{{ \"this is a very long text\" | truncate 10 \" ...\" }}", "this is a ..." ], [ "{{ \"With [Markdown](/markdown) inside.\" | markdownify | truncate 14 }}", "With \u003ca href=\"/markdown\"\u003eMarkdown …\u003c/a\u003e" ] ] } }, "templates": { "Exists": { "Description": "Exists returns whether the template with the given name exists.\nNote that this is the Unix-styled relative path including filename suffix,\ne.g. partials/header.html", "Args": [ "name" ], "Aliases": null, "Examples": [ [ "{{ if (templates.Exists \"partials/header.html\") }}Yes!{{ end }}", "Yes!" ], [ "{{ if not (templates.Exists \"partials/doesnotexist.html\") }}No!{{ end }}", "No!" ] ] } }, "time": { "AsTime": { "Description": "AsTime converts the textual representation of the datetime string into\na time.Time interface.", "Args": [ "v" ], "Aliases": null, "Examples": [ [ "{{ (time \"2015-01-21\").Year }}", "2015" ] ] }, "Duration": { "Description": "Duration converts the given number to a time.Duration.\nUnit is one of nanosecond/ns, microsecond/us/µs, millisecond/ms, second/s, minute/m or hour/h.", "Args": [ "unit", "number" ], "Aliases": [ "duration" ], "Examples": [ [ "{{ mul 60 60 | duration \"second\" }}", "1h0m0s" ] ] }, "Format": { "Description": "Format converts the textual representation of the datetime string into\nthe other form or returns it of the time.Time value. These are formatted\nwith the layout string", "Args": [ "layout", "v" ], "Aliases": [ "dateFormat" ], "Examples": [ [ "dateFormat: {{ dateFormat \"Monday, Jan 2, 2006\" \"2015-01-21\" }}", "dateFormat: Wednesday, Jan 21, 2015" ] ] }, "Now": { "Description": "Now returns the current local time.", "Args": null, "Aliases": [ "now" ], "Examples": [] }, "ParseDuration": { "Description": "ParseDuration parses a duration string.\nA duration string is a possibly signed sequence of\ndecimal numbers, each with optional fraction and a unit suffix,\nsuch as \"300ms\", \"-1.5h\" or \"2h45m\".\nValid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".\nSee https://golang.org/pkg/time/#ParseDuration", "Args": [ "in" ], "Aliases": null, "Examples": [ [ "{{ \"1h12m10s\" | time.ParseDuration }}", "1h12m10s" ] ] } }, "transform": { "Emojify": { "Description": "Emojify returns a copy of s with all emoji codes replaced with actual emojis.\n\nSee http://www.emoji-cheat-sheet.com/", "Args": [ "s" ], "Aliases": [ "emojify" ], "Examples": [ [ "{{ \"I :heart: Hugo\" | emojify }}", "I ❤ Hugo" ] ] }, "HTMLEscape": { "Description": "HTMLEscape returns a copy of s with reserved HTML characters escaped.", "Args": [ "s" ], "Aliases": [ "htmlEscape" ], "Examples": [ [ "{{ htmlEscape \"Cathal Garvey \u0026 The Sunshine Band \u003ccathal@foo.bar\u003e\" | safeHTML}}", "Cathal Garvey \u0026amp; The Sunshine Band \u0026lt;cathal@foo.bar\u0026gt;" ], [ "{{ htmlEscape \"Cathal Garvey \u0026 The Sunshine Band \u003ccathal@foo.bar\u003e\"}}", "Cathal Garvey \u0026amp;amp; The Sunshine Band \u0026amp;lt;cathal@foo.bar\u0026amp;gt;" ], [ "{{ htmlEscape \"Cathal Garvey \u0026 The Sunshine Band \u003ccathal@foo.bar\u003e\" | htmlUnescape | safeHTML }}", "Cathal Garvey \u0026 The Sunshine Band \u003ccathal@foo.bar\u003e" ] ] }, "HTMLUnescape": { "Description": "HTMLUnescape returns a copy of with HTML escape requences converted to plain\ntext.", "Args": [ "s" ], "Aliases": [ "htmlUnescape" ], "Examples": [ [ "{{ htmlUnescape \"Cathal Garvey \u0026amp; The Sunshine Band \u0026lt;cathal@foo.bar\u0026gt;\" | safeHTML}}", "Cathal Garvey \u0026 The Sunshine Band \u003ccathal@foo.bar\u003e" ], [ "{{\"Cathal Garvey \u0026amp;amp; The Sunshine Band \u0026amp;lt;cathal@foo.bar\u0026amp;gt;\" | htmlUnescape | htmlUnescape | safeHTML}}", "Cathal Garvey \u0026 The Sunshine Band \u003ccathal@foo.bar\u003e" ], [ "{{\"Cathal Garvey \u0026amp;amp; The Sunshine Band \u0026amp;lt;cathal@foo.bar\u0026amp;gt;\" | htmlUnescape | htmlUnescape }}", "Cathal Garvey \u0026amp; The Sunshine Band \u0026lt;cathal@foo.bar\u0026gt;" ], [ "{{ htmlUnescape \"Cathal Garvey \u0026amp; The Sunshine Band \u0026lt;cathal@foo.bar\u0026gt;\" | htmlEscape | safeHTML }}", "Cathal Garvey \u0026amp; The Sunshine Band \u0026lt;cathal@foo.bar\u0026gt;" ] ] }, "Highlight": { "Description": "Highlight returns a copy of s as an HTML string with syntax\nhighlighting applied.", "Args": [ "s", "lang", "opts" ], "Aliases": [ "highlight" ], "Examples": [] }, "Markdownify": { "Description": "Markdownify renders a given input from Markdown to HTML.", "Args": [ "s" ], "Aliases": [ "markdownify" ], "Examples": [ [ "{{ .Title | markdownify}}", "\u003cstrong\u003eBatMan\u003c/strong\u003e" ] ] }, "Plainify": { "Description": "Plainify returns a copy of s with all HTML tags removed.", "Args": [ "s" ], "Aliases": [ "plainify" ], "Examples": [ [ "{{ plainify \"Hello \u003cstrong\u003eworld\u003c/strong\u003e, gophers!\" }}", "Hello world, gophers!" ] ] }, "Remarshal": { "Description": "Remarshal is used in the Hugo documentation to convert configuration\nexamples from YAML to JSON, TOML (and possibly the other way around).\nThe is primarily a helper for the Hugo docs site.\nIt is not a general purpose YAML to TOML converter etc., and may\nchange without notice if it serves a purpose in the docs.\nFormat is one of json, yaml or toml.", "Args": [ "format", "data" ], "Aliases": null, "Examples": [ [ "{{ \"title = \\\"Hello World\\\"\" | transform.Remarshal \"json\" | safeHTML }}", "{\n \"title\": \"Hello World\"\n}\n" ] ] }, "Unmarshal": { "Description": "Unmarshal unmarshals the data given, which can be either a string\nor a Resource. Supported formats are JSON, TOML, YAML, and CSV.\nYou can optionally provide an options map as the first argument.", "Args": [ "args" ], "Aliases": [ "unmarshal" ], "Examples": [ [ "{{ \"hello = \\\"Hello World\\\"\" | transform.Unmarshal }}", "map[hello:Hello World]" ], [ "{{ \"hello = \\\"Hello World\\\"\" | resources.FromString \"data/greetings.toml\" | transform.Unmarshal }}", "map[hello:Hello World]" ] ] } }, "urls": { "AbsLangURL": { "Description": "AbsLangURL takes a given string and converts it to an absolute URL according\nto a page's position in the project directory structure and the current\nlanguage.", "Args": [ "a" ], "Aliases": [ "absLangURL" ], "Examples": [] }, "AbsURL": { "Description": "AbsURL takes a given string and converts it to an absolute URL.", "Args": [ "a" ], "Aliases": [ "absURL" ], "Examples": [] }, "Anchorize": { "Description": "Anchorize creates sanitized anchor names that are compatible with Blackfriday.", "Args": [ "a" ], "Aliases": [ "anchorize" ], "Examples": [ [ "{{ \"This is a title\" | anchorize }}", "this-is-a-title" ] ] }, "Parse": { "Description": "", "Args": null, "Aliases": null, "Examples": null }, "Ref": { "Description": "Ref returns the absolute URL path to a given content item.", "Args": [ "in", "args" ], "Aliases": [ "ref" ], "Examples": [] }, "RelLangURL": { "Description": "RelLangURL takes a given string and prepends the relative path according to a\npage's position in the project directory structure and the current language.", "Args": [ "a" ], "Aliases": [ "relLangURL" ], "Examples": [] }, "RelRef": { "Description": "RelRef returns the relative URL path to a given content item.", "Args": [ "in", "args" ], "Aliases": [ "relref" ], "Examples": [] }, "RelURL": { "Description": "RelURL takes a given string and prepends the relative path according to a\npage's position in the project directory structure.", "Args": [ "a" ], "Aliases": [ "relURL" ], "Examples": [] }, "URLize": { "Description": "URLize returns the given argument formatted as URL.", "Args": [ "a" ], "Aliases": [ "urlize" ], "Examples": [] } } } } } hugo-0.68.3/docs/data/homepagetweets.toml000066400000000000000000000314531363637351300203510ustar00rootroot00000000000000[[tweet]] name = "Heinrich Hartmann" twitter_handle = "@heinrichhartman" quote = "Working with @GoHugoIO is such a joy. Having worked with #Jekyll in the past, the near instant preview is a big win! Did not expect this to make such a huge difference." link = "https://twitter.com/heinrichhartman/status/1199736512264462341" date = 2019-11-12T00:00:00Z [[tweet]] name = "Joshua Steven‏‏" twitter_handle = "@jscarto" quote = "Can't overstate how much I enjoy @GoHugoIO. My site is relatively small, but *18 ms* to build the whole thing made template development and proofing a breeze." link = "https://twitter.com/jscarto/status/1039648827815485440" date = 2018-09-12T00:00:00Z [[tweet]] name = "Jens Munch" twitter_handle = "@jensamunch" quote = "Hugo is really, really incredible... Now does resizing/resampling of images as well! Crazy that something so fast can be a static site generator... Amazing open-source project." link = "https://twitter.com/jensamunch/status/948533063537086464" date = 2018-01-03T04:00:00Z [[tweet]] name = "STOQE" twitter_handle = "@STOQE" quote = "I fear @GoHugoIO v0.22 might be so fast it creates a code vortex that time-warps me back to a time I used Wordpress. #gasp" link = "https://twitter.com/STOQE/status/874184881701494784" date = 2017-06-12T00:00:00Z [[tweet]] name = "Christophe Diericx" twitter_handle = "@spcrngr_" quote = "The more I use gohugo.io, the more I really like it. Super intuitive/powerful static site generator...great job @GoHugoIO" link = "https://twitter.com/spcrngr_/status/870863020905435136" date = 2017-06-03T00:00:00Z [[tweet]] name = "marcoscan" twitter_handle = "@marcoscan" quote = "Blog migrated from @WordPress to @GoHugoIO, with a little refresh of my theme, Vim shortcuts and a full featured deploy script #gohugo" link = "https://twitter.com/marcoscan/status/869661175960752129" date = 2017-05-30T00:00:00Z [[tweet]] name = "Sandra Kuipers" twitter_handle = "@SKuipersDesign" quote = "Who knew static site building could be fun 🤔 Learning #gohugo today" link = "https://twitter.com/SKuipersDesign/status/868796256902029312" date = 2017-05-28T00:00:00Z [[tweet]] name = "Netlify" twitter_handle = "@Netlify" quote = "Top Ten Static Site Generators of 2017. Congrats to the top 3: 1. @Jekyllrb 2. @GoHugoIO 3. @hexojs" link = "https://twitter.com/Netlify/status/868122279221362688" date = 2017-05-26T00:00:00Z [[tweet]] name = "Phil Hawksworth" twitter_handle = "@philhawksworth" quote = "I've been keen on #JAMStack for some time, but @GoHugoIO is wooing me all over again. Great fun to build with. And speeeeedy." link = "https://twitter.com/philhawksworth/status/866684170512326657" date = 2017-05-22T00:00:00Z [[tweet]] name = "Aras Pranckevicius" twitter_handle = "@aras_p" quote = "I've probably said it before...but having Hugo rebuild the whole website in 300ms is amazing. gohugo.io, #gohugo" link = "https://twitter.com/aras_p/status/861157286823288832" date = 2017-05-07T00:00:00Z [[tweet]] name = "Hans Beck" twitter_handle = "@EnrichedGamesHB" quote = "Diving deeper into @GoHugoIO. A lot of docs there, top work! But I've the impressed that #gohugo is far easier than its feels from the docs!" link = "https://twitter.com/EnrichedGamesHB/status/836854762440130560" date = 2017-03-01T00:00:00Z [[tweet]] name = "Alan Richardson" twitter_handle = "@eviltester" quote = "I migrated the @BlackOpsTesting .com website from docpad to Hugo last weekend. http://gohugo.io/ Super Fast HTML Generation @spf13 " link = "https://twitter.com/eviltester/status/553520335115808768" date = 2015-01-09T00:00:00Z [[tweet]] name = "Janez Čadež‏" twitter_handle = "@jamziSLO" quote = "Building @garazaFRI website in #hugo. This static site generator is soooo damn fast! #gohugo #golang" link = "https://twitter.com/jamziSLO/status/817720283977183234" date = 2017-01-07T00:00:00Z [[tweet]] name = "Execute‏‏" twitter_handle = "@executerun" quote = "Hah, #gohugo. I was working with #gohugo on #linux but now I realised how easy is to set-up it on #windows. Just need to add binary to #path!" link = "https://twitter.com/executerun/status/809753145270272005" date = 2016-12-16T00:00:00Z [[tweet]] name = "Baron Schwartz" twitter_handle = "@xaprb" quote = "Hugo is impressively capable. It's a static site generator by @spf13 written in #golang . Just upgraded to latest release; very powerful. " link = "https://twitter.com/xaprb/status/556894866488455169" date = 2015-01-18T00:00:00Z [[tweet]] name = "Dave Cottlehuber" twitter_handle = "@dch__" quote = "I just fell in love with #hugo, a static site/blog engine written by @spf13 in #golang + stellar docs" link = "https://twitter.com/dch__/status/460158115498176512" date = 2014-04-26T00:00:00Z [[tweet]] name = "David Caunt" twitter_handle = "@dcaunt" quote = "I had a play with Hugo and it was good, uses Markdown files for content" link = "https://twitter.com/dcaunt/statuses/406466996277374976" date = 2013-11-29T00:00:00Z [[tweet]] name = "David Gay" twitter_handle = "@oddshocks" quote = "Hugo is super-rad." link = "https://twitter.com/oddshocks/statuses/405083217893421056" date = 2013-11-25T00:00:00Z [[tweet]] name = "Diti" twitter_handle = "@DitiPengi" quote = "The dev version of Hugo is AWESOME! <3 I promise, I will try to learn go ASAP and help contribute to the project! Just too great!" link = "https://twitter.com/DitiPengi/status/472470974051676160" date = 2014-05-30T00:00:00Z [[tweet]] name = "Douglas Stephen " twitter_handle = "@DougStephenJr" quote = "Even as a long-time Octopress fan, I’ve gotta admit that this project Hugo looks very very cool" link = "https://twitter.com/DougStephenJr/statuses/364512471660249088" date = 2013-08-05T00:00:00Z [[tweet]] name = "Hugo Rodger-Brown" twitter_handle = "@hugorodgerbrown" quote = "Finally someone builds me my own static site generator" link = "https://twitter.com/hugorodgerbrown/statuses/364417910153818112" date = 2013-05-08T00:00:00Z [[tweet]] name = "Hugo Roy" twitter_handle = "@hugoroyd" quote = "Finally the answer to the question my parents have been asking: What does Hugo do?" link = "https://twitter.com/hugoroyd/status/501704796727173120" date = 2014-08-19T00:00:00Z [[tweet]] name = "Daniel Miessler" twitter_handle = "@DanielMiessler" quote = "Websites for named vulnerabilities should run on static site generator platforms like Hugo. Read-only + burst traffic = static." link = "https://twitter.com/DanielMiessler/status/704703841673957376" date = 2016-03-01T00:00:00Z [[tweet]] name = "Javier Segura" twitter_handle = "@jsegura" quote = "Another site generated with Hugo here! I'm getting in love with it." link = "https://twitter.com/jsegura/status/465978434154659841" date = 2014-05-12T00:00:00Z [[tweet]] name = "Jim Biancolo" twitter_handle = "@jimbiancolo" quote = "I’m loving the static site generator renaissance we are currently enjoying. Hugo is new, looks great, written in Go" link = "https://twitter.com/jimbiancolo/statuses/408678420348813314" date = 2013-05-12T00:00:00Z [[tweet]] name = "Jip J. Dekker" twitter_handle = "@jipjdekker" quote = "Building a personal website in Hugo. Works like a charm. And written in @golang!" link = "https://twitter.com/jipjdekker/status/413783548735152131" date = 2013-12-19T00:00:00Z [[tweet]] name = "Jose Gonzalvo" twitter_handle = "@jgonzalvo" quote = "Checking out Hugo; Loving it so far. Like Jekyll but not so blog-oriented and written in go" link = "https://twitter.com/jgonzalvo/statuses/408177855819173888" date = 2013-12-04T00:00:00Z [[tweet]] name = "Josh Matz" twitter_handle = "@joshmatz" quote = "A static site generator without the long build times? Yes, please!" link = "https://twitter.com/joshmatz/statuses/364437436870696960" date = 2013-08-05T00:00:00Z [[tweet]] name = "Kieran Healy" twitter_handle = "@kjhealy" quote = "OK, so in today's speed battle of static site generators, @spf13's hugo is kicking everyone's ass, by miles." link = "https://twitter.com/kjhealy/status/437349384809115648" date = 2014-02-22T00:00:00Z [[tweet]] name = "Ludovic Chabant" twitter_handle = "@ludovicchabant" quote = "Good work on Hugo, I’m impressed with the speed!" link = "https://twitter.com/ludovicchabant/statuses/408806199602053120" date = 2013-12-06T00:00:00Z [[tweet]] name = "Luke Holder" twitter_handle = "@lukeholder" quote = "this is AWESOME. a single little executable and so fast." link = "https://twitter.com/lukeholder/status/430352287936946176" date = 2014-02-03T00:00:00Z [[tweet]] name = "Markus Eliasson" twitter_handle = "@markuseliasson" quote = "Hugo is fast, dead simple to setup and well documented" link = "https://twitter.com/markuseliasson/status/501594865877008384" date = 2014-08-19T00:00:00Z [[tweet]] name = "mercime" twitter_handle = "@mercime_one" quote = "Hugo: Makes the Web Fun Again" link = "https://twitter.com/mercime_one/status/500547145087205377" date = 2014-08-16T00:00:00Z [[tweet]] name = "Michael Whatcott" twitter_handle = "@mdwhatcott" quote = "One more satisfied #Hugo blogger. Thanks @spf13 and friends!" link = "https://twitter.com/mdwhatcott/status/469980686531571712" date = 2014-05-23T00:00:00Z [[tweet]] name = "Nathan Toups" twitter_handle = "@rojoroboto" quote = "I love Hugo! My site is generated with it now http://rjrbt.io" link = "https://twitter.com/rojoroboto/status/423439915620106242" date = 2014-01-15T00:00:00Z [[tweet]] name = "Ruben Solvang" twitter_handle = "@messo85" quote = "#Hugo is the new @jekyllrb / @middlemanapp! Faster, easier and runs everywhere." link = "https://twitter.com/messo85/status/472825062027182081" date = 2014-05-31T00:00:00Z [[tweet]] name = "Ryan Martinsen" twitter_handle = "@popthestack" quote = "Also, I re-launched my blog (it looks the same as before) using Hugo, a *fast* static engine. Very happy with it. gohugo.io" link = "https://twitter.com/popthestack/status/549972754125307904" date = 2014-12-30T00:00:00Z [[tweet]] name = "The Lone Cuber" twitter_handle = "@TheLoneCuber" quote = "Jekyll is dead to me these days though... long live Hugo! Hugo is *by far* the best in its field. Thanks for making it happen." link = "https://twitter.com/TheLoneCuber/status/495716684456398848" date = 2014-08-02T00:00:00Z [[tweet]] name = "The Lone Cuber" twitter_handle = "@TheLoneCuber" quote = "Finally, a publishing platform that's a joy to use. #NoMoreBarriers" link = "https://twitter.com/TheLoneCuber/status/495731334711488512" date = 2014-08-02T00:00:00Z [[tweet]] name = "WorkHTML" twitter_handle = "@workhtml" quote = " #Hugo A very good alternative for #wordpress !!! A fast and modern static website engine gohugo.io " link = "https://twitter.com/workhtml/status/563064361301053440" date = 2015-02-04T00:00:00Z hugo-0.68.3/docs/data/titles.toml000066400000000000000000000000431363637351300166230ustar00rootroot00000000000000[Showcase] title = "Site Showcase" hugo-0.68.3/docs/go.mod000066400000000000000000000002071363637351300146210ustar00rootroot00000000000000module github.com/gohugoio/hugoDocs go 1.12 require github.com/gohugoio/gohugoioTheme v0.0.0-20200128164921-1d0bc5482051 // indirect hugo-0.68.3/docs/go.sum000066400000000000000000000030421363637351300146460ustar00rootroot00000000000000github.com/gohugoio/gohugoioTheme v0.0.0-20190808163145-07b3c0f73b02/go.mod h1:kpw3SS48xZvLQGEXKu8u5XHgXkPvL8DX3oGa07+z8Bs= github.com/gohugoio/gohugoioTheme v0.0.0-20191014144142-1f3a01deed7b h1:PWNjl46fvtz54PKO0BdiXOF6/4L/uCP0F3gtcCxGrJs= github.com/gohugoio/gohugoioTheme v0.0.0-20191014144142-1f3a01deed7b/go.mod h1:kpw3SS48xZvLQGEXKu8u5XHgXkPvL8DX3oGa07+z8Bs= github.com/gohugoio/gohugoioTheme v0.0.0-20191021162625-2e7250ca437d h1:D3DcaYkuJbotdWNNAQpQl37txX4HQ6R5uMHoxVmTw0w= github.com/gohugoio/gohugoioTheme v0.0.0-20191021162625-2e7250ca437d/go.mod h1:kpw3SS48xZvLQGEXKu8u5XHgXkPvL8DX3oGa07+z8Bs= github.com/gohugoio/gohugoioTheme v0.0.0-20200123151337-9475fd449324 h1:UZwHDYtGY0uOKIvcm2LWd+xfFxD3X5L222LIJdI5RE4= github.com/gohugoio/gohugoioTheme v0.0.0-20200123151337-9475fd449324/go.mod h1:kpw3SS48xZvLQGEXKu8u5XHgXkPvL8DX3oGa07+z8Bs= github.com/gohugoio/gohugoioTheme v0.0.0-20200123204146-589b4c309025 h1:ScYFARz+bHX1rEr1donVknhRdxGY/cwqK1hHvWEfrlc= github.com/gohugoio/gohugoioTheme v0.0.0-20200123204146-589b4c309025/go.mod h1:kpw3SS48xZvLQGEXKu8u5XHgXkPvL8DX3oGa07+z8Bs= github.com/gohugoio/gohugoioTheme v0.0.0-20200123205007-5d6620a0db26 h1:acXfduibbWxji9tW0WkLHbjcXFsnd5uIwXe0WfwOazg= github.com/gohugoio/gohugoioTheme v0.0.0-20200123205007-5d6620a0db26/go.mod h1:kpw3SS48xZvLQGEXKu8u5XHgXkPvL8DX3oGa07+z8Bs= github.com/gohugoio/gohugoioTheme v0.0.0-20200128164921-1d0bc5482051 h1:cS14MnUGS6xwWYfPNshimm8HdMCZiYBxWkCD0VnvgVw= github.com/gohugoio/gohugoioTheme v0.0.0-20200128164921-1d0bc5482051/go.mod h1:kpw3SS48xZvLQGEXKu8u5XHgXkPvL8DX3oGa07+z8Bs= hugo-0.68.3/docs/layouts/000077500000000000000000000000001363637351300152145ustar00rootroot00000000000000hugo-0.68.3/docs/layouts/index.rss.xml000066400000000000000000000035311363637351300176550ustar00rootroot00000000000000 {{ .Site.Title }} – {{ .Title }} {{ .Permalink }} Recent Hugo news from gohugo.io Hugo -- gohugo.io{{ with .Site.LanguageCode }} {{.}}{{end}}{{ with .Site.Author.email }} {{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}{{end}}{{ with .Site.Author.email }} {{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}{{end}}{{ with .Site.Copyright }} {{.}}{{end}}{{ if not .Date.IsZero }} {{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}{{ end }} {{ "img/hugo.png" | absURL }} GoHugo.io {{ .Permalink }} {{ with .OutputFormats.Get "RSS" }} {{ printf "" .Permalink .MediaType | safeHTML }} {{ end }} {{ range first 50 (where .Site.RegularPages "Type" "in" (slice "news" "showcase")) }} {{ .Section | title }}: {{ .Title }} {{ .Permalink }} {{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }} {{ with .Site.Author.email }}{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}{{end}} {{ .Permalink }} {{ $img := (.Resources.ByType "image").GetMatch "*featured*" }} {{ with $img }} {{ $img := .Resize "640x" }} {{ printf "]]>" $img.Permalink $img.Width $img.Height | safeHTML }} {{ end }} {{ .Content | html }} {{ end }} hugo-0.68.3/docs/layouts/maintenance/000077500000000000000000000000001363637351300174765ustar00rootroot00000000000000hugo-0.68.3/docs/layouts/maintenance/list.html000066400000000000000000000031451363637351300213420ustar00rootroot00000000000000{{ define "main" }}
    {{ $byLastMod := .Site.RegularPages.ByLastmod }} {{ $recent := ($byLastMod | last 30).Reverse }} {{ $leastRecent := $byLastMod | first 10 }}

    Last Updated

    {{ partial "maintenance-pages-table" $recent }}

    Least Recently Updated

    {{ partial "maintenance-pages-table" $leastRecent }} {{/* Don't think this is possible with where directly. Should investigate. */}} {{ .Scratch.Set "todos" slice }} {{ range .Site.RegularPages }} {{ if .HasShortcode "todo" }} {{ $.Scratch.Add "todos" . }} {{ end }} {{ end }}

    Pages marked with TODO

    {{ partial "maintenance-pages-table" (.Scratch.Get "todos") }}
    {{ end }}hugo-0.68.3/docs/layouts/partials/000077500000000000000000000000001363637351300170335ustar00rootroot00000000000000hugo-0.68.3/docs/layouts/partials/maintenance-pages-table.html000066400000000000000000000012241363637351300243640ustar00rootroot00000000000000 {{ range . }} {{ end }}
    LastMod Link GitHub
    {{ .Lastmod.Format "2006-01-02" }} {{ .Title }} {{ with .GitInfo }}{{ .Subject }}{{ else }}Source{{ end }}
    hugo-0.68.3/docs/layouts/shortcodes/000077500000000000000000000000001363637351300173715ustar00rootroot00000000000000hugo-0.68.3/docs/layouts/shortcodes/asciicast.html000066400000000000000000000002261363637351300222220ustar00rootroot00000000000000{{ $id := .Get 0 }} hugo-0.68.3/docs/layouts/shortcodes/chroma-lexers.html000066400000000000000000000001711363637351300230270ustar00rootroot00000000000000
    {{ range .Site.Data.docs.chroma.lexers }}
    {{ .Name }}
    {{ delimit .Aliases ", " }}
    {{ end }}
    hugo-0.68.3/docs/layouts/shortcodes/code-toggle.html000066400000000000000000000027101363637351300224500ustar00rootroot00000000000000{{ $file := .Get "file" }} {{ $code := "" }} {{ with .Get "config" }} {{ $file = $file | default "config" }} {{ $sections := (split . ".") }} {{ $configSection := index $.Site.Data.docs.config $sections }} {{ $code = dict $sections $configSection }} {{ else }} {{ $code = $.Inner }} {{ end }} {{ $langs := (slice "yaml" "toml" "json") }}
    {{- with $file -}}
    {{ . }}.
    {{- end -}} {{ range $langs }}   {{ end }}
    {{ range $langs }}
    {{ highlight ($code | transform.Remarshal . | safeHTML) . ""}}
    {{ if ne ($.Get "copy") "false" }} {{/* Functionality located within filesaver.js The copy here is located in the css with .copy class so it can be replaced with JS on success */}} {{end}} {{ end }}
    hugo-0.68.3/docs/layouts/shortcodes/code.html000066400000000000000000000022261363637351300211730ustar00rootroot00000000000000{{ $file := .Get "file" }} {{ $codeLang := "" }} {{ $suffix := findRE "(\\.[^.]+)$" $file 1 }} {{ with $suffix }} {{ $codeLang = (index . 0 | strings.TrimPrefix ".") }} {{ end }} {{ with .Get "codeLang" }}{{ $codeLang = . }}{{ end }} {{ if eq $codeLang "html"}} {{ $codeLang = "go-html-template" }} {{ end }}
    {{- with $file -}}
    {{.}}
    {{- end -}} {{ if ne (.Get "copy") "false" }} {{/* Functionality located within filesaver.js The copy here is located in the css with .copy class so it can be replaced with JS on success */}} {{end}}
    {{ if .Get "nocode" }}{{ $.Inner }}{{ else }}{{ with $codeLang }}{{- highlight $.Inner . "" | -}}{{ else }}
    {{- .Inner | string -}}
    {{ end }}{{ end }}
    hugo-0.68.3/docs/layouts/shortcodes/datatable-filtered.html000066400000000000000000000012301363637351300237700ustar00rootroot00000000000000{{ $package := (index .Params 0) }} {{ $listname := (index .Params 1) }} {{ $filter := split (index .Params 2) " " }} {{ $filter1 := index $filter 0 }} {{ $filter2 := index $filter 1 }} {{ $filter3 := index $filter 2 }} {{ $list := (index (index .Site.Data.docs $package) $listname) }} {{ $fields := after 3 .Params }} {{ $list := where $list $filter1 $filter2 $filter3 }} {{ range $fields }} {{ end }} {{ range $list }} {{ range $k, $v := . }} {{ $.Scratch.Set $k $v }} {{ end }} {{ range $fields }} {{ end }} {{ end }}
    {{ . }}
    {{ $.Scratch.Get . }}
    hugo-0.68.3/docs/layouts/shortcodes/datatable.html000066400000000000000000000007161363637351300222040ustar00rootroot00000000000000{{ $package := (index .Params 0) }} {{ $listname := (index .Params 1) }} {{ $list := (index (index .Site.Data.docs $package) $listname) }} {{ $fields := after 2 .Params }} {{ range $fields }} {{ end }} {{ range $list }} {{ range $k, $v := . }} {{ $.Scratch.Set $k $v }} {{ end }} {{ range $fields }} {{ end }} {{ end }}
    {{ . }}
    {{ $.Scratch.Get . }}
    hugo-0.68.3/docs/layouts/shortcodes/directoryindex.html000066400000000000000000000005141363637351300233130ustar00rootroot00000000000000{{- $pathURL := .Get "pathURL" -}} {{- $path := .Get "path" -}} {{- $files := readDir $path -}} {{- range $files }} {{- end }}
    Size in bytes Name
    {{ .Size }} {{ .Name }}
    hugo-0.68.3/docs/layouts/shortcodes/docfile.html000066400000000000000000000011701363637351300216630ustar00rootroot00000000000000{{ $file := .Get 0}} {{ $filepath := $file }} {{ $syntax := index (split $file ".") 1 }} {{ $syntaxoverride := eq (len .Params) 2 }}
    {{$filepath}}
    {{- readFile $file -}}
    hugo-0.68.3/docs/layouts/shortcodes/exfile.html000066400000000000000000000016331363637351300215360ustar00rootroot00000000000000{{ $file := .Get 0}} {{ $filepath := replace $file "static/" ""}} {{ $syntax := index (split $file ".") 1 }} {{ $syntaxoverride := eq (len .Params) 2 }}
    {{$filepath}}
    {{- readFile $file -}}
    Source
    hugo-0.68.3/docs/layouts/shortcodes/exfm.html000066400000000000000000000016451363637351300212240ustar00rootroot00000000000000 {{ $file := .Get 0}} {{ $filepath := replace $file "static/" ""}} {{ $syntax := index (split $file ".") 1 }} {{ $syntaxoverride := eq (len .Params) 2 }}
    {{$filepath}}
    {{- readFile $file -}}
    Source
    hugo-0.68.3/docs/layouts/shortcodes/funcsig.html000066400000000000000000000002441363637351300217150ustar00rootroot00000000000000

    Syntax

        {{- .Inner -}}
    
    hugo-0.68.3/docs/layouts/shortcodes/gh.html000066400000000000000000000005151363637351300206560ustar00rootroot00000000000000{{ range .Params }} {{ if eq (substr . 0 1) "@" }} {{ . }} {{ else if eq (substr . 0 2) "0x" }} {{ substr . 2 6 }} {{ else }} #{{ . }} {{ end }} {{ end }} hugo-0.68.3/docs/layouts/shortcodes/ghrepo.html000066400000000000000000000001101363637351300215330ustar00rootroot00000000000000GitHub repositoryhugo-0.68.3/docs/layouts/shortcodes/gomodules-info.html000066400000000000000000000012371363637351300232110ustar00rootroot00000000000000{{ $text := ` Most of the commands for **Hugo Modules** requires a newer version of Go installed (see https://golang.org/dl/) and the relevant VCS client (e.g. Git, see https://git-scm.com/downloads). If you have an "older" site running on Netlify, you may have to set GO_VERSION to 1.12 in your Environment settings. For more information about Go Modules, see: * https://github.com/golang/go/wiki/Modules * https://blog.golang.org/using-go-modules ` }} hugo-0.68.3/docs/layouts/shortcodes/imgproc.html000066400000000000000000000015551363637351300217250ustar00rootroot00000000000000{{ $original := .Page.Resources.GetMatch (printf "*%s*" (.Get 0)) }} {{ $command := .Get 1 }} {{ $options := .Get 2 }} {{ if eq $command "Fit"}} {{ .Scratch.Set "image" ($original.Fit $options) }} {{ else if eq $command "Resize"}} {{ .Scratch.Set "image" ($original.Resize $options) }} {{ else if eq $command "Fill"}} {{ .Scratch.Set "image" ($original.Fill $options) }} {{ else }} {{ errorf "Invalid image processing command: Must be one of Fit, Fill or Resize."}} {{ end }} {{ $image := .Scratch.Get "image" }}
    {{ with .Inner }} {{ . }} {{ else }} .{{ $command }} "{{ $options }}" {{ end }}
    hugo-0.68.3/docs/layouts/shortcodes/module-mounts-note.html000066400000000000000000000002271363637351300240330ustar00rootroot00000000000000Also see [Module Mounts Config](/hugo-modules/configuration/#module-config-mounts) for an alternative way to configure this directory (from Hugo 0.56).hugo-0.68.3/docs/layouts/shortcodes/new-in.html000066400000000000000000000006331363637351300214560ustar00rootroot00000000000000{{ $version := .Get 0 }} {{ if not $version }} {{ errorf "Missing version in new-in shortcode "}} {{ end }} {{ $version = $version | strings.TrimPrefix "v" }} hugo-0.68.3/docs/layouts/shortcodes/nohighlight.html000066400000000000000000000000751363637351300225650ustar00rootroot00000000000000
    {{ .Inner }}
    hugo-0.68.3/docs/layouts/shortcodes/note.html000066400000000000000000000006021363637351300212220ustar00rootroot00000000000000{{ $_hugo_config := `{ "version": 1 }` }} hugo-0.68.3/docs/layouts/shortcodes/output.html000066400000000000000000000004241363637351300216170ustar00rootroot00000000000000{{$file := .Get "file"}} {{$icon := index (split $file ".") 1 }}
    {{$file}}
    {{- .Inner | string -}}
    hugo-0.68.3/docs/layouts/shortcodes/readfile.html000066400000000000000000000004041363637351300220300ustar00rootroot00000000000000{{$file := .Get "file"}} {{- if eq (.Get "markdown") "true" -}} {{- $file | readFile | markdownify -}} {{- else if (.Get "highlight") -}} {{- highlight ($file | readFile) (.Get "highlight") "" -}} {{- else -}} {{ $file | readFile | safeHTML }} {{- end -}}hugo-0.68.3/docs/layouts/shortcodes/tip.html000066400000000000000000000005501363637351300210530ustar00rootroot00000000000000{{ $_hugo_config := `{ "version": 1 }` }} hugo-0.68.3/docs/layouts/shortcodes/todo.html000066400000000000000000000000301363637351300212150ustar00rootroot00000000000000{{ if .Inner }}{{ end }}hugo-0.68.3/docs/layouts/shortcodes/warning.html000066400000000000000000000005771363637351300217350ustar00rootroot00000000000000{{ $_hugo_config := `{ "version": 1 }` }} hugo-0.68.3/docs/layouts/shortcodes/yt.html000066400000000000000000000010641363637351300207140ustar00rootroot00000000000000
    {{if (.Get "thumbnail")}}
    {{else}}
    {{end}}
    {{ if (.Get "description") }}
    {{ .Get "description" | markdownify }}
    {{ end }}hugo-0.68.3/docs/netlify.toml000066400000000000000000000012241363637351300160620ustar00rootroot00000000000000[build] publish = "public" command = "hugo --gc --minify" [context.production.environment] HUGO_VERSION = "0.67.1" HUGO_ENV = "production" HUGO_ENABLEGITINFO = "true" [context.split1] command = "hugo --gc --minify --enableGitInfo" [context.split1.environment] HUGO_VERSION = "0.67.1" HUGO_ENV = "production" [context.deploy-preview] command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL" [context.deploy-preview.environment] HUGO_VERSION = "0.67.1" [context.branch-deploy] command = "hugo --gc --minify -b $DEPLOY_PRIME_URL" [context.branch-deploy.environment] HUGO_VERSION = "0.67.1" [context.next.environment] HUGO_ENABLEGITINFO = "true" hugo-0.68.3/docs/pull-theme.sh000077500000000000000000000001701363637351300161250ustar00rootroot00000000000000#!/bin/bash git subtree pull --prefix=themes/gohugoioTheme/ git@github.com:gohugoio/gohugoioTheme.git master --squash hugo-0.68.3/docs/resources/000077500000000000000000000000001363637351300155265ustar00rootroot00000000000000hugo-0.68.3/docs/resources/.gitattributes000066400000000000000000000000621363637351300204170ustar00rootroot00000000000000*.* linguist-generated=true *.* -diff -mergehugo-0.68.3/docs/resources/_gen/000077500000000000000000000000001363637351300164365ustar00rootroot00000000000000hugo-0.68.3/docs/resources/_gen/assets/000077500000000000000000000000001363637351300177405ustar00rootroot00000000000000hugo-0.68.3/docs/resources/_gen/assets/css/000077500000000000000000000000001363637351300205305ustar00rootroot00000000000000hugo-0.68.3/docs/resources/_gen/assets/css/output/000077500000000000000000000000001363637351300220705ustar00rootroot00000000000000hugo-0.68.3/docs/resources/_gen/assets/css/output/css/000077500000000000000000000000001363637351300226605ustar00rootroot00000000000000app.css_d11fe7b62c27961c87ecd0f2490357b9.content000066400000000000000000003436661363637351300321600ustar00rootroot00000000000000hugo-0.68.3/docs/resources/_gen/assets/css/output/css@font-face{font-family:muli;font-style:normal;font-display:swap;font-weight:200;src:local('Muli Extra Light '),local('Muli-Extra Light'),url(/fonts/muli-latin-200.woff2) format('woff2'),url(/fonts/muli-latin-200.woff) format('woff')}@font-face{font-family:muli;font-style:italic;font-display:swap;font-weight:200;src:local('Muli Extra Light italic'),local('Muli-Extra Lightitalic'),url(/fonts/muli-latin-200italic.woff2) format('woff2'),url(/fonts/muli-latin-200italic.woff) format('woff')}@font-face{font-family:muli;font-style:normal;font-display:swap;font-weight:300;src:local('Muli Light '),local(Muli-Light),url(/fonts/muli-latin-300.woff2) format('woff2'),url(/fonts/muli-latin-300.woff) format('woff')}@font-face{font-family:muli;font-style:italic;font-display:swap;font-weight:300;src:local('Muli Light italic'),local(Muli-Lightitalic),url(/fonts/muli-latin-300italic.woff2) format('woff2'),url(/fonts/muli-latin-300italic.woff) format('woff')}@font-face{font-family:muli;font-style:normal;font-display:swap;font-weight:400;src:local('Muli Regular '),local(Muli-Regular),url(/fonts/muli-latin-400.woff2) format('woff2'),url(/fonts/muli-latin-400.woff) format('woff')}@font-face{font-family:muli;font-style:italic;font-display:swap;font-weight:400;src:local('Muli Regular italic'),local(Muli-Regularitalic),url(/fonts/muli-latin-400italic.woff2) format('woff2'),url(/fonts/muli-latin-400italic.woff) format('woff')}@font-face{font-family:muli;font-style:normal;font-display:swap;font-weight:600;src:local('Muli SemiBold '),local(Muli-SemiBold),url(/fonts/muli-latin-600.woff2) format('woff2'),url(/fonts/muli-latin-600.woff) format('woff')}@font-face{font-family:muli;font-style:italic;font-display:swap;font-weight:600;src:local('Muli SemiBold italic'),local(Muli-SemiBolditalic),url(/fonts/muli-latin-600italic.woff2) format('woff2'),url(/fonts/muli-latin-600italic.woff) format('woff')}@font-face{font-family:muli;font-style:normal;font-display:swap;font-weight:700;src:local('Muli Bold '),local(Muli-Bold),url(/fonts/muli-latin-700.woff2) format('woff2'),url(/fonts/muli-latin-700.woff) format('woff')}@font-face{font-family:muli;font-style:italic;font-display:swap;font-weight:700;src:local('Muli Bold italic'),local(Muli-Bolditalic),url(/fonts/muli-latin-700italic.woff2) format('woff2'),url(/fonts/muli-latin-700italic.woff) format('woff')}@font-face{font-family:muli;font-style:normal;font-display:swap;font-weight:800;src:local('Muli ExtraBold '),local(Muli-ExtraBold),url(/fonts/muli-latin-800.woff2) format('woff2'),url(/fonts/muli-latin-800.woff) format('woff')}@font-face{font-family:muli;font-style:italic;font-display:swap;font-weight:800;src:local('Muli ExtraBold italic'),local(Muli-ExtraBolditalic),url(/fonts/muli-latin-800italic.woff2) format('woff2'),url(/fonts/muli-latin-800italic.woff) format('woff')}@font-face{font-family:muli;font-style:normal;font-display:swap;font-weight:900;src:local('Muli Black '),local(Muli-Black),url(/fonts/muli-latin-900.woff2) format('woff2'),url(/fonts/muli-latin-900.woff) format('woff')}@font-face{font-family:muli;font-style:italic;font-display:swap;font-weight:900;src:local('Muli Black italic'),local(Muli-Blackitalic),url(/fonts/muli-latin-900italic.woff2) format('woff2'),url(/fonts/muli-latin-900italic.woff) format('woff')}/*!TACHYONS v4.7.0 | http://tachyons.io*//*!normalize.css v8.0.0 | MIT License | github.com/necolas/normalize.css*/html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{-webkit-box-sizing:content-box;box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{-webkit-box-sizing:border-box;box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{-webkit-box-sizing:border-box;box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}html,body,div,article,aside,section,main,nav,footer,header,form,fieldset,legend,pre,code,a,h1,h2,h3,h4,h5,h6,p,ul,ol,li,dl,dt,dd,blockquote,figcaption,figure,textarea,table,td,th,tr,input[type=email],input[type=number],input[type=password],input[type=tel],input[type=text],input[type=url],.border-box{-webkit-box-sizing:border-box;box-sizing:border-box}img{max-width:100%}.cover{background-size:cover!important}.contain{background-size:contain!important}@media screen and (min-width:30em){.cover-ns{background-size:cover!important}.contain-ns{background-size:contain!important}}@media screen and (min-width:30em) and (max-width:60em){.cover-m{background-size:cover!important}.contain-m{background-size:contain!important}}@media screen and (min-width:60em){.cover-l{background-size:cover!important}.contain-l{background-size:contain!important}}.bg-center{background-repeat:no-repeat;background-position:50%}.bg-top{background-repeat:no-repeat;background-position:50% 0}.bg-right{background-repeat:no-repeat;background-position:50% 100%}.bg-bottom{background-repeat:no-repeat;background-position:50% 100%}.bg-left{background-repeat:no-repeat;background-position:50% 0}@media screen and (min-width:30em){.bg-center-ns{background-repeat:no-repeat;background-position:50%}.bg-top-ns{background-repeat:no-repeat;background-position:50% 0}.bg-right-ns{background-repeat:no-repeat;background-position:50% 100%}.bg-bottom-ns{background-repeat:no-repeat;background-position:50% 100%}.bg-left-ns{background-repeat:no-repeat;background-position:50% 0}}@media screen and (min-width:30em) and (max-width:60em){.bg-center-m{background-repeat:no-repeat;background-position:50%}.bg-top-m{background-repeat:no-repeat;background-position:50% 0}.bg-right-m{background-repeat:no-repeat;background-position:50% 100%}.bg-bottom-m{background-repeat:no-repeat;background-position:50% 100%}.bg-left-m{background-repeat:no-repeat;background-position:50% 0}}@media screen and (min-width:60em){.bg-center-l{background-repeat:no-repeat;background-position:50%}.bg-top-l{background-repeat:no-repeat;background-position:50% 0}.bg-right-l{background-repeat:no-repeat;background-position:50% 100%}.bg-bottom-l{background-repeat:no-repeat;background-position:50% 100%}.bg-left-l{background-repeat:no-repeat;background-position:50% 0}}.ba{border-style:solid;border-width:1px}.bt{border-top-style:solid;border-top-width:1px}.br{border-right-style:solid;border-right-width:1px}.bb{border-bottom-style:solid;border-bottom-width:1px}.bl{border-left-style:solid;border-left-width:1px}.bn{border-style:none;border-width:0}@media screen and (min-width:30em){.ba-ns{border-style:solid;border-width:1px}.bt-ns{border-top-style:solid;border-top-width:1px}.br-ns{border-right-style:solid;border-right-width:1px}.bb-ns{border-bottom-style:solid;border-bottom-width:1px}.bl-ns{border-left-style:solid;border-left-width:1px}.bn-ns{border-style:none;border-width:0}}@media screen and (min-width:30em) and (max-width:60em){.ba-m{border-style:solid;border-width:1px}.bt-m{border-top-style:solid;border-top-width:1px}.br-m{border-right-style:solid;border-right-width:1px}.bb-m{border-bottom-style:solid;border-bottom-width:1px}.bl-m{border-left-style:solid;border-left-width:1px}.bn-m{border-style:none;border-width:0}}@media screen and (min-width:60em){.ba-l{border-style:solid;border-width:1px}.bt-l{border-top-style:solid;border-top-width:1px}.br-l{border-right-style:solid;border-right-width:1px}.bb-l{border-bottom-style:solid;border-bottom-width:1px}.bl-l{border-left-style:solid;border-left-width:1px}.bn-l{border-style:none;border-width:0}}.b--black{border-color:#000}.b--near-black{border-color:#111}.b--dark-gray{border-color:#333}.b--mid-gray{border-color:#555}.b--gray{border-color:#777}.b--silver{border-color:#999}.b--light-silver{border-color:#aaa}.b--moon-gray{border-color:#ccc}.b--light-gray{border-color:#eee}.b--near-white{border-color:#f4f4f4}.b--white{border-color:#fff}.b--white-90{border-color:rgba(255,255,255,.9)}.b--white-80{border-color:rgba(255,255,255,.8)}.b--white-70{border-color:rgba(255,255,255,.7)}.b--white-60{border-color:rgba(255,255,255,.6)}.b--white-50{border-color:rgba(255,255,255,.5)}.b--white-40{border-color:rgba(255,255,255,.4)}.b--white-30{border-color:rgba(255,255,255,.3)}.b--white-20{border-color:rgba(255,255,255,.2)}.b--white-10{border-color:rgba(255,255,255,.1)}.b--white-05{border-color:rgba(255,255,255,.05)}.b--white-025{border-color:rgba(255,255,255,.025)}.b--white-0125{border-color:rgba(255,255,255,.0125)}.b--black-90{border-color:rgba(0,0,0,.9)}.b--black-80{border-color:rgba(0,0,0,.8)}.b--black-70{border-color:rgba(0,0,0,.7)}.b--black-60{border-color:rgba(0,0,0,.6)}.b--black-50{border-color:rgba(0,0,0,.5)}.b--black-40{border-color:rgba(0,0,0,.4)}.b--black-30{border-color:rgba(0,0,0,.3)}.b--black-20{border-color:rgba(0,0,0,.2)}.b--black-10{border-color:rgba(0,0,0,.1)}.b--black-05{border-color:rgba(0,0,0,.05)}.b--black-025{border-color:rgba(0,0,0,.025)}.b--black-0125{border-color:rgba(0,0,0,.0125)}.b--dark-red{border-color:#e7040f}.b--red{border-color:#ff4136}.b--light-red{border-color:#ff725c}.b--orange{border-color:#ff6300}.b--gold{border-color:#ffb700}.b--yellow{border-color:gold}.b--light-yellow{border-color:#fbf1a9}.b--purple{border-color:#5e2ca5}.b--light-purple{border-color:#a463f2}.b--dark-pink{border-color:#d5008f}.b--hot-pink{border-color:#ff41b4}.b--pink{border-color:#ff80cc}.b--light-pink{border-color:#ffa3d7}.b--dark-green{border-color:#137752}.b--green{border-color:#19a974}.b--light-green{border-color:#9eebcf}.b--navy{border-color:#001b44}.b--dark-blue{border-color:#00449e}.b--blue{border-color:#0594cb}.b--light-blue{border-color:#96ccff}.b--lightest-blue{border-color:#cdecff}.b--washed-blue{border-color:#f6fffe}.b--washed-green{border-color:#e8fdf5}.b--washed-yellow{border-color:#fffceb}.b--washed-red{border-color:#ffdfdf}.b--transparent{border-color:transparent}.b--inherit{border-color:inherit}.br0{border-radius:0}.br1{border-radius:.125rem}.br2{border-radius:.25rem}.br3{border-radius:.5rem}.br4{border-radius:1rem}.br-100{border-radius:100%}.br-pill{border-radius:9999px}.br--bottom{border-top-left-radius:0;border-top-right-radius:0}.br--top{border-bottom-left-radius:0;border-bottom-right-radius:0}.br--right{border-top-left-radius:0;border-bottom-left-radius:0}.br--left{border-top-right-radius:0;border-bottom-right-radius:0}@media screen and (min-width:30em){.br0-ns{border-radius:0}.br1-ns{border-radius:.125rem}.br2-ns{border-radius:.25rem}.br3-ns{border-radius:.5rem}.br4-ns{border-radius:1rem}.br-100-ns{border-radius:100%}.br-pill-ns{border-radius:9999px}.br--bottom-ns{border-top-left-radius:0;border-top-right-radius:0}.br--top-ns{border-bottom-left-radius:0;border-bottom-right-radius:0}.br--right-ns{border-top-left-radius:0;border-bottom-left-radius:0}.br--left-ns{border-top-right-radius:0;border-bottom-right-radius:0}}@media screen and (min-width:30em) and (max-width:60em){.br0-m{border-radius:0}.br1-m{border-radius:.125rem}.br2-m{border-radius:.25rem}.br3-m{border-radius:.5rem}.br4-m{border-radius:1rem}.br-100-m{border-radius:100%}.br-pill-m{border-radius:9999px}.br--bottom-m{border-top-left-radius:0;border-top-right-radius:0}.br--top-m{border-bottom-left-radius:0;border-bottom-right-radius:0}.br--right-m{border-top-left-radius:0;border-bottom-left-radius:0}.br--left-m{border-top-right-radius:0;border-bottom-right-radius:0}}@media screen and (min-width:60em){.br0-l{border-radius:0}.br1-l{border-radius:.125rem}.br2-l{border-radius:.25rem}.br3-l{border-radius:.5rem}.br4-l{border-radius:1rem}.br-100-l{border-radius:100%}.br-pill-l{border-radius:9999px}.br--bottom-l{border-top-left-radius:0;border-top-right-radius:0}.br--top-l{border-bottom-left-radius:0;border-bottom-right-radius:0}.br--right-l{border-top-left-radius:0;border-bottom-left-radius:0}.br--left-l{border-top-right-radius:0;border-bottom-right-radius:0}}.b--dotted{border-style:dotted}.b--dashed{border-style:dashed}.b--solid{border-style:solid}.b--none{border-style:none}@media screen and (min-width:30em){.b--dotted-ns{border-style:dotted}.b--dashed-ns{border-style:dashed}.b--solid-ns{border-style:solid}.b--none-ns{border-style:none}}@media screen and (min-width:30em) and (max-width:60em){.b--dotted-m{border-style:dotted}.b--dashed-m{border-style:dashed}.b--solid-m{border-style:solid}.b--none-m{border-style:none}}@media screen and (min-width:60em){.b--dotted-l{border-style:dotted}.b--dashed-l{border-style:dashed}.b--solid-l{border-style:solid}.b--none-l{border-style:none}}.bw0{border-width:0}.bw1{border-width:.125rem}.bw2{border-width:.25rem}.bw3{border-width:.5rem}.bw4{border-width:1rem}.bw5{border-width:2rem}.bt-0{border-top-width:0}.br-0{border-right-width:0}.bb-0{border-bottom-width:0}.bl-0{border-left-width:0}@media screen and (min-width:30em){.bw0-ns{border-width:0}.bw1-ns{border-width:.125rem}.bw2-ns{border-width:.25rem}.bw3-ns{border-width:.5rem}.bw4-ns{border-width:1rem}.bw5-ns{border-width:2rem}.bt-0-ns{border-top-width:0}.br-0-ns{border-right-width:0}.bb-0-ns{border-bottom-width:0}.bl-0-ns{border-left-width:0}}@media screen and (min-width:30em) and (max-width:60em){.bw0-m{border-width:0}.bw1-m{border-width:.125rem}.bw2-m{border-width:.25rem}.bw3-m{border-width:.5rem}.bw4-m{border-width:1rem}.bw5-m{border-width:2rem}.bt-0-m{border-top-width:0}.br-0-m{border-right-width:0}.bb-0-m{border-bottom-width:0}.bl-0-m{border-left-width:0}}@media screen and (min-width:60em){.bw0-l{border-width:0}.bw1-l{border-width:.125rem}.bw2-l{border-width:.25rem}.bw3-l{border-width:.5rem}.bw4-l{border-width:1rem}.bw5-l{border-width:2rem}.bt-0-l{border-top-width:0}.br-0-l{border-right-width:0}.bb-0-l{border-bottom-width:0}.bl-0-l{border-left-width:0}}.shadow-1{-webkit-box-shadow:0 0 4px 2px rgba(0,0,0,.2);box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2{-webkit-box-shadow:0 0 8px 2px rgba(0,0,0,.2);box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3{-webkit-box-shadow:2px 2px 4px 2px rgba(0,0,0,.2);box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4{-webkit-box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.shadow-5{-webkit-box-shadow:4px 4px 8px 0 rgba(0,0,0,.2);box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}@media screen and (min-width:30em){.shadow-1-ns{-webkit-box-shadow:0 0 4px 2px rgba(0,0,0,.2);box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2-ns{-webkit-box-shadow:0 0 8px 2px rgba(0,0,0,.2);box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3-ns{-webkit-box-shadow:2px 2px 4px 2px rgba(0,0,0,.2);box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4-ns{-webkit-box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.shadow-5-ns{-webkit-box-shadow:4px 4px 8px 0 rgba(0,0,0,.2);box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}@media screen and (min-width:30em) and (max-width:60em){.shadow-1-m{-webkit-box-shadow:0 0 4px 2px rgba(0,0,0,.2);box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2-m{-webkit-box-shadow:0 0 8px 2px rgba(0,0,0,.2);box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3-m{-webkit-box-shadow:2px 2px 4px 2px rgba(0,0,0,.2);box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4-m{-webkit-box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.shadow-5-m{-webkit-box-shadow:4px 4px 8px 0 rgba(0,0,0,.2);box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}@media screen and (min-width:60em){.shadow-1-l{-webkit-box-shadow:0 0 4px 2px rgba(0,0,0,.2);box-shadow:0 0 4px 2px rgba(0,0,0,.2)}.shadow-2-l{-webkit-box-shadow:0 0 8px 2px rgba(0,0,0,.2);box-shadow:0 0 8px 2px rgba(0,0,0,.2)}.shadow-3-l{-webkit-box-shadow:2px 2px 4px 2px rgba(0,0,0,.2);box-shadow:2px 2px 4px 2px rgba(0,0,0,.2)}.shadow-4-l{-webkit-box-shadow:2px 2px 8px 0 rgba(0,0,0,.2);box-shadow:2px 2px 8px 0 rgba(0,0,0,.2)}.shadow-5-l{-webkit-box-shadow:4px 4px 8px 0 rgba(0,0,0,.2);box-shadow:4px 4px 8px 0 rgba(0,0,0,.2)}}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.top-1{top:1rem}.right-1{right:1rem}.bottom-1{bottom:1rem}.left-1{left:1rem}.top-2{top:2rem}.right-2{right:2rem}.bottom-2{bottom:2rem}.left-2{left:2rem}.top--1{top:-1rem}.right--1{right:-1rem}.bottom--1{bottom:-1rem}.left--1{left:-1rem}.top--2{top:-2rem}.right--2{right:-2rem}.bottom--2{bottom:-2rem}.left--2{left:-2rem}.absolute--fill{top:0;right:0;bottom:0;left:0}@media screen and (min-width:30em){.top-0-ns{top:0}.left-0-ns{left:0}.right-0-ns{right:0}.bottom-0-ns{bottom:0}.top-1-ns{top:1rem}.left-1-ns{left:1rem}.right-1-ns{right:1rem}.bottom-1-ns{bottom:1rem}.top-2-ns{top:2rem}.left-2-ns{left:2rem}.right-2-ns{right:2rem}.bottom-2-ns{bottom:2rem}.top--1-ns{top:-1rem}.right--1-ns{right:-1rem}.bottom--1-ns{bottom:-1rem}.left--1-ns{left:-1rem}.top--2-ns{top:-2rem}.right--2-ns{right:-2rem}.bottom--2-ns{bottom:-2rem}.left--2-ns{left:-2rem}.absolute--fill-ns{top:0;right:0;bottom:0;left:0}}@media screen and (min-width:30em) and (max-width:60em){.top-0-m{top:0}.left-0-m{left:0}.right-0-m{right:0}.bottom-0-m{bottom:0}.top-1-m{top:1rem}.left-1-m{left:1rem}.right-1-m{right:1rem}.bottom-1-m{bottom:1rem}.top-2-m{top:2rem}.left-2-m{left:2rem}.right-2-m{right:2rem}.bottom-2-m{bottom:2rem}.top--1-m{top:-1rem}.right--1-m{right:-1rem}.bottom--1-m{bottom:-1rem}.left--1-m{left:-1rem}.top--2-m{top:-2rem}.right--2-m{right:-2rem}.bottom--2-m{bottom:-2rem}.left--2-m{left:-2rem}.absolute--fill-m{top:0;right:0;bottom:0;left:0}}@media screen and (min-width:60em){.top-0-l{top:0}.left-0-l{left:0}.right-0-l{right:0}.bottom-0-l{bottom:0}.top-1-l{top:1rem}.left-1-l{left:1rem}.right-1-l{right:1rem}.bottom-1-l{bottom:1rem}.top-2-l{top:2rem}.left-2-l{left:2rem}.right-2-l{right:2rem}.bottom-2-l{bottom:2rem}.top--1-l{top:-1rem}.right--1-l{right:-1rem}.bottom--1-l{bottom:-1rem}.left--1-l{left:-1rem}.top--2-l{top:-2rem}.right--2-l{right:-2rem}.bottom--2-l{bottom:-2rem}.left--2-l{left:-2rem}.absolute--fill-l{top:0;right:0;bottom:0;left:0}}.cf:before,.cf:after{content:" ";display:table}.cf:after{clear:both}.cf{*zoom:1}.cl{clear:left}.cr{clear:right}.cb{clear:both}.cn{clear:none}@media screen and (min-width:30em){.cl-ns{clear:left}.cr-ns{clear:right}.cb-ns{clear:both}.cn-ns{clear:none}}@media screen and (min-width:30em) and (max-width:60em){.cl-m{clear:left}.cr-m{clear:right}.cb-m{clear:both}.cn-m{clear:none}}@media screen and (min-width:60em){.cl-l{clear:left}.cr-l{clear:right}.cb-l{clear:both}.cn-l{clear:none}}.dn{display:none}.di{display:inline}.db{display:block}.dib{display:inline-block}.dit{display:inline-table}.dt{display:table}.dtc{display:table-cell}.dt-row{display:table-row}.dt-row-group{display:table-row-group}.dt-column{display:table-column}.dt-column-group{display:table-column-group}.dt--fixed{table-layout:fixed;width:100%}@media screen and (min-width:30em){.dn-ns{display:none}.di-ns{display:inline}.db-ns{display:block}.dib-ns{display:inline-block}.dit-ns{display:inline-table}.dt-ns{display:table}.dtc-ns{display:table-cell}.dt-row-ns{display:table-row}.dt-row-group-ns{display:table-row-group}.dt-column-ns{display:table-column}.dt-column-group-ns{display:table-column-group}.dt--fixed-ns{table-layout:fixed;width:100%}}@media screen and (min-width:30em) and (max-width:60em){.dn-m{display:none}.di-m{display:inline}.db-m{display:block}.dib-m{display:inline-block}.dit-m{display:inline-table}.dt-m{display:table}.dtc-m{display:table-cell}.dt-row-m{display:table-row}.dt-row-group-m{display:table-row-group}.dt-column-m{display:table-column}.dt-column-group-m{display:table-column-group}.dt--fixed-m{table-layout:fixed;width:100%}}@media screen and (min-width:60em){.dn-l{display:none}.di-l{display:inline}.db-l{display:block}.dib-l{display:inline-block}.dit-l{display:inline-table}.dt-l{display:table}.dtc-l{display:table-cell}.dt-row-l{display:table-row}.dt-row-group-l{display:table-row-group}.dt-column-l{display:table-column}.dt-column-group-l{display:table-column-group}.dt--fixed-l{table-layout:fixed;width:100%}}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}.inline-flex{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.flex-auto{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;min-width:0;min-height:0}.flex-none{-webkit-box-flex:0;-ms-flex:none;flex:none}.flex-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.flex-row{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.flex-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-nowrap{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.flex-column-reverse{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-row-reverse{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.items-start{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.items-end{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.items-center{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.items-baseline{-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.items-stretch{-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.self-start{-ms-flex-item-align:start;align-self:flex-start}.self-end{-ms-flex-item-align:end;align-self:flex-end}.self-center{-ms-flex-item-align:center;align-self:center}.self-baseline{-ms-flex-item-align:baseline;align-self:baseline}.self-stretch{-ms-flex-item-align:stretch;align-self:stretch}.justify-start{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.justify-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.justify-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.justify-around{-ms-flex-pack:distribute;justify-content:space-around}.content-start{-ms-flex-line-pack:start;align-content:flex-start}.content-end{-ms-flex-line-pack:end;align-content:flex-end}.content-center{-ms-flex-line-pack:center;align-content:center}.content-between{-ms-flex-line-pack:justify;align-content:space-between}.content-around{-ms-flex-line-pack:distribute;align-content:space-around}.content-stretch{-ms-flex-line-pack:stretch;align-content:stretch}.order-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-last{-webkit-box-ordinal-group:100000;-ms-flex-order:99999;order:99999}.flex-grow-0{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.flex-grow-1{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.flex-shrink-0{-ms-flex-negative:0;flex-shrink:0}.flex-shrink-1{-ms-flex-negative:1;flex-shrink:1}@media screen and (min-width:30em){.flex-ns{display:-webkit-box;display:-ms-flexbox;display:flex}.inline-flex-ns{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.flex-auto-ns{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;min-width:0;min-height:0}.flex-none-ns{-webkit-box-flex:0;-ms-flex:none;flex:none}.flex-column-ns{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.flex-row-ns{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.flex-wrap-ns{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-nowrap-ns{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-wrap-reverse-ns{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.flex-column-reverse-ns{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-row-reverse-ns{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.items-start-ns{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.items-end-ns{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.items-center-ns{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.items-baseline-ns{-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.items-stretch-ns{-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.self-start-ns{-ms-flex-item-align:start;align-self:flex-start}.self-end-ns{-ms-flex-item-align:end;align-self:flex-end}.self-center-ns{-ms-flex-item-align:center;align-self:center}.self-baseline-ns{-ms-flex-item-align:baseline;align-self:baseline}.self-stretch-ns{-ms-flex-item-align:stretch;align-self:stretch}.justify-start-ns{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.justify-end-ns{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.justify-center-ns{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-between-ns{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.justify-around-ns{-ms-flex-pack:distribute;justify-content:space-around}.content-start-ns{-ms-flex-line-pack:start;align-content:flex-start}.content-end-ns{-ms-flex-line-pack:end;align-content:flex-end}.content-center-ns{-ms-flex-line-pack:center;align-content:center}.content-between-ns{-ms-flex-line-pack:justify;align-content:space-between}.content-around-ns{-ms-flex-line-pack:distribute;align-content:space-around}.content-stretch-ns{-ms-flex-line-pack:stretch;align-content:stretch}.order-0-ns{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1-ns{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2-ns{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3-ns{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4-ns{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5-ns{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-6-ns{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-7-ns{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-8-ns{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-last-ns{-webkit-box-ordinal-group:100000;-ms-flex-order:99999;order:99999}.flex-grow-0-ns{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.flex-grow-1-ns{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.flex-shrink-0-ns{-ms-flex-negative:0;flex-shrink:0}.flex-shrink-1-ns{-ms-flex-negative:1;flex-shrink:1}}@media screen and (min-width:30em) and (max-width:60em){.flex-m{display:-webkit-box;display:-ms-flexbox;display:flex}.inline-flex-m{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.flex-auto-m{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;min-width:0;min-height:0}.flex-none-m{-webkit-box-flex:0;-ms-flex:none;flex:none}.flex-column-m{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.flex-row-m{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.flex-wrap-m{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-nowrap-m{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-wrap-reverse-m{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.flex-column-reverse-m{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-row-reverse-m{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.items-start-m{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.items-end-m{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.items-center-m{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.items-baseline-m{-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.items-stretch-m{-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.self-start-m{-ms-flex-item-align:start;align-self:flex-start}.self-end-m{-ms-flex-item-align:end;align-self:flex-end}.self-center-m{-ms-flex-item-align:center;align-self:center}.self-baseline-m{-ms-flex-item-align:baseline;align-self:baseline}.self-stretch-m{-ms-flex-item-align:stretch;align-self:stretch}.justify-start-m{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.justify-end-m{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.justify-center-m{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-between-m{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.justify-around-m{-ms-flex-pack:distribute;justify-content:space-around}.content-start-m{-ms-flex-line-pack:start;align-content:flex-start}.content-end-m{-ms-flex-line-pack:end;align-content:flex-end}.content-center-m{-ms-flex-line-pack:center;align-content:center}.content-between-m{-ms-flex-line-pack:justify;align-content:space-between}.content-around-m{-ms-flex-line-pack:distribute;align-content:space-around}.content-stretch-m{-ms-flex-line-pack:stretch;align-content:stretch}.order-0-m{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1-m{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2-m{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3-m{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4-m{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5-m{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-6-m{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-7-m{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-8-m{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-last-m{-webkit-box-ordinal-group:100000;-ms-flex-order:99999;order:99999}.flex-grow-0-m{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.flex-grow-1-m{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.flex-shrink-0-m{-ms-flex-negative:0;flex-shrink:0}.flex-shrink-1-m{-ms-flex-negative:1;flex-shrink:1}}@media screen and (min-width:60em){.flex-l{display:-webkit-box;display:-ms-flexbox;display:flex}.inline-flex-l{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.flex-auto-l{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;min-width:0;min-height:0}.flex-none-l{-webkit-box-flex:0;-ms-flex:none;flex:none}.flex-column-l{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.flex-row-l{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.flex-wrap-l{-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-nowrap-l{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.flex-wrap-reverse-l{-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse}.flex-column-reverse-l{-webkit-box-orient:vertical;-webkit-box-direction:reverse;-ms-flex-direction:column-reverse;flex-direction:column-reverse}.flex-row-reverse-l{-webkit-box-orient:horizontal;-webkit-box-direction:reverse;-ms-flex-direction:row-reverse;flex-direction:row-reverse}.items-start-l{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.items-end-l{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.items-center-l{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.items-baseline-l{-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.items-stretch-l{-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.self-start-l{-ms-flex-item-align:start;align-self:flex-start}.self-end-l{-ms-flex-item-align:end;align-self:flex-end}.self-center-l{-ms-flex-item-align:center;align-self:center}.self-baseline-l{-ms-flex-item-align:baseline;align-self:baseline}.self-stretch-l{-ms-flex-item-align:stretch;align-self:stretch}.justify-start-l{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.justify-end-l{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.justify-center-l{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-between-l{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.justify-around-l{-ms-flex-pack:distribute;justify-content:space-around}.content-start-l{-ms-flex-line-pack:start;align-content:flex-start}.content-end-l{-ms-flex-line-pack:end;align-content:flex-end}.content-center-l{-ms-flex-line-pack:center;align-content:center}.content-between-l{-ms-flex-line-pack:justify;align-content:space-between}.content-around-l{-ms-flex-line-pack:distribute;align-content:space-around}.content-stretch-l{-ms-flex-line-pack:stretch;align-content:stretch}.order-0-l{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1-l{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2-l{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3-l{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4-l{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5-l{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-6-l{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-7-l{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-8-l{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-last-l{-webkit-box-ordinal-group:100000;-ms-flex-order:99999;order:99999}.flex-grow-0-l{-webkit-box-flex:0;-ms-flex-positive:0;flex-grow:0}.flex-grow-1-l{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.flex-shrink-0-l{-ms-flex-negative:0;flex-shrink:0}.flex-shrink-1-l{-ms-flex-negative:1;flex-shrink:1}}.fl{float:left;_display:inline}.fr{float:right;_display:inline}.fn{float:none}@media screen and (min-width:30em){.fl-ns{float:left;_display:inline}.fr-ns{float:right;_display:inline}.fn-ns{float:none}}@media screen and (min-width:30em) and (max-width:60em){.fl-m{float:left;_display:inline}.fr-m{float:right;_display:inline}.fn-m{float:none}}@media screen and (min-width:60em){.fl-l{float:left;_display:inline}.fr-l{float:right;_display:inline}.fn-l{float:none}}.i{font-style:italic}.fs-normal{font-style:normal}@media screen and (min-width:30em){.i-ns{font-style:italic}.fs-normal-ns{font-style:normal}}@media screen and (min-width:30em) and (max-width:60em){.i-m{font-style:italic}.fs-normal-m{font-style:normal}}@media screen and (min-width:60em){.i-l{font-style:italic}.fs-normal-l{font-style:normal}}.normal{font-weight:400}.b{font-weight:700}.fw1{font-weight:100}.fw2{font-weight:200}.fw3{font-weight:300}.fw4{font-weight:400}.fw5{font-weight:500}.fw6{font-weight:600}.fw7{font-weight:700}.fw8{font-weight:800}.fw9{font-weight:900}@media screen and (min-width:30em){.normal-ns{font-weight:400}.b-ns{font-weight:700}.fw1-ns{font-weight:100}.fw2-ns{font-weight:200}.fw3-ns{font-weight:300}.fw4-ns{font-weight:400}.fw5-ns{font-weight:500}.fw6-ns{font-weight:600}.fw7-ns{font-weight:700}.fw8-ns{font-weight:800}.fw9-ns{font-weight:900}}@media screen and (min-width:30em) and (max-width:60em){.normal-m{font-weight:400}.b-m{font-weight:700}.fw1-m{font-weight:100}.fw2-m{font-weight:200}.fw3-m{font-weight:300}.fw4-m{font-weight:400}.fw5-m{font-weight:500}.fw6-m{font-weight:600}.fw7-m{font-weight:700}.fw8-m{font-weight:800}.fw9-m{font-weight:900}}@media screen and (min-width:60em){.normal-l{font-weight:400}.b-l{font-weight:700}.fw1-l{font-weight:100}.fw2-l{font-weight:200}.fw3-l{font-weight:300}.fw4-l{font-weight:400}.fw5-l{font-weight:500}.fw6-l{font-weight:600}.fw7-l{font-weight:700}.fw8-l{font-weight:800}.fw9-l{font-weight:900}}.input-reset{-webkit-appearance:none;-moz-appearance:none}.button-reset::-moz-focus-inner,.input-reset::-moz-focus-inner{border:0;padding:0}.h1{height:1rem}.h2{height:2rem}.h3{height:4rem}.h4{height:8rem}.h5{height:16rem}.h-25{height:25%}.h-50{height:50%}.h-75{height:75%}.h-100{height:100%}.min-h-100{min-height:100%}.vh-25{height:25vh}.vh-50{height:50vh}.vh-75{height:75vh}.vh-100{height:100vh}.min-vh-100{min-height:100vh}.h-auto{height:auto}.h-inherit{height:inherit}@media screen and (min-width:30em){.h1-ns{height:1rem}.h2-ns{height:2rem}.h3-ns{height:4rem}.h4-ns{height:8rem}.h5-ns{height:16rem}.h-25-ns{height:25%}.h-50-ns{height:50%}.h-75-ns{height:75%}.h-100-ns{height:100%}.min-h-100-ns{min-height:100%}.vh-25-ns{height:25vh}.vh-50-ns{height:50vh}.vh-75-ns{height:75vh}.vh-100-ns{height:100vh}.min-vh-100-ns{min-height:100vh}.h-auto-ns{height:auto}.h-inherit-ns{height:inherit}}@media screen and (min-width:30em) and (max-width:60em){.h1-m{height:1rem}.h2-m{height:2rem}.h3-m{height:4rem}.h4-m{height:8rem}.h5-m{height:16rem}.h-25-m{height:25%}.h-50-m{height:50%}.h-75-m{height:75%}.h-100-m{height:100%}.min-h-100-m{min-height:100%}.vh-25-m{height:25vh}.vh-50-m{height:50vh}.vh-75-m{height:75vh}.vh-100-m{height:100vh}.min-vh-100-m{min-height:100vh}.h-auto-m{height:auto}.h-inherit-m{height:inherit}}@media screen and (min-width:60em){.h1-l{height:1rem}.h2-l{height:2rem}.h3-l{height:4rem}.h4-l{height:8rem}.h5-l{height:16rem}.h-25-l{height:25%}.h-50-l{height:50%}.h-75-l{height:75%}.h-100-l{height:100%}.min-h-100-l{min-height:100%}.vh-25-l{height:25vh}.vh-50-l{height:50vh}.vh-75-l{height:75vh}.vh-100-l{height:100vh}.min-vh-100-l{min-height:100vh}.h-auto-l{height:auto}.h-inherit-l{height:inherit}}.tracked{letter-spacing:.1em}.tracked-tight{letter-spacing:-.05em}.tracked-mega{letter-spacing:.25em}@media screen and (min-width:30em){.tracked-ns{letter-spacing:.1em}.tracked-tight-ns{letter-spacing:-.05em}.tracked-mega-ns{letter-spacing:.25em}}@media screen and (min-width:30em) and (max-width:60em){.tracked-m{letter-spacing:.1em}.tracked-tight-m{letter-spacing:-.05em}.tracked-mega-m{letter-spacing:.25em}}@media screen and (min-width:60em){.tracked-l{letter-spacing:.1em}.tracked-tight-l{letter-spacing:-.05em}.tracked-mega-l{letter-spacing:.25em}}.lh-solid{line-height:1}.lh-title{line-height:1.25}.lh-copy{line-height:1.5}@media screen and (min-width:30em){.lh-solid-ns{line-height:1}.lh-title-ns{line-height:1.25}.lh-copy-ns{line-height:1.5}}@media screen and (min-width:30em) and (max-width:60em){.lh-solid-m{line-height:1}.lh-title-m{line-height:1.25}.lh-copy-m{line-height:1.5}}@media screen and (min-width:60em){.lh-solid-l{line-height:1}.lh-title-l{line-height:1.25}.lh-copy-l{line-height:1.5}}.link{text-decoration:none;-webkit-transition:color .15s ease-in;transition:color .15s ease-in}.link:link,.link:visited{-webkit-transition:color .15s ease-in;transition:color .15s ease-in}.link:hover{-webkit-transition:color .15s ease-in;transition:color .15s ease-in}.link:active{-webkit-transition:color .15s ease-in;transition:color .15s ease-in}.link:focus{-webkit-transition:color .15s ease-in;transition:color .15s ease-in;outline:1px dotted currentColor}.list{list-style-type:none}.mw-100{max-width:100%}.mw1{max-width:1rem}.mw2{max-width:2rem}.mw3{max-width:4rem}.mw4{max-width:8rem}.mw5{max-width:16rem}.mw6{max-width:32rem}.mw7{max-width:48rem}.mw8{max-width:64rem}.mw9{max-width:96rem}.mw-none{max-width:none}@media screen and (min-width:30em){.mw-100-ns{max-width:100%}.mw1-ns{max-width:1rem}.mw2-ns{max-width:2rem}.mw3-ns{max-width:4rem}.mw4-ns{max-width:8rem}.mw5-ns{max-width:16rem}.mw6-ns{max-width:32rem}.mw7-ns{max-width:48rem}.mw8-ns{max-width:64rem}.mw9-ns{max-width:96rem}.mw-none-ns{max-width:none}}@media screen and (min-width:30em) and (max-width:60em){.mw-100-m{max-width:100%}.mw1-m{max-width:1rem}.mw2-m{max-width:2rem}.mw3-m{max-width:4rem}.mw4-m{max-width:8rem}.mw5-m{max-width:16rem}.mw6-m{max-width:32rem}.mw7-m{max-width:48rem}.mw8-m{max-width:64rem}.mw9-m{max-width:96rem}.mw-none-m{max-width:none}}@media screen and (min-width:60em){.mw-100-l{max-width:100%}.mw1-l{max-width:1rem}.mw2-l{max-width:2rem}.mw3-l{max-width:4rem}.mw4-l{max-width:8rem}.mw5-l{max-width:16rem}.mw6-l{max-width:32rem}.mw7-l{max-width:48rem}.mw8-l{max-width:64rem}.mw9-l{max-width:96rem}.mw-none-l{max-width:none}}.w1{width:1rem}.w2{width:2rem}.w3{width:4rem}.w4{width:8rem}.w5{width:16rem}.w-10{width:10%}.w-20{width:20%}.w-25{width:25%}.w-30{width:30%}.w-33{width:33%}.w-34{width:34%}.w-40{width:40%}.w-50{width:50%}.w-60{width:60%}.w-70{width:70%}.w-75{width:75%}.w-80{width:80%}.w-90{width:90%}.w-100{width:100%}.w-third{width:33.33333%}.w-two-thirds{width:66.66667%}.w-auto{width:auto}@media screen and (min-width:30em){.w1-ns{width:1rem}.w2-ns{width:2rem}.w3-ns{width:4rem}.w4-ns{width:8rem}.w5-ns{width:16rem}.w-10-ns{width:10%}.w-20-ns{width:20%}.w-25-ns{width:25%}.w-30-ns{width:30%}.w-33-ns{width:33%}.w-34-ns{width:34%}.w-40-ns{width:40%}.w-50-ns{width:50%}.w-60-ns{width:60%}.w-70-ns{width:70%}.w-75-ns{width:75%}.w-80-ns{width:80%}.w-90-ns{width:90%}.w-100-ns{width:100%}.w-third-ns{width:33.33333%}.w-two-thirds-ns{width:66.66667%}.w-auto-ns{width:auto}}@media screen and (min-width:30em) and (max-width:60em){.w1-m{width:1rem}.w2-m{width:2rem}.w3-m{width:4rem}.w4-m{width:8rem}.w5-m{width:16rem}.w-10-m{width:10%}.w-20-m{width:20%}.w-25-m{width:25%}.w-30-m{width:30%}.w-33-m{width:33%}.w-34-m{width:34%}.w-40-m{width:40%}.w-50-m{width:50%}.w-60-m{width:60%}.w-70-m{width:70%}.w-75-m{width:75%}.w-80-m{width:80%}.w-90-m{width:90%}.w-100-m{width:100%}.w-third-m{width:33.33333%}.w-two-thirds-m{width:66.66667%}.w-auto-m{width:auto}}@media screen and (min-width:60em){.w1-l{width:1rem}.w2-l{width:2rem}.w3-l{width:4rem}.w4-l{width:8rem}.w5-l{width:16rem}.w-10-l{width:10%}.w-20-l{width:20%}.w-25-l{width:25%}.w-30-l{width:30%}.w-33-l{width:33%}.w-34-l{width:34%}.w-40-l{width:40%}.w-50-l{width:50%}.w-60-l{width:60%}.w-70-l{width:70%}.w-75-l{width:75%}.w-80-l{width:80%}.w-90-l{width:90%}.w-100-l{width:100%}.w-third-l{width:33.33333%}.w-two-thirds-l{width:66.66667%}.w-auto-l{width:auto}}.overflow-visible{overflow:visible}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-auto{overflow:auto}.overflow-x-visible{overflow-x:visible}.overflow-x-hidden{overflow-x:hidden}.overflow-x-scroll{overflow-x:scroll}.overflow-x-auto{overflow-x:auto}.overflow-y-visible{overflow-y:visible}.overflow-y-hidden{overflow-y:hidden}.overflow-y-scroll{overflow-y:scroll}.overflow-y-auto{overflow-y:auto}@media screen and (min-width:30em){.overflow-visible-ns{overflow:visible}.overflow-hidden-ns{overflow:hidden}.overflow-scroll-ns{overflow:scroll}.overflow-auto-ns{overflow:auto}.overflow-x-visible-ns{overflow-x:visible}.overflow-x-hidden-ns{overflow-x:hidden}.overflow-x-scroll-ns{overflow-x:scroll}.overflow-x-auto-ns{overflow-x:auto}.overflow-y-visible-ns{overflow-y:visible}.overflow-y-hidden-ns{overflow-y:hidden}.overflow-y-scroll-ns{overflow-y:scroll}.overflow-y-auto-ns{overflow-y:auto}}@media screen and (min-width:30em) and (max-width:60em){.overflow-visible-m{overflow:visible}.overflow-hidden-m{overflow:hidden}.overflow-scroll-m{overflow:scroll}.overflow-auto-m{overflow:auto}.overflow-x-visible-m{overflow-x:visible}.overflow-x-hidden-m{overflow-x:hidden}.overflow-x-scroll-m{overflow-x:scroll}.overflow-x-auto-m{overflow-x:auto}.overflow-y-visible-m{overflow-y:visible}.overflow-y-hidden-m{overflow-y:hidden}.overflow-y-scroll-m{overflow-y:scroll}.overflow-y-auto-m{overflow-y:auto}}@media screen and (min-width:60em){.overflow-visible-l{overflow:visible}.overflow-hidden-l{overflow:hidden}.overflow-scroll-l{overflow:scroll}.overflow-auto-l{overflow:auto}.overflow-x-visible-l{overflow-x:visible}.overflow-x-hidden-l{overflow-x:hidden}.overflow-x-scroll-l{overflow-x:scroll}.overflow-x-auto-l{overflow-x:auto}.overflow-y-visible-l{overflow-y:visible}.overflow-y-hidden-l{overflow-y:hidden}.overflow-y-scroll-l{overflow-y:scroll}.overflow-y-auto-l{overflow-y:auto}}.static{position:static}.relative{position:relative}.absolute{position:absolute}.fixed{position:fixed}@media screen and (min-width:30em){.static-ns{position:static}.relative-ns{position:relative}.absolute-ns{position:absolute}.fixed-ns{position:fixed}}@media screen and (min-width:30em) and (max-width:60em){.static-m{position:static}.relative-m{position:relative}.absolute-m{position:absolute}.fixed-m{position:fixed}}@media screen and (min-width:60em){.static-l{position:static}.relative-l{position:relative}.absolute-l{position:absolute}.fixed-l{position:fixed}}.o-100{opacity:1}.o-90{opacity:.9}.o-80{opacity:.8}.o-70{opacity:.7}.o-60{opacity:.6}.o-50{opacity:.5}.o-40{opacity:.4}.o-30{opacity:.3}.o-20{opacity:.2}.o-10{opacity:.1}.o-05{opacity:.05}.o-025{opacity:.025}.o-0{opacity:0}.black-90{color:rgba(0,0,0,.9)}.black-80{color:rgba(0,0,0,.8)}.black-70{color:rgba(0,0,0,.7)}.black-60{color:rgba(0,0,0,.6)}.black-50{color:rgba(0,0,0,.5)}.black-40{color:rgba(0,0,0,.4)}.black-30{color:rgba(0,0,0,.3)}.black-20{color:rgba(0,0,0,.2)}.black-10{color:rgba(0,0,0,.1)}.black-05{color:rgba(0,0,0,.05)}.white-90{color:rgba(255,255,255,.9)}.white-80{color:rgba(255,255,255,.8)}.white-70{color:rgba(255,255,255,.7)}.white-60{color:rgba(255,255,255,.6)}.white-50{color:rgba(255,255,255,.5)}.white-40{color:rgba(255,255,255,.4)}.white-30{color:rgba(255,255,255,.3)}.white-20{color:rgba(255,255,255,.2)}.white-10{color:rgba(255,255,255,.1)}.black{color:#000}.near-black{color:#111}.dark-gray{color:#333}.mid-gray{color:#555}.gray{color:#777}.silver{color:#999}.light-silver{color:#aaa}.moon-gray{color:#ccc}.light-gray{color:#eee}.near-white{color:#f4f4f4}.white{color:#fff}.dark-red{color:#e7040f}.red{color:#ff4136}.light-red{color:#ff725c}.orange{color:#ff6300}.gold{color:#ffb700}.yellow{color:gold}.light-yellow{color:#fbf1a9}.purple{color:#5e2ca5}.light-purple{color:#a463f2}.dark-pink{color:#d5008f}.hot-pink{color:#ff41b4}.pink{color:#ff80cc}.light-pink{color:#ffa3d7}.dark-green{color:#137752}.green{color:#19a974}.light-green{color:#9eebcf}.navy{color:#001b44}.dark-blue{color:#00449e}.blue{color:#0594cb}.light-blue{color:#96ccff}.lightest-blue{color:#cdecff}.washed-blue{color:#f6fffe}.washed-green{color:#e8fdf5}.washed-yellow{color:#fffceb}.washed-red{color:#ffdfdf}.color-inherit{color:inherit}.bg-black-90{background-color:rgba(0,0,0,.9)}.bg-black-80{background-color:rgba(0,0,0,.8)}.bg-black-70{background-color:rgba(0,0,0,.7)}.bg-black-60{background-color:rgba(0,0,0,.6)}.bg-black-50{background-color:rgba(0,0,0,.5)}.bg-black-40{background-color:rgba(0,0,0,.4)}.bg-black-30{background-color:rgba(0,0,0,.3)}.bg-black-20{background-color:rgba(0,0,0,.2)}.bg-black-10{background-color:rgba(0,0,0,.1)}.bg-black-05{background-color:rgba(0,0,0,.05)}.bg-white-90{background-color:rgba(255,255,255,.9)}.bg-white-80{background-color:rgba(255,255,255,.8)}.bg-white-70{background-color:rgba(255,255,255,.7)}.bg-white-60{background-color:rgba(255,255,255,.6)}.bg-white-50{background-color:rgba(255,255,255,.5)}.bg-white-40{background-color:rgba(255,255,255,.4)}.bg-white-30{background-color:rgba(255,255,255,.3)}.bg-white-20{background-color:rgba(255,255,255,.2)}.bg-white-10{background-color:rgba(255,255,255,.1)}.bg-black{background-color:#000}.bg-near-black{background-color:#111}.bg-dark-gray{background-color:#333}.bg-mid-gray{background-color:#555}.bg-gray{background-color:#777}.bg-silver{background-color:#999}.bg-light-silver{background-color:#aaa}.bg-moon-gray{background-color:#ccc}.bg-light-gray{background-color:#eee}.bg-near-white{background-color:#f4f4f4}.bg-white{background-color:#fff}.bg-transparent{background-color:transparent}.bg-dark-red{background-color:#e7040f}.bg-red{background-color:#ff4136}.bg-light-red{background-color:#ff725c}.bg-orange{background-color:#ff6300}.bg-gold{background-color:#ffb700}.bg-yellow{background-color:gold}.bg-light-yellow{background-color:#fbf1a9}.bg-purple{background-color:#5e2ca5}.bg-light-purple{background-color:#a463f2}.bg-dark-pink{background-color:#d5008f}.bg-hot-pink{background-color:#ff41b4}.bg-pink{background-color:#ff80cc}.bg-light-pink{background-color:#ffa3d7}.bg-dark-green{background-color:#137752}.bg-green{background-color:#19a974}.bg-light-green{background-color:#9eebcf}.bg-navy{background-color:#001b44}.bg-dark-blue{background-color:#00449e}.bg-blue{background-color:#0594cb}.bg-light-blue{background-color:#96ccff}.bg-lightest-blue{background-color:#cdecff}.bg-washed-blue{background-color:#f6fffe}.bg-washed-green{background-color:#e8fdf5}.bg-washed-yellow{background-color:#fffceb}.bg-washed-red{background-color:#ffdfdf}.bg-inherit{background-color:inherit}.hover-black:hover,.hover-black:focus{color:#000}.hover-near-black:hover,.hover-near-black:focus{color:#111}.hover-dark-gray:hover,.hover-dark-gray:focus{color:#333}.hover-mid-gray:hover,.hover-mid-gray:focus{color:#555}.hover-gray:hover,.hover-gray:focus{color:#777}.hover-silver:hover,.hover-silver:focus{color:#999}.hover-light-silver:hover,.hover-light-silver:focus{color:#aaa}.hover-moon-gray:hover,.hover-moon-gray:focus{color:#ccc}.hover-light-gray:hover,.hover-light-gray:focus{color:#eee}.hover-near-white:hover,.hover-near-white:focus{color:#f4f4f4}.hover-white:hover,.hover-white:focus{color:#fff}.hover-black-90:hover,.hover-black-90:focus{color:rgba(0,0,0,.9)}.hover-black-80:hover,.hover-black-80:focus{color:rgba(0,0,0,.8)}.hover-black-70:hover,.hover-black-70:focus{color:rgba(0,0,0,.7)}.hover-black-60:hover,.hover-black-60:focus{color:rgba(0,0,0,.6)}.hover-black-50:hover,.hover-black-50:focus{color:rgba(0,0,0,.5)}.hover-black-40:hover,.hover-black-40:focus{color:rgba(0,0,0,.4)}.hover-black-30:hover,.hover-black-30:focus{color:rgba(0,0,0,.3)}.hover-black-20:hover,.hover-black-20:focus{color:rgba(0,0,0,.2)}.hover-black-10:hover,.hover-black-10:focus{color:rgba(0,0,0,.1)}.hover-white-90:hover,.hover-white-90:focus{color:rgba(255,255,255,.9)}.hover-white-80:hover,.hover-white-80:focus{color:rgba(255,255,255,.8)}.hover-white-70:hover,.hover-white-70:focus{color:rgba(255,255,255,.7)}.hover-white-60:hover,.hover-white-60:focus{color:rgba(255,255,255,.6)}.hover-white-50:hover,.hover-white-50:focus{color:rgba(255,255,255,.5)}.hover-white-40:hover,.hover-white-40:focus{color:rgba(255,255,255,.4)}.hover-white-30:hover,.hover-white-30:focus{color:rgba(255,255,255,.3)}.hover-white-20:hover,.hover-white-20:focus{color:rgba(255,255,255,.2)}.hover-white-10:hover,.hover-white-10:focus{color:rgba(255,255,255,.1)}.hover-inherit:hover,.hover-inherit:focus{color:inherit}.hover-bg-black:hover,.hover-bg-black:focus{background-color:#000}.hover-bg-near-black:hover,.hover-bg-near-black:focus{background-color:#111}.hover-bg-dark-gray:hover,.hover-bg-dark-gray:focus{background-color:#333}.hover-bg-mid-gray:hover,.hover-bg-mid-gray:focus{background-color:#555}.hover-bg-gray:hover,.hover-bg-gray:focus{background-color:#777}.hover-bg-silver:hover,.hover-bg-silver:focus{background-color:#999}.hover-bg-light-silver:hover,.hover-bg-light-silver:focus{background-color:#aaa}.hover-bg-moon-gray:hover,.hover-bg-moon-gray:focus{background-color:#ccc}.hover-bg-light-gray:hover,.hover-bg-light-gray:focus{background-color:#eee}.hover-bg-near-white:hover,.hover-bg-near-white:focus{background-color:#f4f4f4}.hover-bg-white:hover,.hover-bg-white:focus{background-color:#fff}.hover-bg-transparent:hover,.hover-bg-transparent:focus{background-color:transparent}.hover-bg-black-90:hover,.hover-bg-black-90:focus{background-color:rgba(0,0,0,.9)}.hover-bg-black-80:hover,.hover-bg-black-80:focus{background-color:rgba(0,0,0,.8)}.hover-bg-black-70:hover,.hover-bg-black-70:focus{background-color:rgba(0,0,0,.7)}.hover-bg-black-60:hover,.hover-bg-black-60:focus{background-color:rgba(0,0,0,.6)}.hover-bg-black-50:hover,.hover-bg-black-50:focus{background-color:rgba(0,0,0,.5)}.hover-bg-black-40:hover,.hover-bg-black-40:focus{background-color:rgba(0,0,0,.4)}.hover-bg-black-30:hover,.hover-bg-black-30:focus{background-color:rgba(0,0,0,.3)}.hover-bg-black-20:hover,.hover-bg-black-20:focus{background-color:rgba(0,0,0,.2)}.hover-bg-black-10:hover,.hover-bg-black-10:focus{background-color:rgba(0,0,0,.1)}.hover-bg-white-90:hover,.hover-bg-white-90:focus{background-color:rgba(255,255,255,.9)}.hover-bg-white-80:hover,.hover-bg-white-80:focus{background-color:rgba(255,255,255,.8)}.hover-bg-white-70:hover,.hover-bg-white-70:focus{background-color:rgba(255,255,255,.7)}.hover-bg-white-60:hover,.hover-bg-white-60:focus{background-color:rgba(255,255,255,.6)}.hover-bg-white-50:hover,.hover-bg-white-50:focus{background-color:rgba(255,255,255,.5)}.hover-bg-white-40:hover,.hover-bg-white-40:focus{background-color:rgba(255,255,255,.4)}.hover-bg-white-30:hover,.hover-bg-white-30:focus{background-color:rgba(255,255,255,.3)}.hover-bg-white-20:hover,.hover-bg-white-20:focus{background-color:rgba(255,255,255,.2)}.hover-bg-white-10:hover,.hover-bg-white-10:focus{background-color:rgba(255,255,255,.1)}.hover-dark-red:hover,.hover-dark-red:focus{color:#e7040f}.hover-red:hover,.hover-red:focus{color:#ff4136}.hover-light-red:hover,.hover-light-red:focus{color:#ff725c}.hover-orange:hover,.hover-orange:focus{color:#ff6300}.hover-gold:hover,.hover-gold:focus{color:#ffb700}.hover-yellow:hover,.hover-yellow:focus{color:gold}.hover-light-yellow:hover,.hover-light-yellow:focus{color:#fbf1a9}.hover-purple:hover,.hover-purple:focus{color:#5e2ca5}.hover-light-purple:hover,.hover-light-purple:focus{color:#a463f2}.hover-dark-pink:hover,.hover-dark-pink:focus{color:#d5008f}.hover-hot-pink:hover,.hover-hot-pink:focus{color:#ff41b4}.hover-pink:hover,.hover-pink:focus{color:#ff80cc}.hover-light-pink:hover,.hover-light-pink:focus{color:#ffa3d7}.hover-dark-green:hover,.hover-dark-green:focus{color:#137752}.hover-green:hover,.hover-green:focus{color:#19a974}.hover-light-green:hover,.hover-light-green:focus{color:#9eebcf}.hover-navy:hover,.hover-navy:focus{color:#001b44}.hover-dark-blue:hover,.hover-dark-blue:focus{color:#00449e}.hover-blue:hover,.hover-blue:focus{color:#0594cb}.hover-light-blue:hover,.hover-light-blue:focus{color:#96ccff}.hover-lightest-blue:hover,.hover-lightest-blue:focus{color:#cdecff}.hover-washed-blue:hover,.hover-washed-blue:focus{color:#f6fffe}.hover-washed-green:hover,.hover-washed-green:focus{color:#e8fdf5}.hover-washed-yellow:hover,.hover-washed-yellow:focus{color:#fffceb}.hover-washed-red:hover,.hover-washed-red:focus{color:#ffdfdf}.hover-bg-dark-red:hover,.hover-bg-dark-red:focus{background-color:#e7040f}.hover-bg-red:hover,.hover-bg-red:focus{background-color:#ff4136}.hover-bg-light-red:hover,.hover-bg-light-red:focus{background-color:#ff725c}.hover-bg-orange:hover,.hover-bg-orange:focus{background-color:#ff6300}.hover-bg-gold:hover,.hover-bg-gold:focus{background-color:#ffb700}.hover-bg-yellow:hover,.hover-bg-yellow:focus{background-color:gold}.hover-bg-light-yellow:hover,.hover-bg-light-yellow:focus{background-color:#fbf1a9}.hover-bg-purple:hover,.hover-bg-purple:focus{background-color:#5e2ca5}.hover-bg-light-purple:hover,.hover-bg-light-purple:focus{background-color:#a463f2}.hover-bg-dark-pink:hover,.hover-bg-dark-pink:focus{background-color:#d5008f}.hover-bg-hot-pink:hover,.hover-bg-hot-pink:focus{background-color:#ff41b4}.hover-bg-pink:hover,.hover-bg-pink:focus{background-color:#ff80cc}.hover-bg-light-pink:hover,.hover-bg-light-pink:focus{background-color:#ffa3d7}.hover-bg-dark-green:hover,.hover-bg-dark-green:focus{background-color:#137752}.hover-bg-green:hover,.hover-bg-green:focus{background-color:#19a974}.hover-bg-light-green:hover,.hover-bg-light-green:focus{background-color:#9eebcf}.hover-bg-navy:hover,.hover-bg-navy:focus{background-color:#001b44}.hover-bg-dark-blue:hover,.hover-bg-dark-blue:focus{background-color:#00449e}.hover-bg-blue:hover,.hover-bg-blue:focus{background-color:#0594cb}.hover-bg-light-blue:hover,.hover-bg-light-blue:focus{background-color:#96ccff}.hover-bg-lightest-blue:hover,.hover-bg-lightest-blue:focus{background-color:#cdecff}.hover-bg-washed-blue:hover,.hover-bg-washed-blue:focus{background-color:#f6fffe}.hover-bg-washed-green:hover,.hover-bg-washed-green:focus{background-color:#e8fdf5}.hover-bg-washed-yellow:hover,.hover-bg-washed-yellow:focus{background-color:#fffceb}.hover-bg-washed-red:hover,.hover-bg-washed-red:focus{background-color:#ffdfdf}.hover-bg-inherit:hover,.hover-bg-inherit:focus{background-color:inherit}.pa0{padding:0}.pa1{padding:.25rem}.pa2{padding:.5rem}.pa3{padding:1rem}.pa4{padding:2rem}.pa5{padding:4rem}.pa6{padding:8rem}.pa7{padding:16rem}.pl0{padding-left:0}.pl1{padding-left:.25rem}.pl2{padding-left:.5rem}.pl3{padding-left:1rem}.pl4{padding-left:2rem}.pl5{padding-left:4rem}.pl6{padding-left:8rem}.pl7{padding-left:16rem}.pr0{padding-right:0}.pr1{padding-right:.25rem}.pr2{padding-right:.5rem}.pr3{padding-right:1rem}.pr4{padding-right:2rem}.pr5{padding-right:4rem}.pr6{padding-right:8rem}.pr7{padding-right:16rem}.pb0{padding-bottom:0}.pb1{padding-bottom:.25rem}.pb2{padding-bottom:.5rem}.pb3{padding-bottom:1rem}.pb4{padding-bottom:2rem}.pb5{padding-bottom:4rem}.pb6{padding-bottom:8rem}.pb7{padding-bottom:16rem}.pt0{padding-top:0}.pt1{padding-top:.25rem}.pt2{padding-top:.5rem}.pt3{padding-top:1rem}.pt4{padding-top:2rem}.pt5{padding-top:4rem}.pt6{padding-top:8rem}.pt7{padding-top:16rem}.pv0{padding-top:0;padding-bottom:0}.pv1{padding-top:.25rem;padding-bottom:.25rem}.pv2{padding-top:.5rem;padding-bottom:.5rem}.pv3{padding-top:1rem;padding-bottom:1rem}.pv4{padding-top:2rem;padding-bottom:2rem}.pv5{padding-top:4rem;padding-bottom:4rem}.pv6{padding-top:8rem;padding-bottom:8rem}.pv7{padding-top:16rem;padding-bottom:16rem}.ph0{padding-left:0;padding-right:0}.ph1{padding-left:.25rem;padding-right:.25rem}.ph2{padding-left:.5rem;padding-right:.5rem}.ph3{padding-left:1rem;padding-right:1rem}.ph4{padding-left:2rem;padding-right:2rem}.ph5{padding-left:4rem;padding-right:4rem}.ph6{padding-left:8rem;padding-right:8rem}.ph7{padding-left:16rem;padding-right:16rem}.ma0{margin:0}.ma1{margin:.25rem}.ma2{margin:.5rem}.ma3{margin:1rem}.ma4{margin:2rem}.ma5{margin:4rem}.ma6{margin:8rem}.ma7{margin:16rem}.ml0{margin-left:0}.ml1{margin-left:.25rem}.ml2{margin-left:.5rem}.ml3{margin-left:1rem}.ml4{margin-left:2rem}.ml5{margin-left:4rem}.ml6{margin-left:8rem}.ml7{margin-left:16rem}.mr0{margin-right:0}.mr1{margin-right:.25rem}.mr2{margin-right:.5rem}.mr3{margin-right:1rem}.mr4{margin-right:2rem}.mr5{margin-right:4rem}.mr6{margin-right:8rem}.mr7{margin-right:16rem}.mb0{margin-bottom:0}.mb1{margin-bottom:.25rem}.mb2{margin-bottom:.5rem}.mb3{margin-bottom:1rem}.mb4{margin-bottom:2rem}.mb5{margin-bottom:4rem}.mb6{margin-bottom:8rem}.mb7{margin-bottom:16rem}.mt0{margin-top:0}.mt1{margin-top:.25rem}.mt2{margin-top:.5rem}.mt3{margin-top:1rem}.mt4{margin-top:2rem}.mt5{margin-top:4rem}.mt6{margin-top:8rem}.mt7{margin-top:16rem}.mv0{margin-top:0;margin-bottom:0}.mv1{margin-top:.25rem;margin-bottom:.25rem}.mv2{margin-top:.5rem;margin-bottom:.5rem}.mv3{margin-top:1rem;margin-bottom:1rem}.mv4{margin-top:2rem;margin-bottom:2rem}.mv5{margin-top:4rem;margin-bottom:4rem}.mv6{margin-top:8rem;margin-bottom:8rem}.mv7{margin-top:16rem;margin-bottom:16rem}.mh0{margin-left:0;margin-right:0}.mh1{margin-left:.25rem;margin-right:.25rem}.mh2{margin-left:.5rem;margin-right:.5rem}.mh3{margin-left:1rem;margin-right:1rem}.mh4{margin-left:2rem;margin-right:2rem}.mh5{margin-left:4rem;margin-right:4rem}.mh6{margin-left:8rem;margin-right:8rem}.mh7{margin-left:16rem;margin-right:16rem}@media screen and (min-width:30em){.pa0-ns{padding:0}.pa1-ns{padding:.25rem}.pa2-ns{padding:.5rem}.pa3-ns{padding:1rem}.pa4-ns{padding:2rem}.pa5-ns{padding:4rem}.pa6-ns{padding:8rem}.pa7-ns{padding:16rem}.pl0-ns{padding-left:0}.pl1-ns{padding-left:.25rem}.pl2-ns{padding-left:.5rem}.pl3-ns{padding-left:1rem}.pl4-ns{padding-left:2rem}.pl5-ns{padding-left:4rem}.pl6-ns{padding-left:8rem}.pl7-ns{padding-left:16rem}.pr0-ns{padding-right:0}.pr1-ns{padding-right:.25rem}.pr2-ns{padding-right:.5rem}.pr3-ns{padding-right:1rem}.pr4-ns{padding-right:2rem}.pr5-ns{padding-right:4rem}.pr6-ns{padding-right:8rem}.pr7-ns{padding-right:16rem}.pb0-ns{padding-bottom:0}.pb1-ns{padding-bottom:.25rem}.pb2-ns{padding-bottom:.5rem}.pb3-ns{padding-bottom:1rem}.pb4-ns{padding-bottom:2rem}.pb5-ns{padding-bottom:4rem}.pb6-ns{padding-bottom:8rem}.pb7-ns{padding-bottom:16rem}.pt0-ns{padding-top:0}.pt1-ns{padding-top:.25rem}.pt2-ns{padding-top:.5rem}.pt3-ns{padding-top:1rem}.pt4-ns{padding-top:2rem}.pt5-ns{padding-top:4rem}.pt6-ns{padding-top:8rem}.pt7-ns{padding-top:16rem}.pv0-ns{padding-top:0;padding-bottom:0}.pv1-ns{padding-top:.25rem;padding-bottom:.25rem}.pv2-ns{padding-top:.5rem;padding-bottom:.5rem}.pv3-ns{padding-top:1rem;padding-bottom:1rem}.pv4-ns{padding-top:2rem;padding-bottom:2rem}.pv5-ns{padding-top:4rem;padding-bottom:4rem}.pv6-ns{padding-top:8rem;padding-bottom:8rem}.pv7-ns{padding-top:16rem;padding-bottom:16rem}.ph0-ns{padding-left:0;padding-right:0}.ph1-ns{padding-left:.25rem;padding-right:.25rem}.ph2-ns{padding-left:.5rem;padding-right:.5rem}.ph3-ns{padding-left:1rem;padding-right:1rem}.ph4-ns{padding-left:2rem;padding-right:2rem}.ph5-ns{padding-left:4rem;padding-right:4rem}.ph6-ns{padding-left:8rem;padding-right:8rem}.ph7-ns{padding-left:16rem;padding-right:16rem}.ma0-ns{margin:0}.ma1-ns{margin:.25rem}.ma2-ns{margin:.5rem}.ma3-ns{margin:1rem}.ma4-ns{margin:2rem}.ma5-ns{margin:4rem}.ma6-ns{margin:8rem}.ma7-ns{margin:16rem}.ml0-ns{margin-left:0}.ml1-ns{margin-left:.25rem}.ml2-ns{margin-left:.5rem}.ml3-ns{margin-left:1rem}.ml4-ns{margin-left:2rem}.ml5-ns{margin-left:4rem}.ml6-ns{margin-left:8rem}.ml7-ns{margin-left:16rem}.mr0-ns{margin-right:0}.mr1-ns{margin-right:.25rem}.mr2-ns{margin-right:.5rem}.mr3-ns{margin-right:1rem}.mr4-ns{margin-right:2rem}.mr5-ns{margin-right:4rem}.mr6-ns{margin-right:8rem}.mr7-ns{margin-right:16rem}.mb0-ns{margin-bottom:0}.mb1-ns{margin-bottom:.25rem}.mb2-ns{margin-bottom:.5rem}.mb3-ns{margin-bottom:1rem}.mb4-ns{margin-bottom:2rem}.mb5-ns{margin-bottom:4rem}.mb6-ns{margin-bottom:8rem}.mb7-ns{margin-bottom:16rem}.mt0-ns{margin-top:0}.mt1-ns{margin-top:.25rem}.mt2-ns{margin-top:.5rem}.mt3-ns{margin-top:1rem}.mt4-ns{margin-top:2rem}.mt5-ns{margin-top:4rem}.mt6-ns{margin-top:8rem}.mt7-ns{margin-top:16rem}.mv0-ns{margin-top:0;margin-bottom:0}.mv1-ns{margin-top:.25rem;margin-bottom:.25rem}.mv2-ns{margin-top:.5rem;margin-bottom:.5rem}.mv3-ns{margin-top:1rem;margin-bottom:1rem}.mv4-ns{margin-top:2rem;margin-bottom:2rem}.mv5-ns{margin-top:4rem;margin-bottom:4rem}.mv6-ns{margin-top:8rem;margin-bottom:8rem}.mv7-ns{margin-top:16rem;margin-bottom:16rem}.mh0-ns{margin-left:0;margin-right:0}.mh1-ns{margin-left:.25rem;margin-right:.25rem}.mh2-ns{margin-left:.5rem;margin-right:.5rem}.mh3-ns{margin-left:1rem;margin-right:1rem}.mh4-ns{margin-left:2rem;margin-right:2rem}.mh5-ns{margin-left:4rem;margin-right:4rem}.mh6-ns{margin-left:8rem;margin-right:8rem}.mh7-ns{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:30em) and (max-width:60em){.pa0-m{padding:0}.pa1-m{padding:.25rem}.pa2-m{padding:.5rem}.pa3-m{padding:1rem}.pa4-m{padding:2rem}.pa5-m{padding:4rem}.pa6-m{padding:8rem}.pa7-m{padding:16rem}.pl0-m{padding-left:0}.pl1-m{padding-left:.25rem}.pl2-m{padding-left:.5rem}.pl3-m{padding-left:1rem}.pl4-m{padding-left:2rem}.pl5-m{padding-left:4rem}.pl6-m{padding-left:8rem}.pl7-m{padding-left:16rem}.pr0-m{padding-right:0}.pr1-m{padding-right:.25rem}.pr2-m{padding-right:.5rem}.pr3-m{padding-right:1rem}.pr4-m{padding-right:2rem}.pr5-m{padding-right:4rem}.pr6-m{padding-right:8rem}.pr7-m{padding-right:16rem}.pb0-m{padding-bottom:0}.pb1-m{padding-bottom:.25rem}.pb2-m{padding-bottom:.5rem}.pb3-m{padding-bottom:1rem}.pb4-m{padding-bottom:2rem}.pb5-m{padding-bottom:4rem}.pb6-m{padding-bottom:8rem}.pb7-m{padding-bottom:16rem}.pt0-m{padding-top:0}.pt1-m{padding-top:.25rem}.pt2-m{padding-top:.5rem}.pt3-m{padding-top:1rem}.pt4-m{padding-top:2rem}.pt5-m{padding-top:4rem}.pt6-m{padding-top:8rem}.pt7-m{padding-top:16rem}.pv0-m{padding-top:0;padding-bottom:0}.pv1-m{padding-top:.25rem;padding-bottom:.25rem}.pv2-m{padding-top:.5rem;padding-bottom:.5rem}.pv3-m{padding-top:1rem;padding-bottom:1rem}.pv4-m{padding-top:2rem;padding-bottom:2rem}.pv5-m{padding-top:4rem;padding-bottom:4rem}.pv6-m{padding-top:8rem;padding-bottom:8rem}.pv7-m{padding-top:16rem;padding-bottom:16rem}.ph0-m{padding-left:0;padding-right:0}.ph1-m{padding-left:.25rem;padding-right:.25rem}.ph2-m{padding-left:.5rem;padding-right:.5rem}.ph3-m{padding-left:1rem;padding-right:1rem}.ph4-m{padding-left:2rem;padding-right:2rem}.ph5-m{padding-left:4rem;padding-right:4rem}.ph6-m{padding-left:8rem;padding-right:8rem}.ph7-m{padding-left:16rem;padding-right:16rem}.ma0-m{margin:0}.ma1-m{margin:.25rem}.ma2-m{margin:.5rem}.ma3-m{margin:1rem}.ma4-m{margin:2rem}.ma5-m{margin:4rem}.ma6-m{margin:8rem}.ma7-m{margin:16rem}.ml0-m{margin-left:0}.ml1-m{margin-left:.25rem}.ml2-m{margin-left:.5rem}.ml3-m{margin-left:1rem}.ml4-m{margin-left:2rem}.ml5-m{margin-left:4rem}.ml6-m{margin-left:8rem}.ml7-m{margin-left:16rem}.mr0-m{margin-right:0}.mr1-m{margin-right:.25rem}.mr2-m{margin-right:.5rem}.mr3-m{margin-right:1rem}.mr4-m{margin-right:2rem}.mr5-m{margin-right:4rem}.mr6-m{margin-right:8rem}.mr7-m{margin-right:16rem}.mb0-m{margin-bottom:0}.mb1-m{margin-bottom:.25rem}.mb2-m{margin-bottom:.5rem}.mb3-m{margin-bottom:1rem}.mb4-m{margin-bottom:2rem}.mb5-m{margin-bottom:4rem}.mb6-m{margin-bottom:8rem}.mb7-m{margin-bottom:16rem}.mt0-m{margin-top:0}.mt1-m{margin-top:.25rem}.mt2-m{margin-top:.5rem}.mt3-m{margin-top:1rem}.mt4-m{margin-top:2rem}.mt5-m{margin-top:4rem}.mt6-m{margin-top:8rem}.mt7-m{margin-top:16rem}.mv0-m{margin-top:0;margin-bottom:0}.mv1-m{margin-top:.25rem;margin-bottom:.25rem}.mv2-m{margin-top:.5rem;margin-bottom:.5rem}.mv3-m{margin-top:1rem;margin-bottom:1rem}.mv4-m{margin-top:2rem;margin-bottom:2rem}.mv5-m{margin-top:4rem;margin-bottom:4rem}.mv6-m{margin-top:8rem;margin-bottom:8rem}.mv7-m{margin-top:16rem;margin-bottom:16rem}.mh0-m{margin-left:0;margin-right:0}.mh1-m{margin-left:.25rem;margin-right:.25rem}.mh2-m{margin-left:.5rem;margin-right:.5rem}.mh3-m{margin-left:1rem;margin-right:1rem}.mh4-m{margin-left:2rem;margin-right:2rem}.mh5-m{margin-left:4rem;margin-right:4rem}.mh6-m{margin-left:8rem;margin-right:8rem}.mh7-m{margin-left:16rem;margin-right:16rem}}@media screen and (min-width:60em){.pa0-l{padding:0}.pa1-l{padding:.25rem}.pa2-l{padding:.5rem}.pa3-l{padding:1rem}.pa4-l{padding:2rem}.pa5-l{padding:4rem}.pa6-l{padding:8rem}.pa7-l{padding:16rem}.pl0-l{padding-left:0}.pl1-l{padding-left:.25rem}.pl2-l{padding-left:.5rem}.pl3-l{padding-left:1rem}.pl4-l{padding-left:2rem}.pl5-l{padding-left:4rem}.pl6-l{padding-left:8rem}.pl7-l{padding-left:16rem}.pr0-l{padding-right:0}.pr1-l{padding-right:.25rem}.pr2-l{padding-right:.5rem}.pr3-l{padding-right:1rem}.pr4-l{padding-right:2rem}.pr5-l{padding-right:4rem}.pr6-l{padding-right:8rem}.pr7-l{padding-right:16rem}.pb0-l{padding-bottom:0}.pb1-l{padding-bottom:.25rem}.pb2-l{padding-bottom:.5rem}.pb3-l{padding-bottom:1rem}.pb4-l{padding-bottom:2rem}.pb5-l{padding-bottom:4rem}.pb6-l{padding-bottom:8rem}.pb7-l{padding-bottom:16rem}.pt0-l{padding-top:0}.pt1-l{padding-top:.25rem}.pt2-l{padding-top:.5rem}.pt3-l{padding-top:1rem}.pt4-l{padding-top:2rem}.pt5-l{padding-top:4rem}.pt6-l{padding-top:8rem}.pt7-l{padding-top:16rem}.pv0-l{padding-top:0;padding-bottom:0}.pv1-l{padding-top:.25rem;padding-bottom:.25rem}.pv2-l{padding-top:.5rem;padding-bottom:.5rem}.pv3-l{padding-top:1rem;padding-bottom:1rem}.pv4-l{padding-top:2rem;padding-bottom:2rem}.pv5-l{padding-top:4rem;padding-bottom:4rem}.pv6-l{padding-top:8rem;padding-bottom:8rem}.pv7-l{padding-top:16rem;padding-bottom:16rem}.ph0-l{padding-left:0;padding-right:0}.ph1-l{padding-left:.25rem;padding-right:.25rem}.ph2-l{padding-left:.5rem;padding-right:.5rem}.ph3-l{padding-left:1rem;padding-right:1rem}.ph4-l{padding-left:2rem;padding-right:2rem}.ph5-l{padding-left:4rem;padding-right:4rem}.ph6-l{padding-left:8rem;padding-right:8rem}.ph7-l{padding-left:16rem;padding-right:16rem}.ma0-l{margin:0}.ma1-l{margin:.25rem}.ma2-l{margin:.5rem}.ma3-l{margin:1rem}.ma4-l{margin:2rem}.ma5-l{margin:4rem}.ma6-l{margin:8rem}.ma7-l{margin:16rem}.ml0-l{margin-left:0}.ml1-l{margin-left:.25rem}.ml2-l{margin-left:.5rem}.ml3-l{margin-left:1rem}.ml4-l{margin-left:2rem}.ml5-l{margin-left:4rem}.ml6-l{margin-left:8rem}.ml7-l{margin-left:16rem}.mr0-l{margin-right:0}.mr1-l{margin-right:.25rem}.mr2-l{margin-right:.5rem}.mr3-l{margin-right:1rem}.mr4-l{margin-right:2rem}.mr5-l{margin-right:4rem}.mr6-l{margin-right:8rem}.mr7-l{margin-right:16rem}.mb0-l{margin-bottom:0}.mb1-l{margin-bottom:.25rem}.mb2-l{margin-bottom:.5rem}.mb3-l{margin-bottom:1rem}.mb4-l{margin-bottom:2rem}.mb5-l{margin-bottom:4rem}.mb6-l{margin-bottom:8rem}.mb7-l{margin-bottom:16rem}.mt0-l{margin-top:0}.mt1-l{margin-top:.25rem}.mt2-l{margin-top:.5rem}.mt3-l{margin-top:1rem}.mt4-l{margin-top:2rem}.mt5-l{margin-top:4rem}.mt6-l{margin-top:8rem}.mt7-l{margin-top:16rem}.mv0-l{margin-top:0;margin-bottom:0}.mv1-l{margin-top:.25rem;margin-bottom:.25rem}.mv2-l{margin-top:.5rem;margin-bottom:.5rem}.mv3-l{margin-top:1rem;margin-bottom:1rem}.mv4-l{margin-top:2rem;margin-bottom:2rem}.mv5-l{margin-top:4rem;margin-bottom:4rem}.mv6-l{margin-top:8rem;margin-bottom:8rem}.mv7-l{margin-top:16rem;margin-bottom:16rem}.mh0-l{margin-left:0;margin-right:0}.mh1-l{margin-left:.25rem;margin-right:.25rem}.mh2-l{margin-left:.5rem;margin-right:.5rem}.mh3-l{margin-left:1rem;margin-right:1rem}.mh4-l{margin-left:2rem;margin-right:2rem}.mh5-l{margin-left:4rem;margin-right:4rem}.mh6-l{margin-left:8rem;margin-right:8rem}.mh7-l{margin-left:16rem;margin-right:16rem}}.na1{margin:-.25rem}.na2{margin:-.5rem}.na3{margin:-1rem}.na4{margin:-2rem}.na5{margin:-4rem}.na6{margin:-8rem}.na7{margin:-16rem}.nl1{margin-left:-.25rem}.nl2{margin-left:-.5rem}.nl3{margin-left:-1rem}.nl4{margin-left:-2rem}.nl5{margin-left:-4rem}.nl6{margin-left:-8rem}.nl7{margin-left:-16rem}.nr1{margin-right:-.25rem}.nr2{margin-right:-.5rem}.nr3{margin-right:-1rem}.nr4{margin-right:-2rem}.nr5{margin-right:-4rem}.nr6{margin-right:-8rem}.nr7{margin-right:-16rem}.nb1{margin-bottom:-.25rem}.nb2{margin-bottom:-.5rem}.nb3{margin-bottom:-1rem}.nb4{margin-bottom:-2rem}.nb5{margin-bottom:-4rem}.nb6{margin-bottom:-8rem}.nb7{margin-bottom:-16rem}.nt1{margin-top:-.25rem}.nt2{margin-top:-.5rem}.nt3{margin-top:-1rem}.nt4{margin-top:-2rem}.nt5{margin-top:-4rem}.nt6{margin-top:-8rem}.nt7{margin-top:-16rem}@media screen and (min-width:30em){.na1-ns{margin:-.25rem}.na2-ns{margin:-.5rem}.na3-ns{margin:-1rem}.na4-ns{margin:-2rem}.na5-ns{margin:-4rem}.na6-ns{margin:-8rem}.na7-ns{margin:-16rem}.nl1-ns{margin-left:-.25rem}.nl2-ns{margin-left:-.5rem}.nl3-ns{margin-left:-1rem}.nl4-ns{margin-left:-2rem}.nl5-ns{margin-left:-4rem}.nl6-ns{margin-left:-8rem}.nl7-ns{margin-left:-16rem}.nr1-ns{margin-right:-.25rem}.nr2-ns{margin-right:-.5rem}.nr3-ns{margin-right:-1rem}.nr4-ns{margin-right:-2rem}.nr5-ns{margin-right:-4rem}.nr6-ns{margin-right:-8rem}.nr7-ns{margin-right:-16rem}.nb1-ns{margin-bottom:-.25rem}.nb2-ns{margin-bottom:-.5rem}.nb3-ns{margin-bottom:-1rem}.nb4-ns{margin-bottom:-2rem}.nb5-ns{margin-bottom:-4rem}.nb6-ns{margin-bottom:-8rem}.nb7-ns{margin-bottom:-16rem}.nt1-ns{margin-top:-.25rem}.nt2-ns{margin-top:-.5rem}.nt3-ns{margin-top:-1rem}.nt4-ns{margin-top:-2rem}.nt5-ns{margin-top:-4rem}.nt6-ns{margin-top:-8rem}.nt7-ns{margin-top:-16rem}}@media screen and (min-width:30em) and (max-width:60em){.na1-m{margin:-.25rem}.na2-m{margin:-.5rem}.na3-m{margin:-1rem}.na4-m{margin:-2rem}.na5-m{margin:-4rem}.na6-m{margin:-8rem}.na7-m{margin:-16rem}.nl1-m{margin-left:-.25rem}.nl2-m{margin-left:-.5rem}.nl3-m{margin-left:-1rem}.nl4-m{margin-left:-2rem}.nl5-m{margin-left:-4rem}.nl6-m{margin-left:-8rem}.nl7-m{margin-left:-16rem}.nr1-m{margin-right:-.25rem}.nr2-m{margin-right:-.5rem}.nr3-m{margin-right:-1rem}.nr4-m{margin-right:-2rem}.nr5-m{margin-right:-4rem}.nr6-m{margin-right:-8rem}.nr7-m{margin-right:-16rem}.nb1-m{margin-bottom:-.25rem}.nb2-m{margin-bottom:-.5rem}.nb3-m{margin-bottom:-1rem}.nb4-m{margin-bottom:-2rem}.nb5-m{margin-bottom:-4rem}.nb6-m{margin-bottom:-8rem}.nb7-m{margin-bottom:-16rem}.nt1-m{margin-top:-.25rem}.nt2-m{margin-top:-.5rem}.nt3-m{margin-top:-1rem}.nt4-m{margin-top:-2rem}.nt5-m{margin-top:-4rem}.nt6-m{margin-top:-8rem}.nt7-m{margin-top:-16rem}}@media screen and (min-width:60em){.na1-l{margin:-.25rem}.na2-l{margin:-.5rem}.na3-l{margin:-1rem}.na4-l{margin:-2rem}.na5-l{margin:-4rem}.na6-l{margin:-8rem}.na7-l{margin:-16rem}.nl1-l{margin-left:-.25rem}.nl2-l{margin-left:-.5rem}.nl3-l{margin-left:-1rem}.nl4-l{margin-left:-2rem}.nl5-l{margin-left:-4rem}.nl6-l{margin-left:-8rem}.nl7-l{margin-left:-16rem}.nr1-l{margin-right:-.25rem}.nr2-l{margin-right:-.5rem}.nr3-l{margin-right:-1rem}.nr4-l{margin-right:-2rem}.nr5-l{margin-right:-4rem}.nr6-l{margin-right:-8rem}.nr7-l{margin-right:-16rem}.nb1-l{margin-bottom:-.25rem}.nb2-l{margin-bottom:-.5rem}.nb3-l{margin-bottom:-1rem}.nb4-l{margin-bottom:-2rem}.nb5-l{margin-bottom:-4rem}.nb6-l{margin-bottom:-8rem}.nb7-l{margin-bottom:-16rem}.nt1-l{margin-top:-.25rem}.nt2-l{margin-top:-.5rem}.nt3-l{margin-top:-1rem}.nt4-l{margin-top:-2rem}.nt5-l{margin-top:-4rem}.nt6-l{margin-top:-8rem}.nt7-l{margin-top:-16rem}}.collapse{border-collapse:collapse;border-spacing:0}.striped--light-silver:nth-child(odd){background-color:#aaa}.striped--moon-gray:nth-child(odd){background-color:#ccc}.striped--light-gray:nth-child(odd){background-color:#eee}.striped--near-white:nth-child(odd){background-color:#f4f4f4}.stripe-light:nth-child(odd){background-color:rgba(255,255,255,.1)}.stripe-dark:nth-child(odd){background-color:rgba(0,0,0,.1)}.strike{text-decoration:line-through}.underline{text-decoration:underline}.no-underline{text-decoration:none}@media screen and (min-width:30em){.strike-ns{text-decoration:line-through}.underline-ns{text-decoration:underline}.no-underline-ns{text-decoration:none}}@media screen and (min-width:30em) and (max-width:60em){.strike-m{text-decoration:line-through}.underline-m{text-decoration:underline}.no-underline-m{text-decoration:none}}@media screen and (min-width:60em){.strike-l{text-decoration:line-through}.underline-l{text-decoration:underline}.no-underline-l{text-decoration:none}}.tl{text-align:left}.tr{text-align:right}.tc{text-align:center}.tj{text-align:justify}@media screen and (min-width:30em){.tl-ns{text-align:left}.tr-ns{text-align:right}.tc-ns{text-align:center}.tj-ns{text-align:justify}}@media screen and (min-width:30em) and (max-width:60em){.tl-m{text-align:left}.tr-m{text-align:right}.tc-m{text-align:center}.tj-m{text-align:justify}}@media screen and (min-width:60em){.tl-l{text-align:left}.tr-l{text-align:right}.tc-l{text-align:center}.tj-l{text-align:justify}}.ttc{text-transform:capitalize}.ttl{text-transform:lowercase}.ttu{text-transform:uppercase}.ttn{text-transform:none}@media screen and (min-width:30em){.ttc-ns{text-transform:capitalize}.ttl-ns{text-transform:lowercase}.ttu-ns{text-transform:uppercase}.ttn-ns{text-transform:none}}@media screen and (min-width:30em) and (max-width:60em){.ttc-m{text-transform:capitalize}.ttl-m{text-transform:lowercase}.ttu-m{text-transform:uppercase}.ttn-m{text-transform:none}}@media screen and (min-width:60em){.ttc-l{text-transform:capitalize}.ttl-l{text-transform:lowercase}.ttu-l{text-transform:uppercase}.ttn-l{text-transform:none}}.f-6,.f-headline{font-size:6rem}.f-5,.f-subheadline{font-size:5rem}.f1{font-size:3rem}.f2{font-size:2.25rem}.f3{font-size:1.5rem}.f4{font-size:1.25rem}.f5{font-size:1rem}.f6{font-size:.875rem}.f7{font-size:.75rem}@media screen and (min-width:30em){.f-6-ns,.f-headline-ns{font-size:6rem}.f-5-ns,.f-subheadline-ns{font-size:5rem}.f1-ns{font-size:3rem}.f2-ns{font-size:2.25rem}.f3-ns{font-size:1.5rem}.f4-ns{font-size:1.25rem}.f5-ns{font-size:1rem}.f6-ns{font-size:.875rem}.f7-ns{font-size:.75rem}}@media screen and (min-width:30em) and (max-width:60em){.f-6-m,.f-headline-m{font-size:6rem}.f-5-m,.f-subheadline-m{font-size:5rem}.f1-m{font-size:3rem}.f2-m{font-size:2.25rem}.f3-m{font-size:1.5rem}.f4-m{font-size:1.25rem}.f5-m{font-size:1rem}.f6-m{font-size:.875rem}.f7-m{font-size:.75rem}}@media screen and (min-width:60em){.f-6-l,.f-headline-l{font-size:6rem}.f-5-l,.f-subheadline-l{font-size:5rem}.f1-l{font-size:3rem}.f2-l{font-size:2.25rem}.f3-l{font-size:1.5rem}.f4-l{font-size:1.25rem}.f5-l{font-size:1rem}.f6-l{font-size:.875rem}.f7-l{font-size:.75rem}}.measure{max-width:30em}.measure-wide{max-width:34em}.measure-narrow{max-width:20em}.indent{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps{-webkit-font-feature-settings:"c2sc";font-feature-settings:"c2sc";font-variant:small-caps}.truncate{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}@media screen and (min-width:30em){.measure-ns{max-width:30em}.measure-wide-ns{max-width:34em}.measure-narrow-ns{max-width:20em}.indent-ns{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps-ns{-webkit-font-feature-settings:"c2sc";font-feature-settings:"c2sc";font-variant:small-caps}.truncate-ns{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}@media screen and (min-width:30em) and (max-width:60em){.measure-m{max-width:30em}.measure-wide-m{max-width:34em}.measure-narrow-m{max-width:20em}.indent-m{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps-m{-webkit-font-feature-settings:"c2sc";font-feature-settings:"c2sc";font-variant:small-caps}.truncate-m{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}@media screen and (min-width:60em){.measure-l{max-width:30em}.measure-wide-l{max-width:34em}.measure-narrow-l{max-width:20em}.indent-l{text-indent:1em;margin-top:0;margin-bottom:0}.small-caps-l{-webkit-font-feature-settings:"c2sc";font-feature-settings:"c2sc";font-variant:small-caps}.truncate-l{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}}.overflow-container{overflow-y:scroll}.center{margin-right:auto;margin-left:auto}.mr-auto{margin-right:auto}.ml-auto{margin-left:auto}@media screen and (min-width:30em){.center-ns{margin-right:auto;margin-left:auto}.mr-auto-ns{margin-right:auto}.ml-auto-ns{margin-left:auto}}@media screen and (min-width:30em) and (max-width:60em){.center-m{margin-right:auto;margin-left:auto}.mr-auto-m{margin-right:auto}.ml-auto-m{margin-left:auto}}@media screen and (min-width:60em){.center-l{margin-right:auto;margin-left:auto}.mr-auto-l{margin-right:auto}.ml-auto-l{margin-left:auto}}.clip{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}@media screen and (min-width:30em){.clip-ns{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}@media screen and (min-width:30em) and (max-width:60em){.clip-m{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}@media screen and (min-width:60em){.clip-l{position:fixed!important;_position:absolute!important;clip:rect(1px 1px 1px 1px);clip:rect(1px,1px,1px,1px)}}.ws-normal{white-space:normal}.nowrap{white-space:nowrap}.pre{white-space:pre}@media screen and (min-width:30em){.ws-normal-ns{white-space:normal}.nowrap-ns{white-space:nowrap}.pre-ns{white-space:pre}}@media screen and (min-width:30em) and (max-width:60em){.ws-normal-m{white-space:normal}.nowrap-m{white-space:nowrap}.pre-m{white-space:pre}}@media screen and (min-width:60em){.ws-normal-l{white-space:normal}.nowrap-l{white-space:nowrap}.pre-l{white-space:pre}}.v-base{vertical-align:baseline}.v-mid{vertical-align:middle}.v-top{vertical-align:top}.v-btm{vertical-align:bottom}@media screen and (min-width:30em){.v-base-ns{vertical-align:baseline}.v-mid-ns{vertical-align:middle}.v-top-ns{vertical-align:top}.v-btm-ns{vertical-align:bottom}}@media screen and (min-width:30em) and (max-width:60em){.v-base-m{vertical-align:baseline}.v-mid-m{vertical-align:middle}.v-top-m{vertical-align:top}.v-btm-m{vertical-align:bottom}}@media screen and (min-width:60em){.v-base-l{vertical-align:baseline}.v-mid-l{vertical-align:middle}.v-top-l{vertical-align:top}.v-btm-l{vertical-align:bottom}}.dim{opacity:1;-webkit-transition:opacity .15s ease-in;transition:opacity .15s ease-in}.dim:hover,.dim:focus{opacity:.5;-webkit-transition:opacity .15s ease-in;transition:opacity .15s ease-in}.dim:active{opacity:.8;-webkit-transition:opacity .15s ease-out;transition:opacity .15s ease-out}.glow{-webkit-transition:opacity .15s ease-in;transition:opacity .15s ease-in}.glow:hover,.glow:focus{opacity:1;-webkit-transition:opacity .15s ease-in;transition:opacity .15s ease-in}.hide-child .child{opacity:0;-webkit-transition:opacity .15s ease-in;transition:opacity .15s ease-in}.hide-child:hover .child,.hide-child:focus .child,.hide-child:active .child{opacity:1;-webkit-transition:opacity .15s ease-in;transition:opacity .15s ease-in}.underline-hover:hover,.underline-hover:focus{text-decoration:underline}.grow{-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-transition:-webkit-transform .25s ease-out;transition:-webkit-transform .25s ease-out;transition:transform .25s ease-out;transition:transform .25s ease-out,-webkit-transform .25s ease-out}.grow:hover,.grow:focus{-webkit-transform:scale(1.05);transform:scale(1.05)}.grow:active{-webkit-transform:scale(.90);transform:scale(.90)}.grow-large{-moz-osx-font-smoothing:grayscale;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-transition:-webkit-transform .25s ease-in-out;transition:-webkit-transform .25s ease-in-out;transition:transform .25s ease-in-out;transition:transform .25s ease-in-out,-webkit-transform .25s ease-in-out}.grow-large:hover,.grow-large:focus{-webkit-transform:scale(1.2);transform:scale(1.2)}.grow-large:active{-webkit-transform:scale(.95);transform:scale(.95)}.pointer:hover{cursor:pointer}.shadow-hover{cursor:pointer;position:relative;-webkit-transition:all .5s cubic-bezier(0.165,0.84,0.44,1);transition:all .5s cubic-bezier(0.165,0.84,0.44,1)}.shadow-hover::after{content:'';-webkit-box-shadow:0 0 16px 2px rgba(0,0,0,.2);box-shadow:0 0 16px 2px rgba(0,0,0,.2);border-radius:inherit;opacity:0;position:absolute;top:0;left:0;width:100%;height:100%;z-index:-1;-webkit-transition:opacity .5s cubic-bezier(0.165,0.84,0.44,1);transition:opacity .5s cubic-bezier(0.165,0.84,0.44,1)}.shadow-hover:hover::after,.shadow-hover:focus::after{opacity:1}.bg-animate,.bg-animate:hover,.bg-animate:focus{-webkit-transition:background-color .15s ease-in-out;transition:background-color .15s ease-in-out}.z-0{z-index:0}.z-1{z-index:1}.z-2{z-index:2}.z-3{z-index:3}.z-4{z-index:4}.z-5{z-index:5}.z-999{z-index:999}.z-9999{z-index:9999}.z-max{z-index:2147483647}.z-inherit{z-index:inherit}.z-initial{z-index:auto;z-index:initial}.z-unset{z-index:unset}.nested-copy-line-height p,.nested-copy-line-height ul,.nested-copy-line-height ol{line-height:1.5}.nested-headline-line-height h1,.nested-headline-line-height h2,.nested-headline-line-height h3,.nested-headline-line-height h4,.nested-headline-line-height h5,.nested-headline-line-height h6{line-height:1.25}.nested-list-reset ul,.nested-list-reset ol{padding-left:0;margin-left:0;list-style-type:none}.nested-copy-indent p+p{text-indent:1em;margin-top:0;margin-bottom:0}.nested-copy-separator p+p{margin-top:1.5em}.nested-img img{width:100%;max-width:100%;display:block}.nested-links a{color:#0594cb;-webkit-transition:color .15s ease-in;transition:color .15s ease-in}.nested-links a:hover,.nested-links a:focus{color:#96ccff;-webkit-transition:color .15s ease-in;transition:color .15s ease-in}.header-link:after{position:relative;left:.5em;opacity:0;font-size:.8em;-moz-transition:opacity .2s ease-in-out .1s;-ms-transition:opacity .2s ease-in-out .1s}h2:hover .header-link,h3:hover .header-link,h4:hover .header-link,h5:hover .header-link,h6:hover .header-link{opacity:1}.animated{-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}@-webkit-keyframes fadeIn{from{opacity:0}to{opacity:1}}@keyframes fadeIn{from{opacity:0}to{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}.animated-delay-1{-webkit-animation-delay:.5s;animation-delay:.5s}.note,.warning{border-left-width:4px;border-left-style:solid;position:relative;border-color:#0594cb;display:block}.note #exclamation-icon,.warning #exclamation-icon{fill:#0594cb;position:absolute;top:35%;left:-12px}.admonition-content{display:block;margin:0;padding:.125em 1em;margin-top:2em;margin-bottom:2em;overflow-x:auto;background-color:rgba(0,0,0,.05)}.hide-child-menu .child-menu{display:none}.hide-child-menu:hover .child-menu,.hide-child-menu:focus .child-menu,.hide-child-menu:active .child-menu{display:block}.documentation-copy h2{margin-top:3em}.documentation-copy h2.minor{font-size:inherit;margin-top:inherit;border-bottom:none}.searchbox{display:inline-block;position:relative;width:200px;height:32px!important;white-space:nowrap;-webkit-box-sizing:border-box;box-sizing:border-box;visibility:visible!important}.searchbox .algolia-autocomplete{display:block;width:100%;height:100%}.searchbox__wrapper{width:100%;height:100%;z-index:999;position:relative}.searchbox__input{display:inline-block;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-transition:background .4s ease,-webkit-box-shadow .4s ease;transition:background .4s ease,-webkit-box-shadow .4s ease;transition:box-shadow .4s ease,background .4s ease;transition:box-shadow .4s ease,background .4s ease,-webkit-box-shadow .4s ease;border:0;border-radius:16px;-webkit-box-shadow:inset 0 0 0 1px #ccc;box-shadow:inset 0 0 0 1px #ccc;background:#fff!important;padding:0 26px 0 32px;width:100%;height:100%;vertical-align:middle;white-space:normal;font-size:12px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbox__input::-webkit-search-cancel-button,.searchbox__input::-webkit-search-decoration,.searchbox__input::-webkit-search-results-button,.searchbox__input::-webkit-search-results-decoration{display:none}.searchbox__input:hover{-webkit-box-shadow:inset 0 0 0 1px #b3b3b3;box-shadow:inset 0 0 0 1px #b3b3b3}.searchbox__input:active,.searchbox__input:focus{outline:0;-webkit-box-shadow:inset 0 0 0 1px #aaa;box-shadow:inset 0 0 0 1px #aaa;background:#fff}.searchbox__input::-webkit-input-placeholder{color:#aaa}.searchbox__input:-ms-input-placeholder{color:#aaa}.searchbox__input::-ms-input-placeholder{color:#aaa}.searchbox__input::placeholder{color:#aaa}.searchbox__submit{position:absolute;top:0;margin:0;border:0;border-radius:16px 0 0 16px;background-color:rgba(69,142,225,0);padding:0;width:32px;height:100%;vertical-align:middle;text-align:center;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;right:inherit;left:0}.searchbox__submit:before{display:inline-block;margin-right:-4px;height:100%;vertical-align:middle;content:""}.searchbox__submit:active,.searchbox__submit:hover{cursor:pointer}.searchbox__submit:focus{outline:0}.searchbox__submit svg{width:14px;height:14px;vertical-align:middle;fill:#6d7e96}.searchbox__reset{display:block;position:absolute;top:8px;right:8px;margin:0;border:0;background:0 0;cursor:pointer;padding:0;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;fill:rgba(0,0,0,.5)}.searchbox__reset.hide{display:none}.searchbox__reset:focus{outline:0}.searchbox__reset svg{display:block;margin:4px;width:8px;height:8px}.searchbox__input:valid~.searchbox__reset{display:block;-webkit-animation-name:sbx-reset-in;animation-name:sbx-reset-in;-webkit-animation-duration:.15s;animation-duration:.15s}@-webkit-keyframes sbx-reset-in{0%{-webkit-transform:translate3d(-20%,0,0);transform:translate3d(-20%,0,0);opacity:0}to{-webkit-transform:none;transform:none;opacity:1}}@keyframes sbx-reset-in{0%{-webkit-transform:translate3d(-20%,0,0);transform:translate3d(-20%,0,0);opacity:0}to{-webkit-transform:none;transform:none;opacity:1}}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu{right:0!important;left:inherit!important}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu:before{right:48px}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu{left:0!important;right:inherit!important}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu:before{left:48px}.algolia-autocomplete .ds-dropdown-menu{top:-6px;border-radius:4px;margin:6px 0 0;padding:0;text-align:left;height:auto;position:relative;background:transparent;border:none;z-index:999;max-width:600px;min-width:500px;-webkit-box-shadow:0 1px 0 0 rgba(0,0,0,.2),0 2px 3px 0 rgba(0,0,0,.1);box-shadow:0 1px 0 0 rgba(0,0,0,.2),0 2px 3px 0 rgba(0,0,0,.1)}.algolia-autocomplete .ds-dropdown-menu:before{display:block;position:absolute;content:"";width:14px;height:14px;background:#fff;z-index:1000;top:-7px;border-top:1px solid #d9d9d9;border-right:1px solid #d9d9d9;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);border-radius:2px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions{position:relative;z-index:1000;margin-top:8px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions a:hover{text-decoration:none}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion{cursor:pointer}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion.suggestion-layout-simple,.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion:not(.suggestion-layout-simple) .algolia-docsearch-suggestion--content{background-color:rgba(69,142,225,.05)}.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{position:relative;border:1px solid #d9d9d9;background:#fff;border-radius:4px;overflow:auto;padding:0 8px 8px}.algolia-autocomplete .ds-dropdown-menu *{-webkit-box-sizing:border-box;box-sizing:border-box}.algolia-autocomplete .algolia-docsearch-suggestion{display:block;position:relative;padding:0 8px;background:#fff;color:#02060c;overflow:hidden}.algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#174d8c;background:rgba(143,187,237,.1);padding:.1em .05em}.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl0 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl1 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{padding:0 0 1px;background:inherit;-webkit-box-shadow:inset 0 -2px 0 0 rgba(69,142,225,.8);box-shadow:inset 0 -2px 0 0 rgba(69,142,225,.8);color:inherit}.algolia-autocomplete .algolia-docsearch-suggestion--content{display:block;float:right;width:70%;position:relative;padding:5.33333px 0 5.33333px 10.66667px;cursor:pointer}.algolia-autocomplete .algolia-docsearch-suggestion--content:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;left:-1px}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{position:relative;border-bottom:1px solid #ddd;display:none;margin-top:8px;padding:4px 0;font-size:1em;color:#33363d}.algolia-autocomplete .algolia-docsearch-suggestion--wrapper{width:100%;float:left;padding:8px 0 0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{float:left;width:30%;text-align:right;position:relative;padding:5.33333px 10.66667px;color:#a4a7ae;font-size:.9em;word-wrap:break-word}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;right:0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline{display:none}.algolia-autocomplete .algolia-docsearch-suggestion--title{margin-bottom:4px;color:#02060c;font-size:.9em;font-weight:700}.algolia-autocomplete .algolia-docsearch-suggestion--text{display:block;line-height:1.2em;font-size:.85em;color:#63676d}.algolia-autocomplete .algolia-docsearch-suggestion--no-results{width:100%;padding:8px 0;text-align:center;font-size:1.2em}.algolia-autocomplete .algolia-docsearch-suggestion--no-results:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion code{padding:1px 5px;font-size:90%;border:none;color:#222;background-color:#ebebeb;border-radius:3px;font-family:Menlo,Monaco,Consolas,Courier New,monospace}.algolia-autocomplete .algolia-docsearch-suggestion code .algolia-docsearch-suggestion--highlight{background:0 0}.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--category-header,.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__secondary{display:block}@media(min-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:block}}@media(max-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:inline-block;width:auto;float:left;padding:0;color:#02060c;font-size:.9em;font-weight:700;text-align:left;opacity:.5}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{content:"|"}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{display:inline-block;width:auto;text-align:left;float:left;padding:0}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content:before{display:none}}.algolia-autocomplete .suggestion-layout-simple.algolia-docsearch-suggestion{border-bottom:1px solid #eee;padding:8px;margin:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content{width:100%;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content:before{display:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header{margin:0;padding:0;display:block;width:100%;border:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl0,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1{opacity:.6;font-size:.85em}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1:before{background-image:url(data:image/svg+xml;utf8;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIHZpZXdCb3g9IjAgMCAyMCAzOCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMS40OSA0LjMxbDE0IDE2LjEyNi4wMDItMi42MjQtMTQgMTYuMDc0LTEuMzE0IDEuNTEgMy4wMTcgMi42MjYgMS4zMTMtMS41MDggMTQtMTYuMDc1IDEuMTQyLTEuMzEzLTEuMTQtMS4zMTMtMTQtMTYuMTI1TDMuMi4xOC4xOCAyLjhsMS4zMSAxLjUxeiIgZmlsbC1ydWxlPSJldmVub2RkIiBmaWxsPSIjMWQzNjU3IiAvPjwvc3ZnPg==);content:"";width:10px;height:10px;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--wrapper{width:100%;float:left;margin:0;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--duplicate-content,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--subcategory-inline{display:none!important}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title{margin:0;color:#458ee1;font-size:.9em;font-weight:400}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title:before{content:"#";font-weight:700;color:#458ee1;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text{margin:4px 0 0;display:block;line-height:1.4em;padding:5.33333px 8px;background:#f8f8f8;font-size:.85em;opacity:.8}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{color:#3f4145;font-weight:700;-webkit-box-shadow:none;box-shadow:none}.algolia-autocomplete .algolia-docsearch-footer{width:134px;height:20px;z-index:2000;margin-top:10.66667px;float:right;font-size:0;line-height:0}.algolia-autocomplete .algolia-docsearch-footer--logo{background-image:url(data:image/svg+xml;charset=utf-8;base64,PHN2ZyB3aWR0aD0iMTY4IiBoZWlnaHQ9IjI0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxnIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0iTTc4Ljk4OC45MzhoMTYuNTk0YTIuOTY4IDIuOTY4LjAgMCAxIDIuOTY2IDIuOTY2VjIwLjVhMi45NjcgMi45NjcuMCAwIDEtMi45NjYgMi45NjRINzguOTg4YTIuOTY3IDIuOTY3LjAgMCAxLTIuOTY2LTIuOTY0VjMuODk3QTIuOTYxIDIuOTYxLjAgMCAxIDc4Ljk4OC45Mzh6bTQxLjkzNyAxNy44NjZjLTQuMzg2LjAyLTQuMzg2LTMuNTQtNC4zODYtNC4xMDZsLS4wMDctMTMuMzM2IDIuNjc1LS40MjR2MTMuMjU0YzAgLjMyMi4wIDIuMzU4IDEuNzE4IDIuMzY0djIuMjQ4em0tMTAuODQ2LTIuMThjLjgyMS4wIDEuNDMtLjA0NyAxLjg1NS0uMTI5di0yLjcxOWE2LjMzNCA2LjMzNC4wIDAgMC0xLjU3NC0uMTk5IDUuNyA1LjcuMCAwIDAtLjg5Ny4wNjkgMi42OTkgMi42OTkuMCAwIDAtLjgxNC4yNGMtLjI0LjExNi0uNDM5LjI4LS41ODIuNDkxLS4xNS4yMTItLjIxOS4zMzUtLjIxOS42NTYuMC42MjguMjE5Ljk5MS42MTYgMS4yM3MuOTM4LjM2MiAxLjYxNS4zNjJ6bS0uMjMzLTkuN2MuODgzLjAgMS42MjkuMTA5IDIuMjMxLjMyOC42MDIuMjE4IDEuMDg4LjUyNSAxLjQ0NC45MTUuMzYzLjM5Ni42MDkuOTIyLjc2IDEuNDgzLjE1Ny41Ni4yMzIgMS4xNzUuMjMyIDEuODV2Ni44NzRhMzIuNSAzMi41LjAgMCAxLTEuODY4LjMxNGMtLjgzNC4xMjMtMS43NzIuMTg1LTIuODEzLjE4NS0uNjkuMC0xLjMyNy0uMDY5LTEuODk1LS4xOThhNC4wMDEgNC4wMDEuMCAwIDEtMS40NzEtLjYzNiAzLjA4NSAzLjA4NS4wIDAgMS0uOTUxLTEuMTM0Yy0uMjI2LS40NjUtLjM0My0xLjEyLS4zNDMtMS44MDMuMC0uNjU2LjEzLTEuMDczLjM4NC0xLjUyNWEzLjI0IDMuMjQuMCAwIDEgMS4wNDctMS4xMDZjLjQ0NS0uMjg3Ljk1LS40OTIgMS41MzItLjYxNWE4LjggOC44LjAgMCAxIDEuODItLjE4NSA4LjQwNCA4LjQwNC4wIDAgMSAxLjk3Mi4yNHYtLjQzOGMwLS4zMDctLjAzNS0uNi0uMTEtLjg3NGExLjg4IDEuODguMCAwIDAtLjM4NC0uNzMgMS43ODQgMS43ODQuMCAwIDAtLjcyNC0uNDkzIDMuMTY0IDMuMTY0LjAgMCAwLTEuMTQzLS4yMDVjLS42MTYuMC0xLjE3Ny4wNzUtMS42OS4xNjRhNy43MzUgNy43MzUuMCAwIDAtMS4yNi4zMDdsLS4zMjEtMi4xOTJjLjMzNS0uMTE3LjgzNC0uMjMzIDEuNDc4LS4zNDlhMTAuOTggMTAuOTguMCAwIDEgMi4wNzMtLjE3OHptNTIuODQyIDkuNjI2Yy44MjIuMCAxLjQzLS4wNDggMS44NTQtLjEzVjEzLjdhNi4zNDcgNi4zNDcuMCAwIDAtMS41NzQtLjE5OWMtLjI5NC4wLS41OTUuMDIxLS44OTYuMDY5YTIuNyAyLjcuMCAwIDAtLjgxNC4yNCAxLjQ2IDEuNDYuMCAwIDAtLjU4Mi40OTFjLS4xNS4yMTItLjIxOC4zMzUtLjIxOC42NTYuMC42MjguMjE4Ljk5MS42MTUgMS4yMy40MDQuMjQ1LjkzOC4zNjIgMS42MTUuMzYyem0tLjIyNi05LjY5NGMuODgzLjAgMS42MjkuMTA4IDIuMjMxLjMyNy42MDIuMjE5IDEuMDg4LjUyNiAxLjQ0NC45MTUuMzU1LjM5LjYwOS45MjMuNzU5IDEuNDgzYTYuOCA2LjguMCAwIDEgLjIzMyAxLjg1MnY2Ljg3M2MtLjQxLjA4OC0xLjAzNC4xOS0xLjg2OC4zMTQtLjgzNC4xMjMtMS43NzIuMTg0LTIuODEzLjE4NC0uNjkuMC0xLjMyNy0uMDY4LTEuODk1LS4xOThhNC4wMDEgNC4wMDEuMCAwIDEtMS40NzEtLjYzNSAzLjA4NSAzLjA4NS4wIDAgMS0uOTUxLTEuMTM0Yy0uMjI2LS40NjUtLjM0My0xLjEyLS4zNDMtMS44MDQuMC0uNjU2LjEzLTEuMDczLjM4NC0xLjUyNC4yNi0uNDUuNjA4LS44MiAxLjA0Ny0xLjEwNy40NDUtLjI4Ni45NS0uNDkxIDEuNTMyLS42MTRhOC44MDMgOC44MDMuMCAwIDEgMi43NTEtLjEzYy4zMjkuMDM0LjY3MS4wOTYgMS4wNC4xODV2LS40MzdhMy4zIDMuMy4wIDAgMC0uMTA5LS44NzUgMS44NzMgMS44NzMuMCAwIDAtLjM4NC0uNzMxIDEuNzg0IDEuNzg0LjAgMCAwLS43MjQtLjQ5MiAzLjE2NSAzLjE2NS4wIDAgMC0xLjE0My0uMjA1Yy0uNjE2LjAtMS4xNzcuMDc1LTEuNjkuMTY0YTcuNzUgNy43NS4wIDAgMC0xLjI2LjMwN2wtLjMyMS0yLjE5M2MuMzM1LS4xMTYuODM0LS4yMzIgMS40NzgtLjM0OGExMS42MzMgMTEuNjMzLjAgMCAxIDIuMDczLS4xNzd6bS04LjAzNC0xLjI3MWExLjYyNiAxLjYyNi4wIDAgMS0xLjYyOC0xLjYyYzAtLjg5NS43MjUtMS42MiAxLjYyOC0xLjYyLjkwNC4wIDEuNjMuNzI1IDEuNjMgMS42Mi4wLjg5NS0uNzMzIDEuNjItMS42MyAxLjYyem0xLjM0OCAxMy4yMmgtMi42ODlWNy4yN2wyLjY5LS40MjN2MTEuOTU2em0tNC43MTQuMGMtNC4zODYuMDItNC4zODYtMy41NC00LjM4Ni00LjEwN2wtLjAwOC0xMy4zMzYgMi42NzYtLjQyNHYxMy4yNTRjMCAuMzIyLjAgMi4zNTggMS43MTggMi4zNjR2Mi4yNDh6bS04LjY5OC01LjkwM2MwLTEuMTU2LS4yNTMtMi4xMTktLjc0Ni0yLjc4OC0uNDkzLS42NzctMS4xODMtMS4wMS0yLjA2Ny0xLjAxLS44ODIuMC0xLjU3NC4zMzMtMi4wNjUgMS4wMS0uNDkzLjY3Ni0uNzMzIDEuNjMyLS43MzMgMi43ODguMCAxLjE2OC4yNDYgMS45NTMuNzQgMi42My40OTIuNjgzIDEuMTgzIDEuMDE4IDIuMDY2IDEuMDE4Ljg4Mi4wIDEuNTc0LS4zNDIgMi4wNjctMS4wMTkuNDkyLS42ODMuNzM4LTEuNDYuNzM4LTIuNjN6bTIuNzM3LS4wMDdjMCAuOTAyLS4xMyAxLjU4NC0uMzk3IDIuMzNhNS41MiA1LjUyLjAgMCAxLTEuMTI4IDEuOTA2IDQuOTg2IDQuOTg2LjAgMCAxLTEuNzUyIDEuMjIzYy0uNjg1LjI4Ni0xLjczOS40NS0yLjI2NS40NS0uNTI4LS4wMDYtMS41NzQtLjE1Ny0yLjI1Mi0uNDVhNS4wOTYgNS4wOTYuMCAwIDEtMS43NDQtMS4yMjNjLS40ODctLjUyNy0uODYzLTEuMTYyLTEuMTM3LTEuOTA2YTYuMzQ1IDYuMzQ1LjAgMCAxLS40MS0yLjMzYzAtLjkwMi4xMjMtMS43Ny4zOTctMi41MDhhNS41NTQgNS41NTQuMCAwIDEgMS4xNS0xLjg5MiA1LjEzMyA1LjEzMy4wIDAgMSAxLjc1LTEuMjE2Yy42NzktLjI4NyAxLjQyNS0uNDIzIDIuMjMyLS40MjMuODA4LjAgMS41NTMuMTQyIDIuMjM3LjQyM2E0Ljg4IDQuODguMCAwIDEgMS43NTMgMS4yMTYgNS42NDQgNS42NDQuMCAwIDEgMS4xMzUgMS44OTJjLjI4Ny43MzguNDMxIDEuNjA2LjQzMSAyLjUwOHptLTIwLjEzOC4wYzAgMS4xMi4yNDYgMi4zNjMuNzM4IDIuODgyLjQ5My41MiAxLjEzLjc4IDEuOTEuNzguNDI0LjAuODI4LS4wNjIgMS4yMDQtLjE3OC4zNzctLjExNi42NzctLjI1My45MTctLjQxN1Y5LjMzYTEwLjQ3NiAxMC40NzYuMCAwIDAtMS43NjYtLjIyNmMtLjk3MS0uMDI4LTEuNzEuMzctMi4yMyAxLjAwNC0uNTEzLjYzNi0uNzczIDEuNzUtLjc3MyAyLjc4OHptNy40MzggNS4yNzRjMCAxLjgyNC0uNDY2IDMuMTU2LTEuNDA0IDQuMDA0LS45MzYuODQ2LTIuMzY3IDEuMjctNC4yOTYgMS4yNy0uNzA1LjAtMi4xNy0uMTM3LTMuMzQtLjM5NmwuNDMxLTIuMTE4Yy45OC4yMDUgMi4yNzIuMjYgMi45NS4yNiAxLjA3NC4wIDEuODQtLjIxOSAyLjI5OS0uNjU2LjQ1OS0uNDM3LjY4NC0xLjA4Ni42ODQtMS45NDh2LS40MzdhOC4wNyA4LjA3LjAgMCAxLTEuMDQ3LjM5N2MtLjQzLjEzLS45My4xOTgtMS40OTIuMTk4LS43MzkuMC0xLjQxLS4xMTYtMi4wMTgtLjM0OWE0LjIwNiA0LjIwNi4wIDAgMS0xLjU2Ny0xLjAyNWMtLjQzMS0uNDUtLjc3NC0xLjAxNy0xLjAxMy0xLjY5NC0uMjQtLjY3Ny0uMzYzLTEuODg1LS4zNjMtMi43NzMuMC0uODM0LjEzLTEuODguMzg0LTIuNTc3LjI2LS42OTYuNjI5LTEuMjk4IDEuMTI5LTEuNzk2LjQ5My0uNDk4IDEuMDk1LS44ODEgMS44LTEuMTYyYTYuNjA1IDYuNjA1LjAgMCAxIDIuNDI4LS40NTdjLjg3LjAgMS42Ny4xMDkgMi40NS4yNC43OC4xMjkgMS40NDQuMjY1IDEuOTg1LjQxNVYxOC4xN3oiIGZpbGw9IiM1NDY4ZmYiLz48cGF0aCBkPSJNNi45NzIgNi42Nzd2MS42MjdjLS43MTItLjQ0Ni0xLjUyLS42Ny0yLjQyNS0uNjctLjU4NS4wLTEuMDQ1LjEzLTEuMzguMzkxYTEuMjQgMS4yNC4wIDAgMC0uNTAyIDEuMDNjMCAuNDI1LjE2NC43NjUuNDk0IDEuMDIuMzMuMjU2LjgzNS41MzIgMS41MTYuODMuNDQ3LjE5Mi43OTUuMzU2IDEuMDQ1LjQ5NS4yNS4xMzguNTM3LjMzMi44NjIuNTgyLjMyNC4yNS41NjMuNTQ4LjcxOC44OTQuMTU0LjM0NS4yMy43NDEuMjMgMS4xODguMC45NDctLjMzNCAxLjY5MS0xLjAwNCAyLjIzNC0uNjcuNTQyLTEuNTM3LjgxNC0yLjYwMS44MTQtMS4xOC4wLTIuMTYtLjIyOS0yLjkzNi0uNjg2di0xLjcwOGMuODQuNjI4IDEuODE0Ljk0MiAyLjkyLjk0Mi41ODUuMCAxLjA0OC0uMTM2IDEuMzg4LS40MDcuMzQtLjI3MS41MS0uNjQ2LjUxLTEuMTI1LjAtLjI4Ny0uMS0uNTUtLjMwMi0uNzktLjIwMy0uMjQtLjQyLS40Mi0uNjU1LS41NDItLjIzNC0uMTIzLS41ODUtLjI5LTEuMDUzLS41MDNhNjEuMjcgNjEuMjcuMCAwIDEtLjU4Mi0uMjcxIDEzLjY3IDEzLjY3LjAgMCAxLS41NS0uMjg3IDQuMjc1IDQuMjc1LjAgMCAxLS41NjctLjM1MSA2LjkyIDYuOTIuMCAwIDEtLjQ1NS0uNGMtLjE4LS4xNy0uMzEtLjM0LS4zOS0uNTEtLjA4LS4xNy0uMTU1LS4zNy0uMjI0LS41OThhMi41NTMgMi41NTMuMCAwIDEtLjEwNC0uNzQyYzAtLjkxNS4zMzMtMS42MzguOTk4LTIuMTcuNjY0LS41MzIgMS41MjMtLjc5OCAyLjU3Ni0uNzk4Ljk2OC4wIDEuNzkzLjE3IDIuNDczLjUxem03LjQ2OCA1LjY5NnYtLjI4N2MtLjAyMi0uNjA3LS4xODctMS4wODgtLjQ5NS0xLjQ0NC0uMzA5LS4zNTctLjc1LS41MzUtMS4zMjQtLjUzNS0uNTMyLjAtLjk5LjE5NC0xLjM3My41ODMtLjM4Mi4zODgtLjYyMi45NDktLjcxNyAxLjY4M2gzLjkwOXptMS4wMDUgMi43OTJ2MS40MDRjLS41OTYuMzQtMS4zODMuNTEtMi4zNjIuNTEtMS4yNTUuMC0yLjI1NS0uMzc3LTMtMS4xMzItLjc0NC0uNzU1LTEuMTE2LTEuNzQ0LTEuMTE2LTIuOTY4LjAtMS4yOTcuMzQtMi4zMTYgMS4wMjEtMy4wNTUuNjgtLjc0IDEuNTQ4LTEuMTEgMi42LTEuMTEgMS4wMzMuMCAxLjg1Mi4zMjMgMi40NTguOTY2LjYwNi42NDQuOTEgMS41NzIuOTEgMi43ODQuMC4zMy0uMDMzLjY3Ni0uMDk2IDEuMDM4aC01LjMxNGMuMTA3LjcwMi40MDUgMS4yMzkuODk0IDEuNjExLjQ5LjM3MiAxLjEwNi41NTggMS44NS41NTguODYyLjAgMS41OC0uMjAyIDIuMTU1LS42MDZ6bTYuNjA1LTEuNzdoLTEuMjEyYy0uNTk2LjAtMS4wNDUuMTE2LTEuMzQ5LjM1LS4zMDMuMjM0LS40NTQuNTMyLS40NTQuODk0LjAuMzcyLjExNy42NjQuMzUuODc3LjIzNS4yMTMuNTc1LjMyIDEuMDIyLjMyLjUxLjAuOTEyLS4xNDIgMS4yMDQtLjQyNC4yOTMtLjI4MS40NC0uNjUxLjQ0LTEuMTA4di0uOTF6bS00LjA2OC0yLjU1NFY5LjMyNWMuNjI3LS4zNjEgMS40NTctLjU0MiAyLjQ4OS0uNTQyIDIuMTE2LjAgMy4xNzUgMS4wMjYgMy4xNzUgMy4wOFYxN2gtMS41NDh2LS45NTdjLS40MTUuNjgtMS4xNDMgMS4wMi0yLjE4NiAxLjAyLS43NjYuMC0xLjM4LS4yMi0xLjg0My0uNjYxLS40NjItLjQ0Mi0uNjk0LTEuMDAzLS42OTQtMS42ODQuMC0uNzc2LjI5My0xLjM4Ljg3OC0xLjgxLjU4NS0uNDMxIDEuNDA0LS42NDcgMi40NTctLjY0N2gxLjM0VjExLjhjMC0uNTU0LS4xMzMtLjk3MS0uMzk5LTEuMjUzLS4yNjYtLjI4Mi0uNzA3LS40MjMtMS4zMjQtLjQyM2E0LjA3IDQuMDcuMCAwIDAtMi4zNDUuNzE4em05LjMzMy0xLjkzdjEuNDJjLjM5NC0xIDEuMTAxLTEuNSAyLjEyMy0xLjUuMTQ4LjAuMzEzLjAxNi40OTQuMDQ4djEuNTMxYTEuODg1IDEuODg1LjAgMCAwLS43NS0uMTQzYy0uNTQyLjAtLjk4OS4yNC0xLjM0LjcxOC0uMzUxLjQ3OS0uNTI3IDEuMDQ4LS41MjcgMS43MDdWMTdoLTEuNTYzVjguOTFoMS41NjN6bTUuMDEgNC4wODRjLjAyMi44Mi4yNzIgMS40OTIuNzUgMi4wMTkuNDc5LjUyNiAxLjE1Ljc5IDIuMDEuNzkuNjM5LjAgMS4yMzUtLjE3NiAxLjc4OC0uNTI3djEuNDA0Yy0uNTIxLjMxOS0xLjE4Ni40NzktMS45OTUuNDc5LTEuMjY1LjAtMi4yNzYtLjQtMy4wMzEtMS4xOTctLjc1NS0uNzk4LTEuMTMzLTEuNzkyLTEuMTMzLTIuOTg0LjAtMS4xNi4zOC0yLjE1MSAxLjE0LTIuOTc1Ljc2MS0uODI1IDEuNzktMS4yMzcgMy4wODgtMS4yMzcuNzAyLjAgMS4zNDYuMTQ5IDEuOTMuNDQ3djEuNDM2YTMuMjQyIDMuMjQyLjAgMCAwLTEuNzctLjQ5NWMtLjg0LjAtMS41MTMuMjY2LTIuMDE5Ljc5OC0uNTA1LjUzMi0uNzU4IDEuMjEzLS43NTggMi4wNDJ6TTQwLjI0IDUuNzJ2NC41NzljLjQ1OC0xIDEuMjkzLTEuNSAyLjUwNS0xLjUuNzg3LjAgMS40Mi4yNDUgMS44OTkuNzM0LjQ3OS40OS43MTggMS4xNy43MTggMi4wNDJWMTdoLTEuNTY0di01LjEwNmMwLS41NTMtLjE0LS45OC0uNDIyLTEuMjg0LS4yODItLjMwMy0uNjUyLS40NTUtMS4xMS0uNDU1LS41MzEuMC0xLjAwMi4yMDItMS40MTEuNjA2LS40MS40MDUtLjYxNSAxLjAyMi0uNjE1IDEuODUxVjE3aC0xLjU2M1Y1LjcyaDEuNTYzem0xNC45NjYgMTAuMDJjLjU5Ni4wIDEuMDk2LS4yNTMgMS41LS43NTguNDA0LS41MDYuNjA2LTEuMTU3LjYwNi0xLjk1NS4wLS45MTUtLjIwMi0xLjYyLS42MDYtMi4xMTQtLjQwNC0uNDk1LS45Mi0uNzQyLTEuNTQ4LS43NDItLjU1My4wLTEuMDUuMjI0LTEuNDkxLjY3LS40NDIuNDQ3LS42NjIgMS4xMzMtLjY2MiAyLjA1OC4wLjk1OC4yMTIgMS42Ny42MzggMi4xMzguNDI1LjQ2OS45NDYuNzAzIDEuNTYzLjcwM3pNNTMuMDA0IDUuNzJ2NC40MmMuNTc0LS44OTQgMS4zODgtMS4zNDEgMi40NC0xLjM0MSAxLjAyMi4wIDEuODU3LjM4MyAyLjUwNiAxLjE0OS42NDkuNzY2Ljk3MyAxLjc4MS45NzMgMy4wNDcuMCAxLjEzOC0uMzA5IDIuMTA5LS45MjUgMi45MTItLjYxNy44MDMtMS40NjMgMS4yMDUtMi41MzcgMS4yMDUtMS4wNzUuMC0xLjg5NC0uNDQ3LTIuNDU3LTEuMzRWMTdoLTEuNThWNS43MmgxLjU4em05LjkwOCAxMS4xMDQtMy4yMjMtNy45MTNoMS43MzlsMS4wMDUgMi42MzIgMS4yNiAzLjQxNWMuMDk2LS4zMi40OC0xLjQ1OCAxLjE1LTMuNDE1bC45MDktMi42MzJoMS42NmwtMi45MiA3Ljg2NmMtLjc3NyAyLjA3NC0xLjk2MyAzLjExLTMuNTU5IDMuMTFhMi45MiAyLjkyLjAgMCAxLS43MzQtLjA3OXYtMS4zNGMuMTcuMDQyLjM1MS4wNjQuNTQzLjA2NCAxLjAzMi4wIDEuNzU1LS41NyAyLjE3LTEuNzA4eiIgZmlsbD0iIzVkNjQ5NCIvPjxwYXRoIGQ9Ik04OS42MzIgNS45Njd2LS43NzJhLjk3OC45NzguMCAwIDAtLjk3OC0uOTc3aC0yLjI4YS45NzguOTc4LjAgMCAwLS45NzguOTc3di43OTNjMCAuMDg4LjA4Mi4xNS4xNzEuMTNhNy4xMjcgNy4xMjcuMCAwIDEgMS45ODQtLjI4Yy42NS4wIDEuMjk1LjA4OCAxLjkxNy4yNTkuMDgyLjAyLjE2NC0uMDQuMTY0LS4xM20tNi4yNDggMS4wMS0uMzktLjM4OWEuOTc3Ljk3Ny4wIDAgMC0xLjM4Mi4wbC0uNDY1LjQ2NWEuOTczLjk3My4wIDAgMCAwIDEuMzhsLjM4My4zODNjLjA2Mi4wNjEuMTUuMDQ3LjIwNS0uMDE0LjIyNi0uMzA3LjQ3Mi0uNjAxLjc0Ni0uODc0LjI4MS0uMjguNTY4LS41MjYuODgzLS43NTEuMDY4LS4wNDIuMDc1LS4xMzcuMDItLjJtNC4xNiAyLjQ1M3YzLjM0MWMwIC4wOTYuMTA0LjE2NS4xOTIuMTE3bDIuOTctMS41MzdjLjA2OC0uMDM0LjA4OS0uMTE3LjA1NS0uMTg0YTMuNjk1IDMuNjk1LjAgMCAwLTMuMDgtMS44NjZjLS4wNjguMC0uMTM2LjA1NC0uMTM2LjEzbTAgOC4wNDhhNC40ODkgNC40ODkuMCAwIDEtNC40OS00LjQ4MiA0LjQ4OCA0LjQ4OC4wIDAgMSA0LjQ5LTQuNDgyIDQuNDg4IDQuNDg4LjAgMCAxIDQuNDg5IDQuNDgyIDQuNDg0IDQuNDg0LjAgMCAxLTQuNDkgNC40ODJtMC0xMC44NWE2LjM2MyA2LjM2My4wIDEgMCAwIDEyLjcyOSA2LjM3IDYuMzcuMCAwIDAgNi4zNzItNi4zNjggNi4zNTggNi4zNTguMCAwIDAtNi4zNzEtNi4zNiIgZmlsbD0iI2ZmZiIvPjwvZz48L3N2Zz4=);background-repeat:no-repeat;background-position:50%;background-size:100%;overflow:hidden;text-indent:-9000px;padding:0!important;width:100%;height:100%;display:block}.overflow-x-scroll{-webkit-overflow-scrolling:touch}.row{-webkit-transition:450ms -webkit-transform;transition:450ms -webkit-transform;transition:450ms transform;transition:450ms transform,450ms -webkit-transform;font-size:0}.tile{-webkit-transition:450ms all;transition:450ms all}.details{background:-webkit-gradient(linear,left bottom,left top,from(rgba(0,0,0,.9)),to(rgba(0,0,0,0)));background:linear-gradient(to top,rgba(0,0,0,.9) 0%,rgba(0,0,0,0) 100%);-webkit-transition:450ms opacity;transition:450ms opacity}.tile:hover .details{opacity:1}.row:hover .tile{opacity:.3}.row:hover .tile:hover{opacity:1}.chroma .lntable pre{padding:0;margin:0;border:0}.chroma .lntable pre code{padding:0;margin:0}pre,.pre{overflow-x:auto;overflow-y:hidden;overflow:scroll}code{padding:.2em;margin:0;font-size:85%;background-color:rgba(27,31,35,.05);border-radius:3px}pre code{display:block;padding:1.5em;font-size:.875rem;line-height:2;overflow-x:auto}pre{background-color:#fff;color:#333;white-space:pre;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none;position:relative;border-width:1px;border-color:#ccc;border-style:solid}.highlight pre{background-color:inherit;color:inherit;padding:.5em;font-size:.875rem}.copy:after{content:"Copy"}.copied:after{content:"Copied"}@media screen and (min-width:60em){.full-width,pre.expand:hover{margin-right:-30vw;max-width:100vw}}.code-block .line-numbers-rows{background:#2f3a46;border:none;bottom:-50px;color:#98a4b3;left:-178px;padding:50px 0;top:-50px;width:138px}.code-block .line-numbers-rows>span:before{color:inherit;padding-right:30px}.tab-button{margin-bottom:1px;position:relative;z-index:1;color:#333;border-color:#ccc;outline:none;background-color:#fff}.tab-pane code{background:#f1f2f2;border-radius:0}.tab-pane .chroma{background:0 0;padding:0}.tab-button.active{border-bottom-color:#f1f2f2;background-color:#f1f2f2}.tab-content .tab-pane{display:none}.tab-content .tab-pane.active{display:block}.tab-content .copy,.tab-content .copied{display:none}.tab-content .tab-pane.active+.copy,.tab-content .tab-pane.active+.copied{display:block}.primary-color{color:#0594cb}.bg-primary-color{background-color:#0594cb}.hover-bg-primary-color:hover{background-color:#0594cb}.primary-color-dark{color:#0a1922}.bg-primary-color-dark{background-color:#0a1922}.hover-bg-primary-color-dark:hover{background-color:#0a1922}.primary-color-light{color:#f9f9f9}.bg-primary-color-light{background-color:#f9f9f9}.hover-bg-primary-color-light:hover{background-color:#f9f9f9}.accent-color{color:#ebb951}.bg-accent-color{background-color:#ebb951}.hover-bg-accent-color:hover{background-color:#ebb951}.accent-color-light{color:#ff4088}.hover-accent-color-light:hover{color:#ff4088}.bg-accent-color-light{background-color:#ff4088}.hover-bg-accent-color-light:hover{background-color:#ff4088}.accent-color-dark{color:#33ba91}.bg-accent-color-dark{background-color:#33ba91}.hover-bg-accent-color-dark:hover{background-color:#33ba91}.text-color-primary{color:#373737}.text-on-primary-color{color:#fff}.text-color-secondary{color:#ccc}.text-color-disabled{color:#f7f7f7}.divider-color{color:#f6f6f6}.warn-color{color:red}.nested-links a{color:#0594cb;text-decoration:none}.column-count-2{-webkit-column-count:1;column-count:1}.column-gap-1{-webkit-column-gap:0;column-gap:0}.break-inside-avoid{-webkit-column-break-inside:auto;break-inside:auto}@media screen and (min-width:60em){.column-count-3-l{-webkit-column-count:3;column-count:3}.column-count-2-l{-webkit-column-count:2;column-count:2}.column-gap-1-l{-webkit-column-gap:1;column-gap:1}.break-inside-avoid-l{-webkit-column-break-inside:avoid;break-inside:avoid}}.prose ul,.prose ol{margin-bottom:2em}.prose ul li,.prose ol li{margin-bottom:.5em}.prose li:hover{background-color:#eee}.prose ::selection{background:#0594cb;color:#fff}body{line-height:1.45}p{margin-bottom:1.3em}h1,h2,h3,h4{margin:1.414em 0 .5em;line-height:1.2}h1{margin-top:0;font-size:2.441em}h2{font-size:1.953em}h3{font-size:1.563em}h4{font-size:1.25em}small,.font_small{font-size:.8em}.prose table{width:100%;margin-bottom:3em;border-collapse:collapse;border-spacing:0;font-size:1em;border:1px solid #eee}.prose table th{background-color:#0594cb;border-bottom:1px solid #0594cb;color:#fff;font-weight:400;text-align:left;padding:.375em .5em}.prose table td,.prose table tc{padding:.75em .5em;text-align:left;border-right:1px solid #eee}.prose table tr:nth-child(even){background-color:#eee}dl dt{font-weight:700;font-size:1.125rem}dd{margin:.5em 0 2em;padding:0}.f2-fluid{font-size:2.25rem}@media screen and (min-width:60em){.f2-fluid{font-size:1.25rem;font-size:calc(0.70833rem + 0.83333vw)}}code,.code,pre code,.highlight pre{font-family:inconsolata,Menlo,Monaco,courier new,monospace}.sans-serif{font-family:muli,avenir,helvetica neue,helvetica,ubuntu,roboto,noto,segoe ui,arial,sans-serif}.serif{font-family:Palatino,palatino linotype,palatino lt std,book antiqua,Georgia,serif}.courier{font-family:courier next,courier,monospace}.helvetica{font-family:helvetica neue,helvetica,sans-serif}.avenir{font-family:avenir next,avenir,sans-serif}.athelas{font-family:athelas,georgia,serif}.georgia{font-family:georgia,serif}.times{font-family:times,serif}.bodoni{font-family:bodoni mt,serif}.calisto{font-family:calisto mt,serif}.garamond{font-family:garamond,serif}.baskerville{font-family:baskerville,serif}.pagination{margin:3rem 0}.pagination li{display:inline-block;margin-right:.375rem;font-size:.875rem;margin-bottom:2.5em}.pagination li a{padding:.5rem .625rem;background-color:#fff;color:#333;border:1px solid #ddd;border-radius:3px;text-decoration:none}.pagination li.disabled{display:none}.pagination li.active a:link,.pagination li.active a:active,.pagination li.active a:visited{background-color:#ddd}#TableOfContents ul li ul li ul li{display:none}#TableOfContents ul li{color:#000;display:block;margin-bottom:.375em;line-height:1.375}#TableOfContents ul li a{width:100%;padding:.25em .375em;margin-left:-.375em}#TableOfContents ul li a:hover{background-color:#999;color:#fff}.no-js .needs-js{opacity:0}.js .needs-js{opacity:1;-webkit-transition:opacity .15s ease-in;transition:opacity .15s ease-in}.facebook,.twitter,.instagram,.youtube{fill:#bababa}.facebook:hover{fill:#3b5998}.twitter{fill:#55acee}.twitter:hover{fill:#bababa}.instagram:hover{fill:#e95950}.youtube:hover{fill:#b00}@media(min-width:75em){[data-scrolldir=down] .sticky{position:fixed;top:100px;right:0}[data-scrolldir=up] .sticky{position:fixed;top:100px;right:0}}.fill-current{fill:currentColor}.chroma{background-color:#fff}.chroma .err{color:#a61717;background-color:#e3d2d2}.chroma .lntd{vertical-align:top;padding:0;margin:0;border:0}.chroma .lntable{border-spacing:0;padding:0;margin:0;border:0;width:auto;overflow:auto;display:block}.chroma .hl{display:block;width:100%;background-color:#ffc}.chroma .lnt{margin-right:.4em;padding:0 .4em}.chroma .ln{margin-right:.4em;padding:0 .4em}.chroma .k{font-weight:700}.chroma .kc{font-weight:700}.chroma .kd{font-weight:700}.chroma .kn{font-weight:700}.chroma .kp{font-weight:700}.chroma .kr{font-weight:700}.chroma .kt{color:#458;font-weight:700}.chroma .na{color:teal}.chroma .nb{color:#999}.chroma .nc{color:#458;font-weight:700}.chroma .no{color:teal}.chroma .ni{color:purple}.chroma .ne{color:#900;font-weight:700}.chroma .nf{color:#900;font-weight:700}.chroma .nn{color:#555}.chroma .nt{color:navy}.chroma .nv{color:teal}.chroma .s{color:#b84}.chroma .sa{color:#b84}.chroma .sb{color:#b84}.chroma .sc{color:#b84}.chroma .dl{color:#b84}.chroma .sd{color:#b84}.chroma .s2{color:#b84}.chroma .se{color:#b84}.chroma .sh{color:#b84}.chroma .si{color:#b84}.chroma .sx{color:#b84}.chroma .sr{color:olive}.chroma .s1{color:#b84}.chroma .ss{color:#b84}.chroma .m{color:#099}.chroma .mb{color:#099}.chroma .mf{color:#099}.chroma .mh{color:#099}.chroma .mi{color:#099}.chroma .il{color:#099}.chroma .mo{color:#099}.chroma .o{font-weight:700}.chroma .ow{font-weight:700}.chroma .c{color:#998;font-style:italic}.chroma .ch{color:#998;font-style:italic}.chroma .cm{color:#998;font-style:italic}.chroma .c1{color:#998;font-style:italic}.chroma .cs{color:#999;font-weight:700;font-style:italic}.chroma .cp{color:#999;font-weight:700}.chroma .cpf{color:#999;font-weight:700}.chroma .gd{color:#000;background-color:#fdd}.chroma .ge{font-style:italic}.chroma .gr{color:#a00}.chroma .gh{color:#999}.chroma .gi{color:#000;background-color:#dfd}.chroma .go{color:#888}.chroma .gp{color:#555}.chroma .gs{font-weight:700}.chroma .gu{color:#aaa}.chroma .gt{color:#a00}.chroma .w{color:#bbb}.nested-blockquote blockquote{border-left:4px solid #0594cb;padding-left:1em}.mw-90{max-width:90%}hugo-0.68.3/docs/resources/_gen/assets/css/output/css/app.css_d11fe7b62c27961c87ecd0f2490357b9.json000066400000000000000000000003061363637351300315130ustar00rootroot00000000000000{"Target":"output/css/app.min.2ac9b5935f7ff7709fe13c2b042a4a2d49fa96fb508e3e8870019ee9b72cf329.css","MediaType":"text/css","Data":{"Integrity":"sha256-Ksm1k19/93Cf4TwrBCpKLUn6lvtQjj6IcAGe6bcs8yk="}}hugo-0.68.3/docs/resources/_gen/assets/js/000077500000000000000000000000001363637351300203545ustar00rootroot00000000000000hugo-0.68.3/docs/resources/_gen/assets/js/output/000077500000000000000000000000001363637351300217145ustar00rootroot00000000000000hugo-0.68.3/docs/resources/_gen/assets/js/output/js/000077500000000000000000000000001363637351300223305ustar00rootroot00000000000000hugo-0.68.3/docs/resources/_gen/assets/js/output/js/app.js_8848f55d07695b7ff7188138f23d69e3.content000066400000000000000000004734541363637351300313510ustar00rootroot00000000000000!function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=1)}([function(e,t,n){!function(t,n){var r=function(e,t){"use strict";if(!t.getElementsByClassName)return;var n,r,i=t.documentElement,s=e.Date,o=e.HTMLPictureElement,a=e.addEventListener,c=e.setTimeout,u=e.requestAnimationFrame||c,l=e.requestIdleCallback,h=/^picture$/i,d=["load","error","lazyincluded","_lazyloaded"],f={},p=Array.prototype.forEach,g=function(e,t){return f[t]||(f[t]=new RegExp("(\\s|^)"+t+"(\\s|$)")),f[t].test(e.getAttribute("class")||"")&&f[t]},m=function(e,t){g(e,t)||e.setAttribute("class",(e.getAttribute("class")||"").trim()+" "+t)},v=function(e,t){var n;(n=g(e,t))&&e.setAttribute("class",(e.getAttribute("class")||"").replace(n," "))},y=function(e,t,n){var r=n?"addEventListener":"removeEventListener";n&&y(e,t),d.forEach(function(n){e[r](n,t)})},b=function(e,r,i,s,o){var a=t.createEvent("Event");return i||(i={}),i.instance=n,a.initEvent(r,!s,!o),a.detail=i,e.dispatchEvent(a),a},w=function(t,n){var i;!o&&(i=e.picturefill||r.pf)?(n&&n.src&&!t.getAttribute("srcset")&&t.setAttribute("srcset",n.src),i({reevaluate:!0,elements:[t]})):n&&n.src&&(t.src=n.src)},_=function(e,t){return(getComputedStyle(e,null)||{})[t]},E=function(e,t,n){for(n=n||e.offsetWidth;n0)&&"visible"!=_(s,"overflow")&&(r=s.getBoundingClientRect(),o=R>r.left&&kr.top-1&&T500&&i.clientWidth>500?500:370),L=r.expand,I=L*r.expFactor),H2&&f>2&&!t.hidden?(H=I,q=0):H=f>1&&q>1&&B<6?L:0;for(;s=d&&(T=a.top)<=O&&(R=a.right)>=d*D&&(k=a.left)<=A&&(M||R||k||T)&&(r.loadHidden||"hidden"!=_(m[s],"visibility"))&&(u&&B<3&&!p&&(f<3||q<4)||F(m[s],h))){if(X(m[s]),l=!0,B>9)break}else!l&&u&&!c&&B<4&&q<4&&f>2&&(o[0]||r.preloadAfterLoad)&&(o[0]||!p&&(M||R||k||T||"auto"!=m[s].getAttribute(r.sizesAttr)))&&(c=o[0]||m[s]);else X(m[s]);c&&!l&&X(c)}},K=function(e){var t,n=0,i=r.throttleDelay,o=r.ricTimeout,a=function(){t=!1,n=s.now(),e()},u=l&&o>49?function(){l(a,{timeout:o}),o!==r.ricTimeout&&(o=r.ricTimeout)}:S(function(){c(a)},!0);return function(e){var r;(e=!0===e)&&(o=33),t||(t=!0,(r=i-(s.now()-n))<0&&(r=0),e||r<9?u():c(u,r))}}(U),V=function(e){m(e.target,r.loadedClass),v(e.target,r.loadingClass),y(e.target,W),b(e.target,"lazyloaded")},J=S(V),W=function(e){J({target:e.target})},G=function(e){var t,n=e.getAttribute(r.srcsetAttr);(t=r.customMedia[e.getAttribute("data-media")||e.getAttribute("media")])&&e.setAttribute("media",t),n&&e.setAttribute("srcset",n)},Q=S(function(e,t,n,i,s){var o,a,u,l,f,g;(f=b(e,"lazybeforeunveil",t)).defaultPrevented||(i&&(n?m(e,r.autosizesClass):e.setAttribute("sizes",i)),a=e.getAttribute(r.srcsetAttr),o=e.getAttribute(r.srcAttr),s&&(u=e.parentNode,l=u&&h.test(u.nodeName||"")),g=t.firesLoad||"src"in e&&(a||o||l),f={target:e},g&&(y(e,z,!0),clearTimeout(d),d=c(z,2500),m(e,r.loadingClass),y(e,W,!0)),l&&p.call(u.getElementsByTagName("source"),G),a?e.setAttribute("srcset",a):o&&!l&&(j.test(e.nodeName)?function(e,t){try{e.contentWindow.location.replace(t)}catch(n){e.src=t}}(e,o):e.src=o),s&&(a||l)&&w(e,{src:o})),e._lazyRace&&delete e._lazyRace,v(e,r.lazyClass),x(function(){(!g||e.complete&&e.naturalWidth>1)&&(g?z(f):B--,V(f))},!0)}),X=function(e){var t,n=P.test(e.nodeName),i=n&&(e.getAttribute(r.sizesAttr)||e.getAttribute("sizes")),s="auto"==i;(!s&&u||!n||!e.getAttribute("src")&&!e.srcset||e.complete||g(e,r.errorClass)||!g(e,r.lazyClass))&&(t=b(e,"lazyunveilread").detail,s&&N.updateElem(e,!0,e.offsetWidth),e._lazyRace=!0,B++,Q(e,t,s,i,n))},Z=function(){if(!u)if(s.now()-E<999)c(Z,999);else{var e=C(function(){r.loadMode=3,K()});u=!0,r.loadMode=3,K(),a("scroll",function(){3==r.loadMode&&(r.loadMode=2),e()},!0)}};return{_:function(){E=s.now(),n.elements=t.getElementsByClassName(r.lazyClass),o=t.getElementsByClassName(r.lazyClass+" "+r.preloadClass),D=r.hFac,a("scroll",K,!0),a("resize",K,!0),e.MutationObserver?new MutationObserver(K).observe(i,{childList:!0,subtree:!0,attributes:!0}):(i.addEventListener("DOMNodeInserted",K,!0),i.addEventListener("DOMAttrModified",K,!0),setInterval(K,999)),a("hashchange",K,!0),["focus","mouseover","click","load","transitionend","animationend","webkitAnimationEnd"].forEach(function(e){t.addEventListener(e,K,!0)}),/d$|^c/.test(t.readyState)?Z():(a("load",Z),t.addEventListener("DOMContentLoaded",K),c(Z,2e4)),n.elements.length?(U(),x._lsFlush()):K()},checkElems:K,unveil:X}}(),N=function(){var e,n=S(function(e,t,n,r){var i,s,o;if(e._lazysizesWidth=r,r+="px",e.setAttribute("sizes",r),h.test(t.nodeName||""))for(i=t.getElementsByTagName("source"),s=0,o=i.length;s0&&void 0!==arguments[0]?arguments[0]:{};this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText,this.container="object"===r(e.container)?e.container:document.body}},{key:"listenClick",value:function(e){var t=this;this.listener=(0,a.default)(e,"click",function(e){return t.onClick(e)})}},{key:"onClick",value:function(e){var t=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new s.default({action:this.action(t),target:this.target(t),text:this.text(t),container:this.container,trigger:t,emitter:this})}},{key:"defaultAction",value:function(e){return l("action",e)}},{key:"defaultTarget",value:function(e){var t=l("target",e);if(t)return document.querySelector(t)}},{key:"defaultText",value:function(e){return l("text",e)}},{key:"destroy",value:function(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)}}],[{key:"isSupported",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:["copy","cut"],t="string"==typeof e?[e]:e,n=!!document.queryCommandSupported;return t.forEach(function(e){n=n&&!!document.queryCommandSupported(e)}),n}}]),t}();function l(e,t){var n="data-clipboard-"+e;if(t.hasAttribute(n))return t.getAttribute(n)}e.exports=u},function(e,t,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i=function(){function e(e,t){for(var n=0;n0&&void 0!==arguments[0]?arguments[0]:{};this.action=e.action,this.container=e.container,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""}},{key:"initSelection",value:function(){this.text?this.selectFake():this.target&&this.selectTarget()}},{key:"selectFake",value:function(){var e=this,t="rtl"==document.documentElement.getAttribute("dir");this.removeFake(),this.fakeHandlerCallback=function(){return e.removeFake()},this.fakeHandler=this.container.addEventListener("click",this.fakeHandlerCallback)||!0,this.fakeElem=document.createElement("textarea"),this.fakeElem.style.fontSize="12pt",this.fakeElem.style.border="0",this.fakeElem.style.padding="0",this.fakeElem.style.margin="0",this.fakeElem.style.position="absolute",this.fakeElem.style[t?"right":"left"]="-9999px";var n=window.pageYOffset||document.documentElement.scrollTop;this.fakeElem.style.top=n+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,this.container.appendChild(this.fakeElem),this.selectedText=(0,s.default)(this.fakeElem),this.copyText()}},{key:"removeFake",value:function(){this.fakeHandler&&(this.container.removeEventListener("click",this.fakeHandlerCallback),this.fakeHandler=null,this.fakeHandlerCallback=null),this.fakeElem&&(this.container.removeChild(this.fakeElem),this.fakeElem=null)}},{key:"selectTarget",value:function(){this.selectedText=(0,s.default)(this.target),this.copyText()}},{key:"copyText",value:function(){var e=void 0;try{e=document.execCommand(this.action)}catch(t){e=!1}this.handleResult(e)}},{key:"handleResult",value:function(e){this.emitter.emit(e?"success":"error",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})}},{key:"clearSelection",value:function(){this.trigger&&this.trigger.focus(),window.getSelection().removeAllRanges()}},{key:"destroy",value:function(){this.removeFake()}},{key:"action",set:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"copy";if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function(){return this._action}},{key:"target",set:function(e){if(void 0!==e){if(!e||"object"!==(void 0===e?"undefined":r(e))||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');if("copy"===this.action&&e.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if("cut"===this.action&&(e.hasAttribute("readonly")||e.hasAttribute("disabled")))throw new Error('Invalid "target" attribute. You can\'t cut text from elements with "readonly" or "disabled" attributes');this._target=e}},get:function(){return this._target}}]),e}();e.exports=o},function(e,t){e.exports=function(e){var t;if("SELECT"===e.nodeName)e.focus(),t=e.value;else if("INPUT"===e.nodeName||"TEXTAREA"===e.nodeName){var n=e.hasAttribute("readonly");n||e.setAttribute("readonly",""),e.select(),e.setSelectionRange(0,e.value.length),n||e.removeAttribute("readonly"),t=e.value}else{e.hasAttribute("contenteditable")&&e.focus();var r=window.getSelection(),i=document.createRange();i.selectNodeContents(e),r.removeAllRanges(),r.addRange(i),t=r.toString()}return t}},function(e,t){function n(){}n.prototype={on:function(e,t,n){var r=this.e||(this.e={});return(r[e]||(r[e]=[])).push({fn:t,ctx:n}),this},once:function(e,t,n){var r=this;function i(){r.off(e,i),t.apply(n,arguments)}return i._=t,this.on(e,i,n)},emit:function(e){for(var t=[].slice.call(arguments,1),n=((this.e||(this.e={}))[e]||[]).slice(),r=0,i=n.length;r0&&n.parentNode.classList.add("expand")}}},function(e,t,n){n(9)({apiKey:"167e7998590aebda7f9fedcf86bc4a55",indexName:"hugodocs",inputSelector:"#search-input",debug:!0})},function(e,t,n){ /*! docsearch 2.6.1 | © Algolia | github.com/algolia/docsearch */ !function(t,n){e.exports=n()}("undefined"!=typeof self&&self,function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=22)}([function(e,t,n){"use strict";var r=n(1);function i(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}e.exports={isArray:null,isFunction:null,isObject:null,bind:null,each:null,map:null,mixin:null,isMsie:function(e){if(void 0===e&&(e=navigator.userAgent),/(msie|trident)/i.test(e)){var t=e.match(/(msie |rv:)(\d+(.\d+)?)/i);if(t)return t[2]}return!1},escapeRegExChars:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")},isNumber:function(e){return"number"==typeof e},toStr:function(e){return void 0===e||null===e?"":e+""},cloneDeep:function(e){var t=this.mixin({},e),n=this;return this.each(t,function(e,r){e&&(n.isArray(e)?t[r]=[].concat(e):n.isObject(e)&&(t[r]=n.cloneDeep(e)))}),t},error:function(e){throw new Error(e)},every:function(e,t){var n=!0;return e?(this.each(e,function(r,i){if(!(n=t.call(null,r,i,e)))return!1}),!!n):n},any:function(e,t){var n=!1;return e?(this.each(e,function(r,i){if(t.call(null,r,i,e))return n=!0,!1}),n):n},getUniqueId:function(){var e=0;return function(){return e++}}(),templatify:function(e){if(this.isFunction(e))return e;var t=r.element(e);return"SCRIPT"===t.prop("tagName")?function(){return t.text()}:function(){return String(e)}},defer:function(e){setTimeout(e,0)},noop:function(){},formatPrefix:function(e,t){return t?"":e+"-"},className:function(e,t,n){return(n?"":".")+e+t},escapeHighlightedString:function(e,t,n){t=t||"";var r=document.createElement("div");r.appendChild(document.createTextNode(t)),n=n||"";var s=document.createElement("div");s.appendChild(document.createTextNode(n));var o=document.createElement("div");return o.appendChild(document.createTextNode(e)),o.innerHTML.replace(RegExp(i(r.innerHTML),"g"),t).replace(RegExp(i(s.innerHTML),"g"),n)}}},function(e,t,n){"use strict";e.exports={element:null}},function(e,t){var n=Object.prototype.hasOwnProperty,r=Object.prototype.toString;e.exports=function(e,t,i){if("[object Function]"!==r.call(t))throw new TypeError("iterator must be a function");var s=e.length;if(s===+s)for(var o=0;o was loaded but did not call our provided callback"),JSONPScriptError:s("JSONPScriptError"," hugo-0.68.3/examples/blog/layouts/partials/header.html000066400000000000000000000006221363637351300227620ustar00rootroot00000000000000 {{ partial "meta.html" . }} {{ .Title }} - {{ .Site.BaseURL }} {{ partial "header.includes.html" . }} {{ with .OutputFormats.Get "RSS" -}} {{ printf "" .Permalink .MediaType $.Site.Title | safeHTML }} {{- end }} hugo-0.68.3/examples/blog/layouts/partials/header.includes.html000066400000000000000000000002471363637351300245720ustar00rootroot00000000000000 hugo-0.68.3/examples/blog/layouts/partials/menu.html000066400000000000000000000016141363637351300225000ustar00rootroot00000000000000

    Connect. Socialize.

    Hey, listen!
    You should modify the layouts/partials/menu.html template and include your own profile links.
    hugo-0.68.3/examples/blog/layouts/partials/meta.html000066400000000000000000000005551363637351300224650ustar00rootroot00000000000000 hugo-0.68.3/examples/blog/layouts/partials/navbar.html000066400000000000000000000020441363637351300230030ustar00rootroot00000000000000 hugo-0.68.3/examples/blog/layouts/post/000077500000000000000000000000001363637351300200125ustar00rootroot00000000000000hugo-0.68.3/examples/blog/layouts/post/li.html000066400000000000000000000002301363637351300212770ustar00rootroot00000000000000
  • {{ .Title}}
    posted on {{ .Date.Format "January 2, 2006" }}
  • hugo-0.68.3/examples/blog/layouts/post/list.html000066400000000000000000000012051363637351300216510ustar00rootroot00000000000000{{ partial "header.html" . }} {{ partial "navbar.html" . }}
    Blog Post Archive
      {{ range .Data.Pages }} {{ .Render "li" }} {{ end}}
    {{ partial "menu.html" . }}
    {{ partial "footer.copyright.html" . }}
    {{ partial "footer.html" . }} hugo-0.68.3/examples/blog/layouts/post/single.html000066400000000000000000000023211363637351300221570ustar00rootroot00000000000000{{ partial "header.html" . }} {{ partial "navbar.html" . }}

    {{ .Title }}
    {{ .Description }}


    {{ .Content }}

    {{ .Date.Format "January 2, 2006" }}
    {{ .WordCount }} words


    Categories
      {{ range .Params.categories }}
    • {{ . }}
    • {{ end }}

    Tags
    {{ range .Params.tags }}{{ . }} {{ end }}
    {{ partial "menu.html" . }}
    {{ partial "footer.copyright.html" . }}
    {{ partial "footer.html" . }} hugo-0.68.3/examples/blog/layouts/post/summary.html000066400000000000000000000006011363637351300223720ustar00rootroot00000000000000

    {{ .Title }} Posted on {{ .Date.Format "Jan 2, 2006" }}
    {{ .Description }}


    {{ .Summary }}

    Read More
    hugo-0.68.3/examples/blog/layouts/tags/000077500000000000000000000000001363637351300177635ustar00rootroot00000000000000hugo-0.68.3/examples/blog/layouts/tags/list.html000066400000000000000000000012441363637351300216250ustar00rootroot00000000000000{{ partial "header.html" . }} {{ partial "navbar.html" . }}
    Items with tag {{ .Title | lower }}
      {{ range .Data.Pages }} {{ .Render "li" }} {{ end}}
    {{ partial "menu.html" . }}
    {{ partial "footer.copyright.html" . }}
    {{ partial "footer.html" . }} hugo-0.68.3/examples/blog/static/000077500000000000000000000000001363637351300166145ustar00rootroot00000000000000hugo-0.68.3/examples/blog/static/css/000077500000000000000000000000001363637351300174045ustar00rootroot00000000000000hugo-0.68.3/examples/blog/static/css/bootstrap.min.css000066400000000000000000003714211363637351300227250ustar00rootroot00000000000000@import url("https://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,700italic,400,300,700");/*! * bootswatch v3.3.6 * Homepage: http://bootswatch.com * Copyright 2012-2015 Thomas Park * Licensed under MIT * Based on Bootstrap *//*! * Bootstrap v3.3.6 (http://getbootstrap.com) * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:15px;line-height:1.4;color:#222222;background-color:#ffffff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#008cba;text-decoration:none}a:hover,a:focus{color:#008cba;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:0}.img-thumbnail{padding:4px;line-height:1.4;background-color:#ffffff;border:1px solid #dddddd;border-radius:0;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:21px;margin-bottom:21px;border:0;border-top:1px solid #dddddd}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#999999}h1,.h1,h2,.h2,h3,.h3{margin-top:21px;margin-bottom:10.5px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10.5px;margin-bottom:10.5px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:39px}h2,.h2{font-size:32px}h3,.h3{font-size:26px}h4,.h4{font-size:19px}h5,.h5{font-size:15px}h6,.h6{font-size:13px}p{margin:0 0 10.5px}.lead{margin-bottom:21px;font-size:17px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:22.5px}}small,.small{font-size:80%}mark,.mark{background-color:#fcf8e3;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#999999}.text-primary{color:#008cba}a.text-primary:hover,a.text-primary:focus{color:#006687}.text-success{color:#43ac6a}a.text-success:hover,a.text-success:focus{color:#358753}.text-info{color:#5bc0de}a.text-info:hover,a.text-info:focus{color:#31b0d5}.text-warning{color:#e99002}a.text-warning:hover,a.text-warning:focus{color:#b67102}.text-danger{color:#f04124}a.text-danger:hover,a.text-danger:focus{color:#d32a0e}.bg-primary{color:#fff;background-color:#008cba}a.bg-primary:hover,a.bg-primary:focus{background-color:#006687}.bg-success{background-color:#dff0d8}a.bg-success:hover,a.bg-success:focus{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover,a.bg-info:focus{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover,a.bg-warning:focus{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover,a.bg-danger:focus{background-color:#e4b9b9}.page-header{padding-bottom:9.5px;margin:42px 0 21px;border-bottom:1px solid #dddddd}ul,ol{margin-top:0;margin-bottom:10.5px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:21px}dt,dd{line-height:1.4}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #999999}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10.5px 21px;margin:0 0 21px;font-size:18.75px;border-left:5px solid #dddddd}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.4;color:#6f6f6f}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #dddddd;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:21px;font-style:normal;line-height:1.4}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:0}kbd{padding:2px 4px;font-size:90%;color:#ffffff;background-color:#333333;border-radius:0;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:10px;margin:0 0 10.5px;font-size:14px;line-height:1.4;word-break:break-all;word-wrap:break-word;color:#333333;background-color:#f5f5f5;border:1px solid #cccccc;border-radius:0}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0%}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0%}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0%}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0%}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#999999;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:21px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.4;vertical-align:top;border-top:1px solid #dddddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #dddddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #dddddd}.table .table{background-color:#ffffff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #dddddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #dddddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15.75px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #dddddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:21px;font-size:22.5px;line-height:inherit;color:#333333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:9px;font-size:15px;line-height:1.4;color:#6f6f6f}.form-control{display:block;width:100%;height:39px;padding:8px 12px;font-size:15px;line-height:1.4;color:#6f6f6f;background-color:#ffffff;background-image:none;border:1px solid #cccccc;border-radius:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control::-moz-placeholder{color:#999999;opacity:1}.form-control:-ms-input-placeholder{color:#999999}.form-control::-webkit-input-placeholder{color:#999999}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eeeeee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:39px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:36px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:60px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:21px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:9px;padding-bottom:9px;margin-bottom:0;min-height:36px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{height:36px;padding:8px 12px;font-size:12px;line-height:1.5;border-radius:0}select.input-sm{height:36px;line-height:36px}textarea.input-sm,select[multiple].input-sm{height:auto}.form-group-sm .form-control{height:36px;padding:8px 12px;font-size:12px;line-height:1.5;border-radius:0}.form-group-sm select.form-control{height:36px;line-height:36px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:36px;min-height:33px;padding:9px 12px;font-size:12px;line-height:1.5}.input-lg{height:60px;padding:16px 20px;font-size:19px;line-height:1.3333333;border-radius:0}select.input-lg{height:60px;line-height:60px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:60px;padding:16px 20px;font-size:19px;line-height:1.3333333;border-radius:0}.form-group-lg select.form-control{height:60px;line-height:60px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:60px;min-height:40px;padding:17px 20px;font-size:19px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:48.75px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:39px;height:39px;line-height:39px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:60px;height:60px;line-height:60px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:36px;height:36px;line-height:36px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#43ac6a}.has-success .form-control{border-color:#43ac6a;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#358753;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #85d0a1;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #85d0a1}.has-success .input-group-addon{color:#43ac6a;border-color:#43ac6a;background-color:#dff0d8}.has-success .form-control-feedback{color:#43ac6a}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#e99002}.has-warning .form-control{border-color:#e99002;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#b67102;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #febc53;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #febc53}.has-warning .input-group-addon{color:#e99002;border-color:#e99002;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#e99002}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#f04124}.has-error .form-control{border-color:#f04124;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#d32a0e;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #f79483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #f79483}.has-error .input-group-addon{color:#f04124;border-color:#f04124;background-color:#f2dede}.has-error .form-control-feedback{color:#f04124}.has-feedback label~.form-control-feedback{top:26px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#626262}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:9px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:30px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:9px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:17px;font-size:19px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:9px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:8px 12px;font-size:15px;line-height:1.4;border-radius:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#333333;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333333;background-color:#e7e7e7;border-color:#cccccc}.btn-default:focus,.btn-default.focus{color:#333333;background-color:#cecece;border-color:#8c8c8c}.btn-default:hover{color:#333333;background-color:#cecece;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333333;background-color:#cecece;border-color:#adadad}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#333333;background-color:#bcbcbc;border-color:#8c8c8c}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#e7e7e7;border-color:#cccccc}.btn-default .badge{color:#e7e7e7;background-color:#333333}.btn-primary{color:#ffffff;background-color:#008cba;border-color:#0079a1}.btn-primary:focus,.btn-primary.focus{color:#ffffff;background-color:#006687;border-color:#001921}.btn-primary:hover{color:#ffffff;background-color:#006687;border-color:#004b63}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#ffffff;background-color:#006687;border-color:#004b63}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#ffffff;background-color:#004b63;border-color:#001921}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#008cba;border-color:#0079a1}.btn-primary .badge{color:#008cba;background-color:#ffffff}.btn-success{color:#ffffff;background-color:#43ac6a;border-color:#3c9a5f}.btn-success:focus,.btn-success.focus{color:#ffffff;background-color:#358753;border-color:#183e26}.btn-success:hover{color:#ffffff;background-color:#358753;border-color:#2b6e44}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#ffffff;background-color:#358753;border-color:#2b6e44}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#ffffff;background-color:#2b6e44;border-color:#183e26}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#43ac6a;border-color:#3c9a5f}.btn-success .badge{color:#43ac6a;background-color:#ffffff}.btn-info{color:#ffffff;background-color:#5bc0de;border-color:#46b8da}.btn-info:focus,.btn-info.focus{color:#ffffff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#ffffff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#ffffff;background-color:#31b0d5;border-color:#269abc}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#ffffff;background-color:#269abc;border-color:#1b6d85}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#ffffff}.btn-warning{color:#ffffff;background-color:#e99002;border-color:#d08002}.btn-warning:focus,.btn-warning.focus{color:#ffffff;background-color:#b67102;border-color:#513201}.btn-warning:hover{color:#ffffff;background-color:#b67102;border-color:#935b01}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#ffffff;background-color:#b67102;border-color:#935b01}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#ffffff;background-color:#935b01;border-color:#513201}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#e99002;border-color:#d08002}.btn-warning .badge{color:#e99002;background-color:#ffffff}.btn-danger{color:#ffffff;background-color:#f04124;border-color:#ea2f10}.btn-danger:focus,.btn-danger.focus{color:#ffffff;background-color:#d32a0e;border-color:#731708}.btn-danger:hover{color:#ffffff;background-color:#d32a0e;border-color:#b1240c}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#ffffff;background-color:#d32a0e;border-color:#b1240c}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#ffffff;background-color:#b1240c;border-color:#731708}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#f04124;border-color:#ea2f10}.btn-danger .badge{color:#f04124;background-color:#ffffff}.btn-link{color:#008cba;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#008cba;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#999999;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:16px 20px;font-size:19px;line-height:1.3333333;border-radius:0}.btn-sm,.btn-group-sm>.btn{padding:8px 12px;font-size:12px;line-height:1.5;border-radius:0}.btn-xs,.btn-group-xs>.btn{padding:4px 6px;font-size:12px;line-height:1.5;border-radius:0}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:0.35s;-o-transition-duration:0.35s;transition-duration:0.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:15px;text-align:left;background-color:#ffffff;border:1px solid #cccccc;border:1px solid rgba(0,0,0,0.15);border-radius:0;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:rgba(0,0,0,0.2)}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.4;color:#555555;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#262626;background-color:#eeeeee}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#008cba}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#999999}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.4;color:#999999;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:60px;padding:16px 20px;font-size:19px;line-height:1.3333333;border-radius:0}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:60px;line-height:60px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:36px;padding:8px 12px;font-size:12px;line-height:1.5;border-radius:0}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:36px;line-height:36px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:8px 12px;font-size:15px;font-weight:normal;line-height:1;color:#6f6f6f;text-align:center;background-color:#eeeeee;border:1px solid #cccccc;border-radius:0}.input-group-addon.input-sm{padding:8px 12px;font-size:12px;border-radius:0}.input-group-addon.input-lg{padding:16px 20px;font-size:19px;border-radius:0}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eeeeee}.nav>li.disabled>a{color:#999999}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#999999;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eeeeee;border-color:#008cba}.nav .nav-divider{height:1px;margin:9.5px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #dddddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.4;border:1px solid transparent;border-radius:0 0 0 0}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#6f6f6f;background-color:#ffffff;border:1px solid #dddddd;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #dddddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #dddddd;border-radius:0 0 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#ffffff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:0}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#ffffff;background-color:#008cba}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #dddddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #dddddd;border-radius:0 0 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#ffffff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:45px;margin-bottom:21px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:0}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:12px 15px;font-size:19px;line-height:21px;height:45px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:5.5px;margin-bottom:5.5px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:0}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:6px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:21px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:21px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:12px;padding-bottom:12px}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:3px;margin-bottom:3px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:3px;margin-bottom:3px}.navbar-btn.btn-sm{margin-top:4.5px;margin-bottom:4.5px}.navbar-btn.btn-xs{margin-top:11.5px;margin-bottom:11.5px}.navbar-text{margin-top:12px;margin-bottom:12px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}}@media (min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#333333;border-color:#222222}.navbar-default .navbar-brand{color:#ffffff}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#ffffff;background-color:transparent}.navbar-default .navbar-text{color:#ffffff}.navbar-default .navbar-nav>li>a{color:#ffffff}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#ffffff;background-color:#272727}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#ffffff;background-color:#272727}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:transparent}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:transparent}.navbar-default .navbar-toggle .icon-bar{background-color:#ffffff}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#222222}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#272727;color:#ffffff}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#ffffff}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:#272727}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:#272727}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#cccccc;background-color:transparent}}.navbar-default .navbar-link{color:#ffffff}.navbar-default .navbar-link:hover{color:#ffffff}.navbar-default .btn-link{color:#ffffff}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#ffffff}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#cccccc}.navbar-inverse{background-color:#008cba;border-color:#006687}.navbar-inverse .navbar-brand{color:#ffffff}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-text{color:#ffffff}.navbar-inverse .navbar-nav>li>a{color:#ffffff}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#ffffff;background-color:#006687}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#ffffff;background-color:#006687}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:transparent}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:transparent}.navbar-inverse .navbar-toggle .icon-bar{background-color:#ffffff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#007196}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#006687;color:#ffffff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#ffffff}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:#006687}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444444;background-color:transparent}}.navbar-inverse .navbar-link{color:#ffffff}.navbar-inverse .navbar-link:hover{color:#ffffff}.navbar-inverse .btn-link{color:#ffffff}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#ffffff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444444}.breadcrumb{padding:8px 15px;margin-bottom:21px;list-style:none;background-color:#f5f5f5;border-radius:0}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#999999}.breadcrumb>.active{color:#333333}.pagination{display:inline-block;padding-left:0;margin:21px 0;border-radius:0}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:8px 12px;line-height:1.4;text-decoration:none;color:#008cba;background-color:transparent;border:1px solid transparent;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:0;border-top-left-radius:0}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:0;border-top-right-radius:0}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#008cba;background-color:#eeeeee;border-color:transparent}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#ffffff;background-color:#008cba;border-color:transparent;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#999999;background-color:#ffffff;border-color:transparent;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:16px 20px;font-size:19px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:0;border-top-left-radius:0}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:0;border-top-right-radius:0}.pagination-sm>li>a,.pagination-sm>li>span{padding:8px 12px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:0;border-top-left-radius:0}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:0;border-top-right-radius:0}.pager{padding-left:0;margin:21px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:transparent;border:1px solid transparent;border-radius:3px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eeeeee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#999999;background-color:transparent;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#ffffff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#999999}.label-default[href]:hover,.label-default[href]:focus{background-color:#808080}.label-primary{background-color:#008cba}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#006687}.label-success{background-color:#43ac6a}.label-success[href]:hover,.label-success[href]:focus{background-color:#358753}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#e99002}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#b67102}.label-danger{background-color:#f04124}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#d32a0e}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#ffffff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#008cba;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#008cba;background-color:#ffffff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#fafafa}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:23px;font-weight:200}.jumbotron>hr{border-top-color:#e1e1e1}.container .jumbotron,.container-fluid .jumbotron{border-radius:0;padding-left:15px;padding-right:15px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:68px}}.thumbnail{display:block;padding:4px;margin-bottom:21px;line-height:1.4;background-color:#ffffff;border:1px solid #dddddd;border-radius:0;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#008cba}.thumbnail .caption{padding:9px;color:#222222}.alert{padding:15px;margin-bottom:21px;border:1px solid transparent;border-radius:0}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#43ac6a;border-color:#3c9a5f;color:#ffffff}.alert-success hr{border-top-color:#358753}.alert-success .alert-link{color:#e6e6e6}.alert-info{background-color:#5bc0de;border-color:#3db5d8;color:#ffffff}.alert-info hr{border-top-color:#2aabd2}.alert-info .alert-link{color:#e6e6e6}.alert-warning{background-color:#e99002;border-color:#d08002;color:#ffffff}.alert-warning hr{border-top-color:#b67102}.alert-warning .alert-link{color:#e6e6e6}.alert-danger{background-color:#f04124;border-color:#ea2f10;color:#ffffff}.alert-danger hr{border-top-color:#d32a0e}.alert-danger .alert-link{color:#e6e6e6}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:21px;margin-bottom:21px;background-color:#f5f5f5;border-radius:0;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:21px;color:#ffffff;text-align:center;background-color:#008cba;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#43ac6a}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#e99002}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-danger{background-color:#f04124}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#ffffff;border:1px solid #dddddd}.list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}a.list-group-item,button.list-group-item{color:#555555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333333}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{text-decoration:none;color:#555555;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#eeeeee;color:#999999;cursor:not-allowed}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#999999}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#ffffff;background-color:#008cba;border-color:#008cba}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#87e1ff}.list-group-item-success{color:#43ac6a;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#43ac6a}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#43ac6a;background-color:#d0e9c6}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#43ac6a;border-color:#43ac6a}.list-group-item-info{color:#5bc0de;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#5bc0de}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#5bc0de;background-color:#c4e3f3}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#5bc0de;border-color:#5bc0de}.list-group-item-warning{color:#e99002;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#e99002}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#e99002;background-color:#faf2cc}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#e99002;border-color:#e99002}.list-group-item-danger{color:#f04124;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#f04124}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#f04124;background-color:#ebcccc}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#f04124;border-color:#f04124}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:21px;background-color:#ffffff;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:-1;border-top-left-radius:-1}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:17px;color:inherit}.panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #dddddd;border-bottom-right-radius:-1;border-bottom-left-radius:-1}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:-1;border-top-left-radius:-1}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:-1;border-bottom-left-radius:-1}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:-1;border-top-left-radius:-1}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:-1;border-top-right-radius:-1}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:-1}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:-1}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:-1;border-bottom-left-radius:-1}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-left-radius:-1;border-bottom-right-radius:-1}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:-1}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:-1}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #dddddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:21px}.panel-group .panel{margin-bottom:0;border-radius:0}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #dddddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #dddddd}.panel-default{border-color:#dddddd}.panel-default>.panel-heading{color:#333333;background-color:#f5f5f5;border-color:#dddddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#dddddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#dddddd}.panel-primary{border-color:#008cba}.panel-primary>.panel-heading{color:#ffffff;background-color:#008cba;border-color:#008cba}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#008cba}.panel-primary>.panel-heading .badge{color:#008cba;background-color:#ffffff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#008cba}.panel-success{border-color:#3c9a5f}.panel-success>.panel-heading{color:#ffffff;background-color:#43ac6a;border-color:#3c9a5f}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#3c9a5f}.panel-success>.panel-heading .badge{color:#43ac6a;background-color:#ffffff}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#3c9a5f}.panel-info{border-color:#3db5d8}.panel-info>.panel-heading{color:#ffffff;background-color:#5bc0de;border-color:#3db5d8}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#3db5d8}.panel-info>.panel-heading .badge{color:#5bc0de;background-color:#ffffff}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#3db5d8}.panel-warning{border-color:#d08002}.panel-warning>.panel-heading{color:#ffffff;background-color:#e99002;border-color:#d08002}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d08002}.panel-warning>.panel-heading .badge{color:#e99002;background-color:#ffffff}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d08002}.panel-danger{border-color:#ea2f10}.panel-danger>.panel-heading{color:#ffffff;background-color:#f04124;border-color:#ea2f10}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ea2f10}.panel-danger>.panel-heading .badge{color:#f04124;background-color:#ffffff}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ea2f10}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;left:0;bottom:0;height:100%;width:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#fafafa;border:1px solid #e8e8e8;border-radius:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:0}.well-sm{padding:9px;border-radius:0}.close{float:right;font-size:22.5px;font-weight:bold;line-height:1;color:#ffffff;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#ffffff;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#ffffff;border:1px solid #999999;border:1px solid rgba(0,0,0,0.2);border-radius:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.4}.modal-body{position:relative;padding:20px}.modal-footer{padding:20px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.4;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:0.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;background-color:#333333;border-radius:0}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#333333}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#333333}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#333333}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#333333}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#333333}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#333333}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#333333}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#333333}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.4;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:15px;background-color:#333333;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #333333;border:1px solid transparent;border-radius:0;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:15px;background-color:#333333;border-bottom:1px solid #262626;border-radius:-1 -1 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#000000;border-top-color:rgba(0,0,0,0.05);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#333333}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#000000;border-right-color:rgba(0,0,0,0.05)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#333333}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#000000;border-bottom-color:rgba(0,0,0,0.05);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#333333}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#000000;border-left-color:rgba(0,0,0,0.05)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#333333;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:0.5;filter:alpha(opacity=50);font-size:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);background-color:rgba(0,0,0,0)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0.0001)));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.0001)), to(rgba(0,0,0,0.5)));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;margin-top:-10px;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;line-height:1;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #ffffff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#ffffff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}.navbar{border:none;font-size:13px;font-weight:300}.navbar .navbar-toggle:hover .icon-bar{background-color:#b3b3b3}.navbar-collapse{border-top-color:rgba(0,0,0,0.2);-webkit-box-shadow:none;box-shadow:none}.navbar .btn{padding-top:6px;padding-bottom:6px}.navbar-form{margin-top:7px;margin-bottom:5px}.navbar-form .form-control{height:auto;padding:4px 6px}.navbar .dropdown-menu{border:none}.navbar .dropdown-menu>li>a,.navbar .dropdown-menu>li>a:focus{background-color:transparent;font-size:13px;font-weight:300}.navbar .dropdown-header{color:rgba(255,255,255,0.5)}.navbar-default .dropdown-menu{background-color:#333333}.navbar-default .dropdown-menu>li>a,.navbar-default .dropdown-menu>li>a:focus{color:#ffffff}.navbar-default .dropdown-menu>li>a:hover,.navbar-default .dropdown-menu>.active>a,.navbar-default .dropdown-menu>.active>a:hover{background-color:#272727}.navbar-inverse .dropdown-menu{background-color:#008cba}.navbar-inverse .dropdown-menu>li>a,.navbar-inverse .dropdown-menu>li>a:focus{color:#ffffff}.navbar-inverse .dropdown-menu>li>a:hover,.navbar-inverse .dropdown-menu>.active>a,.navbar-inverse .dropdown-menu>.active>a:hover{background-color:#006687}.btn{padding:8px 12px}.btn-lg{padding:16px 20px}.btn-sm{padding:8px 12px}.btn-xs{padding:4px 6px}.btn-group .btn~.dropdown-toggle{padding-left:16px;padding-right:16px}.btn-group .dropdown-menu{border-top-width:0}.btn-group.dropup .dropdown-menu{border-top-width:1px;border-bottom-width:0;margin-bottom:0}.btn-group .dropdown-toggle.btn-default~.dropdown-menu{background-color:#e7e7e7;border-color:#cccccc}.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a{color:#333333}.btn-group .dropdown-toggle.btn-default~.dropdown-menu>li>a:hover{background-color:#d3d3d3}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu{background-color:#008cba;border-color:#0079a1}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a{color:#ffffff}.btn-group .dropdown-toggle.btn-primary~.dropdown-menu>li>a:hover{background-color:#006d91}.btn-group .dropdown-toggle.btn-success~.dropdown-menu{background-color:#43ac6a;border-color:#3c9a5f}.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a{color:#ffffff}.btn-group .dropdown-toggle.btn-success~.dropdown-menu>li>a:hover{background-color:#388f58}.btn-group .dropdown-toggle.btn-info~.dropdown-menu{background-color:#5bc0de;border-color:#46b8da}.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a{color:#ffffff}.btn-group .dropdown-toggle.btn-info~.dropdown-menu>li>a:hover{background-color:#39b3d7}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu{background-color:#e99002;border-color:#d08002}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a{color:#ffffff}.btn-group .dropdown-toggle.btn-warning~.dropdown-menu>li>a:hover{background-color:#c17702}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu{background-color:#f04124;border-color:#ea2f10}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a{color:#ffffff}.btn-group .dropdown-toggle.btn-danger~.dropdown-menu>li>a:hover{background-color:#dc2c0f}.lead{color:#6f6f6f}cite{font-style:italic}blockquote{border-left-width:1px;color:#6f6f6f}blockquote.pull-right{border-right-width:1px}blockquote small{font-size:12px;font-weight:300}table{font-size:12px}label,.control-label,.help-block,.checkbox,.radio{font-size:12px;font-weight:normal}input[type="radio"],input[type="checkbox"]{margin-top:1px}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{border-color:transparent}.nav-tabs>li>a{background-color:#e7e7e7;color:#222222}.nav-tabs .caret{border-top-color:#222222;border-bottom-color:#222222}.nav-pills{font-weight:300}.breadcrumb{border:1px solid #dddddd;border-radius:3px;font-size:10px;font-weight:300;text-transform:uppercase}.pagination{font-size:12px;font-weight:300;color:#999999}.pagination>li>a,.pagination>li>span{margin-left:4px;color:#999999}.pagination>.active>a,.pagination>.active>span{color:#fff}.pagination>li>a,.pagination>li:first-child>a,.pagination>li:last-child>a,.pagination>li>span,.pagination>li:first-child>span,.pagination>li:last-child>span{border-radius:3px}.pagination-lg>li>a,.pagination-lg>li>span{padding-left:22px;padding-right:22px}.pagination-sm>li>a,.pagination-sm>li>span{padding:0 5px}.pager{font-size:12px;font-weight:300;color:#999999}.list-group{font-size:12px;font-weight:300}.close{opacity:0.4;text-decoration:none;text-shadow:none}.close:hover,.close:focus{opacity:1}.alert{font-size:12px;font-weight:300}.alert .alert-link{font-weight:normal;color:#fff;text-decoration:underline}.label{padding-left:1em;padding-right:1em;border-radius:0;font-weight:300}.label-default{background-color:#e7e7e7;color:#333333}.badge{font-weight:300}.progress{height:22px;padding:2px;background-color:#f6f6f6;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none}.dropdown-menu{padding:0;margin-top:0;font-size:12px}.dropdown-menu>li>a{padding:12px 15px}.dropdown-header{padding-left:15px;padding-right:15px;font-size:9px;text-transform:uppercase}.popover{color:#fff;font-size:12px;font-weight:300}.panel-heading,.panel-footer{border-top-right-radius:0;border-top-left-radius:0}.panel-default .close{color:#222222}.modal .close{color:#222222}hugo-0.68.3/examples/blog/static/css/custom.css000066400000000000000000000003321363637351300214260ustar00rootroot00000000000000body { margin-top: 75px; /* 100px is double the height of the navbar - I made it a big larger for some more space - keep it at 50px at least if you want to use the fixed top nav */ } footer { margin: 50px 0; }hugo-0.68.3/examples/blog/static/css/font-awesome.css000066400000000000000000001007211363637351300225230ustar00rootroot00000000000000/*! * Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) */ /* FONT PATH * -------------------------- */ @font-face { font-family: 'FontAwesome'; src: url('../fonts/fontawesome-webfont.eot?v=4.5.0'); src: url('../fonts/fontawesome-webfont.eot?#iefix&v=4.5.0') format('embedded-opentype'), url('../fonts/fontawesome-webfont.woff2?v=4.5.0') format('woff2'), url('../fonts/fontawesome-webfont.woff?v=4.5.0') format('woff'), url('../fonts/fontawesome-webfont.ttf?v=4.5.0') format('truetype'), url('../fonts/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular') format('svg'); font-weight: normal; font-style: normal; } .fa { display: inline-block; font: normal normal normal 14px/1 FontAwesome; font-size: inherit; text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* makes the font 33% larger relative to the icon container */ .fa-lg { font-size: 1.33333333em; line-height: 0.75em; vertical-align: -15%; } .fa-2x { font-size: 2em; } .fa-3x { font-size: 3em; } .fa-4x { font-size: 4em; } .fa-5x { font-size: 5em; } .fa-fw { width: 1.28571429em; text-align: center; } .fa-ul { padding-left: 0; margin-left: 2.14285714em; list-style-type: none; } .fa-ul > li { position: relative; } .fa-li { position: absolute; left: -2.14285714em; width: 2.14285714em; top: 0.14285714em; text-align: center; } .fa-li.fa-lg { left: -1.85714286em; } .fa-border { padding: .2em .25em .15em; border: solid 0.08em #eeeeee; border-radius: .1em; } .fa-pull-left { float: left; } .fa-pull-right { float: right; } .fa.fa-pull-left { margin-right: .3em; } .fa.fa-pull-right { margin-left: .3em; } /* Deprecated as of 4.4.0 */ .pull-right { float: right; } .pull-left { float: left; } .fa.pull-left { margin-right: .3em; } .fa.pull-right { margin-left: .3em; } .fa-spin { -webkit-animation: fa-spin 2s infinite linear; animation: fa-spin 2s infinite linear; } .fa-pulse { -webkit-animation: fa-spin 1s infinite steps(8); animation: fa-spin 1s infinite steps(8); } @-webkit-keyframes fa-spin { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(359deg); transform: rotate(359deg); } } @keyframes fa-spin { 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); } 100% { -webkit-transform: rotate(359deg); transform: rotate(359deg); } } .fa-rotate-90 { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); -webkit-transform: rotate(90deg); -ms-transform: rotate(90deg); transform: rotate(90deg); } .fa-rotate-180 { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); -webkit-transform: rotate(180deg); -ms-transform: rotate(180deg); transform: rotate(180deg); } .fa-rotate-270 { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); -webkit-transform: rotate(270deg); -ms-transform: rotate(270deg); transform: rotate(270deg); } .fa-flip-horizontal { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1); -webkit-transform: scale(-1, 1); -ms-transform: scale(-1, 1); transform: scale(-1, 1); } .fa-flip-vertical { filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1); -webkit-transform: scale(1, -1); -ms-transform: scale(1, -1); transform: scale(1, -1); } :root .fa-rotate-90, :root .fa-rotate-180, :root .fa-rotate-270, :root .fa-flip-horizontal, :root .fa-flip-vertical { filter: none; } .fa-stack { position: relative; display: inline-block; width: 2em; height: 2em; line-height: 2em; vertical-align: middle; } .fa-stack-1x, .fa-stack-2x { position: absolute; left: 0; width: 100%; text-align: center; } .fa-stack-1x { line-height: inherit; } .fa-stack-2x { font-size: 2em; } .fa-inverse { color: #ffffff; } /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen readers do not read off random characters that represent icons */ .fa-glass:before { content: "\f000"; } .fa-music:before { content: "\f001"; } .fa-search:before { content: "\f002"; } .fa-envelope-o:before { content: "\f003"; } .fa-heart:before { content: "\f004"; } .fa-star:before { content: "\f005"; } .fa-star-o:before { content: "\f006"; } .fa-user:before { content: "\f007"; } .fa-film:before { content: "\f008"; } .fa-th-large:before { content: "\f009"; } .fa-th:before { content: "\f00a"; } .fa-th-list:before { content: "\f00b"; } .fa-check:before { content: "\f00c"; } .fa-remove:before, .fa-close:before, .fa-times:before { content: "\f00d"; } .fa-search-plus:before { content: "\f00e"; } .fa-search-minus:before { content: "\f010"; } .fa-power-off:before { content: "\f011"; } .fa-signal:before { content: "\f012"; } .fa-gear:before, .fa-cog:before { content: "\f013"; } .fa-trash-o:before { content: "\f014"; } .fa-home:before { content: "\f015"; } .fa-file-o:before { content: "\f016"; } .fa-clock-o:before { content: "\f017"; } .fa-road:before { content: "\f018"; } .fa-download:before { content: "\f019"; } .fa-arrow-circle-o-down:before { content: "\f01a"; } .fa-arrow-circle-o-up:before { content: "\f01b"; } .fa-inbox:before { content: "\f01c"; } .fa-play-circle-o:before { content: "\f01d"; } .fa-rotate-right:before, .fa-repeat:before { content: "\f01e"; } .fa-refresh:before { content: "\f021"; } .fa-list-alt:before { content: "\f022"; } .fa-lock:before { content: "\f023"; } .fa-flag:before { content: "\f024"; } .fa-headphones:before { content: "\f025"; } .fa-volume-off:before { content: "\f026"; } .fa-volume-down:before { content: "\f027"; } .fa-volume-up:before { content: "\f028"; } .fa-qrcode:before { content: "\f029"; } .fa-barcode:before { content: "\f02a"; } .fa-tag:before { content: "\f02b"; } .fa-tags:before { content: "\f02c"; } .fa-book:before { content: "\f02d"; } .fa-bookmark:before { content: "\f02e"; } .fa-print:before { content: "\f02f"; } .fa-camera:before { content: "\f030"; } .fa-font:before { content: "\f031"; } .fa-bold:before { content: "\f032"; } .fa-italic:before { content: "\f033"; } .fa-text-height:before { content: "\f034"; } .fa-text-width:before { content: "\f035"; } .fa-align-left:before { content: "\f036"; } .fa-align-center:before { content: "\f037"; } .fa-align-right:before { content: "\f038"; } .fa-align-justify:before { content: "\f039"; } .fa-list:before { content: "\f03a"; } .fa-dedent:before, .fa-outdent:before { content: "\f03b"; } .fa-indent:before { content: "\f03c"; } .fa-video-camera:before { content: "\f03d"; } .fa-photo:before, .fa-image:before, .fa-picture-o:before { content: "\f03e"; } .fa-pencil:before { content: "\f040"; } .fa-map-marker:before { content: "\f041"; } .fa-adjust:before { content: "\f042"; } .fa-tint:before { content: "\f043"; } .fa-edit:before, .fa-pencil-square-o:before { content: "\f044"; } .fa-share-square-o:before { content: "\f045"; } .fa-check-square-o:before { content: "\f046"; } .fa-arrows:before { content: "\f047"; } .fa-step-backward:before { content: "\f048"; } .fa-fast-backward:before { content: "\f049"; } .fa-backward:before { content: "\f04a"; } .fa-play:before { content: "\f04b"; } .fa-pause:before { content: "\f04c"; } .fa-stop:before { content: "\f04d"; } .fa-forward:before { content: "\f04e"; } .fa-fast-forward:before { content: "\f050"; } .fa-step-forward:before { content: "\f051"; } .fa-eject:before { content: "\f052"; } .fa-chevron-left:before { content: "\f053"; } .fa-chevron-right:before { content: "\f054"; } .fa-plus-circle:before { content: "\f055"; } .fa-minus-circle:before { content: "\f056"; } .fa-times-circle:before { content: "\f057"; } .fa-check-circle:before { content: "\f058"; } .fa-question-circle:before { content: "\f059"; } .fa-info-circle:before { content: "\f05a"; } .fa-crosshairs:before { content: "\f05b"; } .fa-times-circle-o:before { content: "\f05c"; } .fa-check-circle-o:before { content: "\f05d"; } .fa-ban:before { content: "\f05e"; } .fa-arrow-left:before { content: "\f060"; } .fa-arrow-right:before { content: "\f061"; } .fa-arrow-up:before { content: "\f062"; } .fa-arrow-down:before { content: "\f063"; } .fa-mail-forward:before, .fa-share:before { content: "\f064"; } .fa-expand:before { content: "\f065"; } .fa-compress:before { content: "\f066"; } .fa-plus:before { content: "\f067"; } .fa-minus:before { content: "\f068"; } .fa-asterisk:before { content: "\f069"; } .fa-exclamation-circle:before { content: "\f06a"; } .fa-gift:before { content: "\f06b"; } .fa-leaf:before { content: "\f06c"; } .fa-fire:before { content: "\f06d"; } .fa-eye:before { content: "\f06e"; } .fa-eye-slash:before { content: "\f070"; } .fa-warning:before, .fa-exclamation-triangle:before { content: "\f071"; } .fa-plane:before { content: "\f072"; } .fa-calendar:before { content: "\f073"; } .fa-random:before { content: "\f074"; } .fa-comment:before { content: "\f075"; } .fa-magnet:before { content: "\f076"; } .fa-chevron-up:before { content: "\f077"; } .fa-chevron-down:before { content: "\f078"; } .fa-retweet:before { content: "\f079"; } .fa-shopping-cart:before { content: "\f07a"; } .fa-folder:before { content: "\f07b"; } .fa-folder-open:before { content: "\f07c"; } .fa-arrows-v:before { content: "\f07d"; } .fa-arrows-h:before { content: "\f07e"; } .fa-bar-chart-o:before, .fa-bar-chart:before { content: "\f080"; } .fa-twitter-square:before { content: "\f081"; } .fa-facebook-square:before { content: "\f082"; } .fa-camera-retro:before { content: "\f083"; } .fa-key:before { content: "\f084"; } .fa-gears:before, .fa-cogs:before { content: "\f085"; } .fa-comments:before { content: "\f086"; } .fa-thumbs-o-up:before { content: "\f087"; } .fa-thumbs-o-down:before { content: "\f088"; } .fa-star-half:before { content: "\f089"; } .fa-heart-o:before { content: "\f08a"; } .fa-sign-out:before { content: "\f08b"; } .fa-linkedin-square:before { content: "\f08c"; } .fa-thumb-tack:before { content: "\f08d"; } .fa-external-link:before { content: "\f08e"; } .fa-sign-in:before { content: "\f090"; } .fa-trophy:before { content: "\f091"; } .fa-github-square:before { content: "\f092"; } .fa-upload:before { content: "\f093"; } .fa-lemon-o:before { content: "\f094"; } .fa-phone:before { content: "\f095"; } .fa-square-o:before { content: "\f096"; } .fa-bookmark-o:before { content: "\f097"; } .fa-phone-square:before { content: "\f098"; } .fa-twitter:before { content: "\f099"; } .fa-facebook-f:before, .fa-facebook:before { content: "\f09a"; } .fa-github:before { content: "\f09b"; } .fa-unlock:before { content: "\f09c"; } .fa-credit-card:before { content: "\f09d"; } .fa-feed:before, .fa-rss:before { content: "\f09e"; } .fa-hdd-o:before { content: "\f0a0"; } .fa-bullhorn:before { content: "\f0a1"; } .fa-bell:before { content: "\f0f3"; } .fa-certificate:before { content: "\f0a3"; } .fa-hand-o-right:before { content: "\f0a4"; } .fa-hand-o-left:before { content: "\f0a5"; } .fa-hand-o-up:before { content: "\f0a6"; } .fa-hand-o-down:before { content: "\f0a7"; } .fa-arrow-circle-left:before { content: "\f0a8"; } .fa-arrow-circle-right:before { content: "\f0a9"; } .fa-arrow-circle-up:before { content: "\f0aa"; } .fa-arrow-circle-down:before { content: "\f0ab"; } .fa-globe:before { content: "\f0ac"; } .fa-wrench:before { content: "\f0ad"; } .fa-tasks:before { content: "\f0ae"; } .fa-filter:before { content: "\f0b0"; } .fa-briefcase:before { content: "\f0b1"; } .fa-arrows-alt:before { content: "\f0b2"; } .fa-group:before, .fa-users:before { content: "\f0c0"; } .fa-chain:before, .fa-link:before { content: "\f0c1"; } .fa-cloud:before { content: "\f0c2"; } .fa-flask:before { content: "\f0c3"; } .fa-cut:before, .fa-scissors:before { content: "\f0c4"; } .fa-copy:before, .fa-files-o:before { content: "\f0c5"; } .fa-paperclip:before { content: "\f0c6"; } .fa-save:before, .fa-floppy-o:before { content: "\f0c7"; } .fa-square:before { content: "\f0c8"; } .fa-navicon:before, .fa-reorder:before, .fa-bars:before { content: "\f0c9"; } .fa-list-ul:before { content: "\f0ca"; } .fa-list-ol:before { content: "\f0cb"; } .fa-strikethrough:before { content: "\f0cc"; } .fa-underline:before { content: "\f0cd"; } .fa-table:before { content: "\f0ce"; } .fa-magic:before { content: "\f0d0"; } .fa-truck:before { content: "\f0d1"; } .fa-pinterest:before { content: "\f0d2"; } .fa-pinterest-square:before { content: "\f0d3"; } .fa-google-plus-square:before { content: "\f0d4"; } .fa-google-plus:before { content: "\f0d5"; } .fa-money:before { content: "\f0d6"; } .fa-caret-down:before { content: "\f0d7"; } .fa-caret-up:before { content: "\f0d8"; } .fa-caret-left:before { content: "\f0d9"; } .fa-caret-right:before { content: "\f0da"; } .fa-columns:before { content: "\f0db"; } .fa-unsorted:before, .fa-sort:before { content: "\f0dc"; } .fa-sort-down:before, .fa-sort-desc:before { content: "\f0dd"; } .fa-sort-up:before, .fa-sort-asc:before { content: "\f0de"; } .fa-envelope:before { content: "\f0e0"; } .fa-linkedin:before { content: "\f0e1"; } .fa-rotate-left:before, .fa-undo:before { content: "\f0e2"; } .fa-legal:before, .fa-gavel:before { content: "\f0e3"; } .fa-dashboard:before, .fa-tachometer:before { content: "\f0e4"; } .fa-comment-o:before { content: "\f0e5"; } .fa-comments-o:before { content: "\f0e6"; } .fa-flash:before, .fa-bolt:before { content: "\f0e7"; } .fa-sitemap:before { content: "\f0e8"; } .fa-umbrella:before { content: "\f0e9"; } .fa-paste:before, .fa-clipboard:before { content: "\f0ea"; } .fa-lightbulb-o:before { content: "\f0eb"; } .fa-exchange:before { content: "\f0ec"; } .fa-cloud-download:before { content: "\f0ed"; } .fa-cloud-upload:before { content: "\f0ee"; } .fa-user-md:before { content: "\f0f0"; } .fa-stethoscope:before { content: "\f0f1"; } .fa-suitcase:before { content: "\f0f2"; } .fa-bell-o:before { content: "\f0a2"; } .fa-coffee:before { content: "\f0f4"; } .fa-cutlery:before { content: "\f0f5"; } .fa-file-text-o:before { content: "\f0f6"; } .fa-building-o:before { content: "\f0f7"; } .fa-hospital-o:before { content: "\f0f8"; } .fa-ambulance:before { content: "\f0f9"; } .fa-medkit:before { content: "\f0fa"; } .fa-fighter-jet:before { content: "\f0fb"; } .fa-beer:before { content: "\f0fc"; } .fa-h-square:before { content: "\f0fd"; } .fa-plus-square:before { content: "\f0fe"; } .fa-angle-double-left:before { content: "\f100"; } .fa-angle-double-right:before { content: "\f101"; } .fa-angle-double-up:before { content: "\f102"; } .fa-angle-double-down:before { content: "\f103"; } .fa-angle-left:before { content: "\f104"; } .fa-angle-right:before { content: "\f105"; } .fa-angle-up:before { content: "\f106"; } .fa-angle-down:before { content: "\f107"; } .fa-desktop:before { content: "\f108"; } .fa-laptop:before { content: "\f109"; } .fa-tablet:before { content: "\f10a"; } .fa-mobile-phone:before, .fa-mobile:before { content: "\f10b"; } .fa-circle-o:before { content: "\f10c"; } .fa-quote-left:before { content: "\f10d"; } .fa-quote-right:before { content: "\f10e"; } .fa-spinner:before { content: "\f110"; } .fa-circle:before { content: "\f111"; } .fa-mail-reply:before, .fa-reply:before { content: "\f112"; } .fa-github-alt:before { content: "\f113"; } .fa-folder-o:before { content: "\f114"; } .fa-folder-open-o:before { content: "\f115"; } .fa-smile-o:before { content: "\f118"; } .fa-frown-o:before { content: "\f119"; } .fa-meh-o:before { content: "\f11a"; } .fa-gamepad:before { content: "\f11b"; } .fa-keyboard-o:before { content: "\f11c"; } .fa-flag-o:before { content: "\f11d"; } .fa-flag-checkered:before { content: "\f11e"; } .fa-terminal:before { content: "\f120"; } .fa-code:before { content: "\f121"; } .fa-mail-reply-all:before, .fa-reply-all:before { content: "\f122"; } .fa-star-half-empty:before, .fa-star-half-full:before, .fa-star-half-o:before { content: "\f123"; } .fa-location-arrow:before { content: "\f124"; } .fa-crop:before { content: "\f125"; } .fa-code-fork:before { content: "\f126"; } .fa-unlink:before, .fa-chain-broken:before { content: "\f127"; } .fa-question:before { content: "\f128"; } .fa-info:before { content: "\f129"; } .fa-exclamation:before { content: "\f12a"; } .fa-superscript:before { content: "\f12b"; } .fa-subscript:before { content: "\f12c"; } .fa-eraser:before { content: "\f12d"; } .fa-puzzle-piece:before { content: "\f12e"; } .fa-microphone:before { content: "\f130"; } .fa-microphone-slash:before { content: "\f131"; } .fa-shield:before { content: "\f132"; } .fa-calendar-o:before { content: "\f133"; } .fa-fire-extinguisher:before { content: "\f134"; } .fa-rocket:before { content: "\f135"; } .fa-maxcdn:before { content: "\f136"; } .fa-chevron-circle-left:before { content: "\f137"; } .fa-chevron-circle-right:before { content: "\f138"; } .fa-chevron-circle-up:before { content: "\f139"; } .fa-chevron-circle-down:before { content: "\f13a"; } .fa-html5:before { content: "\f13b"; } .fa-css3:before { content: "\f13c"; } .fa-anchor:before { content: "\f13d"; } .fa-unlock-alt:before { content: "\f13e"; } .fa-bullseye:before { content: "\f140"; } .fa-ellipsis-h:before { content: "\f141"; } .fa-ellipsis-v:before { content: "\f142"; } .fa-rss-square:before { content: "\f143"; } .fa-play-circle:before { content: "\f144"; } .fa-ticket:before { content: "\f145"; } .fa-minus-square:before { content: "\f146"; } .fa-minus-square-o:before { content: "\f147"; } .fa-level-up:before { content: "\f148"; } .fa-level-down:before { content: "\f149"; } .fa-check-square:before { content: "\f14a"; } .fa-pencil-square:before { content: "\f14b"; } .fa-external-link-square:before { content: "\f14c"; } .fa-share-square:before { content: "\f14d"; } .fa-compass:before { content: "\f14e"; } .fa-toggle-down:before, .fa-caret-square-o-down:before { content: "\f150"; } .fa-toggle-up:before, .fa-caret-square-o-up:before { content: "\f151"; } .fa-toggle-right:before, .fa-caret-square-o-right:before { content: "\f152"; } .fa-euro:before, .fa-eur:before { content: "\f153"; } .fa-gbp:before { content: "\f154"; } .fa-dollar:before, .fa-usd:before { content: "\f155"; } .fa-rupee:before, .fa-inr:before { content: "\f156"; } .fa-cny:before, .fa-rmb:before, .fa-yen:before, .fa-jpy:before { content: "\f157"; } .fa-ruble:before, .fa-rouble:before, .fa-rub:before { content: "\f158"; } .fa-won:before, .fa-krw:before { content: "\f159"; } .fa-bitcoin:before, .fa-btc:before { content: "\f15a"; } .fa-file:before { content: "\f15b"; } .fa-file-text:before { content: "\f15c"; } .fa-sort-alpha-asc:before { content: "\f15d"; } .fa-sort-alpha-desc:before { content: "\f15e"; } .fa-sort-amount-asc:before { content: "\f160"; } .fa-sort-amount-desc:before { content: "\f161"; } .fa-sort-numeric-asc:before { content: "\f162"; } .fa-sort-numeric-desc:before { content: "\f163"; } .fa-thumbs-up:before { content: "\f164"; } .fa-thumbs-down:before { content: "\f165"; } .fa-youtube-square:before { content: "\f166"; } .fa-youtube:before { content: "\f167"; } .fa-xing:before { content: "\f168"; } .fa-xing-square:before { content: "\f169"; } .fa-youtube-play:before { content: "\f16a"; } .fa-dropbox:before { content: "\f16b"; } .fa-stack-overflow:before { content: "\f16c"; } .fa-instagram:before { content: "\f16d"; } .fa-flickr:before { content: "\f16e"; } .fa-adn:before { content: "\f170"; } .fa-bitbucket:before { content: "\f171"; } .fa-bitbucket-square:before { content: "\f172"; } .fa-tumblr:before { content: "\f173"; } .fa-tumblr-square:before { content: "\f174"; } .fa-long-arrow-down:before { content: "\f175"; } .fa-long-arrow-up:before { content: "\f176"; } .fa-long-arrow-left:before { content: "\f177"; } .fa-long-arrow-right:before { content: "\f178"; } .fa-apple:before { content: "\f179"; } .fa-windows:before { content: "\f17a"; } .fa-android:before { content: "\f17b"; } .fa-linux:before { content: "\f17c"; } .fa-dribbble:before { content: "\f17d"; } .fa-skype:before { content: "\f17e"; } .fa-foursquare:before { content: "\f180"; } .fa-trello:before { content: "\f181"; } .fa-female:before { content: "\f182"; } .fa-male:before { content: "\f183"; } .fa-gittip:before, .fa-gratipay:before { content: "\f184"; } .fa-sun-o:before { content: "\f185"; } .fa-moon-o:before { content: "\f186"; } .fa-archive:before { content: "\f187"; } .fa-bug:before { content: "\f188"; } .fa-vk:before { content: "\f189"; } .fa-weibo:before { content: "\f18a"; } .fa-renren:before { content: "\f18b"; } .fa-pagelines:before { content: "\f18c"; } .fa-stack-exchange:before { content: "\f18d"; } .fa-arrow-circle-o-right:before { content: "\f18e"; } .fa-arrow-circle-o-left:before { content: "\f190"; } .fa-toggle-left:before, .fa-caret-square-o-left:before { content: "\f191"; } .fa-dot-circle-o:before { content: "\f192"; } .fa-wheelchair:before { content: "\f193"; } .fa-vimeo-square:before { content: "\f194"; } .fa-turkish-lira:before, .fa-try:before { content: "\f195"; } .fa-plus-square-o:before { content: "\f196"; } .fa-space-shuttle:before { content: "\f197"; } .fa-slack:before { content: "\f198"; } .fa-envelope-square:before { content: "\f199"; } .fa-wordpress:before { content: "\f19a"; } .fa-openid:before { content: "\f19b"; } .fa-institution:before, .fa-bank:before, .fa-university:before { content: "\f19c"; } .fa-mortar-board:before, .fa-graduation-cap:before { content: "\f19d"; } .fa-yahoo:before { content: "\f19e"; } .fa-google:before { content: "\f1a0"; } .fa-reddit:before { content: "\f1a1"; } .fa-reddit-square:before { content: "\f1a2"; } .fa-stumbleupon-circle:before { content: "\f1a3"; } .fa-stumbleupon:before { content: "\f1a4"; } .fa-delicious:before { content: "\f1a5"; } .fa-digg:before { content: "\f1a6"; } .fa-pied-piper:before { content: "\f1a7"; } .fa-pied-piper-alt:before { content: "\f1a8"; } .fa-drupal:before { content: "\f1a9"; } .fa-joomla:before { content: "\f1aa"; } .fa-language:before { content: "\f1ab"; } .fa-fax:before { content: "\f1ac"; } .fa-building:before { content: "\f1ad"; } .fa-child:before { content: "\f1ae"; } .fa-paw:before { content: "\f1b0"; } .fa-spoon:before { content: "\f1b1"; } .fa-cube:before { content: "\f1b2"; } .fa-cubes:before { content: "\f1b3"; } .fa-behance:before { content: "\f1b4"; } .fa-behance-square:before { content: "\f1b5"; } .fa-steam:before { content: "\f1b6"; } .fa-steam-square:before { content: "\f1b7"; } .fa-recycle:before { content: "\f1b8"; } .fa-automobile:before, .fa-car:before { content: "\f1b9"; } .fa-cab:before, .fa-taxi:before { content: "\f1ba"; } .fa-tree:before { content: "\f1bb"; } .fa-spotify:before { content: "\f1bc"; } .fa-deviantart:before { content: "\f1bd"; } .fa-soundcloud:before { content: "\f1be"; } .fa-database:before { content: "\f1c0"; } .fa-file-pdf-o:before { content: "\f1c1"; } .fa-file-word-o:before { content: "\f1c2"; } .fa-file-excel-o:before { content: "\f1c3"; } .fa-file-powerpoint-o:before { content: "\f1c4"; } .fa-file-photo-o:before, .fa-file-picture-o:before, .fa-file-image-o:before { content: "\f1c5"; } .fa-file-zip-o:before, .fa-file-archive-o:before { content: "\f1c6"; } .fa-file-sound-o:before, .fa-file-audio-o:before { content: "\f1c7"; } .fa-file-movie-o:before, .fa-file-video-o:before { content: "\f1c8"; } .fa-file-code-o:before { content: "\f1c9"; } .fa-vine:before { content: "\f1ca"; } .fa-codepen:before { content: "\f1cb"; } .fa-jsfiddle:before { content: "\f1cc"; } .fa-life-bouy:before, .fa-life-buoy:before, .fa-life-saver:before, .fa-support:before, .fa-life-ring:before { content: "\f1cd"; } .fa-circle-o-notch:before { content: "\f1ce"; } .fa-ra:before, .fa-rebel:before { content: "\f1d0"; } .fa-ge:before, .fa-empire:before { content: "\f1d1"; } .fa-git-square:before { content: "\f1d2"; } .fa-git:before { content: "\f1d3"; } .fa-y-combinator-square:before, .fa-yc-square:before, .fa-hacker-news:before { content: "\f1d4"; } .fa-tencent-weibo:before { content: "\f1d5"; } .fa-qq:before { content: "\f1d6"; } .fa-wechat:before, .fa-weixin:before { content: "\f1d7"; } .fa-send:before, .fa-paper-plane:before { content: "\f1d8"; } .fa-send-o:before, .fa-paper-plane-o:before { content: "\f1d9"; } .fa-history:before { content: "\f1da"; } .fa-circle-thin:before { content: "\f1db"; } .fa-header:before { content: "\f1dc"; } .fa-paragraph:before { content: "\f1dd"; } .fa-sliders:before { content: "\f1de"; } .fa-share-alt:before { content: "\f1e0"; } .fa-share-alt-square:before { content: "\f1e1"; } .fa-bomb:before { content: "\f1e2"; } .fa-soccer-ball-o:before, .fa-futbol-o:before { content: "\f1e3"; } .fa-tty:before { content: "\f1e4"; } .fa-binoculars:before { content: "\f1e5"; } .fa-plug:before { content: "\f1e6"; } .fa-slideshare:before { content: "\f1e7"; } .fa-twitch:before { content: "\f1e8"; } .fa-yelp:before { content: "\f1e9"; } .fa-newspaper-o:before { content: "\f1ea"; } .fa-wifi:before { content: "\f1eb"; } .fa-calculator:before { content: "\f1ec"; } .fa-paypal:before { content: "\f1ed"; } .fa-google-wallet:before { content: "\f1ee"; } .fa-cc-visa:before { content: "\f1f0"; } .fa-cc-mastercard:before { content: "\f1f1"; } .fa-cc-discover:before { content: "\f1f2"; } .fa-cc-amex:before { content: "\f1f3"; } .fa-cc-paypal:before { content: "\f1f4"; } .fa-cc-stripe:before { content: "\f1f5"; } .fa-bell-slash:before { content: "\f1f6"; } .fa-bell-slash-o:before { content: "\f1f7"; } .fa-trash:before { content: "\f1f8"; } .fa-copyright:before { content: "\f1f9"; } .fa-at:before { content: "\f1fa"; } .fa-eyedropper:before { content: "\f1fb"; } .fa-paint-brush:before { content: "\f1fc"; } .fa-birthday-cake:before { content: "\f1fd"; } .fa-area-chart:before { content: "\f1fe"; } .fa-pie-chart:before { content: "\f200"; } .fa-line-chart:before { content: "\f201"; } .fa-lastfm:before { content: "\f202"; } .fa-lastfm-square:before { content: "\f203"; } .fa-toggle-off:before { content: "\f204"; } .fa-toggle-on:before { content: "\f205"; } .fa-bicycle:before { content: "\f206"; } .fa-bus:before { content: "\f207"; } .fa-ioxhost:before { content: "\f208"; } .fa-angellist:before { content: "\f209"; } .fa-cc:before { content: "\f20a"; } .fa-shekel:before, .fa-sheqel:before, .fa-ils:before { content: "\f20b"; } .fa-meanpath:before { content: "\f20c"; } .fa-buysellads:before { content: "\f20d"; } .fa-connectdevelop:before { content: "\f20e"; } .fa-dashcube:before { content: "\f210"; } .fa-forumbee:before { content: "\f211"; } .fa-leanpub:before { content: "\f212"; } .fa-sellsy:before { content: "\f213"; } .fa-shirtsinbulk:before { content: "\f214"; } .fa-simplybuilt:before { content: "\f215"; } .fa-skyatlas:before { content: "\f216"; } .fa-cart-plus:before { content: "\f217"; } .fa-cart-arrow-down:before { content: "\f218"; } .fa-diamond:before { content: "\f219"; } .fa-ship:before { content: "\f21a"; } .fa-user-secret:before { content: "\f21b"; } .fa-motorcycle:before { content: "\f21c"; } .fa-street-view:before { content: "\f21d"; } .fa-heartbeat:before { content: "\f21e"; } .fa-venus:before { content: "\f221"; } .fa-mars:before { content: "\f222"; } .fa-mercury:before { content: "\f223"; } .fa-intersex:before, .fa-transgender:before { content: "\f224"; } .fa-transgender-alt:before { content: "\f225"; } .fa-venus-double:before { content: "\f226"; } .fa-mars-double:before { content: "\f227"; } .fa-venus-mars:before { content: "\f228"; } .fa-mars-stroke:before { content: "\f229"; } .fa-mars-stroke-v:before { content: "\f22a"; } .fa-mars-stroke-h:before { content: "\f22b"; } .fa-neuter:before { content: "\f22c"; } .fa-genderless:before { content: "\f22d"; } .fa-facebook-official:before { content: "\f230"; } .fa-pinterest-p:before { content: "\f231"; } .fa-whatsapp:before { content: "\f232"; } .fa-server:before { content: "\f233"; } .fa-user-plus:before { content: "\f234"; } .fa-user-times:before { content: "\f235"; } .fa-hotel:before, .fa-bed:before { content: "\f236"; } .fa-viacoin:before { content: "\f237"; } .fa-train:before { content: "\f238"; } .fa-subway:before { content: "\f239"; } .fa-medium:before { content: "\f23a"; } .fa-yc:before, .fa-y-combinator:before { content: "\f23b"; } .fa-optin-monster:before { content: "\f23c"; } .fa-opencart:before { content: "\f23d"; } .fa-expeditedssl:before { content: "\f23e"; } .fa-battery-4:before, .fa-battery-full:before { content: "\f240"; } .fa-battery-3:before, .fa-battery-three-quarters:before { content: "\f241"; } .fa-battery-2:before, .fa-battery-half:before { content: "\f242"; } .fa-battery-1:before, .fa-battery-quarter:before { content: "\f243"; } .fa-battery-0:before, .fa-battery-empty:before { content: "\f244"; } .fa-mouse-pointer:before { content: "\f245"; } .fa-i-cursor:before { content: "\f246"; } .fa-object-group:before { content: "\f247"; } .fa-object-ungroup:before { content: "\f248"; } .fa-sticky-note:before { content: "\f249"; } .fa-sticky-note-o:before { content: "\f24a"; } .fa-cc-jcb:before { content: "\f24b"; } .fa-cc-diners-club:before { content: "\f24c"; } .fa-clone:before { content: "\f24d"; } .fa-balance-scale:before { content: "\f24e"; } .fa-hourglass-o:before { content: "\f250"; } .fa-hourglass-1:before, .fa-hourglass-start:before { content: "\f251"; } .fa-hourglass-2:before, .fa-hourglass-half:before { content: "\f252"; } .fa-hourglass-3:before, .fa-hourglass-end:before { content: "\f253"; } .fa-hourglass:before { content: "\f254"; } .fa-hand-grab-o:before, .fa-hand-rock-o:before { content: "\f255"; } .fa-hand-stop-o:before, .fa-hand-paper-o:before { content: "\f256"; } .fa-hand-scissors-o:before { content: "\f257"; } .fa-hand-lizard-o:before { content: "\f258"; } .fa-hand-spock-o:before { content: "\f259"; } .fa-hand-pointer-o:before { content: "\f25a"; } .fa-hand-peace-o:before { content: "\f25b"; } .fa-trademark:before { content: "\f25c"; } .fa-registered:before { content: "\f25d"; } .fa-creative-commons:before { content: "\f25e"; } .fa-gg:before { content: "\f260"; } .fa-gg-circle:before { content: "\f261"; } .fa-tripadvisor:before { content: "\f262"; } .fa-odnoklassniki:before { content: "\f263"; } .fa-odnoklassniki-square:before { content: "\f264"; } .fa-get-pocket:before { content: "\f265"; } .fa-wikipedia-w:before { content: "\f266"; } .fa-safari:before { content: "\f267"; } .fa-chrome:before { content: "\f268"; } .fa-firefox:before { content: "\f269"; } .fa-opera:before { content: "\f26a"; } .fa-internet-explorer:before { content: "\f26b"; } .fa-tv:before, .fa-television:before { content: "\f26c"; } .fa-contao:before { content: "\f26d"; } .fa-500px:before { content: "\f26e"; } .fa-amazon:before { content: "\f270"; } .fa-calendar-plus-o:before { content: "\f271"; } .fa-calendar-minus-o:before { content: "\f272"; } .fa-calendar-times-o:before { content: "\f273"; } .fa-calendar-check-o:before { content: "\f274"; } .fa-industry:before { content: "\f275"; } .fa-map-pin:before { content: "\f276"; } .fa-map-signs:before { content: "\f277"; } .fa-map-o:before { content: "\f278"; } .fa-map:before { content: "\f279"; } .fa-commenting:before { content: "\f27a"; } .fa-commenting-o:before { content: "\f27b"; } .fa-houzz:before { content: "\f27c"; } .fa-vimeo:before { content: "\f27d"; } .fa-black-tie:before { content: "\f27e"; } .fa-fonticons:before { content: "\f280"; } .fa-reddit-alien:before { content: "\f281"; } .fa-edge:before { content: "\f282"; } .fa-credit-card-alt:before { content: "\f283"; } .fa-codiepie:before { content: "\f284"; } .fa-modx:before { content: "\f285"; } .fa-fort-awesome:before { content: "\f286"; } .fa-usb:before { content: "\f287"; } .fa-product-hunt:before { content: "\f288"; } .fa-mixcloud:before { content: "\f289"; } .fa-scribd:before { content: "\f28a"; } .fa-pause-circle:before { content: "\f28b"; } .fa-pause-circle-o:before { content: "\f28c"; } .fa-stop-circle:before { content: "\f28d"; } .fa-stop-circle-o:before { content: "\f28e"; } .fa-shopping-bag:before { content: "\f290"; } .fa-shopping-basket:before { content: "\f291"; } .fa-hashtag:before { content: "\f292"; } .fa-bluetooth:before { content: "\f293"; } .fa-bluetooth-b:before { content: "\f294"; } .fa-percent:before { content: "\f295"; } hugo-0.68.3/examples/blog/static/fonts/000077500000000000000000000000001363637351300177455ustar00rootroot00000000000000hugo-0.68.3/examples/blog/static/fonts/FontAwesome.otf000066400000000000000000003261701363637351300227170ustar00rootroot00000000000000OTTO  CFF R?EPAR*0OS/22zU`cmapL.head 6hhea nD$hmtxw|h maxpvP0name'x8postX  FontAwesomeC   U6U6 -r-k ",04<>EGMT\_ehmqy}#)4>HT_lp{ '4=GRYfoy &,39COVcoz"/5;FPUZes}&+16<EOW_hmqv| )04=DPX\aju(,26GYhy %16;>EMUckox    $ 5 G V g l p v    & * - 0 3 6 9 < ? B F O _ c u     & 5 B Q a f m t y    ! % ) - 1 5 9 = A H L P T X \ ` d h l p t x |       % , 3 7 ; ? C G K O V Z ^ b f j n r v z ~   !%)-159=AEJNRVZ^bfjnrvz~ "&*.26:>BFJNRVZ^bfjnrvz~ "&*.2alglassmusicsearchenvelopeheartstarstar_emptyuserfilmth_largethth_listokremovezoom_inzoom_outoffsignalcogtrashhomefile_alttimeroaddownload_altdownloaduploadinboxplay_circlerepeatrefreshlist_altlockflagheadphonesvolume_offvolume_downvolume_upqrcodebarcodetagtagsbookbookmarkprintcamerafontbolditalictext_heighttext_widthalign_leftalign_centeralign_rightalign_justifylistindent_leftindent_rightfacetime_videopicturepencilmap_markeradjusttinteditsharecheckmovestep_backwardfast_backwardbackwardplaypausestopforwardfast_forwardstep_forwardejectchevron_leftchevron_rightplus_signminus_signremove_signok_signquestion_signinfo_signscreenshotremove_circleok_circleban_circlearrow_leftarrow_rightarrow_uparrow_downshare_altresize_fullresize_smallexclamation_signgiftleaffireeye_openeye_closewarning_signplanecalendarrandomcommentmagnetchevron_upchevron_downretweetshopping_cartfolder_closefolder_openresize_verticalresize_horizontalbar_charttwitter_signfacebook_signcamera_retrokeycogscommentsthumbs_up_altthumbs_down_altstar_halfheart_emptysignoutlinkedin_signpushpinexternal_linksignintrophygithub_signupload_altlemonphonecheck_emptybookmark_emptyphone_signtwitterfacebookgithubunlockcredit_cardrsshddbullhornbellcertificatehand_righthand_lefthand_uphand_downcircle_arrow_leftcircle_arrow_rightcircle_arrow_upcircle_arrow_downglobewrenchtasksfilterbriefcasefullscreennotequalinfinitylessequalgrouplinkcloudbeakercutcopypaper_clipsavesign_blankreorderulolstrikethroughunderlinetablemagictruckpinterestpinterest_signgoogle_plus_signgoogle_plusmoneycaret_downcaret_upcaret_leftcaret_rightcolumnssortsort_downsort_upenvelope_altlinkedinundolegaldashboardcomment_altcomments_altboltsitemapumbrellapastelight_bulbexchangecloud_downloadcloud_uploaduser_mdstethoscopesuitcasebell_altcoffeefoodfile_text_altbuildinghospitalambulancemedkitfighter_jetbeerh_signf0fedouble_angle_leftdouble_angle_rightdouble_angle_updouble_angle_downangle_leftangle_rightangle_upangle_downdesktoplaptoptabletmobile_phonecircle_blankquote_leftquote_rightspinnercirclereplygithub_altfolder_close_altfolder_open_altexpand_altcollapse_altsmilefrownmehgamepadkeyboardflag_altflag_checkeredterminalcodereply_allstar_half_emptylocation_arrowcropcode_forkunlink_279exclamationsuperscriptsubscript_283puzzle_piecemicrophonemicrophone_offshieldcalendar_emptyfire_extinguisherrocketmaxcdnchevron_sign_leftchevron_sign_rightchevron_sign_upchevron_sign_downhtml5css3anchorunlock_altbullseyeellipsis_horizontalellipsis_vertical_303play_signticketminus_sign_altcheck_minuslevel_uplevel_downcheck_signedit_sign_312share_signcompasscollapsecollapse_top_317eurgbpusdinrjpyrubkrwbtcfilefile_textsort_by_alphabet_329sort_by_attributessort_by_attributes_altsort_by_ordersort_by_order_alt_334_335youtube_signyoutubexingxing_signyoutube_playdropboxstackexchangeinstagramflickradnf171bitbucket_signtumblrtumblr_signlong_arrow_downlong_arrow_uplong_arrow_leftlong_arrow_rightapplewindowsandroidlinuxdribbleskypefoursquaretrellofemalemalegittipsun_366archivebugvkweiborenren_372stack_exchange_374arrow_circle_alt_left_376dot_circle_alt_378vimeo_square_380plus_square_o_382_383_384_385_386_387_388_389uniF1A0f1a1_392_393f1a4_395_396_397_398_399_400f1ab_402_403_404uniF1B1_406_407_408_409_410_411_412_413_414_415_416_417_418_419uniF1C0uniF1C1_422_423_424_425_426_427_428_429_430_431_432_433_434uniF1D0uniF1D1uniF1D2_438_439uniF1D5uniF1D6uniF1D7_443_444_445_446_447_448_449uniF1E0_451_452_453_454_455_456_457_458_459_460_461_462_463_464uniF1F0_466_467f1f3_469_470_471_472_473_474_475_476f1fc_478_479_480_481_482_483_484_485_486_487_488_489_490_491_492_493_494f210_496f212_498_499_500_501_502_503_504_505_506_507_508_509venus_511_512_513_514_515_516_517_518_519_520_521_522_523_524_525_526_527_528_529_530_531_532_533_534_535_536_537_538_539_540_541_542_543_544_545_546_547_548_549_550_551_552_553_554_555_556_557_558_559_560_561_562_563_564_565_566_567_568_569f260f261_572f263_574_575_576_577_578_579_580_581_582_583_584_585_586_587_588_589_590_591_592_593_594_595_596_597_598f27euniF280uniF281_602_603_604uniF285uniF286_607_608_609_610_611_612_613_614_615_616_617_618_619_620_621_622_623_624_625_626_627_628_629Copyright Dave Gandy 2015. All rights reserved.FontAwesome aoC  %)M16=_fmqu|:>BFRhl'07>CjZ^)5:>CGKPTY]   & - 1 : E Q U \ b h m      ) , ; @ G u y   ! ( 0 [ e q     B F R [ i n s w ~   " , 1 6 > C H g  %19@GNTn $)>LR^jx} -9>EINSh}(09>CLSWdk} %+39=CJPU]bipu|#16DIOX_ensy %-28=BGLQ\akr}+ ! T fAVS @? x lfPzz  c 4 B KH K\j l vvo K KW l '  l  /@EXXE+y}}yKd:+EXXE 33 33 (  `lT~~  4 fT @4 s ) .TO@O << / 2 A 5P y_ V- ? G c < A  M HU ; C < e8 }y hnnhhnd  (T$ E  5 nh h w  y} } y}}yy}}y^ w ʆiimdod $@~ Kz&w{yyw}| |}xz{wa&zK $|'˒a . 9 - |zKz||zKz|K   ff ~ ) T* U " Z $   o ! ) T  [=s T , }yTy}}yT  VT- T? `V hh h@@h |z b c k  j]^hYE֊ׅB ?Gߩмqٴ̟'(͔͂z'w!q=wVF7HJ?xs]C$ 8 8 . 3CC   z  W (K$ hn .TO a T0   tkQE;wOVVOcZwE;ɩL1HD hnnhhnnh =  J ! TT TT} [ A ;(=ZXWG/9;/_Mknmn9:YIƑP`q~d_i iii G! } . 9 l - F/Bi NPuc]T!o>9U G @X V``V}~d3fTw@t(suwN5~w}+}PV q y}>  rcrr jih t <<rcrr rrcr     tp    yyrrrry * t D$$D !5   ! MQ :< 0A  &T+ 5e 11e BB  quuqqu;;uq tH t ZKS  { * }t / `   `uttu~w STdJ,]շ49 arwwvyr/ (DB%$AΌ 4 4 x T s wrr   Ez*6z*E!  0  D$$D _  yy >T 8 ;; ' : y  TT_Ld g__gg__g ,l [ ˻WL @ E##EE##E  ~w] NTQ    o"7l $> j s   P : G 0    << x G z{ y}|z !5 $$   l c c   $ EQj ip q~ 1   @h c  t44t :z{ `M`M   - t) & ( y} E##E i tB   ^ ɽYM s%$  *10 B ~v `V ; =  @@ yT 5 !4 ,$P++ 0 h  0   r  ^ w  z zz{  \$"WT f  ` S Z  j   )Wbit     }hv,0/vdpW  X 0 8 F  h\_h3`7cSg4^ 3U^ VIM I | !?!""m"""#h$$%%&':'()X)**A*}+.++,&,f,,-[-k-./002)2=223Y34 4G456B7C788H89s99::;5;<=<=>?@ABB]BBGVGGH4HIIIIIKKLKM[MNO?OGO[OPQSSbSTwU*UVOVW`WhWpWWWWXX XYY;Z$ZZ[2[\\]&^^h^^_`V``aAaabccddde$eMe~eeeeefffYffg>gGg]guhh hziEij"j$j&jqjjkNl0lmOmjmn@noowpqqKqqr0r}sYst2ttu9uvvFvwvvw?wxTxxxyy{yzwzz{ {}{|+|||}%}d}}~=P7>.0;=1|Ab#*/+B%V;jR!B'?h$:'aPÉŏzưǙ_ȿq˟b́ϓ$)lաV׳ءq0ۥb޼cG8]^>:<?lBsH[Na z    ,   ^  t>".GqsuA1 A nA 3 !""#N$[$%F%&&R&&'( (*;+,g-f./0001M334557B789z::;X=>?O?f??@@k@AAB2BpBC[CDCE+EEFGGHXHIJJJJK KLMJMN#NNNNNNNNNNTt TT4c 4 z..ȮhKhh3c # ^uiƭRl  @- ? FMffMZnnw   c  `Vc~ofa[Y  T=  @suw#$L>$#69JX"!!`V+/EE+V1RE __r@3CC3e \ ; p]  ksu[ztg U1 q9 [[9:QQ:Mqksu[ztg U1l vVlXXlVv6*336W) Ki l  i4e @ { { { { \ R T1R `VV``VTV`ԜT1\ R T1 TV``VT R  TV``VT TVTV``VT  ^y$%'+ hhjyy''+ +  ttB KH ttH K\tt jtt=  H K\j= n tW&S:aR`S:a))6 z6)õ`a;R`W&tP;;QEEQQEEQь STT@kmzK}zaEV" nmloL{yry}{{OJNll~n|i&js^^[{m~mkNo|y|rz{Kpijki\f_i]QM[!|Lz~rǑ̒Ȫ'fgiM    ([popHH4h l nnt, s~oJ,lW`aGahc~v~AHHF!4t4tt 4# ){||||N g|5pp Ty~}y:y~Tppur5|gccn_Tz} y}}zT Tdgf[wXX[fe? tqT% T TT TTlT~~ 8 6(' TT6k,T,ThXhYm}}chhcqj}}iVgvW wxrwwvttv# c w!SY;;PylD&)'C3 Y4# T[ t}|}zcesd,.9/F- . T4 T"Q>W"SX5z|[,9FZ3} T[ _ " "" T@Ա Q @3CC3e TTT T+ kT^^^^Tkwh ]bt\jK__=1lno1"-SKq~n}s{x}zsz: ;3n L T T/WW/!(ZMj: kBP K* k+8V=_GxɁHKxMG_8+  Me e N-hnog? ?go e N-hnog? ?go_QPox}yCQ(Csyrp}t{xodPQ_K n{}|zx8 S``*S8 qxozo||{}s}|{n:  K     ;x ʪʪꪫʪ骫kihvvvijiʌq|1|w|||1| g1| | | | Q kllqʁ qijivvviijp )p 8_^X*DtcX_^sjii}jttjjhs, g|vtywxog`vf/TFw.qra\zzzaM{tswxyzzVc,sj|wut{tv\h2p]yx}xzuxWi:mY{pvzs~{sww}e_^#:/r8u 4S 4K 4"Kme,,eBV4K"44"4\t4T? 4t* T33333333T4tXr=EE=UIrXt` ( l PT, ie%/,xxx(((#Ɏ wR'VbgfVpoqqq{\/j}}Yh^?DFG@EatV@ha%-n<scsŔO5*VJM(0x[[_}~ %;AHW{'Qbgfg FIGf=R!Gv^]^z8'n\PuH#hPMqJK{-ЊxġMMN[ĐơϦԖУ!!!x$ǁΓmr;ni~GhftnOlFKwz6 ;p6p_ph6hpo;_}oh6h6}_Ǐ\|}Cy ^^^LuZq< R eptcCDC  ǐ]|zb||}3mrS667W, "< R ~yv}u ] y]h vp|zwwzv {y{  |p hy ' 9 -' 9 c -' 9 [ y ' 9 -t' 9 [ y . 9 -. 9 c -. 9 [ y EEEt  @\ tX=l TX \ T: H k utX {tz{~'&9+ T'T& T&:'' )TG4444Tl  |z@ g4ka@ @  xD~~UT448~sjiij}st:944::,mM NLT_p’tH @M ϠHGwwsr@ mXXj:bkkcv`~:jX;Y;l-&@yyL _  S+,,||~KK. fccL +4444400f,,fMff// gl }{|y~wj. |z@ "L   {zt{tqT4 7\3ulz* p4Tqt   l KK.  fccL {kkYkkkYkkkkYkBBk   } 0 ` .  ` gs EfZE Z SfZEZZZZrZhlvlr|h@h|kc @_G_[ kc @  ZC ZZ ZZrwhZ c  ZC Z  @C }rrw_rZZ w. ::zzzzr:: ' zz:::: zzJb $Z !  Jhn~ k}2zz11zIIII{zzz1IIIIIIII1zzz{IIII{zv zz{z&vv,+&1zz6 k4y}}yTeTN T4,#Q?`\pnZt ҫȧPKgjzx}wy\O~#7@TKT k4< T.4O+.4O8C 4 4 44 `$$` $`${ $$w $`$9  #Zk==k# #kZ==Zk#9 #k==kZ#w #k==k#[ ]  &&  &&  &&  &&kK# g %''%% ::!8#  %56&{SjjQh[=<<=>o>n ^CT}s@skiij}sstDjt }sTӸ~ssjiik}ss@@st jtTC^OGGOTsDjs@t  K8sjiij~stsDks@sTC^ǸTs KT8@sjiij}ttT Ttjiij}tsA@sDjt t ,jl t,Qa! KtkvqCt kt Ԅ k <<p+>|Ri/8Crb{Zja_qV  P_ 44T( V``V N tY c  T s ^ nc  TT1 noqqon1 !5  Tft//tq:v++n+*mm*+n33+ äyppv-) mERQDEQ6 ERQDEQҌQE9},~ q 2srqt-}}N}}~ZTYprr~n pwefc~rrq/s~|~M}~,soppndmfnen s -}N1kmo/DD\ l y[  p6$7dI.3Tfo1\s\k <^  U/Sk ?Ÿj-@  +6 @ Dɝ·lZ'#ik}ts')2OKebh`i_mdG1dq^ nm]a".e G.3GNOH 6  t@K̬-*osr^ ?<k篞 Y xxytR]ssvkc\k}\vs򺊧1fzk~rvdOJ.eY$n:mo^ nq1d_`cJl2)t}ǏymD g  @KM>M>KR4)<5Mnɿ<5)4RP p];  dr3CT ~ϧX'T& ~ϧ4 {{{J{J IYU:=YϿڼWG j8Ke`bz|vw{ ̋{&,(i"z 4t4ToN T480QEEQQEEQ08: (y{wA[ _ l & . T/TL _@ DD D N DDl  + ^GofC3Tz ^Go  ^!Y1/)Yb1+ o ԹV``VRzf|Xm}[YKKkK+++K+K$>+++k˙̚zfR_L<L aNi`ʆ ŕXP+ ! t]r[t ˺?ApDU88Dp?? \pTTz{{z~TT# T~ Tp !8ZZ.n82Y\uZHm{(r^-Ʒ֫Ϧ [ {wx^^]Up[c\ˀtbdee  $fb%aa>"ipuleǞëѯ wC3. 4+ t 3&   w&;*226;*u qXsIm[FHNMo;otpлͩ&oxtt_Jdwry0Ayu{&Ay  (TQrLyJγʣMfEpB}P7.G$%Frrs3Xo[{TO(QVY`1(mpnnvww ."4X+prq/#>VK?ʹķSp.v/nQ1h/ p%]8rwsp TTT]]TT4V+T ,[ ) j @ @ @Q ttf g   TGzi.],++,]i{{}zyjpnjry''{{~{y#joicciq#44VV4@Ա Q 2t1v~z1vF4YtHAAHZEtYrtpԊ  c 4TttfT EuFF6!1=۴ n_F( RD\\ T$4` .G^SSG^J(@twT3fX V``V}~d3fTw@t(EQT!yTk`wrPNxyprNV[Pwrqqyxyprrwwr[PNrpyxxyprNP[rwwrrpyxyprrwP[VNrpyxNPrw}PNVVNPx_ 4.TO l FPPFs\k >\V?Ckk++JL@ =3`?.Qm\ibgbjnG5[^ nfuel.=  _ .Gc4`C>[B atĹixFP+֫ঽtttuV]]B1 s [GngimQ`?34=_`b    =acf}|}KKYS#L "K V?Ck1B]]Vvuut+PFxiԹta ?MQYKK}|}fca=    b`_=43?`QmigجnG[w  ʰ"l ZB xxyatRt]ssvikcx\j_qFPPFGOLJ++kkC>[J G! kfufs ^ [5Gjnbgbi\m.Q?`3<    =؉ˠSL@JQQ{z@r0060  {zz{QQW  00TQQ{QQ %0{z% 00{QQb QQT {z 00y &QQd QQ {z E݂v <<>Gww|&xjUt=N,BQ?FE    {tq z z w44@  44te takw$$Ti Tqt{stoy$$$$tqT4 TA $$v v$$# T-T$$* Wn|`_]#v:[vVi\\iVv6*446Y TWu܎v#6]_`uuu0n1W@^;Y  TT`4S2S@ zyrrrrybcyjdL djyddysqSUmtvwjoXV``VXojvwtnrry@dd> ybcyrrUnTddUA??BnUU'&UVlA?>CTddUmի3STk@< ?BUbcTmԨ'&* J,>i KQtd_O>Kj }|},D!/G  # # @*! ! @i##flA\3T3T K"~xF͇F6)-1?pWSRWn?=%(EUmþBB_XS-(mU6EF(%=?VXp򎬇F˞y\&sqb]NENewdG&NS6}dNDwO0]bqNñџsSe&GF\}w~vt:4+q4CKtېE,5  4dYztdV4VAlff,,fflAV4S T? Vi?fflAV4L444L4|+fLdUS55TTd..Ġ ..||eWT6LL6UVe[o!"m\à B)%h;=h&)CMe0 0 4VԚ44S ? 4{}~bx4TԱ TQ kmeeBV4@? kc kc Tttt\ Gl 4B 3 E Gl 4B 3 E T 3 E  h $@7_H,`djXg]SˈScfzhebpR3^v"Om(;.?GdFjPyi7voMyyy4 @(!?:::  (l T@sTz|@=\ @3/{pkgGR[".__ušȟmNgG&߅ȂAP_ATeAa6226^%OLJnpsosxZWS]{`lcmcbnXzyY\a\^cbhnnpszf%_whY+W~ cv͉ΒИhv9!݉}t{D$p_Civ9U:j\i9%9) o'0qi? ?@ieM#&nYA ,Ómxwr]9 FfH4 ze`c``c#NW[S 9Z))));7eefeefeefee)l  {r|sv>(T+J~ff~JJ~ff~J`  P ( _4 ,[ q nTT{zTTlTT TT  o 4 f@ @ Tq nTq n mjingr;<7 M7#?#77 <:fime B4@ V7)0[/1/^//10#sEAA*,?m6"mF=(G`$.ƣ 0n ;;YS<! 8sjiel{ppmoy,,yrrUg[giyxtq]um~~~~mu]qtyxgi[gUrry,,+ ompp{leijtt, MTTM@u^9v:p%"M$%MڑhiMMTTMT&&&&@;$yz%:@ %%_ T DddDWXYV_lw}v~v*AdD[  yo6$7p ^~ )?cwrvy~x]͈}|*YvvT  +TT? VԿT T+V``VS ? V+TT+? V+TT+?   XvvuuvvHNNHHN?0   1j j/ b zb zeU=k?0 ) $ 4S 4T˱ TQ K4ime,,~V4T? #x:4tT.H pF E 4KqHaZxuuvwtD6O'xODwuxaq\_ II_ \DD$2?? nzykjstz{ztsjmy}z{JlQeűťž̛{yn׭ |zT|a T`t3 `Tz|* tE TQ tC tu* 4z}|yt Tty}u tT4T?hnnhiN[cG=B^60QEEQQEhuI7#e  #7upjj_pB:1 !5ܾئ_Wc[7+447W 5!1 7EpF m;4U?ua[t RҢ&F & RD[apdu茆0 U;4mph]@ @h֦t t KH wK K$4` (@twT3fX V``V}~d3fTw@t(EQT!yT)T1 K5!( Phh4 tT ?0 4nh0 4nh0 :Bp|צ_)\tEQF!44K$T/T* ttT3T/T3T/ t" "KT|zKz||zKz|FT|zKz||zKz||zKz||zKz|2 E 4c @_4 ,[ It" "2 "=4 kS T? K+ KԱ Q + *Q _UVTk,[ )x` MWWl2M4" T. 4 4hZwrrlZZrrwZh4!""( "T[ 4l 4̒4" TtkH w44K k)tK +4Kk44Tt+kkTkTsTskkTkTt44Kk4 Ftˋ |g>DRTT˫kTTktkKh@@hTTx Tb b d d 4 Jb $Z W Z4 ~]  ~] Zx x P tIIP 4I I t] ~YY Y P IP I )g|ze3C4KGf9-K ) 4ԋT fT kE Q T ԃ`t4+V`@Ӷ+A: a 4ԃT Q TC3v  d_gg_ d4T Q TT` A EQ 6 Ԗ TNT@"RDEQRDEQb@TT@QE^ EQҌXx z  @T b'&Qk *j4a,t{ztC8qbbb{y{x{K  t44t224\<-7ʗ7-tD&c+zi0&H. 0,-##s& &2iGz@@RQT+c& &t  l c tV``V V`T5TTTK 4 &)l |~aiEjVulѬo70 XDQ547mGGT4+ &naxjigxi j(C(jgjixhi5'=='5G5 n5Y'=='5YihC ix5  T_-T5 )TT< TTr TTAOTTA 8TTC KM`M  M yy p< ZL )xIpm F m t:+tm F 4m  :+m F m HF m  F m F m F m ` :+t$as ^ na jM Pdioo '.X@Qh  @\  s]QT3T)&  Y ff ff zM{yz zyz  %tJjZ!! !"н $yf+/Y kzX,Hn|}1d Z\IێĬ TTTpK =b/tQ( 0>mUzxwyysq ggKgywxzpTmӨ'&h~zUB>>CnUU'&TUmC>>CTz~p> y 7Q( 0>/+=  K : Khnnh% T,[ P% t, wohhonhhn S3@B< ;|#&%6Nkj>hW@ x}pU3@@B< Y;|$&%6Nli>hW y|p* 9Iv]Yfh{osjeV]]nw uKJQT*FhltnݖݘƎqDA5%!*QTFhulstnl_a99:P~݀*Pk9okթ ? ]]?  DvD)D$$DK? ?CI 9 .. 9~`n ? TAENK ^ )T% 7;L9\XpqTT_4 9 $9 x#4@a T+}~| z knr]J'V{ke{ohc-#/&|~T+ `t{yS;RQPIODwt{K6K tqn;<-=vvkhF@8k!!7 ZZ ZZ9 %! ka!7 %  9 ZZ !7 7 % ZZ9 ZZ! 7 ZZ 9 9 %X ?6IY(uC XVYx\b66 PeSGQGz5:5'DN5(TKKT( Ta 4Q~~'1 A3ZpT2T7׷i ` ,9_7XT4  / TZA1 ~P(~uQ1  Q1.g TTt/ G]]CkVY  M yyL ? ? % UTUTUUTUTUsM- |a99az~ z |33z} z99S k <<`C3+ L 9{sYsn{xput}T4T~T>Tw}4TTru|utpxnurT}ynnA7  9 gggg9 % T(@WWS+}}F簰ɋf,,fMff zq{ttz{v7 % vxt~ t 4G{zs{4O!mFNB9x*}}~5W]4xG ttTc## yussu~uvqxTzTQK y7}TxvvxzT}xqvu~K zTxqvu~ussuTTt< T.TOT}yf dyDs4>$0K_|h)!Ch&5`Q?vk}>P * z|% e@1* %$?nPDsQ](E5UW+M3T)3w'T<|#P >}ykאSS8x_uaz`{{sk=Vjs#$6$$q @{_,1!T!1NH( t()$t t* $tTq ;>TP NH\ @3uk1@:6zi 4QG%/쎔|~}.)|}~}*1~|3"C3d4}3;e:}38i1..`zJ1Z.cbb.jjlh8ʟgk&wl`lK`\..H̢W/&~kSڡ#ڨZDpA4Ikl,,}V``VS @? V`k,,}llp8V`V``VS @? t T T )8 }3 | H4 )8 1H4 2 }3 | t)8 Q4^4^T4T^4kQ4>t)8 4QT4T>TTQ4>TTQ4G s=)8 І ma G =)8 d   4Tgnohgo! 4' 4 ,-3#؋Gt `aMPQOddlli`g]_Q+ fjoojhovuf\#ͥȅ֤ TnhgooghnG40  q~ )|mxrze`I3}y?z#\fLuOvhimohjo Q]`ldOQPMatGmqvin4^ːΆ—̀ƏnX+}j{xtzj1HLzii|E;;]SHv|~}Iqzxcypst}qv5Hίp}Gq|z{t}ypjip~rx}xoddnyr~Wvuyi0izj60w7~Q[`R|R[~wߋƻő|ą`P805]A]|s|z|WW[ dm}yrxq~jiqy}~rxndI mpr|rv|{H l Dzك{цԨ_~q|||||f|mm|t^]Z'X"-Ibgiwknvv}(]jvgrxhklm[2+*mxfwj]Ynwwy{hsfy\\hqxAzireV$G4]t~%]~smn}ft]fcqyJ>LNMMNwK=KQx<rCu)k,##,)CrrutturӠ,#ˮ&~'+'}~~}}3 +t4b4tD809mi%if+qU3? ==BRippiip!~b^^jcjc~9?>99>?9elleBel9Ble9Bd2222v< <g  k&]&8t#4#4-_G_G r 9*Hb=gh`̀, ް5-"MM/8(x,(90KDzіɕOTOm̀ցQ\Y5Yy{))+)jxYhmG{IUsV7=o{vu! z'f@o&d1caaPEb4"f|aunO鿦ɯ˱nno5.OB\WQĦdRۛ~-aOpbKI2C@lU[s^Yoc`̄ƃ~ƒΑ~vD,@aD1"@3byЀѐl"k"rbsIr3p1o1]_qewG1('$:er)n'y*ԧӥؘؒ6;2]zt[uns PDcl|P~_q<}Nx0k<Nkpti"d-"`#69VѺDMV"TAK$ `~tJ t~~@`@~t ttQ t~򕃘t~~t <t~qqPV]]tסжihhMD;ZQuItI[nt]FEQZ-[+@@*e-8;@@4uvǹߤ p7ZYCYCq5( >>>-r>->j7)1auabtavzyvvzyu:uzyvvzyvLR]]SBR]ĸB]Sx*.NZwR]ĹwwR]ĹwǼ|CNGCCG|pNC!C,313, q|]RS]^RBR]Ĺw$䔻kiᦿůI7Y=+kt}n~x?z}}}b;u{{~YP KS{TSm{qiTAsFGKiwzwo_ewkjZ˒lshztu|Цyu"5@'\ϊ؊sqٱ.&7e}|_g͗5|qD|unlaK]~diqqquzw|wʎó^=~Şv}M,7QupzTS(pzKYNGJ b/ѓcctup4K6gp1zyyr7Y}{w\ @wxFis}txyoGqt sp^)X )iz=JFdf|oL{1$+#~[G0`SQRne*wXjsIx[Ͽ^d7,vX9 ZY deҦt-tE##E)o}}4u{zu\ O#nWvZh,lt:$4Zsj{rglb1XldvG'bQ^{yqa|x|{jjs}.Ӣѡ?IY–Kk.#4)sV 1| XRf 7n]Mw]^}ǟxwVo] ytyywyB A'!3EMM!#] ([B4WtImnxWxWtIWȇ$rzӎlQ3J>Rq_(%vv==)G/H{uAR6=zkwlkkwllaelj{RI7 A5ifsgffsh./gge0lF kmiE#=[Z\Z#=EOiNQ@QyQ@QzE&}9ً܉{H[1N[GCJۋz"q*g2EKa"81&*a/rwxrrwT(v]*I0 330H 3 Tz|4# T|a 5T4# T?~~TzwwvxT24K Y 6 dpF47zw8,lr7RZ(x[ts[{+;f DK^Fxukrlqv}K ?(&PX+)#JU ^mmm jgenyiYW»ëP7iSպԤÎ˒rSppoG.B%r tTt TQ4( Zdz{ IP 4* . l  tQ) K* [s`C3+ L )4՘ΖT˫KT]HAF-"Kg_yz}>Q~{{~؉}zy_gK飳ܩn_ZZp_bn:vkbA*t%ndʋ̫44m4tbm++44kkLJJl.d |{|8S"1ÞH=|}}6TV5wSLTT=g}}RIcZYccYZccYZccYZc \pcdwywxRj.j.Rcoͭ}t qZbZZcbYZc\L gSVIm> k.L.k?+llH\\HlZ釧鏼0T T kcthjz{{z7LvvK7isùĨwлQahaahhaai?Ul[Ĺ]SZ +)**MOvrqvvq 25 3 + qv6!Mr342oqv*  )```NW{WM}|XLyR]^SS]TTVQ~ùù]SS]^SS]WQURTTl 4''tTTttTTtT a`aa`aMk`8aMakap`a9M<97Ba8M97Bagg[o2 @2 CG%:`dhbgbۏ֯Ȱ:%G?G%;adhbgbN;%GH 7@ Q Yr3FZXaXxwx_blkx B) K%Lo3BJwu~kuxuk?Oz!xyxvzAY Ϲ[Djmhl|{{̡ԡԈ֊ j8ч5T&9E Z$j@b<r(B{]<6TY uZ|iJC^E,g_zsyubՖӪu^@q-1ݛzJ1jI1jgTiԻ EY}MF{M`@]~tvtz,~@Y=U/0Aqtתdz}PPxvtnos~}mzVz-cObPru[N S=)id<&li@XsŒՍ0ZZ6:3W4U_U266WBN@ h[aj6GUv@cLj^HI,+T(jjc+,54+,mmZZ;ZZ۽+,33m0vH9*/o⩩+,44>4 q{7$//)9wh 0m+,54+,44,,nZܼۋZ,,>'l4n,,44,,44,,mZ;ZZZZ;Z+,/o-D/#5>'}n00nm,,54,,44,,ۋZZ;ZZ+,jJѲ"^ z}i{ѧ錐zss^myzSvnnU{uuwz~˜ڦLvewe :rnwt]R{ϝȹ̯\jtazm|}l~~nh~uN?MamJ}fg^%llI%uXBlznxj|Z6{&1~\NULܿI4'6kZ6nNwa T v  `77lf,,fAV4 PW?tqCCC44@4 ,-i ; KT C KT; KT; Ky}}yKy}}yT6 96 y}}yKy}}yT6 ttpfeOefxxxxeOeffeOe  8  *`7Q `6w% Y4W%*% X4j%1g6` Q7*` D4 Y%*&4 X%WT#EE#\[^hnT^\z.}TNNNiYT}||||}TYyi[U\`uTT + @ 8TjMQMQMQWm[FN$l\TT{zzzz{TT\vl]X$FN\vl]X4[^vTtZ TtZ Vo8>A , '>&&2uQeGWn!eq=s)b?ɽX/c o E`(yk2@ /POlAAg e1j*.Nz+8a{z{aY%#y=<==<=<<*```^+LPzlX1Az/-6D&@I`_B   44!3}|~jk/k;j:/d;jkjL`+ T'h uY54Y\55\Z56\~  q@-& T&kD>m2W._Z8nE 5<hLhLQRSu'/>0Agz8(ҒӑP0KC'ZL{o_uOn ɋ#xW{D ߥpBdȋeE)3 +57wp 44tTz  z 4'c7E 7D 44 cT(K7K7D ' t aXt Xt al&'y &'Y  } Y&'} y&'} bKHJjp̃Έb[ aouwr~'89{={mx<*e>okjqpi{AR*7}xE|}jp]VY0-|xpaime{}ld""p*}|blv\&A}xfa) po"_m3m"3s¿8~~}~hs׌ $zctc^_Pvv~w~yf{h{ Z~}}}}}||{|Z} z}{10df}itj\KMuTuzy~00kzzz <!!o !<Ǒml!D4CPWhЌnjʕ|vw||ryIs7h3^1c:gJlXJU>]wD&_nr6Hgdalor@/K&``m}",y }z~|{@Ë)ҧ̞ȭBO`)y)o3hm^Zx:F!4i 1J{z~v$${z~J1 E8)3y{||y38)E1 !4gVQG ?33A HWT! 5|x$5!~ !4t/|h7S.1l~gd`;!Ъwgvph  !4;TTT      PfAVS @? x lfPzz $ c ;44rn99l>SO~~zzK!4 EQj 1g F!44v{v}JJ}X}w}vw}Xe}w}JJ}wevaʁӎyLzzyӈzzyuYaaff6&̶Q HyA~`Dޟ(#PgQ+<3%!!!S|BDMhߺ ђ.-.-.lHs-U7sH<JJJ?H&Urs&l~v~||||~v}~rrrr}d ^)[OK0-npq D:)rJ?t~rIFo9$"%9/iüIIR^rdclmkԧ2*:8)0\pFN[BA\ŸghgGDDl)3=L > jRVVVTPQSyVVV:RjVVyVTPQSVxVVyÁ•VVRj xmŁyVVjRttF4xPp? px4MFqqqqv|y*|8 G}AIrw-u\? 5'p$ PY84I5K G3#T1!I%>HGUB&- -%bbd&-JRprvQiu,t~՗Ӣ9RMgĬx{}ާEvhrjplJ- ?&n@5dbbI,ueui`M6 fXPljiijlPXlf`M6`ZiRuL};pommop|;LRZM6`m[ [ƗM6Ġ|}+vjS&zzgMRjhed9oICAA~CtIo}d{fxgj ;v+Iz5&o? mjhĬ7;jjjjjjjj> \O+:xOa_UTS˄@gftXRweWWk :{z{zzy"J<%wly}jhw|m'!+\! ոϡnMbx7tttpopyjef{m~ Ǻ iii yzyWuf^ V]g`[[f_\ `Ujf#b'^jTm4=yBF$3P:kS43g߫ޯG@pFAw@UMMM%O&iWtLXU_ogBF bWR?d/yH(#-:=;ra``^_^rrukedA~ R?‰“wnmm(?+RVB=jȕwS<;QE>?F X`X4! 55 pqsa_^U^HKʲJpwm7ųu~`//:q~iykkkkkkgfhopypoon0 +(\fmjő¡CB{gtzldg{S)ik-z/Rɮ٫ސq,Þ2=5qnYVL9+3zZ$;;#}MwzVqzvy^oyzzUggTUT¯¯gT{fggTgg¯ggUggUTUgTffgUgggg!Mm#[8ICnyy|죢Ԟ[TI&%7~~Tvtsrv61psYMwpv~Tv~tsrvlUXqsk%]rn ;;YS<!  w? ? U bXkC_}g555333g}cm6ﳽmv%f~~O~~~a}g767/./h~bn1lp.[Rh5kuZi/4oe ^Wf7h7jvWi'2nfz#zCpisL2r@;pEVP<Q;Odlw}#>}x ƭ 4tt ttTttk7>jVRH %HVj[HR>7E##EجHE##E[ ++ +  heXuS + þuh  + ++ SXe  %  +  9/ː/4Gj{fj}^11^rt|qj|$$P|jBGrbrrKK& j Sˤr(Ge~1~w~~w~1 zz0v~0 KQ+( 0NT:< +0A +~w~10  dd> mcFr@:}77:@ڳm-T0>2tM2V33V2Y&Lt>T0-KKKKKKKKTtSTSTS@5gn~STSTS$5 H~HfJT gnT<}~}2TT~}</ Q(4tQ(\ Y:YY%$~~$%YY:YZ$%**44ool8II8oo44**%$Zu*  +  uHd8lhTwwvym\_u5^/7hVfJC22C=+JVhX[<*N?Y3: ]#"S:Y3N%I%%%%F%"F%F%"mmm%@5z"mmmmFFVmyjjgwrPE]}~Su8ӗ)xm6 |uw}un]~')kp{u~ y nkuptogo>4y}Ϧ)Q4  gyr=7TRyytvz3*WJttx~8tA&ysjmm}՗ J T  0 5c 0ta  eepZp %$ B((BP! (''$$ GG(GGs$$zhl?9%$ _{_{b= $ MM M MM MEQQEEQQEM0  q~ $  EQl  lT^_|_j-Z7BG:?)_s:y8CXccs{~syyyyzyoto֎~@,="H(`dine|Anq˗NJܨ,+@מaI Ɓ8%m^9^9&^5 LZ_mOMrqs7bh%7fUiU>!Vvj1 zA@LF){B90kMKpo}q4^i4c2!b˱̩,|l-ƒs|eW"}fڋ\GQ+L~bGDCd5.26J:#:t|mcUJmopmvn]TB4B@Dd$rvJL88˿}~=.|Նs=xzo<BY$lŖ›/¸le3k{ut~irgk{ut(ӥ`xnqx}p[!T77:_\\]k]: rZwxo_(|MfmWisu͐0|u~Lvkcpy}~uz{y\ƊosTuwurl{~CBm]SbVBMjʞwywkws~~zqXIHI}Ons@WJ-E`Ǜx|}jxĨ@6'r[vyo_|MgmWisu͐!t~~yqWIHI}!?|zvYaOD Vhx/Ym1V:FMFVmY%0DF/bbF9@O)nH4(nO9Y"Ω̵i&L̔+`~tvqazpubw& SJZu\ek pkfY ,F):J\^GZgmn|@~~rNvƯri_z{wow{vy}psV1}nso(>}>ptlN[XKH[ͨ>0 "?4'::''::',Ah"ttLR AS1 Sc1J@ֶgLXpjZ  =PBBPOA AOD=̹|ͻMV˹$QG̟^ͫw_BG.O`IΤwϓRϺT}c 3" @"7<`ߊmQ1ryt 8spvu:@rfqvu:@r_F />L6L!+Ohhhh[Nc92;1 y,((, mm<}nik<ytgn(Bnlmv2gW@TPQ~wezuEu@ :PBBPNBG=_"Z*y@u!_M"_HDJiQwrSrNG2JDt( w\Dx]nrTrN:BNcTX.]^ggTW-|cQf@+((+ll>vII<5 YaqT;Qvy{QŷbZ Y`qT;Rwz{Q9RIPP(*/inW|ϊL/b\04]O__@@e,l,} v)@eiyz ) v?} ? 4or^{g=Zi| *>薚=v*0} 9  3os^{f=Z@i| E(J-I4i^xz xY~**)(!= xetpq@tJ͉yiiylHXzdipsl_~UGJhsxyW9Yӿwyk]]s}zw~{mh7k>Yi{ ztdYgrn|oM򹓝gptx*kSk*kl1wGb_]aTfvst+*r\zheN;h_hg__hh_ilu~~$rfP|KEUfav,ɼuaaP@YT@A :~@7뀙v~6{ T4` * ** >TQ4* **) 4* T$drrZ\Jxk^kwwkkw^~|}T|zxk*kw U|zwk-jx T}һxjҺ\DE[[DS^mxH||T}.һһ\D.####k'V''8Ltt22T22 22T22O )$ xrOrmcqly|~"|yy|~ |ylqrkew}xt[pwtoptbptUkr#$Ua m}||}#V䕌OVP[d\R\D?G!cLm?J9_ lq1:KI>?DB(DD(BzD)ANZȼxȼXN=k:jTRR;;PPQ2<;5 ,$()MU]()++\TMqqz΂34ypm1 .oQke^ 'uv& ^ekex#B9o=9B]:#/ݠ"\&"iRex hB RXD@ _* pX@RchE:dM+A * [ $qf]]]U9pttp.ptqtoq$ #$ A#A$ #lL6HpAOYKI++srs I0"/rIHqqIHrﷰg(7]F$ gVc p'7)28]8 j @ j j j @o]" -]" -]" .\#<]i|i|i|j| 66 66Fٯ6Vg <- gwr r r r r ;A A@ !A@!!@A! @9ŵwvmQuLflD^A94wHMZXaǂݏ,|) *) )* )* ** )* *) *) )[OCPZ[P55ZPCO[[PP[(ǻ@:M`edeSO[/:~~|yw{ >g7.iczdfptð+&4R l^vQBR{xxgd~y</Rc4jc'^dcvYXwrlO[MOO[Olr}twXPYv@c>kPS/k_`bjpN1kI7+447o uU)4S'-{:d@G{ &zzEwvlmulchr]tbFs^[XVvN;mЋD1 %/O,jF?j}yykDvDK'wsxx l DvD)l _>hjthhjbgSgT.  T譁bjh>n_KD;Ds ^ ,~ 2+ \ suS&yprxo@nrR/Eoqwn썍c@ ";;dxpXBB}tq۽F Tdmlsur|jt[ttstt/t G ]]  43) \<B4i , {uNvQ*33Q~Fu{uv+NR-Xv T  vXRX,  *6xllsvr}jR_  )[=)R~[~w~5-!/4 B"~v_V=)[ R5 uqu f!D! }qquur|jt[ttsttBtt/tì|rPZ<:`jvg$gJAv<ֽYi}=af44 )5Mk4444_  E E TTE Tl TWTTH 3  TjTtTsR@6{@),\,)əEQTW IIs~xxx{?+)])+8s~T @`c Ti mGTu kc TTTTT//TTTlT T!5 1  4 a4 a4\ }}{ptrmg}e}Mpvwyۏ c ״( ¯#wmݿbt@r|kj>Slst=Sls_tiqnv„Ņ3I`QnN^DyagTQ3I`nȜn;((5;!!6ryPqhn}.d9=k%)}|||{zvvuyyvvx}̖ҹ֐acrppxswzn}{wvvDӍ⟳͂pTlZxeyR{o|WbeVHquOz|n*)j4_SnNe]_\]“†gwkrmn nny{ʼnZlvTdp@JI4X@^xԉjwvw@~ny yorpmue{`nYnpr@^rss~~xvvyv}yuwz{{|z|{}{x}~yz~~} ; `ˉˬ7y88Siˎ; Lp` d|jK='t< $k:tt $K^ \buBs <<[=:0  Yvk2  OTV0OUƀGԫafob~hGSwk9&&  gY8>%˻XM,ɾYMr}QQ|Q'%`em_Jppuiuzzwɺ˿gYv*ʹ%q-u*+?q8$@q+ )5x}2#xww;Q" 7=YjyJLkttTtTg[ MCΫ MC1XNgZ´[VmJJ{K/oqwnbI ѵvj+^ ` d^]  Ub[Քm)xyx^HCii}l\NJp" #kkgko t c7/{{{ ` zf+!` lln%( 0 ǓEt^+jffllɽYM{{}.}PHT/7qͻ]H{4cycq_MYɛǦsjZ\ !}Zcdznp% 0DRɹXNMTYNdkdEXÿ!0WV~Y6R}XcP^Zt|z* z_ q  }z!~q{yzp~"{}~{=UP? Q={~ 4Z]41YW36ЧubQEd]"* T$>/V,'t> 44'%YT8?9|2'8 (%XU7?9|3'94> tt++UUttttC<<4444 TT UUttttC++<<44\ aJZZZZ44cTSc++TS33ZZ> DORKPKaXWaaXWaaWWabWWa 45! 54! 54!-..-......-..-..Xcccccccc0ɂь8`a@aNdC9sbccc@ccbcX9XE-JF,bH5@Y&nË49HbFs̷N{R{ `_`_`_`_9''''pqD-A&aa-D`qX_1`AMtCC%&*)GGbbIc~c͋%)Gc͋cBս_k3PD33DD33DjKgl:VF_-zMWSRn\nnnn\nZECSSnn\nnӾN+F:g˝VC&&ӋlgZG%%GG%%GG%%GG%%GP8 X@ 6DD6srpsG4Tmmv)t~̩vVJk}ltu(vumm $O?$d`zw~y8Mva\tiN߶܎`4s~nkA["gwdLaG$lΥэv~{ҊꅮK-5%L .U \  @j<Z\ fzd?* 1"0-)/!U=ITAIzWdd],O+2=q4{E)|肙i54_:vxH|Q̋yPBCĻ*O8Qz }y2!v\ 2!dx%%uouyf"2E"ciP8+ H>VV> 8PicE0}D8F?:/5mV?_@)*_AUm֡F8~_ :hI K6AOR||| 7::-R=6jsnVK {Qr2w..4$<1Unk;HKTC$[EEq;rI/(6F+G-7+`=(c2F]U=PO>Ul gT|z TeT t3/t  KWWKKW#1bnZyOL/õB+ h'X=-k7yS[rWmK|CO]ew,i@RF˿WK)}xyk~JJ?X7gf3.x,+.46?JGXjkځLJvl~doJLN*4A@Pbaul~xyJJJww}IIJÐN~LkR{mmaUULEC><;;{mDRs*MSPwms}wy<u|ƌ  Y10 Y 1122X48C1£dzʧr]^NJqZoe~|Z~W43XV32X+1fIHJLh67:gfs˂uncor~EMUUaml|ؚѩʵɩӛlG@/' "vg9~{~iyenaMxxw^Fyl}l 66xtm|cw&LL+dtjiJ4qq˚|O)xOpYpZ,,pWwT,JyIE7wt4vQ^6_ c wo K KW l j d ( d (  @l TtP K(t[ttstt/ 4Q3>t# +PPPP]w~PPPP QPQP]PQPQk# ]w~PPpp iP#\ TO ,-] ] i 4tT_`b#w #b`_ yyL Mt33V22VN (!!yrr. K0 , !! e+w TTTrryy!! !!+ @  yuw{{{s{sqvwl zz zm m`mm\ H @= = = = %%WBS qg@\LP{|@)҅%_ ``@@@%% \h<;v-;ݯ].Sg9GFXVi_d:ftl\mM>U:\!-B o-Bvˌ{bє~8w F2SXtegJ]lA9HH8QXi[syxy\HN-fXR22"E`B5 3352E%%%%W*~wwwwA.#C'K]fT O'R/+,{{a{L{{44   km +{t ?0 sw{    oT~ƣ@V 5!7EV@p -F1M \ZG#n' - ! ϼ 1-+q >P * ++EZ[spkT\ ~O@GA BHEB Bc> ----mJ#66"-!!!p[mmVJE46H``Z[|]~c`}pG;-7-m{<8Yn,=auKKvQ.-QjKs[hshs\hF:87s;\Fsh[t3]-3s\hsht[h"eE!sh\s-3~ + ** * }Mz]c.p%$fM55277<&UA++Kq5PPm;XY ;v2 ,TTT ttttk< .O8T tԁtN P * $ Fh͉yy}~a pjM M jprk5jThh i itt R*N^Ȗ* RDejok4ph4hplh/nh4nh9joqjhp4lh\ƙ;/ ;ǾbP0&M q$ ;. O ; $9 q&MsT |~}StK|}Sth =h u=h ttt*w)))((.ddZNNZZNNZQ+A@AA@![  [c `@ W0+. 4wx{0~}94l 4Wp@   &.1<@EIMWktx|#'v ")-;?DTY%=BFNRW[_~,GNY] BGKchrx%.5:]ej,27>Ft{ $*5fl   ) U l u   = H L ] d k | ) 7 I i s w * 2 C N S f n q w & , 7 = F L S Y ] b g l w -:BIPW\q ,38AHMR[bt!&4DTZbhr| #27<@EN\iw $)5AIQW_ejpv{<<T'T& "  t% M   33 0 y}}y : ( 33 ]]]]B TS  ? :  hnnh 9T KTFTKB KH K\ H T\ @  @@? ? % y}}yKy}}yTJ < K. r O8 4 , d N  (  ]]G }t ""  %%%%%% L 0 X N   +  z||z  ff m Tm Tm TT T|zf '& & t R }y J r )  1 V` +[+s/+ " @h `w _OG`E}n\>l9 , EQ |z@z||zTz||zz||zTz| @3 E  - y G~ - YQ ffD ffN~ DRRD } -! O  Z 4 ,  T tzuxu[Brlmyz~5qsU RD^ .    y}}yKy}7 1  TTM8_^X*D4 4D*Y_`t, _@ TTTT < . Bi  ^ D lnl||}_zob^^bzM zz zr^``^?a  }D}}k K$  _hnnhW   0  ~ < T. .O   yy ! ` +t!t      |z@* Tz| }t.+ݭB @3 j l  1 F 4m  6g _ c   Y nh z{ 8T(A(A(A ̍t|~}: @C ~ ~~w~ B T3 Tj fz\J$9:lA . O  ~w]]w~ z  R !!PTj ; %0  ZZ @ ~ o E l  ,, , ,   +S S T?   \xcikvss]tRatyxx h@@hh@ { HM tk G MY } ~w~~  V @ nh ttC xyots{ pttp&pt . 4 QK* _ !- ! < ) y   ` n +<< B !55! QDnty y  @$$@!  QE rrcr  r  p] w__c $  y'& OG  qt ]]Ch   !$DD$ `F B && cesz 0 hn + yy  > 4 z |z a `=db97 haahi`ah <<<< '0cGv=< !  `V  Tt y6%6- _$cX ?}|A ɽ  z P@zyz Nba] ;   @    f    c    ' f RD 3 h@  DR  60 ++P, -  EGxZny /  , _hmx     }y XtxmihbW_)   z} t $4 z T_  5!  `  qt{tsoy 333vK _gg_ &  }jii V @hh   ] ?  wkz||   g }y +: s}  ^   f    %t~  nh &m/ ofZedZd rsyy'& 4X *   ]] @   _33spyrs@  "" n@. !"""`>N^fin~'(.>N^n~>N^n~ !"""`!@P`gjp ()0@P`p!@P`p\QA0ޕR     lT  7A[_<Pt@  npv_]yn2@zZ@55 ZZ@,_@f@ @(@@@- MM- MM@@@ -b   5-8@ D@,*@  m)@@   ' D9>dU*q    R     @ e  %RE    $ k(Pv/ /: /Q /Qc    ^ [ q . [ $ [  s  * <Copyright Dave Gandy 2015. All rights reserved.FontAwesomepyrs: FontAwesome: 2012Version 4.4.1 2015Please refer to the Copyright section for the font trademark attribution notices.Fort AwesomeDave Gandyhttp://fontawesome.iohttp://fontawesome.io/license/Copyright Dave Gandy 2015. All rights reserved.FontAwesomeRegularpyrs: FontAwesome: 2012Version 4.4.1 2015Please refer to the Copyright section for the font trademark attribution notices.Fort AwesomeDave Gandyhttp://fontawesome.iohttp://fontawesome.io/license/hugo-0.68.3/examples/blog/static/fonts/fontawesome-webfont.eot000066400000000000000000002122271363637351300244550ustar00rootroot00000000000000LPj^FontAwesomeRegular$Version 4.4.1 2015&FontAwesome RegularBSGP݈YD MFx>ޝƏ)[1ɵH-A)Fٜ1fi)׺U'&a n;c)2nb$'3JV䂡@ꯔy|[\AXFCp-B̄ VܭU_^dV/Hvsrx9*cN%]72Fb-$}3*>q5N6d狲{*q%}BH$Mx{2ꎟ } d! C_ ugƒK.~Ey:G*# Ot5apOҌ) Щ?HVCi`@'@8(P@EefԌ6aGu?e$k DYyC6$FLfV2v㵦UklI&\β[/*d! l 1 D X̨ CH?d. }XBsH'_5 D3˼Pȏjmx׉ @ v{KIJVЕ4p%QH, ¾L|ݍ9@_NS%3hԳ̫G|EH oǙFzk_vȍ2&䅐ZۚII;2H!#nR5Q>YT!~JZf~ #Kiw躛jzd%>aĸ:)ˏՠפS`@`'`/>í#npib?X`_Uʃ(7W,G  H݂A vqߥKEeYbf[<',y j}G c-\\w.<=K+z>jܠ"B'kD e( DbI:Jj)ƴ=+canL/6bVHN}t/ӠvPC2!G \"" L⿅e(nWI+;\M $܎~УGu"0 X]-[Og73gfPE_4\e[m]S:ŘeћG;8Y ,3`2'5Y71ߘLL>54V9 P.VI-Ux9~Ht=%'ng < *3F'y?#[/Jsc $OeHH#F'Lq'kos!hG<Ƚ|4t1BZapq WӞ|:櫌SmGhN 糃D 1HVƵw  W鈢2?J ă0(8 ZJ!Vb;^*IQiuY`sjF T* i1@qJly$q؉Ű qX0@]0& Rw3l]yT8tyJFtiYSNmU&S2nRRUҊ[ #-?Ӹ}yw :h: HG 0 _c`pLJB"j$2c: G2ƏWobh`/%6)ύ!lܢX/ I8]^o { ]dr^O1u,4,R[T??*?Kĉլf;fާ451ЭN3V)'`P61wT,cr-MSPTX Ͳ`,Bt,9uBN0/g [\y0tSx\h)_B.F7o[~7\m𲇂;X}6ĄQ"y"A`=ZI6T'lO!k\W#{z͉%'R։ ۈ]򗌆 CѩM:>_.(4_ƃ|#*+k[2L2u$B9-4.(e5,=@B!{ZED-(%2gsLih[#ϟ>-@;:cEakJ=F2υ'D tGuMޫBz( Ca("% s2K$ﻺ^oO V{Yᵖ: 4Iя5%onm] \:DP;/ /ȸeE-w^&9:~gC 7Bnl,wkf'>>I If3^5_jB@5.@5GqH! R= O[aDgA@Tɧ7.JVxB FuHG1"* hBON8U) Em* ȩ0l lF k,!!I 3 Hn<6@Yqzk 3Ģ3)Q5H[ B hB, Zı,4Z_+C df)]F"k=Zǹi4@ᯘV`T*d7i.Ge]OZv{TmFc&pUq_ 8(z駪jD9XQѤ7, CKMo9CH2g:d]QSnj31jnHxY!l, Y`O<@Gh0 )KAʘa$̑p2HCݸzE3gs7hc<8P)1" x-%/ Ϝb|v~6^AdǑNS'>=Ba' ^ً[.kܲ[bG:ëGEKm&!<7>$CSA uvJT-=c*dX7yҵ7؟ɵJ*6Fvg=璚)N t|:'LQ\6Չ֯&lņ(nHe(3g Q` 8!,,5ށٳ81 szW/si !1;4$g3^w"JtB06pM+2xINP=&*T뽒sZ/Z-0jgYSU_s`Uc`aD>WЦv`w,A .j׍*BǐAKXml{C@LF啴5<<%v*upKI&}*lR{_ ~ʟ0ï hA/>t'u]Mڭh*x !%MVJ]e l .`4\/g߂:FM"Gqiw2'C(e3P{0R$<# -M8@"tÎRjuGk_-`,tIԺQg4c(cl̠hL8E)iݩfmm3 ʻc (\ѓ@4YM'Du` ,e|KEL~%6DUf&m@xT&wV, /' BJ"YC:-!cvkb>ۂb>{d-@WU8AڼRXXbmF2!Xt6Mۑ~B J6\] ~`x^ta4 \N,7' \7A;ҁH "fp#夶`:IDfT6p#MH4^=[!q(Surm?WQ[Э1\`Xg 13>ŲJJT *]U#թ^\ d 4eKo]D,3sb=O62QnD(5)kp_hsCⅧ‰[ԥR8 1d9)$FXˁPx!]NQSw4,IpG#(4GaQ$b86Gь8 ũc`te[9O# $2L)Nn4ګdBY.һޒG=hBxAlaRUܶ.98ЀqL<&܁jԔL.ǃ9i2 yRkҳT/131'@hc hy-)ܘЬK;(MU}NL@OHOB$gKӸMQ4T;`K7JZ(~Kkk(N0Ma%ehl$Y3H]SuO+' V{;I,SC+J("ORIV4[F> !ΛQ3a$4da?(aٺN!EgsWmo>F!Jђ4{T4A (^+42/h5"m/)E掚 c U!`S-ꄳ @Nѓe'G돂n)4VUNy(@HUJDB@NPvEW|4b!8hU}(t0CL/-7΍rwQaeª#mᥳg$:sC+Q_yGnLF@/@psXtPC;v#;?4x&q4߳ѻ2? m #QGHyM > /9j:ݼBuTkMNmWse md#3ƨSTAhqS4wCŔ ̅ P]#C, *@B(볂ܡ}=>yQ1`_g%|&,x#ΘsQZbCLS=p s<7Yv4nզIa2:;t! H/C |9iB/Jgu y`fp2ل7Iu΂s`M\s݀0˳+8 Eg;]cGؾPL%|/ȉa }T9hi Rfݻm#Jզh(7)0Oy}1v*z@(]U%6_q a(AjgE  'fN#~QlG)/-pS5}M*A,]SMCkv8O{M%7˝8,Q@8hG/Yt",Y `4D -V~p՚cA2ߝǡ4?aL ;šRkYz5=ho<8kɑS1 #(%A%(V^<#Kq?Z<8:sF<<:9iiG@GOI "%P͜#HB)2K´%T F:?ʼ?뇶II]1 P1FMHN=4QXc'ZE.eetE62 y`"CFQ#kqx9r>d=@L\H,eBE oj_U@eɏ).qe|)ϵ-Wًp-P.\D#芳w$N@ΌFBQ<8FuYV ;,ӄ!LGg+-Ohű AE<`((u *zN3b %u"nrBu Ńd |̙4\U}HYEPQ$F)ؤSCeCCmPㄊWt$A\W3R(<2s̋ST#F9ncI4URK3$M"Q- .j 5L>?-"ZG= .q `0N7 p'Š;C_s0 ѐe]Wvp"ʛFl+ ,ƏBhHnwg4>\ATRYEJ$m`"#&G2|b$Nx k8?v_oWf3 &#ӤdiHaZLr~f(:'҇wp4of`0Y'[ЄX]4V/VƲRo3Jȓz1wOfވǠbDI 3 ,sC!)}dtz)`t.=!݀O,ʞ0Պ[WOY%1tlsPN|%6;"Ry6Aaĩe cuPS,%|~ $y =[49ees*ZI&#̚]ll!E ղKqNn㈳4'IhN-Ģ z䍣K$Q^spUIN-6DlRg!@h@;%Gf 0(qL'3Z;{]gC¦?I7EiT.L_$JI}TXc~v<%RPb2O"6}uT;aGu( 3Fy =b΂UΒ(]$f*PN'@?IrS8}JPlsKuSNӐ[lPٺgf&[EkeO9KWa҈;1@Is'̊((iI>? ##o4F&Q.:.P?ۋ ʾ4}R8Kk4P)B1z;᧑Lުr_yPZRdƯ7fHºw@z`Xwe0#QhR9?MɷeoiH1*LI?/A9ݒioO;Nܹ si$(˷1"e g | V`o>7#P_W(? $p +XKz(GkGig0!R8*_*$Ƅ1{:~Ip(pوj_ҧM!!˵m:kyi㯗zѢ \T㩥VBpNfB5w\erP6ȥ?9U7k6qB~`l c+xn ^\,/f)SD=ô꒰_ݲaFp q L$1Ur8&,^he?Y_^lK{]b>(Q[>kA/*ʄ9(xKU,td !i2R= ,C&$mEBJLBy|H/%*s{zw@ tXՓ,.MtdP|_BO|mr&T~հī-`ZJId+(&ߴ*4,=gз@fFc ! =eFy3rXy?*X}X*JFݩ1z;X.,>kGX'DZG.PYYq /g,$ 0,(urSKiƔ%9PQh+/xI )ǟKfx0yM/#+s1d (bfđQuJ 6-jfƼ^R[^;tL 9d ¶ sah5,hB ;E ͢Bf<^f u#}$3 l5Xm1! /l NАj9m GAPE-d ,~pJ` w8qZaL WTTԖ ǘȘ"2YcwO벞!uπX#0C~_1VSv,u (`$cMO>$%ͰbGMP&sp0dCNVqm'Ő!72RA$˞1;lp$(0@O?FcԐɹgv3mOEe|o~X6ms'SO%vjwb`)&9H;cr(x:r:{[f(d<'ܧ ƕS+%UU|(1i9S|C PtP "Bu!3栾l뎊a >1'((ăw:@fA hW7Z`,/T# 8aeT J_1̍-ŋxH [Sy۴\TTLG:LLh,MG֧G H[c]> Olu4"8ԭ=U* <`Yf$µ.@9"}D9тq"t8k'4{F҄V_@bhCс(qlu>啢N6/YqUsi~8(By=ApYz,´\tV52y+}aB=1.XCX} 2 `V_4("4ݕJPBZ0"_O&de6@M0C1๢$ՎGMif{?^d1"lsś]R6`@[$ zQ{9Ev[: e'KJhd ƌ ٝ:,`İ$'ъ,g")~f\9\?50NT lӫ^H-(2!)}oG _}y"osZ#L(@܀fCy$~IόL e8ڞ8_[ȅ7[Y $V E[sڱE3ʌ}J'-,8X̸ 'X(d7RЧdJW)t\ޠc87ya#B^_bG[f +c+G:!C*Z:HCP [.GH4C#T _݆J cAcj4e8Z &iQQ*̀&}|UD\X儴J_NK%@6#[xsK,^ `B)8Q}fBoA6GUGFVB jQ!x3vӺk3нE 3`,tH+Y?]Sar"sĈnhEnˆ"aG!G͢%9TĢ2=H!òtVD+o~l;(O p8UbTT;Q9&˔܁*6B7o40ۙٚ Ro/?XH&J=d> YtSH.BW+FܨRR됕DRY~vms$^j¶F݇G(Xk]6X*T hslq=06\Ѳ0gk! HARL)\dD""K^5wQ1P$d_ݹa8TDl0 D+&F2%h6g Ґa`;K #ss~|KVqjTuC-fr`CX5F ?l% Q8 ;)cNH{@rt=K^)]X0Yq? wxXdLJ"\8f5_\c1H#| 7$`/ZИ ni6}$k7*ܩJphnբH5O;$m9wAN#XW9#vĨeoۮ`{p)s~mp_[d`Dw ؤ /$6?#b&eg ޒn̥PW665mfĀ.Gͬa|EHM^Pjp/$@2bk=vspt5p|Vf1 e~\DtKdPV6Ӂn:*RVR*|`82:ip7:ټx)Ѕ'%/OztB$ӅbZ=xOG1g}eQ3sp/PL',v8~ͼیp#Qla20c 2dT!'u%\;$FL :15)Ȁ"i"_:$+Yޚz?<F c+)QiY~U<@:_1#m05 bpx1C!sVrvв)& ؅(i-M,s5EiQZy L9_ɐ,mnA);~fb)@q}C^p;/AS&9:8$ Gs. K[JCoOlXro-S0CRi Y`(e{=*`@R- t:"N~0_kxcT6u%d7&C!׋Y92_9M]< -y=('ua2 Z0aW?#fhXYG7Z k1`DkAݠHJXPH"7-V+s5y]|g  xpcFL~&(/)Em0R4}t@aWSqzi~tOv&j>'Ʌt" S 5ý;tū4R,l%v=x+~ybDKo4L LB$jG*qR t$WY."ΫYxH8#C9pm9H=Snrrz>*2zS~dC3Zb=oQXj,YEHGNyc\~T6Ďj[݃/*'[QT`!@/ (,ˑ}DlH"W6̉`[ #y=6|2lM\kpkewւlS8Bp Oդ!0#F{@ciqP)2(hɑ-Gb Qh?y7EZ~ˑeGx.B6)'ajKʀ߂}R. CXc]C S)ƌM'#,S=:'`HS?u321D S hn@Gev&hU[d0֦֗9 P %@a0= 7Ơ*lLzd(!B5ϒ%-:ug|6OHQT O/= aA˔r }M<:T mN' D+alJ̋.Tl0n2M l'[̀T0XD_k▵v 8Q/sRN @("(OZjo YgjRѰ%RJz*[{dZzC"#QV@0dR!\-3H2U| /QbD:tÒJRŏG糊箊N"s9Ìp#(0?)pN%dX P[3P/[-Gr~,Q]̷5t Jnʗ ғ6jρ`L+nE{!YL_q-q;#gAYX˅X63hDNOUا`59J#&6~XM1P&`pI"3&CoAf^:ZYJƗ8ZD[ D BB lư ިB+͠V[vL dUdt mīD 1*u 3mIk[xJS"nUm/wHzzm/R. B5~v:D(*\V$8_m$0WCd(:k3=w\*싕m /{}Chb Ɣ-(<)~ 8NwV >.%pD~Aێ,<4-wPB- ~-WuBXK`( $4-~nB&Oa*8Q2z g 12Q_Dvl-DrTքᕟ~'q:5j&="%&|Y&~[,aI28DPORsFX;Da1dzf!Wi4iց,MV^#!NjʕogT8Pm'M7@vt DMbLM]QB|1 "Esl̼= r`d NJ[}𢐴&Rrx_ OIϓ%^EϾNq0DU̺= ؙ2+xxɓtO6g>t5 t&NiM!:VaA F9Ddԑ,ţiht=zD:GNr0<ņ-F5 j!ms(T W+02Ѵhd) UA~ov r\x 8nb%>/ Z]ˡ)acpRSc@>--+$c੦r%P llӺ6CCPI̿1jIxyrrabBiaOqX?C^wwC=XL Z1V!b*1 /)JPjM̘=t@rХ&[c+g NͽZšR1"6]"g#(͞ц l+hRϾ+eC!$KHuY O)nյl h<",bL՗جOuYX7˦'W\`0#ů;3`#QdSx5)"wx2>H`g><`R fَp،j.Tɯ|k^LZ]V%u;В'.ZEN`aCpq | `פLqrevuRNj-+`Z6+G D_9G'*;t8&%G=ݙȺMBL~vd+.GYT*; w+idf~{}l?6J/S9y=f4):' .Tb/6IpAa5Q8?&Ց+hyhO9D@s +W%d K9&{F#3EhT2|/גETt~aذxWi㴻e⼍*'2mۨ|Ks`4y9|T$\ Fҟ.hJMOlL7*jPwrKM%GM]\/6:}Ċ|\M"fKMdP6}ӰOD5 yհC'z`pOڀWal@=O %-EOEܘANt}MI]%7+<փ pF#hBd}M7*[ #f#56piΆqj1\:1ڂMV"'Hkr7wחnnMX! DZXrAw| _>RGܠ%К Gm1 {>%:_JeL@bԯa*)_2DǛ+R@5GRD<9,a[Cn q+1uWpS0s =x㎊B狮o+CGa'{ W+xg5t̙=8c[#֓ɸ:Ƨ YB6p,4g̓^?2 z@ FAr.fw ).*.kܘu y{oP=p֒e4I7t,## lޗe:I/4 [jDZjw"8 &?+Nͪxd%R#%Bo§Aݒ٘ ?<&,"[qR@e3L5Q|[||l44HEQ.l u`aPOlS1BX VJ 9 fJԙgFKJL䁭&߈D_0D=roܽ< MGyPKF`8ӕI ZO _ ab9j7|J~h=ů%LY-/Af b0xz.cI `7Yp,4&{M,;e tF%q"&_Y_rA m,jS{.y@ҷ:ofsp)wB_w ;@0 Rl0#/C@,Y9,]蒅l ] ٹ]Okޤ Knլ4a>Oc;oTň^Kqq8FĭEva=E`3{篅=kmgqhRI,QI[ʳլԇðC a2]jj<+,n21#"F 4/# &A _l5޳&8Xΐf3Gp]F̥J6@`1qŅ'&v*0$:WήmTs ?$SliF*-Tp9S P "ۿsiZײz`NE;d'̮.zq|/8\Cr/i =4`Yݒe0lN>z`ҕװk9V㟽ey0+~HPSMIݴ(`f}B蕬5l<]  !K 4\.`dFk!nj~ `P)TDœ&I(X(8|&V+["O+9a\~ %lz\s.GWQG3%Tno(ʑ!_`GH7UVh(cP,x m7"@:TŲ8кGGݑc+Hقs1fբTȼ5m_`R_ܗ{hP\~c7l:M"X{_=s: 8΀N]>әwtvG~7T@yWJ1P# $?7`zx`z?rL2XejiA&Т:Cd4v^.4x'J)XlId:$-cLb8:d$@?50p,Gf⛋*Fajf<@5b($W5 lsGcR]c"K<O^C&!\@b8 F|5-*5a3 ( *l(>V1UO XּC\3DŲlڐ"qfK)WDB -:DOoڝ[ ( !92vOݮU^$+ H桄mt'ACHU6=];{!I0o?V(BFb ^H2 jqF5c|r07WB}֤$6B䥌(m 0t 8,4bUm9@CpTdҝOAB+ZlȨk|*ǻsow;5,NOR ւx6q_SEiTS#"o0+h>9k;!7@Ĉ-S1rjL1k=,=N'V e 4PbRmM6Nz$2p~ֻ(:$?EHZ8yYe0恀͈e};݊J w#GќWG94˜d&ʞ.c#c~o2:b@8y&Zhs|g[Qd`yլ[̔d `[߮6,>F {L͌mZQb:qjUNL2rSAƨJȍ34`5ܯ,UrXJEethfgah%}"K- T;*"Bysݬ#@xEJAAck@L|' '۟ &~8?3e,2݇+ A:ukX2FK_!qKL~fd!ۦ65g Ub O>#CxzP(ٯ0dЕa5.x ^pjwU=1]m[zֵPq^~'@5'jNӽ`qWŦ/٪{E}:? :l|&1 >x/EX$lϤ>?aݣmec0DSpT"CYMЄ:Ѕ샂ԫEٻNM` IrI:2h]-5n԰u+ ƃCٖvҖt5 A 1ֺulAwyA6 Ty>,WŖƐ)K گYմHEc &jP`n?~  @^~Y*G ͋Cͣ!q )UX:1h$.{9&-Y`A`C8 mf/1 \r.U8Y/x / mʁ X\:* R=ˑT0ژ)Ӓ_&txU &`|-uoN3KLRtH9Z7Eaa*/'-RkO<>g8 jW@*F\! H7ҚƄd2M%2@ƖPj`P_/_MQ3phk; 5 ˚ 1 S ieՆ`YX9"basfd9]-$}(,ôE.Qbx)ǢȂ灒a-y<0[$,2%QM@ Á){!ߥR?D'`1$: H>vCʼn6,H:1Gz&+h`+ { <1z -2){-}!#]P(<>w-xبJ?0jF#DVM  3) aݨ?XO4FV}:@4GflS]{ brxĊ4ce9+W(\YiUeKu*sNx&ʱN8z IaD#U#e;MU{\h]vTa`!(mDӽH"Al= 7O&hI[Cԓ|x UV„pr?e (&Lv6 m?ۄ,)XYjռ oquupw {6d=S#;iY ~¹E0\OeTB*yZqTrP0pHP_Dg9+cuۉUeEm;a^c"8}A97D7l .e|<е"L܀JA-jCqH B`M)sg?g;`bheNWJQ_[avwtF߉pO]w{~^W ߣɋ|_] un!!im;0$Y(Ţ$`I 5rZӊb6C+f ֤ Cccx |N8:i*I3'JJg;w3S[Pq#Or!DF+Hm1,CNh<<xs"+5HH/et qr~+d8Cw(2"an1>$p K.ǘD?Tc"F8#! 6+eVp@4 XgMk)h詵2Ǥ4<2zQ9Cv?<({W'o<%'0ܮ.%_J _ś~Z([ ;M@T܏fe_ț<17XD$o"cI Q'U3%TTT^0Q))lÓ. L+A#o"!3]-R( d3fPHត̡{3!6^R WW qm~H?~י7?P"rh/8qЇ"eP<@V)F^|D0G]CqNFȪ=.}U^mX^9=b5esZCS5qtk1fh}ꤋ+k]G\g8 =u&a`%w2cK,mCvՄ )@``Td<1sw d7zz1)ȡxNpA^<-xrCJrE= 79L $Doމ?W_⽫h!'7Lq_(f9!Z*Lbmw|R[- ]Ұ* \m^@U*q2⎏g5@t`dM[l3OħCl6O[BQk";":gѨjf-.J^$rJxP52-c IoFm@,vn@ $V%{.p( ҥ:Ink[Dq.@>\v$5ͬ }pOũ~{ -ɨAt&uWUM_d +_UInjM^pSK m EA5/a/9COVcR?=R$3HA/P$f`967 & [+<.܂jFu:gWTNzZVPܕ+ͅP7V֬ Όbp~o3ӗjŒl*zAJU0U)d`DZ(a `?jKjn u!+@:3ŸG 1# s0 IO>fNMHj!6&. LyG1D`&Y3s."ɔ 6"x1I!uxE^_s74uaO#&Iyo!+ H@G@xr7ի&j`*Q٤ ({BhX*u1V<"$nN\- &b6f89w6>np鰠p>3b+*< NA7ZAhzWqЂ[dsT&ggG A8KCu 蹲"W<ܿ7R95$ $S AY[x:6C$T! ѷ9\9F4YyY50tQޓߌ1`mG7+ 5֑̠uѐr@F1lHY^4lcNwkeR'-Tk\ժ/3Ҟ<"h! ļ%=PQnnO@aN@j')ֹCCt%!ȯΫ @J9 v` l Au7ƉR^3i", RN&g2S,`Bj͚&vbKSp¬=R,f2GRd&N}@?ÆEE)!$ua F>brI&sтZ1a#3EJU,ī*PߒJ,vJ˷6-=ydJqM3 eG+Q%YwȲ$.7 VHi/}Nt&5۬ƓBҔ䩸+V4M@fk~o 5#_!I i~4>C-\ec>pnCqvvBwn HXKfwTŏSw%uc؊[OɠHf$ `!q48Vl\uUnii H3q\V ;Iqp-x"XÂ=\?$|}dz˦<*@P1=㐶hY6^qDՎ\7d)/L膄,DnV2iwJ-g@KYAl?* /=.|9ՙ  q0tu<\rdp8?]%Xe-!g zx6?庍ϧt4 ((̍_D0ۖ|Sɰ֙|܂bpGK_|ɇHmk#KG*:z5]k31O,16frt,ll*rv["~U=xUz3WNL`zAUvy5V'q|L La|:)k ,36&K)Bz׋KM1ŻSC|M2jɚ$ͤ@D[kH aVBBT4r$Mt 1e7;vSZg@tȨEG8P2f;1fq W wCl-xv\ .H$0 !XB5.^7+y1iF)V^AM=\300_~/Gŀ`7<U&m ǛI[dt[ӿx!`p 0r˹<̣[̈Rx4c[?ƹ?S%DPIR2b;"ih;F |Y4,R8YD"M5V=Ed=na:%qV0*2#>o3 r6rCڮSLJjf'܂fZ#7Q|+hYn%6 z=eXDb؈M_8 JzY 5gGN6ޯ96$;Y+MF87٩SQ70Ie$6_984z(Jd$h?!M#A f3 taos<ˤfx1+lp[ Sbӡ딀 tW""#RUr 'V=kcL2YSęNd L,U3"k<::?PҙX,l/nHa8&c}!u>!M-f=;J@7!m~3`)V.wܰx8f HgDc.".i  @ GD;)gn]g y r; ^tA uWG$zEdȷ2/6k}R*PQCT;wPđd֦b|A>?n]y@Ff "AoWZ КoNO& 6W ``zR 5ԁBWIEaU»=I1jc2ȆoKC#]?'D\dMB^|ӿ8u>;YmǀPʈuu'X<%EcV73пwAAQK Fhqm3dk'ɥa,0blMhgٻYwQ2"--zlhr y v@  z0#} X1I6 :HL D0WWYQG#1 -.1)QSE4 $-ďNFz$24ϞzNXWpDET{Y0dQ# MI,fU?O/O>pn;t{KF4A3 l ^  [ʍ[ rDZԔԮa`4_P÷&A,eW⅌Kn8605 B9w|j{d*Vj(yzQ]:u+pp*-s(x08x)o@\0vH1^Mc?>r%'3 wI" o2d2Xp 2j[NBIAm`$%pVÀ\8CD(=(σ( neF6n¡9lvё|xObH09su9mR]L˗(sxll25r <eѪbbpJ%mj>3  .»mg)FH80b9(Q}f7|%6t#]CK0̠cV@ !-rRk1rgC%&a(2r^ft3k o!Y$p۪ E#ȡo;fǰ1a e a@6+vZM 1V]H;} DO*h~ @E$w;1{r~ J6kyG9,WHvazFe%f5T%u ]'tVPth7K)%NEXR; I_ۑ V백f;FL" @ZHT-+NopŹ#I&AȓMy w'3[h"xXae:hCWW"`3T1-M܉!Y_6/l-9`C?CT{d`?IE5V"FygDRQۃ n+kz`aw-劔.Uei0 OsV0JSPޕ7 Uxz+QԬߍ`:#!5chH:F h3rsm.0-J(0RF8v~:6F:е9%@,,uH\ Z NZ.'LoZi-JF&h B\šwӝ;%'%Sښg=qGQ,N"gU>÷M1‚Ke]5l(a@`ZaX5ӄtkV od* a48dV4z1c9)À@@bZ#Xȧ+kj qaWCιzt 9TI?a GA|BwKqT%BZ~ټ;,hjWHi>DM~Vմ?ޱb'e!.#nVe|<#p#b%'=GӎŃn\ (*H.8:Eι9;LF?+Ig/y]Dz%rAZÔf\}!C*W@uղ*ɱv)Zΐ8Vn;ֆ| PT춮 oڊ^<WY%A,@DןT I`yjBW%8ՉOVG5k7n"ĐDƂFt$ M}6@3\ ˸mF3M1>|HgM6P{,ԲU%3 `{plPD$?2ɇ%@ԓ6J"$a3/|ZQ9WM ;n)# Ők)Ґ9F7I5Fql5jJJ%9BmJ89c# B6r@'37DOǢIyr6V2e>7rX9BΧ*6yFҮ,Q$_OaFwv6b=xJH:ESz܎H}41zg\D1>5{T bL^;v86Eq&zz=IΙX ta`|b#6#eUW4'2*Һ`b{S&@qJzY#g@R"SZ%f'f( DI$"@&Bc[J\UB<ekv#}=AyKK:lxځFCRsw\$ミFTٰ /Ic(4\|$^Ol~hԣcL[4ߥ i:_ $ pm5ڸxSN@P=#7jB>N|G| _o#*jcd@DŖ:K[BCSʢB@e8 +U"O`k86nKK&Wim;\ґ޷"U"rs“s5(NN3W.Ȏ @C(zQGd@̰ɖ2p$0}nwbµRr C6>]j ŏ)GJSȐD֒-nC]Ax3 cL hq'o,܊?y9]yZj\`ot$/#w a RŁdo`ɃXœ( (nBɋN+n*n mjZ X00m:: o}¤$rv7BĒB = )L1@Jj 1BV2Gjl`tlɻW {DpO쀁2]D@^/pa˓c~cH QpdiTxRWHM7꠰]"ΐUͣIcdX #v7 q:"С  U-RdB0 ?@vh#_@%ǿM0zdٍ:0.!,0Un!{HB3r5j]NףdLYQlwl|S 6N""oJ ;]x<-p%D^̦*$znF3Wz4 v۶4FOR$xIP\ÊVeeb;*IHDv_#r`!g*#"mi^i?1шs1M0&Ɏht872&eGjqi % hTE^$.CTU@(åxcw~ڨ\App6FVp5Ŷ C)BOv|gebNvdW8B+udȫ,JYQnߋU _2u?gyZ) _BشOe !J q=] ˏWP4F!R"b ҭLOL %>& pi0ѳݢvtm Mꦲb/PC@o  "`CX^MJԲIԁtPqx,pFDJ J"_3VU' qNeƳDN(L`$אq*Vo"Y_ىc *ʾ9)'j/PPkkfEedrhM)לjX('SYj<*} kiL|^laq+ tфlnq@eh^ ޾tɶǨAdfd.S8&?vhLUSsVB3G~MM-hC Qo' FY|D dl2|,S{sg0![(ؒ ;њ 7JV ϒ0+){;S݃ LcȌOMYh= #Ga$@QҌ^'@o=!ma=Ҿ7/^ WҐ;a-iĢ@GD%']K/W>CFԮd2ǩ]rW35XRX M۬&A,* a)_}t'"k :da}1?D45Ӊ` a׹ۙF =ZWY,=PKOH>5 COݻG0;)A@c!Y ގ7 Rjљ}1z>VPa 0,+=oޣQ> F 賱]M\ y腽Q;r:z7%zia&MߩR e9Ä[n9 ϕ#*{X晴ڃՆ9N`YYz%3fm$0F77`/B!V*G@Žjoc0ߘH֛C!>8 2Ơ H{rg*# ⠻Cvɘ5([ 'Pr%ii‚'F4ٽR=!9!SO$l/,Ǘ61fx7,obO!c$}K.A:e<Ot (BS;F &5G y'!Jۿ>ky3L&^-c[WG`i)nW;/aOGT^QؿU\)B ~(j)0qI nRN (vK,(+ ΕHtҞ&m,1H4D2O<1)JS@~ $L|݈*G4l!5ydoa([bT%wJ3- avN$y<khIebI4Zx.)Ù=B*=AbߏбwN q1V#_x?ip`Afw@*E|gdagC1z(ؕ̾* [4~  ~"X;phjP@-(kFFa  aGY4iDj2x4By(4gshi0ͺc މǐ1sSgߥ0 %[hp}񽄲I9VF x90_D.ut*;;zOxC}F|{BTWUMpȹ`LY ܢo_f*Mi{j-pH 1mOfV1&oK,9]ntv&0iلrC~E"OڦE88ףT< 8 ,@9jͫȴ$z=M&ŋYB|R2cs4T`b;i! 3l6$K\W7/ e Q6YaUE{KU_m'=FuBܾ6W["GRkfP&fκt/GT y ʾ)l筮!A y%ʇa e$3uQ1b |ܰN4@S۽ !iz >4AYqbZezHh/Рa FV)aFRnL'%]Q=ny0֤K4b%xс)!e%9>-;b[XV Ƌrʱ<h6$%!Ed$KT[4.DFDG9r.֌b#H+,,:q3P0[q8uQ'|(/$_YW*UyS [ K*+HCbmqSb>%51^? ˠqx% A_&ZEuBn`JFgR~/lOoAR>pvQ.? Fi⍌#?ŕ×bM҇pblU쁽YR(M? N(E4⌓뽥m[}Zmn[7Q{tA__g/rHIIG0 BQ:g[j=FAsG@G޷ᛴ=.(7foUuiƃ5qO88 Y(Y!"WlR,@+3E) `PH՗\UQFi5)/5hȄAd:奺nhw6;ʟЎZN2?o2<1Ll¾R҃aV3ԻDP:c P%`}V[O5_ uTvJFa) d gO $c9.>]?mfс;@}tC>FKό.w[3 Ǐ@dD-'hrSmx8D["15Z=6^4asM&z %lKyH5hW]q ,]G&_$=mAA3!$tc煄7Pnst 4Z\"x,oM/9WH0$pMRؙSep3ˮgZ^nB4o X*E"l }R;pEmȟ{'is<-6MrɷZk"vFxM/dPҘ.B~ /ӁD[3yf;-Wh̹.VZ9Kf QїѢY`u> ]bwC:۱^l9tŢ֬_"V7c+bjsZɐ%Xz45G/azQJ2fCWWN Ue 0<ס/2%J!4Vb t&ǚeʂϽ(vNBroG7^\J@$9!wTХ:@H\[ ͺJ*xOp5a`6rڋN9,/Lzk  a).^iKd`p4ZsC{1b}(k(_p(_*D܇>{@ B ֹX}T cU:Pc?aZ* 1P!|yc%CU|.l i*YKK{N@o^>j=ȼYW,Ӱ8g T=dg(;ϲk|1 |@ͳCkjʹ`)m}ZZB4K!-k:THtFgp.xō4[ƇQUIζ[?w2'f^Ճ괜ԆWZ1eq.@"'tAWN Ԙ?QpIBdy.;.I'0udQx8WЄJs> `nQ΂ttזQ²~Eƍ>]d&5ȳ4_Um2LϚ`2g>q\(e7&DG|}~]t84 e A[YITxo -;b]| 8`utu8WabOخf(qII>o'RM Kp>8G롖EűX1*f]IhX40.({7~d( eّпXy?AR-E{T Q׻HmFz);O<u@l?_qK f2( H> 0@G#fѱjmZ9 # \scHw&GZ%[4Mf A+mUTe:UsO& _l.OLWQJ B$t}厇TX5J2dkzŒwUSk? ǕiKm{s뷃 uqʞ,t7m5ʏj -*\\ٕE*1b%NDN" \ٲC8" FxD` NbE#PTG7vv! 5Ophqmf7W"%ccMo3p,Od8 I{֭,8?w%r6xy7֫ i2JZE@ XFaD/yF\a5̔ۏ oՠI6O~ʘBDS'ao1xuda_2^""' kI9Bm,{ҭyCRߤpX47JW] 8 B3"rtKڝ| ͸E ;l2eE- ᖌ͹G!Ki KT|mo }g$\&b\eܗ0  @~h{@(.: !dz"5w#I/J$ZA'`UT]we}Eb6b!2TcYM+;Tk˳ًT{2{F3LsWod8} U&D$t\hyJsǣ+jF< 8;FCl: 3\ǎEwS:Мj6ZJ$(' 玊Á;57y8oj?W)s:0Լ^TzŸ·HX>l sRc}?^7a#uhOhI4v}LXVZAE'`q)9GEa(_UR H움Q',xdN1lg|:h%)a^); AA-_ P9*:\c۟Qo' -F) (+ ,ɂA0xY557X#@\p|ͱ)o&^_>OFPj=S Z?ҜCYZTռLe]ʼn?SxM- K<[)x&Xj45,%ZN?ɵjSufKM.`"&Vs4(AJ3w&Ab"Xd])B۳JIv=) Isx6nVULO"0;crPP{ڠV"iRjfF3>56.qQd&qisF%^plrF2]V P/ ِdB1H`@"Mơ1~1& LG|V| b(4  P3*eB) ߾Gg?#u; |iS*WrlPhu"՚:4&r 8M%EUXCK&fA&xRV;f4K*@eDC<Z楴% ]J]v^> D1SƓ'9‹/f"cU6j"g}Ƞw~O L+.8XY ~*}Q ђq`"(P+Yt 6d4p0%#\ƒ,n _E(o9uA .ұL{|ڱBzt)PY8~t@jiKiEh*D]A%;8cTdSp+;3oa5!ZCBV,BgL \n z6k4|b3Pc4ߥz9L0xs :dc.QY`YR|QcjAgU2yA/B!B7quyXu o@ [4 XEG,PIfxuS*ƪ25YiVՎ7DS-z}'ԡh.}xS[tLRBg&=7b*:D%@-@xarPؔG,,Ȟ?OuHijdJEBKY0|`L$M䔇ڮce QR>^#٭l:A vNg2h%ӽf\;ͼ/ + dÝ~$z`_.(@IQJ6}t7Ö)=d)1#]=Ɩn)aq8P -v2 B-u!Au^@8tUӕ0 ?Na:8t\12^4k  ;}\a?>CB|%!H'Dq<+CKXD('`tdbQR# B Tb9+}/`^`G QZ fS?&tV^e2|feuI߻,GM2T j(Y."P+ FRLrE#Hp[WKw1뒷|aR\02ڈIẇB6I8o(x L)u+L"TԐtY:ҊVs0g]?NA`Ț%I8qJaGlhL~9aFz]EqJz i, #1fB7 i Kgau Zȁ^J2URp?lKH9gbltp8<&7BO?]9j)$¹^Ő<ER 1_=uJ$H.`GjMo>켗d [bX^!s=H:A ؝n5қ \ۢZY Bkg~m2u\97 xڢ@R˛!S O88L(ָE$Xy)qT^& &V4?bTewfQlŵuI4rTDʿ$Q l %J20lr`gIITl<%l.97֎zyB'qYq'i4ԊS{@d֌7NRkdT/ߍ`#Qt64?m׀uHؚ6Yԇj|3ٗ=bl&ɶhƖ94AW(>}i"y nY|53X1\cVki(KlGMa@]A7T nц/_{Gg _7g2M`+zƑض H~*~(+Jή:Ax ^?F[GdJP<ߪ=)|+#Ц9'_[z9 &$T|S_;Qy&X |H1%%:N8sQ\[fȭ(Qh]HIŃ(Y1WՂ3id[Es=e0_ĀL[{, 8%GnqI)!cL@+IImY"|v.'=b3Yᮄ1++a@,1j…Cwء=#\8-R'@,\Sǝu7ƛ ^_*q)ƧM8<=B蟝:JV^d.HV Iۮ2[mA!,QV=-[33irtDaa!ƽR#,fD'eF kӹƦ6P2DmQP킶>vrE-`%vY2Gv# ֜f <h}'mDaOC+YyEa۳(#AhU Jz$37-J&p$ӛ@`XQLSYMzLjx6.={ 5V;l{ UjA`q [ cކ[ 8"lG!ՅKOY*Ph\m܏ITR&݉;{N[d=>>Yv'^0@"nag7*"LQYGg!驨.$0PȉJբH4ӷ5oTʅ 7iArw-+r4HLEݭy|wJe-=| ߴE#SS G(fhû.-k0Y \ݝƘ)D<,~vl8:Da0k5;|]?:؍fӧZn y'ƌU0i:.Xᖪoz+U49 YF2X̌ ;I\7$BآnۅkqHݑ2wW`t2UIT m9`M'Ljk^b< JԽ u8|"G5_qG \A|Gmk1W<\*>>` `"эK8( qܢrU'p ZhO%T|o0Va17*[%ABC¤ X8YJP!f @_ndi;g=@HN_PUc]d0N\E#MB'*9X=z"P=K-K KXs܎/4~]BKqܞࢠ\ӟxsZF5QD:i䈦:-1P %8R>KT` "9a8SfH6eKg?AAJX[P7R'{頝$ǐ?n%׍cDяE!~Z!IVw/}0*`y3̰s|߾b@j"hL)ϙBWݱWMpל8Vomks VpŹ{$p#i {HAB%0%P׾2ZJkX|7)!IN[4#KjneUZ2=i ,,e`y9,-R\"e];XYgL0+Dn;lg6E{ Ф{;\av'mQT{}QAԾqIQ}A'qq&ݔF;F{#2aPOE!;n4t UvBP9G] 1fnH9h&IX :c@wr"IQF@-{\ $yB7fk/O`Kd%Gi>Z]QT,"%llC YFF\-M_nK۴^yB? Yl<|`oK$󱝎v+C$̘zgCe疤T$(sYӫ̌ :|v?~Kʏ}ȸJF^","ǏJʰzh5EU{V#ibxGTؐINؕmy9]qEwI 55^BzJRfHZY;, gqDޙX mCn5f|3.xFs֖Z$mOgwƠr(4ba_Z{Apl eZܥ gUHF.%tT[D8~*PO9i aWCo,16ԗӾAx2{>ͩ_f\HkEo7;8L`ZASe1bՐ%`;$D#4>\aL G)FzAy'4.2ST 5Yn̚US-;qysn2aSTƓeȄ6;+jx`Z%k.*vܣqكP6Uϫθi<)^n%;&ʠ;k^`.(w:Dk|D̬q9NXnOjAH1 S黸r56]9ҽ/+3b(bypfz,vA}x.ŸF[)E7]+?MȮl6iCDHǒ@kR 9k4MJt'ƐS80kdQ Oܩ&ZO íFax{+HZ+@8=|OvxF?tށx?.~fA>E?9Uݱm'?2҂UNZ ]%dR/@ټ:腾) A9/gun} {%9Jˡ SIK: H@)t=*9II:G&KfGnqHǃ{s]bl^|^݊Z%6̙Ovq9 xJЕ ,n-\0`'$CCSfK+@&L㞇*Ax%$Cbx0nAp/oaIJt"7P%̓k90rۉcśÔͬ#`CVUaIf Eaf шXU]/L20"RAr1#-nW5sdۭHU"W:2yD'4䉈IUȦ$E$b5!P.[nGx*O 8ْ_/Q_,iV ƺn6AW)ǯ%D|Lk&mb…e8 r$8*Sx0ak!IF qi عUHP-08J42%E0U%eht/{Ij|'iP#+y .&o=HLgJlr M^ON WY*}叼񜶉^\2 \C?[u111&Gރ? "44DC ˚͸ؒRl|й{*8GMN/@4fJҊx$f_JǓIJ A n,΁AIOtP#8w0cıYŧsyoSe@P1q 63 w?NP L%^% *ר|$]àČy%6#w)#¹dP~&"cL9* -vt%Wa8zQ o8qܬykɇl V?bтSK4Ga'Rj:_\;h? }·Q2GgZ pf~wװ AmKz xN( uHmI+b0L>M:IR]_нRj xFkѫACmA&EpkVHOdq˙~oZiG;*ؕ(yXQ0Bo:j{Aҟg/ZA3bjȴ:@؏SKKkrܖ*&dm-#QI7FSr{.;x Dnt44NP:Xx` foYPV!(1Hyg55ՠQB+9MHa @zr&j:ɓ;š]F`B_I IsoVE"9ǂaW}0ua;/_n_HI䜾QAI"# hKcn|Sƿ$)O}Pcgjfhɒ~''QeS^>Ha}@Zѭ ג ??( UԆPNg|G{!%gD`6<'B1>5e1 u*)l_ᲔYlz(E42:iQb܍" "BO(<& !vL8E䉩6ψ+'+"_o]yisٺ7l=B?}P `}pm-cnKBMQpȂrEGUk MaoK>LH 2(0NZɐ Tg74;9]Mdz03v̭я/LA5 )}+0k Y/Q#ءZڵxydDG61l4^%yo qS٪"Hc\Oâl랦GS[.6f^kMz${z7} F]8 dXC׏"(# N S qh6ih@-94P[/ޜO{կMqְ}{2V.|*w9f}9v+g ec:wIiˬd J4yaB1Bo9ftE<%ngܝJ`q/,;O39&T8c=L)OMw AQ6U6 SH *:q0ڃ_ Bk١س_P Mk.msx`r,M p1lc;$: o7 PUq*x^cp֨.-<N:OzP3,Ԑٙ8Răl4!h^,&]hLlܷaͬL¨%c* : 2PPY 8IkGRKPE AgB&6 J )mxC"p%-4b*X8auWjPQf!V⬔Ç֡5ČEɔ7XyqjRNHw݄!64#p㴆t)(,nm>86$6PH8{ 1:9V9+\Rcbt '-! BGNLTȝ K̪f[s2L=A!0HZ m:\P;ۑZ zW=r&yjtEuB/R~8iaᖺ..wK" "Qr(D]g&4# U>V›&)j7lqF%|Gd'rP8VĩYawIȀ|G-~fHJ6-*%J@ K`H ] qׯC|q d[)ى%&?L`/+ QQ6Ics[:Uv&{ɯ@ 81&$mKg ^얨2D \KfnO?~݈NeJmZўL5E@ϺfK2 ꚳ^hl94 CoG=%mzfYA{ ٵ)n=n׷ۜo"gƪb\KٌlNXd\p"0앶x-pDaݷ,$Fȴ#H̷͢ėEE0̯mړ,غLE^d.戇|YD"BAZXFǚEYg1%-T,4no 4aTT(?%Dl<0 iֳC`~Hsr*7\*Tɘ4TT;pA0/XjQDNa.bE# T& l)veS.[$:ב@|=QdkToNh7r0>%m2cܛĖ)u‚aio"Sx[qw-}i`$rspl:  0NoDeHwIANS.:<֖j7WN yd b7ߋQ Q0|yuO;3]9@+mj$m~Lۄ4C0D;ugzZT߫UqF*AD%q!) )6.KjTusm*S7r:;'~ >;Ʈ7s*Ի+h0h~ DT-cU'Hl5<MG)LjiAAT%ȫX3f2&-<eGjEʇ5L^^XwY>):(kw&`mEMgH`N"$_m5;N(Zgh#SgS:3iAs4 V;QP"2Ǘ%cCw5M1/.xJspJ.(?@af6J"P1)+a뗶uEf>PZ1URJ"xp@~-Ѯ޻gb>d1<Jg+ƣM/Ƅ(Iy'ZtY*`XK h ٠ .\5wΈ:' Jt6-VI#1uZ_f7<-v||$Qi5#2: Zl-­JDM/ ;ń tn6N?>r΃N,=A?}i;a!?;^TF$ VXA;1M7olj#}74m})gM HԹճrE})K%iWH_nQsz%7gr[N z3²{S)Z_+%ܚRDWfXJKQca(t h~%?"o#ɻFaR\wN؏Zh $U\Tw=.D $$j]#[KW;L3Iq( <_ Uuw,^p>fNB'd7wx:#zYautxP22w iwgܾE^oHfC|Wڸ|vm> p‰$uf nkI&qrrdlѽ>n]w{2'6ɰ<< iALdC9+*o|}A5 a y?Y>ߐ ,>_^*xBm557 j6)yDxi`~= >}"/i%}d{'yLdQ$c[ f 6jT-!.'V5& K }&3OGm 2 =L!s,D=l$$72wI0sr;u/, 6!%9%rC~e†b SU!Y`2G-CE5d=kCkOc F'mZMW>g;ídD3×M8&7/!$FYf{H2tTk2R4[4%x0q~I+zYSab4e a8p![€]3Ƞj tTuRdVv=\5KWΰC-UҾe<[m#{&䪧6("J4W0}lYZShݳI]ڎWZSчC74xFUzq5$NUT ZDADBM閍U@s&1[7PCH<xkM i|85GhFW\那= ߀Q 9Pל8u'r4eqjwˊbD%$ k9lݯ1t0xj4Nr]V( q-e%qV *i@Ơ׺? F1HţE]ZbY}դ,0y3|L NXW>EKHFJ޷"^DB3pV|pjHA`~crip&69]'?H|)*sjbPO֑9F ;</w|s[v3=U!֗f8[߿)]uִʼnz GZ&;Z,Ұlyy!W4,.j6[dgc_{aX{>8wf]k0@ؗg˴@D}"rvwqTSHie`+c;i7qg( "u1\* A>]إUڂbRRkJՋ] -vTQ.>WPPE hT[rF3k2W lƹEC 2T&`~7V , Ki )˵Żs°KD8;oaN1 _@JW_pVԝkHHP,>q4&"1\-ftq4ìyq1hk[j܃ZN\! b}33-OOYBfZ6߲B cۅ&c0ό+`p_1n6QEZp9Ŵ&^%YYl!g|bIܱ$;'R yAL&/{֮`&(=׸Vxu8n0~EҦo7"]U6O"vk$%%-~{}`+Ml3ڟa%!b`q<-//BhIဝK&6l$זZ\ P:?fWr1ާMh2P@[Ԧ08_P D@jl'o5LD"Aj53~"ښ*+R]M@eDlK@!b8q`ty!:Ir@*zS: (U6BZsM魼t*s kcKQt\%9qSbwFf3K8 }Eٍ`.OPJKPWhz0]Dj0XAdwѫwf9!IȲ6'VVppI7U?JH-- ßw2g,a 5L`epVBr[%zUu .n(=&[X?}߯$8ѻB2LI6{G) luэúLc/H0A'ɹ L|DH-8:d(|fk#BJ![;>{k]~Cy+z>c'kT֔`d@0`Y0vJ:7^'؉G,05?иJ Xz%:|'O[*t>fX$ ~YP(pgN3_.P!`T"Hhɼ쏒D")5 Gi湁/IX>y8pAփGGp郆 6f(#A J3iHQ#,F#0+݊.*TAo )LP@"! *8Uqa♅{ )@ThBE' y^$B@Gb%tI(a=fD&HHA="AD*K 懿 M:h?a [  z6 z M T ~ ol `2т HUhrpt (IA  $4x ` qp@NGp .dPGu_bo>O ?|_cۿZ*w?ɟ7]gVx_3zYꯣ>>}b/k=C޾aҮü&vWKɯf9S&yqhok56x&][<'mտKt&- ;&v mlm~Ǜo`k#UB9 EgP^e{u[nyn+Lf:+a.. G!\e󌋍ƍ@wQvY"uTQ+dPv@!c&w`fuO(Fjh0 9aU&Yb$je}AcLWt; ]g2I<ㅀ?#fQ+H<^2l:.BacӈB,Q^G靲`aϱƣ9ˊQcPveK?pN%00,2ȟ}M}KB )MGtigPvab/ *Z H5RE0uG[89p/f]҅-: d)#l'~'U(6-(j0`TtӤpƣǗ^X* 8rbkL!n3χ~F30Ne/~D)x5P@o30|GymB¡(@k~.aFnP! _{+f@'}}b 2ÕtdFDKg8m6E鎕yWZ" EaLk(zCq0vu&OPŖ!uƶK5ƐMٳ&F{I=X;+ʂ_3M:#㑎\=ߘ4h"_?HVÚ7xxi" (mŢsN Jz7W$[~-yHNq@"uStav½ MiYb,z1hb-"I~%xK6%F=~dPMKC|^HDjM>XihH]r%f-%lYVW|vEby[I[_TxVXMLTau<0K!'[¬ -I(u먶t-E"iMK{BNx-"s)gzP5Ea9)*OZxp;LvHcxk.T >ZR1ǐ) tM,7zW4RSCeT`6SŲlFdN2,ob'z\&* D騊MCe|=<9r(RUV:J֗8J$fЗV8һ$wثu@[JxыJ~Q9;a``)wF3I4元_ q1Q2?뛉9'b|:P6A@Y8iǚxQZgaMW4x(]W'鉐11PCF([*.EA^S+ _x:b`T@ـ`$SE:".'W#+I;<6d-O3Bseٸ\%8t< .?^pz4Nhdlxr\nF=/^Fhݺy~66įMtܝ8Ŵs`lH&jׂgŘQ 4#ɫۈ9aElGh B3* N|4 roHY࿂BJjJŭGW*QCUy$&mZ`- Pi9m+Wð$(@X ǒ~$#yMEHvMp'a8 O'gk\J[4faI \Dž'T`0;K`?PQU$ Y,:aCˍi6c 2Ev٩gpb"ΞX-2]B՝ATYi^U` ^)Bbzm| & )jJlOQq$SΡe=E=Q#> baJw]v8g{`QOQBK /I[+&̓"R|x» _S}x آ|RD|f1 1{?S@0A?TӕrxDgNo|錼8NnF A 8V c#t} N%-_ "гhϼݿ_dG<3|{ y 0.< `i^ @JtR{,ݯ|lס WHahcY{r՜V#!IaqZ7וU00DlBݢȬ[l٬[E`V*_rU8!^QPXVXR|*e%f ZJxPr,|-|p@^y>4,ʅ MTAG =鱃0rPj `:D''\ !4߅'g|櫪X@.ʋZ~qAbӑ'T0'=Cy!uDݸ|s2ف|5~UmLQ% j4ǁt5 ([L=ަZisTG/`#Zhrr>$'[@pq-3cVEĝdgwe7p԰p[ hugo-0.68.3/examples/blog/static/fonts/fontawesome-webfont.ttf000066400000000000000000004253701363637351300244700ustar00rootroot00000000000000`FFTMjo)GDEF OS/2Yz(`cmapmgasp|glyf,q,head U6hhea [$hmtx)* locaiV maxp( name3FHpost7cA webf*VO*=Pu>G33spyrs@ # p@0 / _!"""`%>N^n~.>N^n~>N^n~ / _!"""`%!@P`p 0@P`p!@P`pd]YTC2 ߸ݺ  p7!!!@pp p1]!2#!"&463!&54>3!2+@&&&&@+$(($F#+&4&&4&x+#+".4>32".4>32467632DhgZghDDhg-iWDhgZghDDhg-iW&@ (8 2N++NdN+';2N++NdN+'3 8!  #"'#"$&6$ rL46$܏ooo|W%r4L&V|oooܳ%=M%+".'&%&'3!26<.#!";2>767>7#!"&5463!2 %3@m00m@3%    @ :"7..7":6]^B@B^^BB^ $΄+0110+$ (   t1%%1+`B^^B@B^^"'.54632>324 #LoP$$Po>Z$_dC+I@$$@I+"#"'%#"&547&547%62V??V8<8y   b% I))9I  + % %#"'%#"&547&547%62q2ZZ2IzyV)??V8<8)>~>[   2 b% I))9I '%#!"&54>322>32 &6 yy 6Fe= BSSB =eF6 >xx5eud_C(+5++5+(C_due> /?O_o54&+";2654&+";2654&+";264&#!"3!2654&+";2654&+";264&#!"3!2654&+";2654&+";2654&+";267#!"&5463!2&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&^BB^^B@B^@&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&B^^B@B^^/?#!"&5463!2#!"&5463!2#!"&5463!2#!"&5463!2L44LL44LL44LL44LL44LL44LL44LL44L4LL44LL4LL44LL4LL44LL4LL44LL /?O_o#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!28((88(@(88((88(@(88((88(@(88((88(@(88((88(@(88((88(@(88((88(@(88((88(@(88((88(@(8 (88((88(88((88(88((88(88((88(88((88(88((88(88((88(88((88(88((88/?O_#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!28((88(@(88((88(@(88(@(88((88((88(@(88(@(88((88(@(88((8 (88((88(88((88(88((88(88((88(88((88(88((88y"/&4?62 62,PP&PP,jPn#$"' "/&47 &4?62 62 PP&P&&P&P&P&&P&P#+D++"&=#"&=46;546;232  #"'#"$&6$   @    @  rK56$܏ooo|W@    @   rjK&V|oooܳ0#!"&=463!2  #"'#"$&6$   @ rK56$܏ooo|W@  @ rjK&V|oooܳ)5 $&54762>54&'.7>"&5462zz+i *bkQнQkb* j*LhLLhLzzBm +*i JyhQQhyJ i*+ mJ4LL44LL/?O%+"&=46;2%+"&546;2%+"&546;2+"&546;2+"&546;2`r@@r@@n4&"2#"/+"&/&'#"'&'&547>7&/.=46?67&'&547>3267676;27632Ԗ #H  ,/ 1)  ~'H  (C  ,/ 1)  $H ԖԖm 6%2X  % l2 k r6 [21 ..9Q $ k2 k w3 [20/;Cg+"&546;2+"&546;2+"&546;2!3!2>!'&'!+#!"&5#"&=463!7>3!2!2@@@@@@@`0 o`^BB^`5FN(@(NF5 @@@L%%Ju  @LSyuS@%44%f5#!!!"&5465 7#"' '&/&6762546;2&&??>  LL >  X   &&&AJ A J Wh##!"&5463!2!&'&!"&5!(8((88((`x c`(8`((88(@(8(D 9 8( ,#!"&=46;46;2.  6 $$ @(r^aa@@`(_^aa2NC5.+";26#!26'.#!"3!"547>3!";26/.#!2W  .@   @.$S   S$@   9I   I6>  >%=$4&"2$4&"2#!"&5463!2?!2"'&763!463!2!2&4&&4&&4&&48(@(88(ч::(8@6@*&&*4&&4&&4&&4& (88(@(8888)@)'&&@$0"'&76;46;232  >& $$ `  (r^aa` @`2(^aa$0++"&5#"&54762  >& $$ ^ ?  @(r^aa` ? (^aa #!.'!!!%#!"&547>3!2<<<_@`&& 5@5 @  &&>=(""='#"'&5476.  6 $$   ! (r^aaJ %%(_^aa3#!"'&?&#"3267672#"$&6$3276&@*hQQhwI mʬzzk)'@&('QнQh_   z8zoe$G!"$'"&5463!23267676;2#!"&4?&#"+"&=!2762@hk4&&&GaF * &@&ɆF * Ak4&nf&&&4BHrd@&&4rd  Moe&/?O_o+"&=46;25+"&=46;25+"&=46;2#!"&=463!25#!"&=463!25#!"&=463!24&#!"3!26#!"&5463!2 @  @  @  @  @  @  @    @    @    @   ^B@B^^BB^`@  @ @  @ @  @ @  @ @  @ @  @ 3@  MB^^B@B^^!54&"#!"&546;54 32@Ԗ@8(@(88( p (8jj(88(@(88@7+"&5&5462#".#"#"&5476763232>32@@ @ @KjKך=}\I&:k~&26]S &H&  &H5KKut,4, & x:;*4*&K#+"&546;227654$ >3546;2+"&="&/&546$ <X@@Gv"DװD"vG@@X<4L41!Sk @ G< _bb_ 4.54632&4&&M4&UF &""""& F&M&&M&%.D.%G-Ik"'!"&5463!62#"&54>4.54632#"&54767>4&'&'&54632#"&547>7676'&'.'&54632&4&&M4&UF &""""& FU &'8JSSJ8'&  &'.${{$.'& &M&&M&%.D.%7;&'66'&;4[&$ [2[ $&[  #/37#5#5!#5!!!!!!!#5!#5!5##!35!!! #'+/37;?3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3#3???? ^>>~??????~??~??^??^^? ^??4&"2#"'.5463!2KjKKjv%'45%5&5L45&% jKKjK@5%%%%54L5&6'k54&"2#"'.5463!2#"&'654'.#32KjKKjv%'45%5&5L45&%%'4$.%%5&55&% jKKjK@5%%%%54L5&6'45%%%54'&55&6' yTdt#!"&'&74676&7>7>76&7>7>76&7>7>76&7>7>63!2#!"3!2676'3!26?6&#!"3!26?6&#!"g(sAeM ,*$/ !'& JP$G] x6,& `   h `   "9Hv@WkNC<.  &k& ( "$p" . #u&#  %!' pJvwEF#  @   @  2#"' #"'.546763!''!0#GG$/!''! 8""8  X! 8" "8  <)!!#"&=!4&"27+#!"&=#"&546;463!232(8&4&&4 8(@(8 qO@8((`(@Oq8(&4&&4&@` (88( Oq (8(`(q!)2"&42#!"&546;7>3!2  Ijjjj3e55e3gr`Ijjjj1GG1rP2327&7>7;"&#"4?2>54.'%3"&#"#ժ!9&WB03& K5!)V?@L' >R>e;&L::%P>vO 'h N_":- &+# : ' +a%3 4'.#"32>54.#"7>7><5'./6$3232#"&#"+JBx)EB_I:I*CRzb3:dtB2P$ $5.3b[F|\8!-T>5Fu\,,jn OrB,7676'5.'732>7"#"&#&#"$ zj=N!}:0e%  y + tD3~U'#B4 # g  '2 %/!: T bRU,7}%2"/&6;#"&?62+326323!2>?23&'.'.#"&"$#"#&=>764=464.'&#"&'!~:~!PP!~:~!P6 ,,$$% *'  c2N  ($"LA23Yl !x!*%%%% pP,T NE Q7^oH!+( 3  *Ueeu  wga32632$?23&'.5&'&#"&"5$#"#&=>7>4&54&54>.'&#"&'2#".465!#".'&47>32!4&4>Q6 ,,Faw!*' =~Pl*  ($"LA23Yl  )!* <7@@7<  <7@@7<  pP,T MF Q747ƢHoH!+( 3  tJHQ6  wh',686,'$##$',686,'$##$/?%#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2&&&&&&&&&&&&&&&&&&&&f&&&&f&&&&f&&&&/?%#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2&&&&&&&&&&&&&&&&&&&&f&&&&f&&&&f&&&&/?%#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2&&&&&&&&&&&&&&&&&&&&f&&&&f&&&&f&&&&/?%#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2&&&&&&&&&&&&&&&&&&&&f&&&&f&&&&f&&&&/?O_o%+"&=46;2+"&=46;2+"&=46;2#!"&=463!2+"&=46;2#!"&=463!2#!"&=463!2#!"&=463!2        @     @   @   @   s  s    s    s  s  /?O#"'&47632#!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2     @     @   @  @          s  s  s  /?O#"&54632 #!"&=463!2#!"&=463!2#!"&=463!2#!"&=463!2`      @     @   @  @     @   s  s  s  #"'#!"&5463!2632' mw@www '*wwww."&462!5 !"3!2654&#!"&5463!2pppp@  @ ^BB^^B@B^ppp@@  @    @B^^BB^^k%!7'34#"3276' !7632k[[v  6`%`$65&%[[k `5%&&'4&"2"&'&54 Ԗ!?H?!,,ԖԖmF!&&!Fm,%" $$ ^aa`@^aa-4'.'&"26% 547>7>2"KjKXQqYn 243nYqQ$!+!77!+!$5KK,ԑ ]""]ً 9>H7'3&7#!"&5463!2'&#!"3!26=4?6 !762xtt`  ^Qwww@?6 1B^^B@B^ @(` `\\\P`tt8`  ^Ͼww@w 1^BB^^B~ @` \ \P+Z#!"&5463!12+"3!26=47676#"'&=# #"'.54>;547632www M8 pB^^B@B^ 'sw- 9*##;Noj' #ww@w "^BB^^B  *  "g`81T`PSA:'*4/D#!"&5463!2#"'&#!"3!26=4?632"'&4?62 62www@?6 1 B^^B@B^ @ BRnBBn^ww@w 1 ^BB^^B @ BnnBC"&=!32"'&46;!"'&4762!#"&4762+!54624&&4&&44&&4&&44&&44&&4&&44&&6'&'+"&546;267: &&&& s @  Z&&&&Z +6'&''&'+"&546;267667: : &&&&  s @  :  Z&&&&Z  : z6'&''&47667S::s @  : 4 : | &546h!!0a   $#!"&5463!2#!"&5463!2&&&&&&&&@&&&&&&&&#!"&5463!2&&&&@&&&&&54646&5-:s  :  :4:  +&5464646;2+"&5&5-&&&&:s  :  : &&&& :  &54646;2+"&5-&&&&s  : &&&&  62#!"&!"&5463!24 @ &&&&-:&&&& "'&476244444Zf "/&47 &4?62S44444#/54&#!4&+"!"3!;265!26 $$ &&&&&&&&@^aa@&&&&&&&&+^aa54&#!"3!26 $$ &&&&@^aa@&&&&+^aa+74/7654/&#"'&#"32?32?6 $$ }ZZZZ^aaZZZZ^aa#4/&"'&"327> $$ [4h4[j^aa"ZiZJ^aa:F%54&+";264.#"32767632;265467>$ $$ oW  5!"40K(0?i+! ":^aaXRd D4!&.uC$=1/J=^aa.:%54&+4&#!";#"3!2654&+";26 $$ ```^aa^aa/_#"&=46;.'+"&=32+546;2>++"&=.'#"&=46;>7546;232m&&m l&&l m&&m l&&ls&%&&%&&%&&%&&&l m&&m l&&l m&&m ,&%&&%&&%&&%&#/;"/"/&4?'&4?627626.  6 $$ I     ͒(r^aaɒ    (_^aa , "'&4?6262.  6 $$ Z4f44fz(r^aaZ&4ff4(_^aa "4'32>&#" $&6$  WoɒV󇥔 zzz8YW˼[?zz:zz@5K #!#"'&547632!2A4@%&&K%54'u%%&54&K&&4A5K$l$L%%%54'&&J&j&K5K #"/&47!"&=463!&4?632%u'43'K&&%@4AA4&&K&45&%@6%u%%K&j&%K55K&$l$K&&u#5K@!#"'+"&5"/&547632K%K&56$K55K$l$K&&#76%%53'K&&%@4AA4&&K&45&%%u'5K"#"'&54?63246;2632K%u'45%u&&J'45%&L44L&%54'K%5%t%%$65&K%%4LL4@&%%K',"&5#"#"'.'547!34624&bqb>#  5&44& 6Uue7D#  "dž&/#!"&546262"/"/&47'&463!2 &@&&4L  r&4  r L&& 4&&&L rI@& r  L4&& s/"/"/&47'&463!2#!"&546262&4  r L&& &@&&4L  r@@& r  L4&& 4&&&L r##!+"&5!"&=463!46;2!28(`8((8`(88(8((8(8 (8`(88(8((8(88(`8#!"&=463!28(@(88((8 (88((88z5'%+"&5&/&67-.?>46;2%6.@g.L44L.g@. .@g. L44L .g@.g.n.4LL43.n.gg.n.34LL4͙.n.g -  $54&+";264'&+";26/a^    ^aa fm  @ J%55!;263'&#"$4&#"32+#!"&5#"&5463!"&46327632#!2$$8~+(888(+}(`8((8`]]k==k]]8,8e8P88P8`(88(@MMO4&#"327>76$32#"'.#"#".'.54>54&'&54>7>7>32&z&^&./+>*>J> Wm7' '"''? &4&c&^|h_bml/J@L@ #M6:D 35sҟw$ '% ' \t3#!"&=463!2'.54>54''  @ 1O``O1CZZ71O``O1BZZ7@  @ N]SHH[3`)TtbN]SHH[3^)Tt!1&' 547 $4&#"2654632 '&476 ==嘅}(zVl''ٌ@uhyyhu9(}VzD##D# =CU%7.5474&#"2654632%#"'&547.'&476!27632#76$7&'7+NWb=嘧}(zVi\j1  z,X Y[6 $!%'FuJiys?_9ɍ?kyhun(}Vz YF  KA؉La  02-F"@Qsp@_!3%54&+";264'&+";26#!"&'&7>2    #%;"";%#`,@L 5 `   `  L`4LH` `   a 5 L@ #37;?Os!!!!%!!!!%!!!!!!!!%!!4&+";26!!%!!!!74&+";26%#!"&546;546;2!546;232 `@ `@ @@ @ @  @  @  @  @ L44LL4^B@B^^B@B^4L  @@@@    @@   @@    M4LL44L`B^^B``B^^B`L7q.+"&=46;2#"&=".'673!54632#"&=!"+"&=46;2>767>3!546327>7&54>$32dFK1A  0) L.٫C58.H(Ye#3C $=463!22>=463!2#!"&5463!2#!"&5463!2H&&/7#"&463!2!2LhLLhLhLLh! &&&&& &4hLLhLLhLLhL%z< 0&4&& )17&4& &&#!"&5463!2!2\@\\@\\@\\\\ W*#!"&547>3!2!"4&5463!2!2W+B"5P+B@"5^=\@\ \H#t3G#3G:_Ht\\ @+32"'&46;#"&4762&&4&&44&&44&&4@"&=!"'&4762!54624&&44&&44&&4&& !!!3!!0@67&#".'&'#"'#"'32>54'6#!"&5463!28ADAE=\W{O[/5dI kDtpČe1?*w@www (M& B{Wta28r=Ku?RZ^GwT -@www$2+37#546375&#"#3!"&5463ww/Dz?swww@wS88 ww#'.>4&#"26546326"&462!5!&  !5!!=!!%#!"&5463!2B^8(Ԗ>@|K55KK55K^B(8ԖԖ€>v5KK55KKHG4&"&#"2654'32#".'#"'#"&54$327.54632@pp)*Pppp)*Pb '"+`N*(a;2̓c`." b PTY9ppP*)pppP*)b ".`(*Nͣ2ͣ`+"' b MRZB4&"24&"264&"26#"/+"&/&'#"'&547>7&/.=46?67&'&547>3267676;27632#"&'"'#"'&547&'&=4767&547>32626?2#"&'"'#"'&547&'&=4767&547>32626?2ԖLhLKjKLhLKjK "8w s%(  ")v  >  "8x s"+  ")v  <  3zLLz3 3>8L3)x3 3zLLz3 3>8L3)x3 ԖԖ4LL45KK54LL45KK #)0C wZ l/ Y N,& #)0C vZl. Y L0"qG^^Gqq$ ]G)FqqG^^Gqq$ ]G)Fq%O#"'#"&'&4>7>7.546$ '&'&'# '32$7>54'VZ|$2 $ |E~E<| $ 2$|ZV:(t}X(  &%(Hw쉉xH(%& (XZT\MKG<m$4&"24&#!4654&#+32;254'>4'654&'>7+"&'&#!"&5463!6767>763232&4&&4N2`@`%)7&,$)' %/0Ӄy#5 +1 &<$]`{t5KK5$e:1&+'3TF0h4&&4&3M:;b^v+D2 5#$IIJ 2E=\$YJ!$MCeM-+(K55KK5y*%Au]c=p4&"24&'>54'64&'654&+"+322654&5!267+#"'.'&'&'!"&5463!27>;2&4&&4+ 5#bW0/% ')$,&7)%`@``2Nh0##T3'"( 0;e$5KK5 tip<& 1&4&&4&#\=E2 JIURI$#5 2D+v^b;:M2gc]vDEA%!bSV2MK55K(,,MeCM$!J@#"&547&547%6@?V8 b% I)94.""'." 67"'.54632>32+C`\hxeH>Hexh\`C+ED4 #LoP$$Po>Q|I.3MCCM3.I|Q/Z$_dC+I@$$@I+ (@%#!"&5463!2#!"3!:"&5!"&5463!462 ww@  B^^B  4&@&&&4 `  ww   ^B@B^ 24& && &%573#7.";2634&#"35#347>32#!"&5463!2FtIG9;HIxI<,tԩw@wwwz4DD43EEueB&#1s@www .4&"26#!+"'!"&5463"&463!2#2&S3 Ll&c4LL44LL4c@& &{LhLLhL'?#!"&5463!2#!"3!26546;2"/"/&47'&463!2www@B^^B@B^@&4t  r &&`ww@w@^BB^^B@R&t r  4&&@"&5!"&5463!462 #!"&54&>3!2654&#!*.54&>3!24&@&&&4 sw  @B^^B  @w4& && &3@w   ^BB^    I&5!%5!>732#!"&=4632654&'&'.=463!5463!2!2JJSq*5&=CKuuKC=&5*q͍S8( ^B@B^ (8`N`Ѣ΀GtO6)"M36J[E@@E[J63M")6OtG(8`B^^B`8%-3%'&76'&76''&76'&76'&6#5436&76+".=4'>54'6'&&"."&'./"?+"&5463!2  2  5    z<: Ʃw 49[aA)O%-j'&]]5r,%O)@a[9( 0BA; + >HCwww  5 /)  u    @wa-6OUyU[q ( - q[UyUP6$C +) (  8&/ &ww'?$4&"2$4&"2#!"&5463!3!267!2#!#!"&5!"'&762&4&&4&&4&&48(@(88(c==c(8*&&*6&4&&4&&4&&4& (88(@(88HH88`(@&&('@1d4&'.54654'&#"#"&#"32632327>7#"&#"#"&54654&54>76763232632   N<;+gC8A`1a99gw|98aIe$IVNz<:LQJ  ,-[% 061I()W,$-7,oIX()oζA;=N0 eTZ  (O#".'&'&'&'.54767>3232>32 e^\3@P bMO0# 382W# & 9C9 Lĉ" 82<*9FF(W283 #0OMb P@3\^e FF9*<28 "L 9C9 & #!"3!2654&#!"&5463!2`B^^B@B^^ީwww@w^BB^^B@B^ww@w#!72#"' #"'.546763YY !''!0#GG$/!''!&UUjZ 8""8  X! 8" "8 EU4'./.#"#".'.'.54>54.'.#"32676#!"&5463!2G55 :8 c7 )1)  05.D <90)$9w@wwwW + AB 7c  )$+ -.1 9$)0< D.59@www,T1# '327.'327.=.547&54632676TC_LҬ#+i!+*pDNBN,y[`m`%i]hbEm}a u&,SXK &$f9s? _#"!#!#!54632V<%'ЭHH (ںR&=4'>54'6'&&"."&'./"?'&54$ 49[aA)O%-j'&]]5r,%O)@a[9( 0BA; + >HCaaoMa-6OUyU[q ( - q[UyUP6$C +) (  8&/ &fMa%+"&54&"32#!"&5463!54 &@&Ԗ`(88(@(88(r&&jj8((88(@(8#'+2#!"&5463"!54&#265!375!35!B^^BB^^B   `^B@B^^BB^  ` !="&462+"&'&'.=476;+"&'&$'.=476; pppp$!$qr % }#ߺppp!E$ rqܢ# % ֻ!)?"&462"&4624&#!"3!26!.#!"#!"&547>3!2/B//B//B//B @   2^B@B^\77\aB//B//B//B/@    ~B^^B@2^5BB52.42##%&'.67#"&=463! 25KK5L4_u:B&1/&.- zB^^B4LvyKjK4L[!^k'!A3;):2*547&5462;U gIv0ZZ0L4@Ԗ@4L2RX='8P8'=XR U;Ig0,3lb??bl34LjjL4*\(88(\}I/#"/'&/'&?'&'&?'&76?'&7676767676` (5 )0 ) *) 0) 5(  (5 )0 )))) 0) 5( *) 0) 5(  )5 )0 )**) 0) 5)  )5 )0 )*5h$4&"24&#!4>54&#"+323254'>4'654&'!267+#"'&#!"&5463!2>767>32!2&4&&4N2$YGB (HGEG HQ#5K4Li!<;5KK5 A# ("/?&}vh4&&4&3M95S+C=,@QQ9@@IJ 2E=L5i>9eME;K55K J7R>@#zD<7?s%3#".'.'&'&'.#"!"3!32>$4&"2#!"#"&?&547&'#"&5463!&546323!2` #A<(H(GY$2NL4K5#aWTƾh&4&&4K5;=!ihv}&?/"( #A  5K2*!Q@.'!&=C+S59M34L=E2 JI UR@@&4&&4&5K;ELf9>igR7J K5h4&"24#"."&#"4&#"".#"!54>7#!"&54.'&'.5463246326326&4&&4IJ 2E=L43M95S+C=,@QQ9@@E;K55K J7R>@#zD9eMZ4&&4&<#5K4LN2$YGB (HGEG HV;5KK5 A# ("/?&}vhi!<4<p4.=!32>332653272673264&"2/#"'#"&5#"&54>767>5463!2@@2*! Q@.'!&=C+S59M34L.9E2 JI UR&4&&4&Lf6Aig6Jy#@>R7J K55K;E@TƾH #A<(H(GY$2NL4K#5#a=4&&4&D=ihv}&?/"( #A  5KK5;+54&#!764/&"2?64/!26 $$ & [6[[j6[&^aa@&4[[6[[6&+^aa+4/&"!"3!277$ $$ [6[ &&[6j[ ^aae6[j[6&&4[j[^aa+4''&"2?;2652?$ $$ [6[[6&&4[^aaf6j[[6[ &&[^aa+4/&"4&+"'&"2? $$ [6&&4[j[6[j^aad6[&& [6[[j^aa   $2>767676&67>?&'4&'.'.'."#&6'&6&'3.'.&'&'&&'&6'&>567>#7>7636''&'&&'.'"6&'6'..'/"&'&76.'7>767&.'"76.7"7"#76'&'.'2#22676767765'4.6326&'.'&'"'>7>&&'.54>'>7>67&'&#674&7767>&/45'.67>76'27".#6'>776'>7647>?6#76'6&'676'&67.'&'6.'.#&'.&6'&.5/a^D&"      4   $!   #          .0"Y +  !       $     "  +       Α      ^aa                        P   ' -( # * $  "  !     * !   (         $      2 ~/$4&"2 #"/&547#"32>32&4&&4V%54'j&&'/덹:,{ &4&&4&V%%l$65&b'Cr! " k[G +;%!5!!5!!5!#!"&5463!2#!"&5463!2#!"&5463!2&&&&&&&&&&&&@&&&&&&&&&&&&{#"'&5&763!2{' **)*)'/!5!#!"&5!3!26=#!5!463!5463!2!2^B@B^&@&`^B`8(@(8`B^ B^^B&&B^(88(^G 76#!"'&? #!"&5476 #"'&5463!2 '&763!2#"'c)'&@**@&('c (&*cc*&' *@&('c'(&*cc*&('c'(&@*19AS[#"&532327#!"&54>322>32"&462 &6 +&'654'32>32"&462QgRp|Kx;CByy 6Fe= BPPB =eF6 ԖV>!pRgQBC;xK|Ԗ{QNa*+%xx5eud_C(+5++5+(C_due2ԖԖ>NQ{u%+*jԖԖp!Ci4/&#"#".'32?64/&#"327.546326#"/&547'#"/&4?632632(* 8( !)(A(')* 8( !USxySSXXVzxTTUSxySSXXVzxT@(  (8 *(('( (8 SSUSx{VXXTTSSUSx{VXXT#!"5467&5432632t,Ԟ;F`j)6,>jK?s !%#!"&7#"&463!2+!'5#8EjjE8@&&&&@XYY&4&&4&qDS%q%N\jx2"&4#"'#"'&7>76326?'&'#"'.'&676326326&'&#"32>'&#"3254?''74&&4&l NnbSVZ bRSD zz DSRb)+USbn \.2Q\dJ'.2Q\dJ.Q2.'Jd\Q2.'Jd`!O` ` &4&&4r$#@B10M5TNT{L5T II T5L;l'OT4M01B@#$*3;$*3;;3*$;3*$: $/ @@Qq`@"%3<2#!"&5!"&5467>3!263! !!#!!46!#!(88(@(8(8(`((8D<++<8(`(8(`8(@(88( 8((`(8((<`(8(``(8||?%#"'&54632#"'&#"32654'&#"#"'&54632|udqܟs] = OfjL?R@T?"& > f?rRX=Edudsq = _MjiL?T@R?E& f > =XRr?b!1E)!34&'.##!"&5#3463!24&+";26#!"&5463!2 08((88(@(8  8((88((`(1  `(88((88(@  `(88(@(8(`#!"&5463!2w@www`@www/%#!"&=463!2#!"&=463!2#!"&=463!2&&&&&&&&&&&&&&&&&&&&&&&&@'7G$"&462"&462#!"&=463!2"&462#!"&=463!2#!"&=463!2ppppppp @   ppp @    @   Рpppppp  ppp    <L\l|#"'732654'>75"##5!!&54>54&#"'>3235#!"&=463!2!5346=#'73#!"&=463!2#!"&=463!2}mQjB919+i1$AjM_3</BB/.#U_:IdDRE @  k*Gj @   @   TP\BX-@8 C)5Xs J@$3T4+,:;39SG2S.7<  vcc)( %Ll}    5e2#!"&=463%&'&5476!2/&'&#"!#"/&'&=4'&?5732767654'&@02uBo  T25XzrDCBBEh:%)0%HPIP{rQ9f#-+>;I@KM-/Q"@@@#-a[ $&P{<8[;:XICC>.'5oe71#.0(  l0&%,"J&9%$<=DTIcs&/6323276727#"327676767654./&'&'737#"'&'&'&54'&54&#!"3!260% <4"VRt8<@< -#=XYhW8+0$"+dTLx-'I&JKkmuw<=V@!X@ v '|N;!/!$8:IObV;C#V  &   ( mL.A:9 !./KLwPM$@@ /?O_o%54&#!"3!2654&#!"3!2654&#!"3!2654&#!"3!2654&#!"3!2654&#!"3!2654&#!"3!2654&#!"3!2654&#!"3!26#!"&5463!2@@@@@@@@@^BB^^B@B^NB^^B@B^^#+3 '$"/&4762%/?/?/?/?%k*66bbbb|<<<bbbbbbbb%k66Ƒbbb<<<<^bbbbbb@M$4&"2!#"4&"2&#"&5!"&5#".54634&>?>;5463!2LhLLh LhLLhL! 'ԖԖ@' !&  ?&&LhLLhL hLLhL jjjj &@6/" &&J#"'676732>54.#"7>76'&54632#"&7>54&#"&54$ ok; -j=yhwi[+PM 3ѩk=J%62>VcaaQ^ ]G"'9r~:`}Ch 0=Z٤W=#uY2BrUI1^Fk[|aL2#!67673254.#"67676'&54632#"&7>54&#"#"&5463ww+U ,iXբW<"uW1AqSH1bdww'74'!3#"&46327&#"326%35#5##33#!"&5463!20U6cc\=hlࠥYmmnnnnw@wwww&46#Ȏ;edwnnnnn@www ]#/#"$&6$3 &#"32>7!5!%##5#5353Еttu{zz{SZC` cot*tq||.EXN#?? ,<!5##673#$".4>2"&5!#2!46#!"&5463!2rM* *M~~M**M~~M*jjj&&&&`P%挐|NN||NN|*jjjj@&&&&@ "'&463!2@4@&Z4@4&@ #!"&4762&&4Z4&&4@@ "'&4762&4@4&@&4&@ "&5462@@4&&44@&&@ 3!!%!!26#!"&5463!2`m` ^BB^^B@B^  `@B^^BB^^@ "'&463!2#!"&4762@4@&&&&44@4&Z4&&4@ "'&463!2@4@&4@4&@ #!"&4762&&4Z4&&4@:#!"&5;2>76%6+".'&$'.5463!2^B@B^,9j9Gv33vG9H9+bI\ A+=66=+A [">nSMA_:B^^B1&c*/11/*{'VO3@/$$/@*?Nh^l+!+"&5462!4&#"!/!#>32]_gTRdgdQV?U I*Gg?!2IbbIJaaiwE3300 084#"$'&6?6332>4.#"#!"&54766$32z䜬m IwhQQhbF*@&('kz   _hQнQGB'(&*eoz(q!#"'&547"'#"'&54>7632&4762.547>32#".'632%k'45%&+~(  (h  &  \(  (  &  ~+54'k%5%l%%l$65+~  &  (  (\  &  h(  (~+%'!)19K4&"24&"26.676&$4&"24&"24&"2#!"'&46$ KjKKj KjKKje2.e<^P,bKjKKjKjKKj KjKKj##LlLKjKKjK jKKjK~-M7>7&54$ LhяW.{+9E=cQdFK1A  0) pJ2`[Q?l&٫C58.H(Y':d 6?32$64&$ #"'#"&'&4>7>7.546'&'&'# '32$7>54'Yj`a#",5NK ~EVZ|$2 $ |: $ 2$|ZV:(t}hfR88T h̲X(  &%(Hw(%& (XZT\MKG{x|!#"'.7#"'&7>3!2%632u  j H{(e 9 1bU#!"&546;5!32#!"&546;5!32#!"&546;5463!5#"&5463!2+!2328((88(``(88((88(``(88((88(`L4`(88(@(88(`4L`(8 (88(@(88((88(@(88((88(@(84L8(@(88((8L48OY"&546226562#"'.#"#"'.'."#"'.'.#"#"&5476$32&"5462И&4&NdN!>! 1X:Dx+  +ww+  +xD:X1 -U !*,*&4&hh&&2NN2D &  ..J< $$ 767#"&'"&547&547&547.'&54>2l4  2cKEooED ) ) Dg-;</- ?.P^P.? -/<;-gYY  .2 L4H|O--O|HeO , , Oeq1Ls26%%4.2,44,2.4%%62sL1qcqAAq4#!#"'&547632!2#"&=!"&=463!54632  @  `     ` ?`   @  @  !    54&+4&+"#"276#!"5467&5432632   `  _ v,Ԝ;G_j)``    _ ԟ7 ,>jL>54'&";;265326#!"5467&5432632    v,Ԝ;G_j) `   `7 ,>jL>X`$"&462#!"&54>72654&'547 7"2654'54622654'54&'46.' &6 &4&&4&yy %:hD:FppG9Fj 8P8 LhL 8P8 E; Dh:% >4&&4&}yyD~s[4Dd=PppP=d>hh>@jY*(88(*Y4LL4Y*(88(*YDw" A4*[s~>M4&"27 $=.54632>32#"' 65#"&4632632 65.5462&4&&4G9& <#5KK5!!5KK5#< &ܤ9Gpp&4&&4&@>buោؐ&$KjKnjjKjK$&jjb>Ppp %!5!#"&5463!!35463!2+32@\\8(@(8\@@\\@\(88(\@ 34#"&54"3#!"&5!"&5>547&5462;U gI@L4@Ԗ@4L2RX='8P8'=XR U;Ig04LjjL4*\(88(\@"4&+32!#!"&+#!"&5463!2pP@@Pjj@@\@\&0pj \\&-B+"&5.5462265462265462+"&5#"&5463!2G9L44L9G&4&&4&&4&&4&&4&L44L &=d4LL4 d=&&`&&&&`&&&&4LL4  &#3CS#!"&5463!2!&'&!"&5!463!2#!"&52#!"&=4632#!"&=463(8((88((`x c`(8@@@`((88(@(8(D 9 8(`@@@@@/?O_o-=%+"&=46;25+"&=46;2+"&=46;2%+"&=46;2+"&=46;2%+"&=46;2%+"&=46;2%+"&=46;2+"&=46;2%+"&=46;2%+"&=46;2%+"&=46;2+"&=46;2%+"&=46;2%+"&=46;2+"&=46;2%+"&=46;2+"&=46;2!!!5463!2#!"&5463!2 @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @ &&&&@  @ @  @  @  @ @  @ @  @ @  @ @  @ @  @ @  @ @  @ @  @ @  @ @  @ @  @ @  @ @  @ @  @  @  @   `&&&& /?O_o%+"&=46;25+"&=46;2+"&=46;2%+"&=46;2+"&=46;2%+"&=46;2%+"&=46;2+"&=46;2%+"&=46;2+"&=46;2!!#!"&=!!5463!24&+"#54&+";26=3;26%#!"&5463!463!2!2 @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @  @ 8(@(8 @  @  @  @  @ &&&@8((8@&@  @ @  @  @  @ @  @ @  @ @  @ @  @ @  @ @  @  @  @  (88(  @  ``   `` -&&& (88(&@<c$4&"2!#4&"254&+54&+"#";;26=326+"&5!"&5#"&46346?>;463!2KjKKjKjKKj&ԖԖ&&@&&KjKKjK jKKjK .&jjjj&4&@@&&#'1?I54&+54&+"#";;26=326!5!#"&5463!!35463!2+32 \\8(@(8\ \\@\(88(\: #32+53##'53535'575#5#5733#5;2+3@E&&`@@` `@@`&&E%@`@ @ @      @ :#@!3!57#"&5'7!7!K5@   @5K@@@ #3%4&+"!4&+";265!;26#!"&5463!2&&&&&&&&w@www&&@&&&&@&&@www#354&#!4&+"!"3!;265!26#!"&5463!2&&&&&@&&@&w@www@&@&&&&&&@&:@www-M3)$"'&4762 "'&4762 s 2  .   2 w 2  .   2 w 2    2  ww  2    2  ww M3)"/&47 &4?62"/&47 &4?62S .  2 w 2   .  2 w 2  M . 2    2 .  . 2    2 .M3S)$"' "/&4762"' "/&47623 2  ww  2    2  ww  2    2 w 2   .v 2 w 2   .M3s)"'&4?62 62"'&4?62 623 .  . 2    2 .  . 2    2 .   2 w 2v .   2 w 2-Ms3 "'&4762s w 2  .   2 ww  2    2 MS3"/&47 &4?62S .  2 w 2  M . 2    2 .M 3S"' "/&47623 2  ww  2   m 2 w 2   .M-3s"'&4?62 623 .  . 2    2- .   2 w 2/4&#!"3!26#!#!"&54>5!"&5463!2  @ ^B && B^^B@B^ @  MB^%Q= &&& $$ (r^aa(^aa!C#!"&54>;2+";2#!"&54>;2+";2pPPpQh@&&@j8(PppPPpQh@&&@j8(Pp@PppPhQ&&j (8pPPppPhQ&&j (8p!C+"&=46;26=4&+"&5463!2+"&=46;26=4&+"&5463!2Qh@&&@j8(PppPPpQh@&&@j8(PppPPp@hQ&&j (8pPPppP@hQ&&j (8pPPpp@@ #+3;G$#"&5462"&462"&462#"&462"&462"&462"&462#"&54632K54LKj=KjKKjKjKKjL45KKjK<^^^KjKKjppp\]]\jKL45KjKKjKujKKjK4LKjKK^^^jKKjKpppr]]\  $$ ^aaQ^aa,#"&5465654.+"'&47623   #>bqb&44&ɢ5"  #D7euU6 &4&m 1X".4>2".4>24&#""'&#";2>#".'&547&5472632>3=T==T==T==T=v)GG+v@bRRb@=&\Nj!>3lkik3hPTDDTPTDDTPTDDTPTDD|x xXK--K|Mp<# )>dA{RXtfOT# RNftWQ,%4&#!"&=4&#!"3!26#!"&5463!2!28(@(88((88((8\@\\@\\(88(@(88(@(88@\\\\ u'E4#!"3!2676%!54&#!"&=4&#!">#!"&5463!2!2325([5@(\&8((88((8,9.+C\\@\ \6Z]#+#,k(88(@(88(;5E>:5E\\\ \1. $4@"&'&676267>"&462"&462.  > $$ n%%/02 KjKKjKKjKKjKfff^aayy/PccP/jKKjKKjKKjKffff@^aa$4@&'."'.7>2"&462"&462.  > $$ n20/%7KjKKjKKjKKjKfff^aa3/PccP/y jKKjKKjKKjKffff@^aa +7#!"&463!2"&462"&462.  > $$ &&&&KjKKjKKjKKjKfff^aa4&&4&jKKjKKjKKjKffff@^aa#+3C54&+54&+"#";;26=3264&"24&"2$#"'##"3!2@@KjKKjKKjKKjKܒ,gjKKjKKjKKjKXԀ,, #/;GS_kw+"=4;27+"=4;2'+"=4;2#!"=43!2%+"=4;2'+"=4;2+"=4;2'+"=4;2+"=4;2+"=4;2+"=4;2+"=4;2+"=4;54;2!#!"&5463!2`````````````````````p`K55KK55Kp`````````````````````````5KK55KK@*V#"'.#"63232+"&5.5462#"/.#"#"'&547>32327676R?d^7ac77,9xm#@#KjK# ڗXF@Fp:f_ #WIpp&3z h[ 17q%q#::#5KKu't#!X: %#+=&>7p @ *2Fr56565'5&'. #"32325#"'+"&5.5462#"/.#"#"'&547>32327676@ͳ8 2.,#,fk*1x-!#@#KjK# ڗXF@Fp:f_ #WIpp&3z e`vo8t-  :5 [*#::#5KKu't#!X: %#+=&>7p  3$ "/&47 &4?62#!"&=463!2I.  2 w 2   -@). 2    2 . -@@-S$9%"'&4762  /.7> "/&47 &4?62i2  .   2 w E > u > .  2 w 2   2    2  ww !   h. 2    2 . ;#"'&476#"'&7'.'#"'&476' )'s "+5+@ա' )'F*4*Er4M:}}8 GO *4*~ (-/' #"'%#"&7&67%632B;>< V??V --C4 <B=cB5 !% %!b 7I))9I7 #"'.5!".67632y( #  ##@,( )8! !++"&=!"&5#"&=46;546;2!76232-SSS  SS``  K$4&"24&"24&"27"&5467.546267>5.5462 8P88P88P88P8P88P4,DS,4pp4,,4pp4,6d7AL*',4ppP88P8P88P8HP88P8`4Y&+(>EY4PppP4Y4Y4PppP4Y%*54&#"#"/.7!2<'G,')7N;2]=A+#H  0PRH6^;<T%-S#:/*@Z}   >h.%#!"&=46;#"&=463!232#!"&=463!2&&&@@&&&@&&&&&&&&&&&&f&&&&b#!"&=463!2#!"&'&63!2&&&&''%@% &&&&&&&&k"G%#/&'#!53#5!36?!#!'&54>54&#"'6763235 Ź}4NZN4;)3.i%Sin1KXL7觧* #& *@jC?.>!&1' \%Awc8^;:+54&#"'6763235 Ź}4NZN4;)3.i%PlnEcdJ觧* #& *-@jC?.>!&1' \%AwcBiC:D'P%! #!"&'&6763!2P &:&? &:&?5"K,)""K,)h#".#""#"&54>54&#"#"'./"'"5327654.54632326732>32YO)I-D%n  "h.=T#)#lQTv%.%P_ % %_P%.%vUPl#)#T=@/#,-91P+R[Ql#)#|'' 59%D-I)OY[R+P19-,##,-91P+R[YO)I-D%95%_P%.%v'3!2#!"&463!5&=462 =462 &546 &&&&&4&r&4&@&4&&4&G݀&&&&f s CK&=462 #"'32=462!2#!"&463!5&'"/&4762%4632e*&4&i76`al&4&&&&&}n  R   R zfOego&&5`3&&&4&&4& D R   R zv"!676"'.5463!2@@w^Cct~5  5~tcC&&@?JV|RIIR|V&&#G!!%4&+";26%4&+";26%#!"&546;546;2!546;232@@@@L44LL4^B@B^^B@B^4L  N4LL44L`B^^B``B^^B`LL4&"2%#"'%.5!#!"&54675#"#"'.7>7&5462!467%632&4&&4  @ o&&}c ;pG=(  8Ai8^^.   &4&&4&` ` fs&& jo/;J!# 2 KAE*,B^^B! ` $ -4&"2#"/&7#"/&767%676$!28P88PQr @ U @ {`PTP88P8P`  @U @rQ!6'&+!!!!2Ѥ 8̙e;<*@8 !GGGQII %764' 64/&"2 $$ f3f4:4^aaf4334f:4:^aa %64'&" 2 $$ :4f3f4F^aa4f44f^aa 764'&"27 2 $$ f:4:f4334^aaf4:4f3^aa %64/&" &"2 $$ -f44f4^aa4f3f4:w^aa@7!!/#35%!'!%j/d jg2|855dc b @! !%!!7!FG)DH:&H dS)U4&"2#"/ $'#"'&5463!2#"&=46;5.546232+>7'&763!2&4&&4f ]wq4qw] `dC&&:FԖF:&&Cd`4&&4& ]] `d[}&&"uFjjFu"&&y}[d#2#!"&546;4 +"&54&" (88(@(88( r&@&Ԗ8((88(@(8@&&jj'3"&462&    .  > $$ Ԗ>aX,fff^aaԖԖa>TX,,~ffff@^aa/+"&=46;2+"&=46;2+"&=46;28((88((88((88((88((88((8 (88((88((88((88((88((88/+"&=46;2+"&=46;2+"&=46;28((88((88((88((88((88((8 (88((88(88((88(88((885E$4&"2%&'&;26%&.$'&;276#!"&5463!2KjKKj   f  \ w@wwwjKKjK"H   ܚ  f   @www   $64'&327/a^ ! ^aaJ@%% 65/ 64'&"2 "/64&"'&476227<ij6j6u%k%~8p8}%%%k%}8p8~%<@% %% !232"'&76;!"/&76  ($>( J &% $%64/&"'&"2#!"&5463!2ff4-4ff4fw@wwwf4f-f4@www/#5#5'&76 764/&"%#!"&5463!248` # \P\w@www4`8  #@  `\P\`@www)4&#!"273276#!"&5463!2& *f4 'w@www`&')4f*@www%5 64'&"3276'7>332#!"&5463!2`'(wƒa8! ,j.( &w@www`4`*'?_`ze<  bw4/*@www-.  6 $$  (r^aaO(_^aa -"'&763!24&#!"3!26#!"&5463!2yB(( @   w@www]#@##   @ @www -#!"'&7624&#!"3!26#!"&5463!2y((@B@u @   w@www###@  @ @www -'&54764&#!"3!26#!"&5463!2@@####@w@wwwB((@@www`%#"'#"&=46;&7#"&=46;632/.#"!2#!!2#!32>?6#  !"'?_  BCbCaf\ + ~2   }0$  q 90r p r%D p u?#!"&=46;#"&=46;54632'.#"!2#!!546;2D a__ g *`-Uh1    ߫}   $^L  4b+"&=.'&?676032654.'.5467546;2'.#"ǟ B{PDg q%%Q{%P46'-N/B).ĝ 9kC< Q 7>W*_x*%K./58`7E%_ ,-3  cVO2")#,)9;J) "!* #VD,'#/&>AX>++"''&=46;267!"&=463!&+"&=463!2+32Ԫ$   pU9ӑ @/*f o  VRfq f=SE!#"&5!"&=463!5!"&=46;&76;2>76;232#!!2#![       % )   "  Jg Uh BW&WX hU g 84&#!!2#!!2#!+"&=#"&=46;5#"&=46;463!2j@jo g|@~vv u n#467!!3'##467!++"'#+"&'#"&=46;'#"&=46;&76;2!6;2!6;232+32QKt# #FNQo!"դѧ !mY Zga~bm] [o"U+, @h h@@X hh @83H\#5"'#"&+73273&#&+5275363534."#22>4.#2>ut 3NtRP*Ho2 Lo@!R(Ozh=,GID2F 8PuE>.'%&TeQ,jm{+>R{?jJrL6V @`7>wmR1q uWei/rr :Vr" $7V4&#"326#"'&76;46;232!5346=#'73#"'&'73267##"&54632BX;4>ID2F +>R{8PuE>.'%&TeQ,jm{?jJrL6 @`rr :Vr3>wmR1q uWei@ \%4&#"326#!"&5463!2+".'&'.5467>767>7>7632!2&%%&&&& &7.' :@$LBWM{#&$h1D!  .I/! Nr&&%%&&&&V?, L=8=9%pEL+%%r@W!<%*',<2(<&L,"r@ \#"&546324&#!"3!26%#!#"'.'.'&'.'.546767>;&%%&&&& &i7qN !/I.  !D1h$&#{MWBL$@: '.&&%%&&&&=XNr%(M&<(2<,'*%<!W@r%%+LEp%9=8=L  +=\d%54#"327354"%###5#5#"'&53327#"'#3632#"'&=4762#3274645"=424'.'&!  7>76#'#3%54'&#"32763##"'&5#327#!"&5463!2BBPJNC'%! B? )#!CC $)  54f"@@ B+,A  A+&+A  ZK35N # J!1331CCC $)w@www2"33FYF~(-&"o4*)$(* (&;;&&:LA3  8334S,;;,WT+<<+T;(\g7x:&&::&&<r%-@www  +=[c}#"'632#542%35!33!3##"'&5#327%54'&#"5#353276%5##"=354'&#"32767654"2 '.'&547>76 3#&'&'3#"'&=47632%#5#"'&53327''RZZ:kid YYY .06 62+YY-06 R[!.'CD''EH$VVX::Y X;:Y fyd/%jG%EC&&CE%O[52. [$C-D..D^^* ly1%=^I86i077S 3 $EWgO%33%OO%35 EEFWt;PP;pt;PP;pqJgTFQ%33&PP%33%R 7>%3!+}{'+"&72'&76;2+"'66;2U &  ( P *'eJ."-dZ-n -'74'&+";27&+";276'56#!"&5463!2~} 7e  ۩w@www"  $Q #'!# @www/4'&327$ '.'.4>7>76 "!!jG~GkjGGk[J@&& @lAIddIAllAIddIA@ '5557 ,VWQV.RW=?l%l`~0  !#!#%777 5! R!!XCCfff݀# `,{{{`/?%##"547#3!264&#"3254&+";267#!"&5463!2R܂#-$䵀((((tQQttQvQtn?D~|D?x##))((QttQvQtt2#!"&54634&"2$4&"2ww@ww||||||w@www||||||| !3 37! $$ n6^55^h ^aaM1^aaP *Cg'.676.7>.'$7>&'.'&'? 7%&'.'.'>767$/u5'&$I7ob?K\[zH,1+.@\7':Yi4&67&'&676'.'>7646&' '7>6'&'&7>7#!"&5463!2PR$++'TJXj7-FC',,&C ."!$28 h /" +p^&+3$ i0(w@www+.i6=Bn \C1XR:#"'jj 8Q.cAj57!? "0D$4" P[ & 2@wwwD"%.5#5>7>;!!76PYhpN!HrD0M C0N#>8\xx: W]oW-X45/%'#.5!5!#"37>#!"&5463!2p>,;$4 5eD+WcEw@wwwK()F ,VhV^9tjA0/@www@#"'&76;46;23   &  ++"&5#"&7632  ^  c  & @#!'&5476!2 &  ^  b '&=!"&=463!546  &    q&8#"'&#"#"5476323276326767q'T1[VA=QQ3qpHih"-bfGw^44O#A?66%CKJA}} !"䒐""A$@C3^q|z=KK?6 lk)  %!%!VVuuu^-m5w}n~7M[264&"264&"2"&546+"&=##"&5'#"&5!467'&766276#"&54632    *<;V<<O@-K<&4'>&4.'.'.'.'.'&6&'.'.6767645.'#.'6&'&7676"&'&627>76'&7>'&'&'&'&766'.7>7676>76&6763>6&'&232.'.6'4.?4.'&#>7626'.'&#"'.'.'&676.67>7>5'&7>.'&'&'&7>7>767&'&67636'.'&67>7>.'.67 \ U7  J#!W! '  " ';%  k )"    '   /7*   I ,6 *&"!   O6* O $.( *.'  .x,  $CN      * 8   7%&&_f& ",VL,G$3@@$+ "  V5 3"  ""#dA++ y0D- %&n 4P'A5j$9E#"c7Y 6" & 8Z(;=I50 ' !!e  R   "+0n?t(-z.'< >R$A"24B@( ~ 9B9, *$        < > ?0D9f?Ae  .(;1.D 4H&.Ct iY% *  7      J  <    W 0%$  ""I! *  D  ,4A'4J" .0f6D4pZ{+*D_wqi;W1G("% %T7F}AG!1#%  JG 3  '.2>Vb%&#'32&'!>?>'&' &>"6&#">&'>26 $$ *b6~#= XP2{&%gx| .W)oOLOsEzG< CK}E $MFD<5+ z^aa$MWM 1>]|YY^D եA<KmE6<" @9I5*^aa>^4./.543232654.#"#".#"32>#"'#"$&547&54632632':XM1h*+D($,/9p`DoC&JV;267676&#!"&=463!267 #!"'&5463!26%8#! &&Z"M>2! ^I 7LRx_@>MN""`=&&*%I},  L7_jj9/%4&#!"3!264&#!"3!26#!"&5463!2  &&&&&&&&19#"'#++"&5#"&5475##"&54763!2"&4628(3- &B..B& -3(8IggI`(8+Ue&.BB.&+8(kk`%-"&5#"&5#"&5#"&5463!2"&4628P8@B\B@B\B@8P8pPPp@`(88(`p.BB.0.BB.(88(Pppͺ!%>&'&#"'.$ $$ ^/(V=$<;$=V).X^aaJ`"(("`J^aa,I4."2>%'%"/'&5%&'&?'&767%476762%6[՛[[՛o ܴ   $ $ " $ $  ՛[[՛[[5` ^ ^ 2` `2 ^ ^ ` 1%#"$54732$%#"$&546$76327668ʴhf킐&^zs,!V[vn) 6<ׂf{z}))Ns3(@ +4&#!"3!2#!"&5463!2#!"&5463!2@&&&f&&&&@&&&&4&&4&@&&&&&&&& `BH+"/##"./#"'.?&5#"&46;'&462!76232!46 `&C6@Bb03eI;:&&&4L4&F Z4&w4) '' 5r&4&&4&&4}G3#&/.#./.'&4?63%27>'./&'&7676>767>?>%6})N @2*&@P9A #sGq] #lh<* 46+(  < 5R5"*>%"/ +[>hy  K !/Ui%6&'&676&'&6'.7>%.$76$% $.5476$6?62'.76&&'&676%.76&'..676#"NDQt -okQ//jo_  %&JՂYJA-.-- 9\DtT+X?*<UW3' 26$>>W0 {"F!"E    ^f`$"_]\<`F`FDh>CwlsJ@ ;=?s  :i_^{8+?` ) O`s2RDE58/Kr #"'>7&4$&5mī"#̵$5$"^^W=acE*czk./"&4636$7.'>67.'>65.67>&/>z X^hc^O<q+f$H^XbVS!rȇr?5GD_RV@-FbV=3! G84&3Im<$/6X_D'=NUTL;2KPwtPt=  &ռ ,J~S/#NL,8JsF);??1zIEJpqDIPZXSF6[?5:NR=;.&1 +!"&=!!%!5463!2sQ9Qs***sQNQsBUw wUBFHCCTww%1#"&=!"&=463!54632.  6 $$     ` ?(r^aa    (_^aa%1#!#"'&47632!2.  6 $$   @  ` (r^aa  ?  @  (_^aa/#"'&476324&#!"3!26#!"&5463!2&@& @   w@www& @B@ &  @ @www"&462  >& $$ Ԗ*(r^aaԖԖ (^aa]6#"$54732>%#"'!"&'&7>32'!!!2f:лѪz~u: ((%`V6B^hD%i(]̳ޛ *>6߅r#! 3?^BEa߀#9#36'&632#"'&'&63232#!"&5463!2 Q,&U #+' ;il4L 92<D`w@www`9ܩ6ɽ ]`C477&@wwwD+"&5#"'&=4?5#"'&=4?546;2%6%66546;2  wwwwcB G]B Gty]ty #3C#!+"&5!"&=463!46;2!24&#!"3!26#!"&5463!2@`@`^BB^^B@B^www@w@`@`2@B^^BB^^ww@w'/?P+5#"&547.467&546;532!764'!"+32#323!&ln@ :MM: @nY*Yz--zY*55QDDU9pY-`]]`.X /2I$ t@@/!!/@@3,$,3$p$00&*0&& !P@RV2#"&/#"&/#"&546?#"&546?'&54632%'&54632763276%>S]8T;/M77T7%>ww@ww!"5bBBb./ * 8(@(87)(8=%/' #?w@www#~$EE y &L(88e):8(%O r    O?GQaq47&67>&&'&67>&"$32#"#"'654  $&6 $6&$ CoL.*K  Px.* iSƓ i 7J ?~pi{_Я;lLUZ=刈刈_t'<Z :!   @! j`Q7  $ky, Rfk*4LlL=Z=刈&$&546$7%7&'5>]5%w&P?zrSF!| &0 ##!"&5#5!3!3!3!32!546;2!5463) );));;))&&&@@&&&  6 $&727"'%+"'&7&54767%&4762֬>4P t+8?::  ::A W` `EvEEvE<."e$IE&O &EI&{h.`m"&#"&'327>73271[ >+)@ (]:2+D?*%Zx/658:@#N C= E(oE=W'c:#!#"$&6$3 &#"32>7! ڝyy,{ۀہW^F!LC=y:yw߂0H\R%"N^ '&76232762$"&5462"&46274&"&'264&#"'&&#"32$54'>$ $&6$ G>>0yx14J55J5J44J5Fd$?4J55%6E#42F%$fLlLq>>11J44%&4Z%44J54R1F$Z-%45J521Z%F1#:ʎ 9LlL#Qa"'&7622762%"&5462"&546274&#"&'73264&#"'&&#"32654'>#!"&5463!2 55 **.>.-@-R.>.-@-<+*q6- -- 0OpoOxzRrqP6z~{{Prr^aa]054&"#"&5!2654632!#"&57265&'&#".'&'#"&5467%&4>7>3263232654.547'654'63277.'.*#">7?67>?>32#"'7'>3'>3235?KcgA+![,7*  2(-#=  /~[(D?G  |,)"# +)O8,+'6 y{=@0mI#938OAE` -  )y_/FwaH8j7=7?%a % %!?)L J 9=5]~pj  %(1$",I  $@((  +!.S -L__$'-9L 5V+ 6 T+6.8- $ 0 + t |S 16]&#"'&#"67>76'&'&#"67>32764.#"#.32>67>7 $&54>7>7>7rJ@ "kb2)W+ ,5/1   #   Z -!$IOXp7sLCF9vz NAG#/ 5|Հ';RKR/J#=$,9,+$UCS7'2"1  ! / ,   /--ST(::(ep4AM@=I>".)xΤlsY|qK@ %(YQ&N EHv~<Zx'#"&5467&6?2?'&"/.7.546326#"&'&/7264/7'764&"'?>>32.AUpIUxYE.A %%%h% %hJ%D,FZxULs TgxUJrVD %hJ%@/LefL.C %Jh%CV sNUxϠ@.FZyUHpVA %h&%% %Ji%CWpIUybJ/Uy^G,D %Jh%@U sMt UC %hJ%C-KfyEX[_gj&/&'.''67>7>7&'&'&'>76763>7>#&'&'767672'%'7'+"&'&546323267>7%#"'4'6767672,32,+DCCQLDf' % :/d B 4@ }  &!0$?Jfdf-.=6(:!TO? !IG_U% . j+.=; 5gN_X "  ##  292Q41   *6nA;| BS N.  %1$ 6 #nk^ '7GWgw2+"&5463#!"&5463!254&+";2654&+";2654&+";2654&+";2654&+";2654&+";2654&+";2654&+";2654&+";26#"&=! B^^BB^^B:FjB^8((`( `(8^BB^^B@B^"vEj^B(8(`(8(/?O_o/?2#!"&5463;26=4&+";26=4&+";26=4&+";26=4&+"54&+";2654&+";2654&+";2654&+";2654&+";2654&#!"3!2654&+";2654&+";2654&+";2654&+";2654&+";2654&+";2654&+";2654&+";2654&+";26@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`% "&5#"&5&462!762$"&462B\B@B\B8PpP8.BB..BB.8$P88P広3CQ#".54>32#".546322#"&#"#"54>%".54>32%2#"&54> &X=L|<&X=M{2r_-$$-_rUU%&&5%ő'- "'.546762@FF$@B@$.&,&.]]|q#<<#(BB B%'-%'-'%'-"'%&'"'%.5467%467%62@ll@ll,@GG&!@@@@@@!&+#+#6#+$*`:p:px p=`$>>$&@&@ @&p@ &.A!!"!&2673!"5432!%!254#!5!2654#!%!2#!8Zp?vdΊens6(N[RWu?rt1SrF|iZ@7މoy2IMC~[R yK{T:%,AGK2#!"&5463!!2654'654.#532#532"&5!654&#"327#2#>!!ww@ww~uk'JTMwa| DH> I1q Fj?w@wwwsq*4p9O*¸Z^qh LE "(nz8B M'?"&4624&#"'.'324&#"3267##"&/632632.ʏhhMALR vGhг~~K „yO^   ʏʏВ*LM@!שwwȍde)qrOPqȦs:03=7'.?67'67%'>&%'7%7./6D\$>  "N,?a0#O 1G9'/P(1#00  ($=!F "9|]"RE<6 'o9%8J$\ :\HiTe<?}V#oj? d,6%N#" HlSVY]C =@C4&"2!.#!"4&"2+"&=!"&=#"&546;>3!232^^^Y ^^^`pppp`]ibbi]~^^^e^^^PppPPppP]^^]3;EM2+"&=!"&=#"&546;>;5463!232264&"!.#!"264&" ]`pppp`]ibbi^^^dY !^^^]@PppP@@PppP@]^^] ^^^e^^^ 3$#!#!"&5467!"&47#"&47#"&4762++&2 $$ 2&&&4&&Z4&&##&&4&4&44&m4&m+DP4'&#"32763232674'&!"32763 3264'&$#"32763232> $$ g* o`#ə0#z#l(~̠) -g+^aaF s" +g (* 3#!| #/IK/%*%D= )[^aa !!!'!!77!,/,-a/G t%/;<HTbcq%7.#"32%74'&"32765"/7627#"5'7432#"/7632#"5'7432#"&5'74632 #"/6327#"/6327#"/46321"&/462"&/>21"&/567632#!.547632632  *     X    ^  `    ^  b  c   fu U`59u  4J   l~ ~ F 2    m | O,           ru| u  " )9 $7 $&= $7 $&= $7 $&=  $&=46w`ww`ww`wb`VTEvEEvETVTEvEEvET*VTEvEEvET*EvEEvEEvEEv#^cu#!"&5463!2!&'&!"&5!632#"&'#"/&'&7>766767.76;267674767&54&5&'67.'&'&#3274(8((88((`x c`(8!3;:A0?ݫY   ^U 47D$    74U3I  |L38wtL0`((88(@(8(D 9 8(Q1&(!;  (g- Up~R2(/{E(Xz*Z%(i6CmVo8 #Q#!"&5463!2!&'&!"&5!3367653335!3#'.'##'&'35(8((88((`x c`(8iFFZcrcZ`((88(@(8(D 9 8(kk" kkJ ! k#S#!"&5463!2!&'&!"&5!%!5#7>;#!5#35!3#&'&/35!3(8((88((`x c`(8-Kg kL#DCJg  jLD`((88(@(8(D 9 8(jj jjkk kk#8C#!"&5463!2!&'&!"&5!%!5#5327>54&'&#!3#32(8((88((`x c`(8 G]L*COJ?0R\wx48>`((88(@(8(D 9 8(jjRQxk !RY#*2#!"&5463!2!&'&!"&5!!57"&462(8((88((`x c`(8Pppp`((88(@(8(D 9 8(ppp  #*7JR5#5#5#5##!"&5463!2!&'&!"&5##5!"&54765332264&"<(8((88((`x c`(8kޑcO"jKKjK`((88(@(8(D 9 8(SmmS?M&4&&4#9L^#!"&5463!2!&'&!"&5!#"/#"&=46;76276'.'2764'.(8((88((`x c`(8 6ddWW6&44`((88(@(8(D 9 8(. G5{{5]]$5995#3C#!"&5463!2!&'&!"&5!2#!"&5463#"'5632(8((88((`x c`(84LL44LL4l  `((88(@(8(D 9 8(L44LL44L  Z #7K[#!"&5463!2!&'&!"&5!>&'&7!/.?'&6?6.7>'(8((88((`x c`(8` 3  3  3  3 v  ?  `((88(@(8(D 9 8( & & - & &  ?   '6#'. '!67&54632".'654&#"32eaAɢ/PRAids`WXyzOvд:C;A:25@Ң>-05rn`H( ' gQWZc[ -%7' %'-'% %"'&54762[3[MN 3",""3,3"ong$߆]gn$+) ")")" x#Z#"&#!+.5467&546326$32327.'#"&5463232654&#"632#".#"oGn\ u_MK'̨|g? CM7MM5,QAAIQqAy{b& BL4PJ9+OABIRo?z.z n6'+s:zcIAC65D*DRRD*wya$, @B39E*DRRD*'/7  $&6$ 6277&47' 7'"' 6& 6'lLRRZB|RR>dZZLlLZRR«Z&>«|R ! $&54$7 >54'5PffP牉@s-ff`-c6721>?>././76&/7>?>?>./&31#"$&(@8!IH2hM>'  )-* h'N'!'Og,R"/!YQG54'63&547#5#"=3235#47##6323#324&"26%#!"&5463!2F]kbf$JMM$&N92Z2&`9UW=N9:PO;:dhe\=R +)&')-S99kJ<)UmQ/-Ya^"![Y'(<`X;_L6#)|tWW:;X  #'#3#!"&5463!2) p*xeשw@www0,\8@www9I#"'#"&'&>767&5462#"'.7>32>4."&'&54>32JrO<3>5-&FD(=Gq@C$39aLL²L4 &) @]v q#CO!~󿵂72765'./"#"&'&5 }1R<2" 7MW'$  ;IS7@5sQ@@)R#DvTA ; 0x I)!:> +)C 6.> !-I[4&#"324&#"3264&#"324&#"326&#"#".'7$4$32'#"$&6$32D2)+BB+)3(--(31)+BB+)4'--'4'#!0>R HMŰ9ou7ǖD䣣 R23('3_,--,R23('3_,--,NJ ?uWm%#"'%#"'.5 %&'&7632! ; `u%"(!]#c)(  #"'%#"'.5%&'&76 !  (%##fP_"(!)'+ʼn4I#"$'&6?6332>4.#"#!"&54766$32#!"&=46;46;2z䜬m IwhQQhbF*@&('k@z   _hQнQGB'(&*eozΘ@@`  >. $$ ffff^aafff^aa>"&#"#"&54>7654'&#!"#"&#"#"&54>765'46.'."&54632326323!27654'.5463232632,-,,",:! %]& %@2(/.+*)6! <.$..**"+8#  #Q3,,++#-:#"$$ /:yuxv)%$ /?CG%!5%2#!"&5463!5#5!52#!"&54632#!"&5463#5!5`&&&& &&&&&&&&@&&&&&&&&&&&&%2 &547%#"&632%&546 #"'6\~~\h ~\h\ V V VV%5$4&#"'64'73264&"&#"3272#!"&5463!2}XT==TX}}~>SX}}XS>~}w@www~:xx:~}}Xx9}}9xX}@www/>LXds.327>76 $&6$32762#"/&4762"/&47626+"&46;2'"&=462#"'&4?62E0l,  *"T.D@Yooo@5D [  Z  Z  [ ``[ Z  2 ,l0 (T" .D5@oooY@D, Z  [  [  Z ``EZ  [ 5%!  $&66='&'%77'727'%amlLmf?55>fFtuutFLlLHYC L||L Y˄(E''E*( /?IYiy%+"&=46;2+"&=46;2+"&=46;2+"&=46;2%"&=!#+"&=46;2+"&=46;2+"&=46;2+"&=46;2!54!54>$ +"&=46;2#!"&=@&&@3P > P3&&rrr&&rrr he 4LKM:%%:MKL4WT&&%/9##!"&563!!#!"&5"&5!2!5463!2!5463!2&&&&&&  &&&i@&&@&7'#5&?626J%o;j|/&jJ%p&`Jj&p/|jţ%Jk%o%  :g"&5462#"&546324&#!"263662>7'&75.''&'&&'&6463!276i~ZYYZ~@OS;+[G[3YUD#o?D&G3I=JyTkBuhNV!WOhuAiSy*'^CC^'*SwwSTvvTSwwSTvvWID\_"[ gq# /3qFr2/ $rg%4 HffHJ4d#!#7!!7!#5!VFNrmNNN N!Y+?Ne%&'&'&7>727>'#&'&'&>2'&'&676'&76$7&'&767>76 '6# <;11x# *# F-T93%/#0vNZ;:8)M:( &C.J}2 %0  ^*  JF &7'X"2LDM" +6 M2+'BQfXV#+] #' L/(eB9  #,8!!!5!!5!5!5!5#26%!!26#!"&5!5&4& &pPPp@@&&@!&@PppP@*  9Q$"&54627"."#"&547>2"'.#"#"&5476$ "'&$ #"&5476$ (}R}hLK NN Ud: xx 8    ,, |2222 MXXM ic,>>,   ̺  '/7?KSck{4&"2$4&"24&"24&"24&"24&"24&"24&"24&"264&"24&#!"3!264&"2#!"&5463!2KjKKjKjKKjKjKKjKKjKKjKjKKjKjKKjKKjKKjKjKKjKLhLLhLKjKKj&&&&KjKKjL44LL44L5jKKjKKjKKjKjKKjKjKKjKjKKjKjKKjKjKKjKjKKjK4LL44LLjKKjK&&&&jKKjK4LL44LL 'E!#"+"&7>76;7676767>'#'"#!"&7>3!2W",&7' #$ &gpf5 O.PqZZdS -V"0kqzTxD!!8p8%'i_F?;kR(` !&)w.<\.'.>%#"'.7>.'&67632&'6'&' #"'.766.'&67632Z &+\cc:>'D> 6KD3W6,9(<*0-?")/SW7.Crb  :+OIX3'#C3:@ #*"-A%,1U=}AQfO$"|'"S*`H(:UܳJ?27sZy%+A07C~Ӗ5A"3 >IY#6?>7&#!%'.'33#&#"#"/3674'.54636%#"3733#!"&5463!24  : @7vH%hEP{0&<'VFJo1,1.F6A#L44LL44L"% 7x'6 O\JYFw~v^fH$ ! "xdjD"!6`J4LL44LL $1Ol-#"326%356.#"#"326%4#"326%3#7#'#3%#7#"&546324>54#"47632&#"'"'473254&'&54323#327#"'47673#327#"546327&#7673>7&#"327#"&54632#7#"&54632654#"47632&#7673>73#7#"&54632.#"#&'#67&#"327&'3673326#!"&5463!2 />  0@[W,8 G'"5,Q4/&4/ $&J (W" +Tl +7o _7*#) 83 ( -5G8 .'3/$&I8 48+5%7%{,2,rr,2,x-2.jj.2-xL44LL44L[ < J 2)(*(8$e  '+ , 1)H/ 'H4/// ,~i6_7G*''4fE!%97+" ;=4FYqO" '+ , &2hh_ ,0(5N(ntggtnno__on4LL44LL  BWbjq}+532%+5324&+32763#4&'.546327&#"#"'3265#"&546325&#"32 !264&"2%#'#735#535#535#3'654&+353#!"&5463!29$<=$@?SdO__J-<AA@)7")9,<$.%0*,G3@%)1??.+&((JgfJ*A!&jjjGZYGиwsswPiL>8aA !M77MM77M3! 4erJ]&3YM(, ,%7(#)  ,(@=)M%A20C&Mee(X0&ĖjjjV 8Z8J9N/4$ 8NN88NN  #&:O[ $?b3'7'#3#%54+32%4+324+323'%#5#'#'##337"&##'!!732%#3#3##!"&53733537!572!56373353#'#'#"5#&#!'#'#463!2#"5#"5!&+&+'!!7353273532!2732%#54&+#32#46.+#2#3#3##+53254&".546;#"67+53254&.546;#"#'#'##"54;"&;7335wY-AJF=c(TS)!*RQ+*RQ+Y,B^9^Ft`njUM ') ~PSPRm٘M77Mo7q @)U 8"E(1++NM77Mx378D62W74;9<-A"EA0:A F@1:ؗBf~~""12"4(w$#11#@}}!%+%5(v$:O\zK?* $\amcrVlOO176Nn23266&+"&#"3267;24&+"'&+";27%4&+";2?>23266&+"&#"3267;254+";27#76;2#!"&5463!23%#2%%,,  _3$$2%%M>AL Vb5)LDHeE:< EM j,K'-R M ~M>AR  Vb5)LEHeE:< E J ABI*'! ($rL44LL44Lv%1 %3!x*k $2 %3!;5h n a !(lI;F   rp p8;5h t a !(lI;F ` #k 4LL44LL  2HW[lt#"'5632#6324&'.54327&#"#"&'32767#533275#"=5&#"'#36323#4'&#"'#7532764&"24'&#"327'#"'&'36#!"&5463!2=!9n23BD$ &:BCRM.0AC'0RH`Q03'`.>,&I / * / 8/n-(G@5$ S3=,.B..B02^`o?7je;9G+L44LL44LyE%# Vb;A !p &'F:Aq)%)#orgT$ v2 8)2z948/{ 8AB..B/q?@r<7(g/4LL44LL ?#!"&'24#"&54"&/&6?&5>547&54626=L4@ԕ;U g3 T 2RX='8P8|5 4Ljj U;Ig@   `  "*\(88(]k  &N4#"&54"3 .#"#!"&'7!&7&/&6?&5>547&54626;U gIm*]Z0L4@ԕ=o=CT T 2RX='8P8|5  U;IgXu?bl3@4Ljja`   `  "*\(88(]k/7[%4&+";26%4&+";26%4&+";26!'&'!+#!"&5#"&=463!7>3!2!2@@@@@@0 o`^BB^`5FN(@(NF5@@@u  @LSyuS@%44%,<H#"5432+"=4&#"326=46;2  >. $$ ~Isy9"SgR8vHD w ffff^aam2N+ )H-mF+10*F +fff^aab4&#"32>"#"'&'#"&54632?>;23>5!"3276#"$&6$3 k^?zb=ka`U4J{K_/4^W&  vx :XB0܂ff ) fzzXlz=lapzob35!2BX G@8  ' '=vN$\ff  1 SZz8zX#("/+'547'&4?6276 'D^h  i%5@%[i  h]@]h  i%@5%[i  h^@@)2#"&5476#".5327>OFi-ay~\~;'S{s:D8>)AJfh]F?X{[TC6LlG]v2'"%B];$+l|%!2>7>232>7>322>7>32"&'.#"#"&'.#"#"&'.#"#546;!!!!!32#"&54>52#"&54>52#"&54>52-P&+F) $P.-P$'#+&PZP&+#"+&P-#) $P-.P$(#+$P.-P$'#+&P-.P$+#pP@@PpH85K"&ZH85K"&ZH85K"&Z@Pp@@@pMSK5, :&LMSK5, :&LMSK5, :& !!3 ! @@@  #"$$3!!2"jaѻxlalxaaj!!3/"/'62'&63!2'y  `I  yMy `I y'W`#".'.#"32767!"&54>3232654.'&546#&'5&#" 4$%Eӕ;iNL291 ;XxR`f՝Q8TWiWgW:;*:`Qs&?RWXJ8 oNU0 J1F@#) [%6_POQiX(o`_?5"$iʗ\&>bds6aP*< -;iFn* -c1BWg4'.'4.54632#7&'.#"#"'.#"32767'#"&54632326#!"&5463!2#$( 1$6]' !E3P|ad(2S;aF9'EOSej]m] <*rYshpt.#)$78L*khw@wwwB % $/$G6 sP`X):F/fwH1pdlqnmPHuikw_:[9D'@www34."2>$4.#!!2>#!".>3!2QнQQнQQh~wwhfffнQQнQQнQZZQffff#>3!2#!".2>4."fffнQQнQQffffQнQQн ,\!"&?&#"326'3&'!&#"#"'  5467'+#"327#"&463!!'#"&463!2632(#AHs9q ci<= #]$ KjKKjKKjKKjH#j#H&&&KjKKjKg V i jKKjKKjKKjK ..n(([5KK55KK5[poNv<+#"'#"&546;&546$32322$B$22$$*$22$Xڭӯ$22$tX'hs2$ϧkc$22$1c$2F33F3VVT2#$2ԱVT2#$2g#2UU݃ 2$#2UU1݃2 ,u54#"67.632&#"32654'.#"32764.'&$#"7232&'##"&54732654&#"467&5463254632>32#"'&ru&9%" *#͟O%GR=O&^opC8pP*bY _#$N Pb@6)?+0L15 "4$.Es  5IQ"!@ h "Y7e|J>ziPeneHbIlF>^]@n*9 6[_3#"&54632#.#"32%3#"&54632#.#"326%4&'.'&! ! 7>7>! =39? 6'_ >29? 5'17m-VU--,bW.뮠@Fyu0HC$뮠@Fyu0HC$L= ?? <=! A <`;+"&54&#!+"&5463!2#!"&546;2!26546;2pЇ0pp@Ipp>Sc+"&=46;254&+"&+";2=46;2;2=46;2;2%54&#!";2=;26#!"&5463!2A5DD5A7^6a7MB55B7?5B~```0`rr5A44A5v5AA5f*A``0` !!!! #!"&5463!2ړ7H7jv@vvv':@vvvMUdkpu{#"'!"'!#"&547.547.54674&547&54632!62!632!#!6227'!%!"67'#77!63!!7357/7'%# %'3/&=&' 5#?&547 6!p4q"""6" 'h*[ |*,@?wAUMpV@˝)Ϳw7({*U%K6=0(M "! O dX$k !! ! b [TDOi @6bxBAݽ5  ɝ:J +3,p x1Fi (R 463!#!"&5%'4&#!"3`а@..@A-XfB$.BB..C} )&54$32&'%&&'67"w`Rd]G{o]>p6sc(@wgmJPAjyYWa͊AZq{HZ:<dv\gx>2ATKn+;"'&#"&#"+6!263 2&#"&#">3267&#">326e~└Ȁ|隚Ν|ū|iyZʬ7Ӕްr|uѥx9[[9jj9ANN+,#ll"BS32fk[/?\%4&+";26%4&+";26%4&+";26%4&+";26%#!"&5467&546326$32]]eeeeee$~i qfN-*#Sjt2"'qCB8!'> !%)-159=AEIMQUY]agkosw{! %! 5!#5#5#5#5#57777????#5!#5!#5!#5!#5!#5!#5!#5#537#5!#5!#5!#5!#5!#55#535353535353%"&546326#"'#32>54.&54>3237.#"Q%%%%%%%%%?iiihOiixiiyiixiiArssrrssr%sssrrssNs%%%%%%%%%%'32#".543232654&#"#"&54654&#"#"&547>326ڞUzrhgrxSПdU 7#"&463!2!2&&4&&&&4&KjKKjKjKKj &&&%&& &&4&&&&4&&&5jKKjKKjKKjK%z 0&4&&3D7&4& %&'S4&"4&"'&"27"&462"&462!2#!"&54>7#"&463!2!2&4&4&4&4KjKKjKjKKj &&&%&& &&4&%&&ے&4"jKKjKKjKKjK%z 0&4&&3D7&4& %& & !'! !%!!!!%"'.763!2o]FooZY@:@!!gf//I62'"/"/"/"/"/"/"/7762762762762762762%"/77627&6?35!5!!3762762'"/"/"/"/"/"/%5#5!4ZSS6SS4SS4SS4SS4SS4SS4ZSS4SS4SS4SS4SS4SS4S-4ZSS4S@4SS4ZSS6SS4SS4SS4SS4SS4S@ZSSSSSSSSSSSSSSZSSSSSSSSSSSSSyZRRR@%:= :+: =RRZSSSSSSSSSSSSSCv!/&'&#""'&#" 32>;232>7>76#!"&54>7'3&547&547>763226323@``` VFaaFV      $. .$     yy .Q5ZE$ ,l*%>>%*>*98(QO!L\p'.'&67'#!##"327&+"&46;2!3'#"&7>;276;2+6267!"'&7&#"(6&#"#"' Dg OOG`n%ELL{@&&Nc,sU&&!Fre&&ss#/,<= #]gL oGkP'r-n&4&2-ir&&?o  4 _5OW! .54>762>7.'.7>+#!"&5#"&5463!2"&462{{BtxG,:`9(0bԿb0(9`:,GxtB&@&&@&K55K`?e==e?1O6# ,  #$  , #6OO&&&&5KK?!"'&'!2673267!'. ."!&54632>321 4q#F""8'go#- #,"tYg>oP$$Po> Zep#)R0+I@$$@I++332++"&=#"&=46;.7>76$  @ ᅪ*r@@r'/2+"&5".4>32!"&=463  &@~[՛[[u˜~gr&`u՛[[՛[~~@r=E32++"&=#"&=46;5&547&'&6;22676;2  >``@``ٱ?E,,=?rH@``@GݧH`jjrBJ463!2+"&=32++"&=#"&=46;5.7676%#"&5   &@~``@``  vXr&@``@+BF`rks463!2+"&=32++"&=#"&=46;5&547'/.?'+"&5463!2+7>6 %#"&5   &@~``@``~4e  0  io@& jV  0  Z9r&@``@Gɞ5o , sp &@k^ , c8~~`r8>KR_32++"&=!+"&=#"&=46;.767666'27&547&#"&'2#" @@ 'Ϋ'sggsww@sgg@@-ssʃl99OOr99FP^l463!2+"&=$'.7>76%#"&=463!2+"&=%#"&54'>%&547.#"254&' &@L?CuГP vY &@;"ޥ5݇ޥ5`&_ڿgwBF@&J_ s&&?%x%xJP\h463!2+"&='32++"&=#"&=46;5.7676632%#"&56'327&7&#"2#" &@L? ߺu``@``} ຒɞueeu9uee&_"|N@``@""|a~lo99r9@9;C2+"&5"/".4>327'&4?627!"&=463  &@Ռ .  N~[՛[[u˜N .  gr&`֌  . Ou՛[[՛[~N  . @r9A'.'&675#"&=46;5"/&4?62"/32+  '֪ \  . 4 .  \r|ݧ憛@\ .    . \@r~9A"/&4?!+"&=##"$7>763546;2!'&4?62  m  - @ݧ憛@& -  @rm4 -  ٮ*   - r+"&5&54>2  @[՛[rdGu՛[[r  ".4>2r[՛[[՛r5՛[[՛[[$2#!37#546375&#"#3!"&5463#22#y/Dz?s!#22#2##2S88 2#V#2L4>32#"&''&5467&5463232>54&#"#"'.Kg&RvgD $ *2% +Z hP=DXZ@7^?1 ۰3O+lh4`M@8'+c+RI2 \ZAhSQ>B>?S2Vhui/,R0+ ZRkmz+>Q2#"'.'&756763232322>4."7 #"'&546n/9bLHG2E"D8_ pdddxO"2xxê_lx2X  !+'5>-pkW[C I I@50Oddd˥Mhfxx^ә #'+/7!5!!5!4&"2!5!4&"24&"2!!! 8P88P 8P88P88P88PP88P8 P88P88P88P8 +N &6 !2#!+"&5!"&=463!46;23!#!"&54>32267632#"_>@`     `  L4Dgy 6Fe=OOU4L>   ` `  4L2y5eud_C(====`L43V &6 #"/#"/&54?'&54?6327632#!"&54>32 7632_>     %%Sy 6Fe=J%>     %65%Sy5eud_C(zz.!6%$!2!!!46;24&"2!54&#!"&&&@ԖV@&&@&&ԖԖ@&3!!! !5!'!53!! #7IeeI7CzCl@@@#2#!"&?.54$3264&"!@մppp((ppp#+/2#!"&?.54$3264&"!264&"!@մ^^^@^^^@((^^^^^^v(#"'%.54632 "'% 632U/@k0G,zD# [k# /tg F Gz  #'#3!) p*xe0,\8T #/DM%2<GQ^lw &'&676676&'&7654&'&&546763"#"'3264&7.>&'%'.767&7667&766747665"'.'&767>3>7&'&'47.'.7676767&76767.'$73>?>67673>#6766666&'&6767.'"'276&67&54&&671&'6757>7&"2654&57>&>&'5#%67>76$7&?5.''&'&'#'""#''&'&'&'65.'&6767.'#%&''&'#2%676765&'&'&7&5&'6.7>&5R4&5S9 W"-J0(/r V"-J0(.)#"6&4pOPppc|o}vQ[60XQW1V  # 5X N"& . ) D>q J:102(z/=f*4!> S5b!%  (!$p8~5..:5I  ~T 4~9p# ! ) & ?()5F 1   d%{v*: @e s|D1d {:*dAA|oYk'&<tuut&v HCXXTR;w 71™  Z*&' 1  9? . $Gv 5k65P.$.`aasa``Z9k'9؋ӗa-*Gl|Me_]`F& OܽsDD!/+``aa``a154&'"&#!!26#!"&5463!2    iLCly5)*Hcelzzlec0hb,,beIVB9@RB9J_L44LL44L44%2"4:I;p!q4bb3p (P`t`P(6EC.7BI64LL44LL  .>$4&'6#".54$ 4.#!"3!2>#!"&5463!2Zjbjj[wٝ]>oӰٯ*-oXL44LL44L')꽽)J)]wL`ֺ۪e4LL44LL;4&#!"3!26#!"&5463!2#54&#!";#"&5463!2  @ ^BB^^B@B^  B^^B@B^`@  MB^^B@B^^>  ^B@B^^5=Um ! !!2#!"&=463!.'!"&=463!>2!2#264&"".54>762".54>762?(``(?b|b?B//B/]]FrdhLhdrF]]FrdhLhdrF@@@(?@@ ?(@9GG9@/B//BaItB!!BtI Ѷ!!ь ItB!!BtI Ѷ!!ь-M32#!"&=46;7&#"&=463!2#>5!!4.'.46ՠ`@`ՠ`MsFFsMMsFFsMojjo@@jj@@<!(!!(!-3?32#!"&=46;7&#"&=463!2+!!64.'#ՠ`@`ՠ`  DqLLqDojjo@@jj@@B>=C-3;32#!"&=46;7&#"&=463!2+!!6.'#ՠ`@`ՠ`UVU96gg6ojjo@@jj@@β**ɍ-G32#!"&=46;7&#"&=463!2#>5!!&'.46ՠ`@`ՠ`MsFFsMkkojjo@@jj@@<!(!33!(!9I2#!"&=4637>7.'!2#!"&=463@b":1P4Y,++,Y4P1:"":1P4Y,++,Y4P1:"b@@@7hVX@K-AA-K@XVh77hVX@K-AA-K@XVh7Aj"#54&#"'54&#"3!26=476=4&#"#54&'&#"#54&'&'2632632#!"&5&=4632>3265K @0.B @0.B#6'&& l @0.B 2' .B A2TA9B;h" d mpPTlLc _4.HK5]0CB.S0CB./#'?&&)$$)0CB. }(AB.z3M2"61d39L/PpuT(Ifc_E`1X"#4&"'&#"3!267654&"#4&"#4&26326#!"&'&5463246326\B B\B&@5K&@"6LB\B B\B sciL}QP%&#"!"3!754?27%>54&#!26=31?>Ijjq,J[j.-tjlV\$B.R1?@B.+?2`$v5K-%5KK5.olRIS+6K5̈$B\B 94E.&ʀ15uE& ԖPjjdXUGJ7!.B P2.B %2@ 7K5(B@KjKj?+fU E,5K~!1.>F.F,Q5*H$b2#!"&=%!"&=463!7!"&'&=4634'&#!">3!!"3!32#!"3!23!26=n$7654&#"#654&#"#.!"'.54632&5467>32>3200?t ='/@H@"+4K8"*!4dtB/&> c@0&=  =_JUD29i1"07 {x\YSgSSW]|t eyD0&0D/  I4C+) t .B3%h#/B0&&03|&p>i +#] WsgQT\QglU ]#-39oK_3[_cg"'&#"3!2676=4&"#54&#"#54&#"#4&'2632632632#!"&'&5463246#!#!#5K)B4J&@#\8P8 @0.B J65K J6k cJ/4qG^\hB2.1!~K5y?^\Vljt-.j[J,qjjI7$?1R.B+.B$`2?gvEo.5KK5%-K6+SIR[&.E49 B\B$5KG#!+"&5!"&=463!2+"&' +"' +"'&5>;2>76;2Y    M .x - N     u  , u ?  LW   #  *:J4'&+326+"'#+"&5463!2  $6& $&6$ UbUI-uu,uuڎLlLAX!Jmf\$ 6uuu,KLlL-[k{276/&'&#"&5463276?6'.#"!276/&'&#"&5463276?6'.#"  $6&  $&6]h - %Lb`J%E 5 ,5R- h - %Lb`J%E 5 ,5R-'uu,uulL/hR    dMLc  NhR   dMLc  N1uuu,LlL@  ' 7 '7 ``H ``H !``H ```H` '%  7' 7'7 ' $&6$ X`(W:,:X`(WLLlLX`(W:BX`(XLlL $ %/9ES[#"&54632$"&4624&"26$4&#"2%#"&462$#"&4632#"32&! 24>  !#"&'.'#"$547.'!6$327&'77'&77N77N'qqqqqPOrqEsttsst}||}uԙ[WQ~,> nP/R U P酛n >,m'77'&77N77N6^Orqqqqqqt棣棣(~|| on[usј^~33pc8{y%cq33dqpf L 54 "2654"'&'"/&477&'.67>326?>< x ,  (-'sI  VCV  Hr'-(  $0@!BHp9[%&!@0$u  ]\\]-$)!IHV D V HI!)$-#36>N"&462."&/.2?2?64/67>&  #!"&5463!2]]]3 $; &|v;$ (CS31 =rM= 4TC(G zw@www]]]($-;,540= sL =45,; @www(2#"$&546327654&#" &#"AZ\@/#%E1/##.1E$![A懇@@\!#21E!6!E13"|! gL&5&'.#4&5!67&'&'5676&'6452>3.'5A5RV[t,G'Q4}-&r! G;>!g12sV&2:#;d=*'5E2/..FD֕71$1>2F!&12,@K r#"&5462>%.#"'&#"#"'>54#".'7654&&5473254&/>7326/632327?&$  $6 $&6$ !&"2&^ u_x^h ;J݃HJǭ qE Dm! M G?̯' %o8 9U(F(ߎLlL&!&!SEm|[n{[<ɪ "p C Di% (K HCέ  pC B m8 @Kނ  HF(LlL "*6%&6$ 7&$5%%6'$2"&4}x3nQH:dΏX e8z' li=! 7So?vM '&7>>7'7>''>76.'6'El:Fg r *t6K3U Z83P)3^I%=9 )<}Jk+C-Wd &U-TE+]Qr-< Q#0 C+M8 3':$ _Q =+If5[ˮ&&SGZoMkܬc#7&#"327#"'&$&546$;#"'654'632ե›fKYYKf¥yͩ䆎L1hvvƚwwkn]*]nlxDLw~?T8bb9SA}+5?F!3267!#"'#"4767%!2$324&#"6327.'!.#"۔c28Ψ-\?@hU0KeFjTlyE3aVsz.b؏W80]TSts<hO_u7bBtSbF/o|V]SHކJ34&#!"3!26#!!2#!"&=463!5!"&5463!2  @ ^B `` B^^B@B^   @ @B^@@^BB^^>3!"&546)2+6'.'.67>76%&F8$.39_0DD40DD0+*M7{L *="# U<-M93#D@U8vk_Y [hD00DD00Dce-JF1 BDN&)@ /1 dy%F#"'&'&'&'&763276?6#"/#"/&54?'&763276"&'&'&5#&763567632#"'&7632654'&#"32>54'&#"'.5463!2#!3>7632#"'&'&#"'&767632yqoq>* 432fba  $B? >B BB AA.-QPPR+ 42 %<ciђ:6% hHGhkG@n`IȌ5 !m(|.mzyPQ-.  je  r=@@?ppgVZE|fb6887a %RB? =B ABBAJvniQP\\PRh cDS`gΒ 23geFGPHXcCI_ƍ5" n*T.\PQip [*81 / 9@:>t%6#".'.>%6%&7>'.#*.'&676./&'.54>754'&#"%4>327676= >vwd" l "3 /!,+ j2.|%& (N &wh>8X}xc2"W<4<,Z~fdaA`FBIT;hmA<7QC1>[u])  u1V(k1S) - 0 B2* %M ;W(0S[T]I) A 5%R7&&=,Xq&&@X,LΒw%%;#!"&5463!546;2!2!+"&52#!"/&4?63!5! (&&@&&(&&@&&( (  &&@&&@&&&&  #''%#"'&54676%6%% hh @` !   !    #52#"&5476!2#"&5476!2#"'&546        @  @  @    84&"2$4&"2$4&"2#"'&'&7>7.54$ KjKKjKjKKjKjKKjdne4" %!KjKKjKKjKKjKKjKKjK.٫8  !%00C'Z'.W"&462"&462"&462 6?32$6&#"'#"&'5&6&>7>7&54>$ KjKKjKjKKjKjKKjhяW.{+9E=cQdFK1A  0) LlLjKKjKKjKKjKKjKKjKpJ2`[Q?l&٫C58.H(Yee    Y'w(O'R@$#"&#"'>7676327676#" b,XHUmM.U_t,7A3ge z9@xSaQBLb( VU  !!!==w)@T!!77'7'#'#274.#"#32!5'.>537#"6=4>5'.465! KkkK _5 5 #BH1`L I& v6S F!Sr99rS!`` /7K%s}H XV  P V  e  Vd/9Q[ $547.546326%>>32"&5%632264&#"64'&""&'&"2>&2654&#";2 P 3>tSU<)tqH+>XX|Wh,:UStW|XX>=X*  ))  +^X^|WX=>X:_.2//a:Ru?  Q%-W|XW>J( =u>XX|WX`  *((*  +2 2X>=XW|E03>$32!>7 '&'&7!6./EUnohiI\0<{ >ORDƚ~˕VƻoR C37J6I`Tb<^M~M8O  5!#!"&!5!!52!5463 ^B@B^`B^^B `B^^"^BB^ #D2+#!"$&6$3227%#"$$ %&$#" 7=D9KqMLw9'qnH.Ktfw㿢p??pY9n6 LlLkT ၌.?p㿢p?   7!' !\W\ d;tZ`_O; k54+";2%54+";2!4&"!4;234;2354;2354;&5462!2#!32354;2354;2354;2````pp``` &4& ```@PppPpppppp$&&$ ppppp j#"'&=!;5463!2#!"&=#".'.#!#"&463232>7>;>32#"&'#"!546 %. `@` :,.',-XjjXh-,'.,: kb>PppP>bk .%Z & :k%$> $``6&L')59I"TlԖlT"I95)'L&69GppG9$ >$%k: !+32&#!332 $&6$ ~O88OLlL>pN  iLlL '':Ma4&'#"'.7654.#""'&#"3!267#!"&54676$32#"'.76'&>$#"'.7654'&676mD5)  z{6lP,@KijjOoɎȕ>>[ta) GG 4?a) ll >;_-/ 9GH{zyN@,KԕoN繁y! ?hh>$ D" >â? $ n"&5462'#".54>22654.'&'.54>32#"#*.5./"~~s!m{b6# -SjR,l'(s-6^]Itg))[zxȁZ&+6,4$.X%%Dc* &D~WL}]I0"  YYZvJ@N*CVTR3/A3$#/;'"/fR-,&2-" 7Zr^Na94Rji3.I+ &6W6>N%&60;96@7F6I3+4&#!"3!26%4&#!"3!26 $$ ^aa`@@^aa '7  $ >. %"&546;2#!"&546;2#/a^(^aa(N@@4&#!"3!26 $$ @@^aa`@^aa '  $ >. 7"&5463!2#/a^(n@^aa(N@ %=%#!"'&7!>3!26=!26=!2%"&54&""&546 ##]VTV$KjKKjK$&4&Ԗ&4&>9G!5KK55KK5!&&jj&&#/;Im2+#!"&'#"&463>'.3%4&"26%4&"26%6.326#>;463!232#.+#!"&5#"5KK5sH..Hs5KK5e# )4# %&4&&4&&4&&4&` #4) #%~]eZ&&Ze] E-&&-EKjKj.<<.KjK)#)`"@&&`&&&&`&&)#`)"dXo&&oXG,8&&8!O##!!2#!+"'&7#+"'&7!"'&?63!!"'&?63!6;236;2!2@@8@7 8Q NQ N 8G@ 8GQ NQ N7   8 8  H H  k%  ".>2I20]@]@oo@@oo㔕a22]]p^|11|99|11|(%7'7' ' 7T dltl)qnluul)1$4&"24&"2 &6 +"&5476;2 &6 LhLLhLLhLLhL>  &   &`>hLLhLLhLLhL>&&>jP_< u>u>  ~pU3U3]yn2@ zZ@55 zZZ@,_@s@ @(@@@- MM- MM@@@ -`b $ 648""""""@ D@ ,,@  m)@@   ' D9>dY* w    T     @ f %RE    $!k(PBp<$H<TfT H R , D x 6 \ DLX*(2^n0|bX*Z >n@jDH. 4 n !>:>>?|@@>@xAVABBBBCRCDE:FFxFGVGHH\HHHII0IbIIIJ*JrJK`KL@LMM~NN\NO.OOPZPQQNQQR`SU6UV(VzVVW>WWX"XnXXXYY^YYZ2ZdZ[[[[\l\]]]]]^R^_```a`abb:bbcd$dfdeelef&fvfg gghBhphhi2iriijBjzjk kbkll\llmm8mvmnnbnno8op pbpql Ǣ"ɚʔ| ͜VΤ zвTXҾ&`ӎӎӎ,Ԩn(\֚8\tۆ`ܨRݼ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopq rstuvwxyz{|}~     " !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuuni00A0uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni202Funi205Funi25FCglassmusicsearchenvelopeheartstar star_emptyuserfilmth_largethth_listokremovezoom_inzoom_outoffsignalcogtrashhomefile_alttimeroad download_altdownloaduploadinbox play_circlerepeatrefreshlist_altlockflag headphones volume_off volume_down volume_upqrcodebarcodetagtagsbookbookmarkprintcamerafontbolditalic text_height text_width align_left align_center align_right align_justifylist indent_left indent_rightfacetime_videopicturepencil map_markeradjusttinteditsharecheckmove step_backward fast_backwardbackwardplaypausestopforward fast_forward step_forwardeject chevron_left chevron_right plus_sign minus_sign remove_signok_sign question_sign info_sign screenshot remove_circle ok_circle ban_circle arrow_left arrow_rightarrow_up arrow_down share_alt resize_full resize_smallexclamation_signgiftleaffireeye_open eye_close warning_signplanecalendarrandomcommentmagnet chevron_up chevron_downretweet shopping_cart folder_close folder_openresize_verticalresize_horizontal bar_chart twitter_sign facebook_sign camera_retrokeycogscomments thumbs_up_altthumbs_down_alt star_half heart_emptysignout linkedin_signpushpin external_linksignintrophy github_sign upload_altlemonphone check_emptybookmark_empty phone_signtwitterfacebookgithubunlock credit_cardrsshddbullhornbell certificate hand_right hand_lefthand_up hand_downcircle_arrow_leftcircle_arrow_rightcircle_arrow_upcircle_arrow_downglobewrenchtasksfilter briefcase fullscreengrouplinkcloudbeakercutcopy paper_clipsave sign_blankreorderulol strikethrough underlinetablemagictruck pinterestpinterest_signgoogle_plus_sign google_plusmoney caret_downcaret_up caret_left caret_rightcolumnssort sort_downsort_up envelope_altlinkedinundolegal dashboard comment_alt comments_altboltsitemapumbrellapaste light_bulbexchangecloud_download cloud_uploaduser_md stethoscopesuitcasebell_altcoffeefood file_text_altbuildinghospital ambulancemedkit fighter_jetbeerh_signf0fedouble_angle_leftdouble_angle_rightdouble_angle_updouble_angle_down angle_left angle_rightangle_up angle_downdesktoplaptoptablet mobile_phone circle_blank quote_left quote_rightspinnercirclereply github_altfolder_close_altfolder_open_alt expand_alt collapse_altsmilefrownmehgamepadkeyboardflag_altflag_checkeredterminalcode reply_allstar_half_emptylocation_arrowcrop code_forkunlink_279 exclamation superscript subscript_283 puzzle_piece microphonemicrophone_offshieldcalendar_emptyfire_extinguisherrocketmaxcdnchevron_sign_leftchevron_sign_rightchevron_sign_upchevron_sign_downhtml5css3anchor unlock_altbullseyeellipsis_horizontalellipsis_vertical_303 play_signticketminus_sign_alt check_minuslevel_up level_down check_sign edit_sign_312 share_signcompasscollapse collapse_top_317eurgbpusdinrjpyrubkrwbtcfile file_textsort_by_alphabet_329sort_by_attributessort_by_attributes_alt sort_by_ordersort_by_order_alt_334_335 youtube_signyoutubexing xing_sign youtube_playdropbox stackexchange instagramflickradnf171bitbucket_signtumblr tumblr_signlong_arrow_down long_arrow_uplong_arrow_leftlong_arrow_rightwindowsandroidlinuxdribbleskype foursquaretrellofemalemalegittipsun_366archivebugvkweiborenren_372stack_exchange_374arrow_circle_alt_left_376dot_circle_alt_378 vimeo_square_380 plus_square_o_382_383_384_385_386_387_388_389uniF1A0f1a1_392_393f1a4_395_396_397_398_399_400f1ab_402_403_404uniF1B1_406_407_408_409_410_411_412_413_414_415_416_417_418_419uniF1C0uniF1C1_422_423_424_425_426_427_428_429_430_431_432_433_434uniF1D0uniF1D1uniF1D2_438_439uniF1D5uniF1D6uniF1D7_443_444_445_446_447_448_449uniF1E0_451_452_453_454_455_456_457_458_459_460_461_462_463_464uniF1F0_466_467f1f3_469_470_471_472_473_474_475_476f1fc_478_479_480_481_482_483_484_485_486_487_488_489_490_491_492_493_494f210_496f212_498_499_500_501_502_503_504_505_506_507_508_509venus_511_512_513_514_515_516_517_518_519_520_521_522_523_524_525_526_527_528_529_530_531_532_533_534_535_536_537_538_539_540_541_542_543_544_545_546_547_548_549_550_551_552_553_554_555_556_557_558_559_560_561_562_563_564_565_566_567_568_569f260f261_572f263_574_575_576_577_578_579_580_581_582_583_584_585_586_587_588_589_590_591_592_593_594_595_596_597_598f27euniF280uniF281_602_603_604uniF285uniF286_607_608_609_610_611_612_613_614_615_616_617_618_619_620_621_622_623_624_625_626_627_628_629VO)hugo-0.68.3/examples/blog/static/fonts/fontawesome-webfont.woff000066400000000000000000002432041363637351300246260ustar00rootroot00000000000000wOFFF*FFTMDjo)GDEF` OS/2?`Yzcmapwmgasp8glyf@*,,qhead.<16 Uhhea.p$ [hmtx. )*loca1LiVmaxp6D name6d3Fpost8r 7cAwebfF|*VO=Pu>xc`d``b `b`d`dj,` $xc`fsgbʢb l |6Fe ňDfsx͒?kqgI]5 5C W NW "R: %SX!c{M6o~hK҃{{@^;%$ȧ&=d2,<jT֬浨ej]N:Bq!,(*hF-ky+Z٪V$=~!&49-hI+ZӆtWSA# r( jh]уX2b;;r 6݆[WSY'YG$ 2'axBx?x7W+/ʟ|Ƨ|z|[^^(+5Y|`&DTxڼ |T0~9w}Ν-d&&$a'Ĉ. P VZQv_;ݴԶn~b[۾U[߶?[!s?ܙ$$}{Ͼ>y<#6q٠$rPF5m'IC\տiiN|RsuqHH&\1l2ɠTJ~$>\Ѩw$O(W9w yw<, AtG89jYPu4GvXpC Nd- cLe xK7΂Vz~3BPbQټbxpͻJ}Ҁ8ì yh6.@CG͞ x HBi G=cW]u ȏcW݈VF0$@Xͧhō):/G#tvy8us 9."/Yp3E#јpXg.B`DrN!Leemr2| d6ڮ%U (f`V t'sf7^;--نodϯ;[O( .?mڴ="gV>zYg3[?%LFwOhn1[qC§ ?vP:䡔x!4ժrpxU oj]ƿ*>yaAQ U(f#J&V t(NW u57.M~;UUMYgzSSΈ~>zQ>_OԭЫG#L-vL jPW;Fh'8y5[{ԟk^yL|H+ia@U BR=]Y~-9tЭ[>O߽aN&›7|q;]|xs3/xG-M35%zPs+˝]]t*ڌ:pu"2/-4>c?[}GlgsQon4FʩSLX$BUC9^ V ?5$IԇR'Y[<xz>n=fjи;K<R*Haud1@ 'ag䇓plLXSkU7Z%a=qQ7W>zj7 0'}_TQ'0 p.>Č0aX 8,8̐ĆV^HWroG(~,wD>K|x+OEDžV$6Mecw9$=dW꯴P\PT Cc}R4|F/Bp6fY{i is 2<:*a^d)a h0 1Xz2| :P=$OV͵>^Y{?rKKH[#&g3.K,zkA?]vgk;4ųwW~Wh>`mZyɾc۷d&k~SӁNj)wGO}]47]X!9x 55[W/EAcA?# \.DdO7-=P5*sӠ2&[o5n ^+$.Z!toL.DL^Cnn l͹Yo&c055iifi[Z/1 =Չ ۓ:͇(tr3K57?"q,:n:ilGCA*k{QVwJ`ZPl~p6 )l$aX'_Q4yYpGDWw|U֯aؾbvq8Ih!,U~]h!P4s)<+kĥqDRf6Iv?wz<Z s&X":gMˬxFZ}l.k|niPvO6#h%+)>rйo6Fc˖-pǢ^y?S3iLZ7wC,}q)D1G5מX1ί)u y3_]l(lk5u!Ĉ| ;¹ĭ9V U }/R8ndiId$%;py+|Fy.~4p4BP)yS>3bgÙqͥtRx2$'{#w3[{l:WȟEohglQ0" *rl"3JGhz (A7~5H0O@:ZʸR]&h@HBɏ g?z=Bо C& ?֚M8jS%v ڢ*N>AtWn `zXyw;XPi sչVt y?ͺzF]~A~}y/ϋ^d̈́}eP%s , o޵yU2lV><s\8LJSf:j̊þilF3F< "PvUm#r_a2pRِ\z,^:O&GiR<ЦisNTUFy.f$qFv>ND 4;O@):%@=B:[DOKI#Ő+ѕ#d.uF:UgQPw#Ω7 =K;C!ɏG;G2X=ވOX$5H cZ'F,9 6tǿIpnZLow,%:]N/丈+S$C#pGa{.AVDI4H'NH< Ў}CĦKwOv\/Xa( Ň-I_~۽57mN]ޓ~9{fglR9M ʼ!}"۾|ݺ|e>sMޖ-xZ ެ3- v,?rzGzdOti)OtsP/[p,KISw PiQjwγ,>MӽHQ_m]>'3z\{]v B3ll6m훕='6jF\DZ!bUZo.ׯ_zNa$ f.j7atCz[0At]B=`SñB@a[n(/Lv3r Sb8#r-kAfGŋ=8cz,|OEDi5 :b3#ѤHuX((G τ0~"ϻܣ`pCM|".sxsYĘd/?1o!m?G:`ޒ`5odc~tlJ8۝$3% ׇ0Շru ?ݬO%.I%SLD`ը$\)Y4,GInʒ:̇/[GIm>c,w)fN!$&=\) ];s'?a=cGJECȠ\L^Q@o1+?`=YSN'MCx9T:AA@K.j :IbfS]bnѣqaQt^k2(ItH9E+ϵБI&$U@V{K m2o9G! "&R,K0xlx8|$8fN p\0I'J=nh@ ڼ5y| + )ۑ#p&};6ɐ2h遲#4ӑ#hhϱkr\ (czM@ zZՃA4=\wŜh4H9W@ScdJ*1\Ns{&rA>>>PsB{JĢ wB3zON pœչ|t ѿs uzbxyWTR%(`mf ;BNw;y/|RK[⿠"tf\H TJ/S`i"l%p&Fvl=usY}BhݒG\oJiv00$b5>Au_V^[ :bqRNG/il?Z#d(F5!u}7~U.BQطŕgwr:MQ:Rn HbJHvIA|i]n{gym]5VzS[  u.js`*Z,S1 cjn#6[.>me3:b.@T`[Ԡ<Ѵ.9t'Sݭ̨Lısj0#?yԥϕF^Wz:cҀ+ST~Yi!%ӰDa>gfc+|͙WL>)HiNI s F28vI@> h>^zelmU<a<(hvlSdOW)v*IypbyM ~Yo(.܀q6EǗ?I5,Q&+Vj;N=IMbkf*5/j (6A7am0ų(P =Yx5w0¢  07FZ:xU $4F>!7JTS@29q 4Ѽ6vJܥJ4~ >::raS#~9`a Je89|yW7kvV#e*|vYP![0 ղ^댥Z"PɒS?+UGV=ouL6}:ؐj돷^"`9ªCK_,fy<`63Lnֺ{<0^>ɣ $W<<q¾htAt$P(էы*<*mE("mT2H11# ꯡh*wFp. P? (ΥaՠGU/u".Px+uw.!mmp|Ys YbHouz/uG^ ƜZKܮQ켼Z+*]t{јn7_Wi{,kկP-IϢw,}E .,C*Z3Kp־1Y 87aC ]u!hX  ݤ%TyyP& eKuah48>1-q I4ӇyDMmg*pJ{# &JZo{i>tK_ۂ ԢA[R>_ џT_ejOBCdٯVbJLe?^( UBpe|%`v8av`[a<r/Y%CA+LN' Vkn ڕ̜ KA,}IvpS yN&4j}0bOL$\dH-}_Xmf9xoѳGtj߽|fB_ؿҎN ZWE0i~~§Z/'c^І"J2Ie91QTMޮc*Sc 9SNX^g:^$}Ջ_>|>䐱=>_KWd/=3 1O7`#T;=<7"7UXȹuE4KeHcv+"֯ݳU"P>jBoXlӍS.i47s{Wg5_|Cu^YeIj\ϭ/R%T<ȌDckpQrLtBn1nMß@s>M_};W8j75؏~-qm:U}_9VT2+mz+4+r~IT[pL\l bMog]T삶8`ǯ-\]Z y㖿1C'/yjA7G+('tZ'ϾvKfգ7ifpݾ| 'yAF-?if6`fi$wIulYϓܖ-Jc-7zYkh&o5} =/ГF zl/?o:yvh˖Mʖ[8 si?'PW< iCN^o.]ݧV)/3$üq亴A䊫ƏC||?U~ bATK6Z@Tip'>Q7XD=H6V&:iry˘W[6km5<Ήs\ƒj:75ϡq:+yUapl"Æ) `=ʶ_|{-zfzs]fMe|#zJILW`E:`?AO颤9T4Z3GYPs^Oѕ5S1[ `Եۄ ChOG;]_aK'7tLͱ=f ;~й~O4g @:dx^m@bvMֆ[ /tmXxSiO{vko*,i7]\g&EL*~Mh1Qj^rLrVF2\#m+*["@k OYWcDEm n[5čsCX kk˶<"Q4^ӯTZ$wN̷.eUy{8$YO\] f͞ _™XۣZ|ʔG 73 4$qΰKr- 'suI^¨t: G&C9~o9v <gކl~Ƴ^̿U>me%7o%\ 7.ykgeDGeT).q,pJ2O*edc$X*ФJ^@ ,x2"1 ,0^&g]_1׷'R4 $l-5<ڠ1C[ R2rpC9}|:t9w$䏒kVt܉zj֬Tr쑧=mC_q?=4ߛJ1Ryz2%hFdrԞ ;0`wT%lB€z7ECu0{d3ɵ譨`NT;ڋiv}+'Ŭ\EEBjWx&BY%, 2Cd)hd G"GmK)NJRQrJ `'AtT,b=QK0[ ,A%* ruXWh}*nӻ4P~H:dr: Kl]5h<'2շ)=mkDi]fz\lV:M4l0{ͤ,\d/mD J Dh FAD 6#611</2RzTѓ9gןj}z@31 Xksc "v;jF<ܤBm# ift;t-Z,+&YE݈ȉ>ˌ5QK*]yPB}t#}海xy9-(WS44bz2c^v*v2 GYb)k|,GӤL` ]ɠ3xKg1kZ\X3]z϶<|opՄW,z;ء 8,0`c^9Us)S)uuWrogǿ:{QarjA .1X`4( K^ 1]1b`'y,TC; &sտ"~]J'jVZ${ XIeɉ7XjDRL ׮I'%OBm 9p~q}.YvADH7o8v}rJ(RG1dUN,w64~pTdoFUECF#3ZS"j6 eu#C G8y硧MZ.NEѡsU7 ?܆(/m6ե:ZQ%]~a~;tZ v\{,J BA2-56+].aVKLgrA8 X` 5Wknr;n.Т|ƌ|h՟|N7Co>{ّiYMyYwW F.;߸~wZ>~B6>JܽlU_6D÷9^k?Gb|n )#kwj?Yх"1U=~; P5o1E='WK<Ƨټ.k?(-ENjks['eJ?^P:GX;cMg]AdU(X[7:ЉCejH,OUNTk{EMɆ7ήNf dO@7l :a?hJfE+f<GPQT6+8ŌCfk2%BCU.IHg@j]`.<gb65Z+kإVM){!۱;{d;ׄv/A"?Ͽ:Ҵl`[h knۯZ}Z#Ts}Ɍ"5a~`IO+Ms{O%X6]&ZZ[P+{=V{*c_FymXkЅ}Z66E5˲xs$t__D-¥4P ~\{gAd+h 2/)/b ^n>5ZZJ-1;Y@^N݇'y7M 5AeXpFߑmru3}@j$LWҨmr9E~gbJ PS-pb̸?bسELʇ̈́k<7puC}m'6SsUݱ?k_ܮ{ϱUK iͿ)ؑ|}o˓wRMk~owFOqP|w3ײ5OS}'̲̓g/cAg6=!t' }~)bT_|$;nhh{ޔ~1n2KXwuclEG5h0yh/H&GOW͏,C [>{ڭI,J >9>o@`KYrąD^v2N'}Ć gŃgMOuHwNq,^rLȁe{kٝ+M>,:Bu,U5\3F"EO=d_?b4n^2Q ߋ O5ʳ"C{Ќx&xbw9usσ+R_N\KhFOg&Aeވs=yS!nK6@?DS/ɹF3;&S'p\.Z" V {_vY;o z:  `/5wЂ=$k23}AgcvU'_P 2fU;2fSg@hi/N<헎j]09Zgz|R\oS]/vx(׀'eF eO`QXnIdw&쮒t 2 *MLJ!rE6zaIo>:\ :י>n霍sJ'ې mq~Acz1l'z~2NǑc?n_6Tr"cMIC >\Kя'Q}BhTE5ѕȢl֞ ƨ%_j*ڴ7mChC!:c]1MiMETqX3z^ YƷZ$})]l*2ÍXFv]<:wtɌ3Nwfj(eQ"1sH+j@)Ih,ɢ$.zB(v; _?U^dueb.BtG-@DDNJ|EHZ!@Ny*Ya m+ [䆷Xb Pcǒh~ņ.lQjque3i1(etDg!Qr>A,AʦYWUmg+ Mg,m|=CBmI Ʉh# !eJ% qS&%~Q7^ V mh݄x6`AD؊!p%FbD=du] 2x%$a$ <1*wB&(`G&B&@LV6 :ZV` P 0YyDx iiEtECM ,m 9̎+JL-s|$*~\|4 jl<4طNEN h,!ڵ![^W-96u*32TF*H;e64#^t;K1{ExM8biE}2+ZwFh.RкEM䘝pMfp˸5SN MRġ+ _`2?LR Ko[FG>hCmqͶYQ0%-Ko%B⍚!(\]YLi!җ-Zrκ mbe]{-{\]V8gdbQ2l<-wӴٵ}&Vң/)`Q>g}M~0*R{Z5ՓxmcwW;|6OEv{pَ_jՊ;|Pzԛ5x{__ ֏MT|ee;nXj<[g9 .8j䄚%Ү9%?o>v[1rQ: n:x3(؛ug=<{wϡMq-93QR 겚t|IbAK!)}SM?seTQoN}G}W}ϑ_uޮ]tOIY2G:m;$(q&nwfq 9:ٓL96o^mSAҤScfD2Az((YAG!Č;Kk% ]NϛmJ8e{cj~f;wسt$46=KRw%E~NmI,Y{jYh-xB/'|Î9{`/b#Iz#ǣim J/_:/Onnde{I1fS^m_<ϫxknP|K6 ޥ uf2^tU7}cd6 t?{ٞh]Vz UK֏zγod08Qx9YfyXGyAͪa ҮWɆ㋳- (+ǟ4k QFX7xv[vWثg펎mi6?u챶&sWYDNv$j@cqYєqsij{շm'V_cнޡ1b!UZ~?9?ص/n퀭:XΦG3ȘڝI]Sfn2}1`:ئ(ŲIpK6M62nZXͰmB /HvaZW:sAg-v nJfuMs$SS=Z[5Ηӵf6N^ui='kj;:ӗM,ktbWu]D$Gv7U"ƍ+!Js^:FH0)d4êGB ;*$X8[ӔB(ޜj@4*]%2e4 v'whL-̚;"Fw[dofV/BhjsO\©Kp~u <ߥ7tk|}MgǪ3g8Z|\,}ՆPKL:6427,GNW{uU|ы譓mՌɲ>%)jrj=nц̊ܮ2X4Kq\L 46`[DG̵]= +nu)f,P6lonòSͭ44_l_|JtiFo۶wulrn x%4%X3ķ?ݸ3þ:g3! 1YQzQQo-3:-?X>ykyngqfu8?_ol|W}=6F&)ݔe7DwWꨓX& =kТ/t}% 9lV2Ea&7ZqӝI٬7Og/H'~?t㷿?RHђ,CB k>_|].+`x o<ª[vjOxa!M(=?@dz5LL$Gf&"t%hJRJ6GbExb~Yzyd4z "7|a-z?R 4%QfAŖ݈(iOtBuhKW$5~.]uMm͝~cS/mۻ/5͋u؄E9ݻ{Eqg=+j.jƧ ?ዱ{;tw?>ޙm5I+;Փݩ,ElM! Øfӱh'&$P!$BK![3{E6y`Wݍ.ӣ8匛޻X߶}iK=*[ruΓ3dr-rd=e#bpJ2y3}O:b Ѱof\9[ecl~EB ywл{Xl[| lao⚉NV5̛m5ֈA ɯqMX D(qkdJIߣ]V]y媥-}nA!_۝}ꗯnZk_ڎ/!5.St-0Tc牫0:zm+H4bexT7J_ut#pm fμZy#C _ _: * ZPL @`(QJ`˄H3HZ).e'z 1LS8n?(;&$Q,3W1>$L0ye&Hg0LsGƨQTK#Oq:{I=;2tvc=nا?J͏A4H>5FϞOM9+̉0sʑ&^3 IXV|sՆ5M[[Lp%9~lDKU l_] șP>v; .埝G*yQ4>}üV6@EV6N(h8dM/b4f3ϨqT> T1"k5@kt H5+a>PAhrqí$Ez$>/Cz%hd뮃> +>?/g;MuץsI fgQ(g̱ZYˈM\]21 $AOnG'o~`]pV+굺EUVFk~v+yjtZ` MWcGn03gNmP/ji͚lJ4FԳY`?B)Њ؅W Wx(KX薑"D{O#ݥ$f8Lm&L:PBzR9cK})RV# X'>域&|PVcӊވެ\ITLT)&IxfBͯD6XdHL&#`,^)2؟Z("fj9 #>Qc[elYd=]&tń+40cm\lmMSV,{?5y [6|փݭGǖ1DenDAV8icP+ܥ+)8h5Au: 6I Is"7gat}$_8 p4b?>n&!z춡 4u' Li(&+?tu&1R {߹%ƺW,[zzZV[^i-+nM_\T?w"׹ݧX\W.l9БݖbFNҋxJ0BI>@}NH~{8*!Dm6laJ |A'17ۻP)ⴿ٬Ň֡eDJЇg]8A:hh 1ֵ#lEMevU ȾQlb"YW(< 2"38L%e(H[@$^۷FHޒ=SK>Ԧ8Ȩ(F'g0 eÄ"ț&^ӣ[1K$=}SSćbH9DOz>F}ʃ ax.K|6TRd i6ӟ]:7Lɇ)Q,9#J'g15h-P KG#޴g+ǯh6qdVh#;ob^Qf0%eGYG[#A'K{ 4::7P7bP&T00 {K']8b.+ҁ18p{3F#`κwʥq4u~-1'/eŠ ~gGz>Ϯ?]Ũ挷L#͜rT.}"/MI,3 u#ST>P[cs3JqSrrmoQ< xQNZqc_.ʁ 6a<K)QGRr77P߀sޝdos3z|ON===:Is*vhYnqGzd[ŝ]׵hUK~z㑉=4Ip0&20 ][x 14shy> FǶ?ue""3F:4Z"`0~|P3SX:(C7 &Ӡ(SF{s nqx.QVY*ȲY9'0n d(-̭% !Y)$H+~^ʍF%Q|:X`1يWVs#qm:̲֕nm%&~(!uw @3su n+] `TKXjEx&0_]FdH7)h/̄21YoD -Z %|~eNydOpޢW U/7.1WsbY;МE[Κ̙vك#+;~ ʸS2Z93&^CB4ɹDV~2Hb.u2ja bott•ͱ嗋X6T;!$Jp BZ!,Wqx*[nKΰ2Et,mO 0hNQ1:)W5aOH.J:CLA7FcRh`?4!|s~P9ժK@5!id_/. Z^לw˫7VБ2y<6Jmt!EN0j/,QX5$-!JdFQet)Oa01x*_"UE>\uz~.9y~9Rfьp =px6 $]uz= xո||M=5VNƯ\7GckWV:V@7*=FBQh!pt1]#ێ<~1(7v$mƑ3oڵ^g*')G哎,JQPf;K@$b8I"H5fZqkRԆ66vtGRThJ4͠}D;%73]9TÀo@ƾ`O'ͥJl~`a)%y~L*K50ɋ &!M :xe `U|)n9z*87DdT1<8rA7/j7İY7< 7j5p]02/fYӣ|Ʊ̵R,qΊ>$Q~S9u^[YVu&:>OP/a0/\@VprG++*҂sd%*x<&e6eo<gw̧ .xkʁ$š)83Zl]2?U/Y s9Ɩ75lyX5zg1Q+P |!_Ԍq1p3AʄjXkȄ:hQxVYWUgi}{-e Á@=0:~ (׼'Հe_Yek驘<3 tsE&*xɜ[U`Q*%iG=MŘ$။YqtHGIYCfIJGޓ*'#ҷG-H~ =';Ts)CHqJԾ#GA=j,v0[5=yySs` |kpXNȾx ϓϮs$4hVڑȾYk(W M}GވR爪;% ҉of}e!ۀKl1,2?$Ku|IW3Ewo|U0yiя^t.'qk=@bBxhQcGE )]6ZM&s?11T\ގ :$ "g'f)G9M!$u| c ÛF:ƣm@q,Z)ڋND T:Z judki`J1v'/Xo Zt+^)eR ڵǷ ?X4ͫZ3}$[`/ոn%'G5b,: z%{'|UzUOfx4K'=)L/xXZUe9oޡZ+k "k*Q/:x(MU,|u"Q =)|BoW+χɷC5RzR| W DȰQgʫ$@nхn H3 1TF?'0AċIah"Doxi6m/pVmT&F?Xӏ+OWU4xʻ&Ww"KYt_PS@YFhx{Eh e?Q<UyjY7-HƲmn @-G,.mMۗ ʂF^Je\p8'7;7~ݱڨR@A`>&c4hSAkej(KvYDZǷm2w9>߲kjh 1Z؇uenOˣH W Fy\rt)5҆%뉴C z8C(dvؔx'pDDi !SL!^Z}Zkѡ =Ig0ƬO'KI;iړIs9,10f?\oK5󔋊bKkWED0( 不c& K}b>=UVZ#_KF !(~'`Xyh߿UooZh4(TUQӯ\X/PNyZb 3حLfM4$DA QF2v"ʽr]liY Cmˇ20~mPhN(~4 cA4n 1m 0ҋiùUuzxhp[EhgW`vÔ_dJa*='zi|Rrhyh-ĕCYTKhF|JQ4N=T!9rQDŽTA $R B+z.֒ cJ @1HlRC2$gP}>)^"!<+UZRRiFR^f)0|4 LjS8R(ɓ@(' õ^ߊ8eosVP9"}I̍٭;@*Sfps]}/x`>0 f7KǡGJɥ7.#XN_bK ۔`RtͅK{O`Zג3,Aq +HrC@۵K-"BeE8i9OdͰ|4׼\Vg"3" AL ,A%2nEg{5k3d2FKiN&=ov8`5h`e2Xd͠!F%^֟OP;FgȆN oG}!CQIAHoNx4baS7MׅmN+\#ܸmܺgέ= Sŗ7֪LF߽9r]9yQ,1Y31\4vUL&_{eSDtbʆ6q0LF;`0_tfGLN_|x54= ⰌA$Il׷r`ޔP6`H?P_ =YXZ` 6Oi ʃᑽo)n6{H~d\&{>{=f/JON3%.r\i1NUړ]xI,PvqټjE0G2'y!*[-/ Ê3FEJ#"s0J#{GH)Kҙ~lҩ1QN<Z[VO>3}61wgL%pz4 j5 -YB%h! L˶zzrfOZo0f){O jiZKù1{4_Q)Xix]@uaܸ)^Háx5 x$9Iv$\!EvNPdW<&)Ows])^( i<Uk'O*k @<;p}>`pޡ`(.ˡq?"T"A .0 ۾vrΓT g}϶Ia2ykL:ky[@^%Ic[ݱ9޺95&g Y zf8`M:иfjL:WSs'9G̯ORWd#G+2af޺1ZbdAo#a%fcC!Xk`"0ct38tJ < 37aR7&..6߾pN3XR NZDgkTQh֙AwA[!00‚ BsP;RՂZc5z2XKpj$0,SxE}of!X`daЀH_jAbufԂ:BEDRC`Z#ܔj!qIVa RR1 &K=fv^5bmֹuEVKZb҅ˤϤ/X4+.+P:?cz$:Sik-VWtG|_5 E"L'+*4Oc:kyY r3"M( .lr#Nj#V6F#T*qbJsRY_(,j$W3,$> j}h %*ju9uYcdBY$"CZ2//zG@O:L yqjC<`p+<#b 8=~%d!03K/[ <] t 1pXmV,^\5!fV9Kа~ &ME \4,j|.|qމMIzعՆ@aLa`RG01)Pf-ֆ%\nP6Pe ;._%BJ{GeK]{uq\}DS2iYH`a\jgoMO6pV+4N ҌA$?kf=̑ր#Ky}(1W)GN^APf֌R>kqZ4ii/KWGؾ,wH BkiZ؇ +4ju b6VsZbs%ޗO,WLUA=O?' =ZTJ~:[fΝxY[w.Tg[<Ǿ} ^_aYY}sٷ}F1$Dwj [/x MGcʿof^6w+[.E>G# ^Og y{ {,; Ḝ [ADD$mHNHIh4$*'r 3 昈oVm %]_lN3/]#pBp/7~[tQ_Y Ox80>dLO;糕aozjթ|%]GNPv[ ں=9ŝɼ~se$U_5>g_Ta26,E8_=]Wht \uڗw>2Yva!0mi%Rg tP$}w$͊u` FF@8p0r[itr0FSR*Baj5X:B=X>/kY]R:i'}njso[0*[ T_$v3@Kحae`[QR<4Zkp|EtH(g4͇ ~NwklWx82j{\:2yK:Oc)\@ jG1SY}ؖ0(Ok-nԂ=}` ̿ c7>X]eVh8}]uo#WC èV,w('PͥI4Oir j|3.M.BXi 5Ph.SD,4)\QӠʯj/&ԞA%,0HX%%SdHeb8n ͻ0YdĖٳ#7xGU\;eYmX>q@Yx]/z<^aсknobI#|`vL܍֗&e} v<+S0#e J/\rxvBzrX'}6 H31-Vv7S,DR ~eʳܹeG؂da"5=ӱh1v<2>8ci_zc9ٴNY8*&?S;L"|6ing쬰"W7kzsa͔R}*QW wMzkZZ)ۥ5fbɱfGt,ꩽ~`:)˅eo;uіI;4?cI"T%3&w6G+ܚ`%J:c35x.^|Ny羉/?lW|mXU}$ u/ Xx؅JR#LW3uӲf8voJgP&+Ԇ%&/0Nscqь>wa`Y0HogrcGpڂg<=#kkj#z뒍`F:FSXޫth6he8J׫Ur[.=>oEv':3g9$z@XdbEז\_tI_mJE\ E#py`i@=`HtfcĔC!J젴!) d)vp%֛63Ȥ..FlFbaHџQ`= sQ@.@ދ뢋 W5F )}E\^J:^|ErY\`U]IręDv=03 I %yS=\92://[oj D"^artAѲ,\d61F 0lzHZ)--gq4hm6{.%fh@m4P&ĝ6ĮXƌo-'%vZr;sy62&} ƣyJz`KVSj1t<%$(QNBm6h5&[^rN1^h}ބ΂ZN'^GgMo){(P*5x )x8*Xj\u${i>ypҲbO\u)fe&V&lW1}:328_\=M\\uچZc?l[N%Smxد^'㿏? ,o^[ #/Ų9m ΄0!ѥ~50($|A:A.iz_3[F]ڮlHG^ pU;4]5eY6u ,Z2 @,?^ilUBtdU{RK2 4HrFi#'w:U¸!#[ߢB8 d`쟎zH0{JMnv%xPT:RKE i LsLOo10/4-QUcr.y|>{_6 !eEwQ7 << jfXV'6F*K*#F '0AM|Á=*`+ړP1e+ZXB6@!2sI5Ͳ_]H=?z1.:\mRdm}N[xQD b8sny~su :-gz:Īalj{tm4T]u8K87^WIց5em0+ @~)=6Ӂ ZA =T]޾2j]NˆS-CtPtX-VR4FO-%&y*)k/ *lvBQmF+V6"|>>zj6u&D4!A'hx$f&HgÉB^E(jjhQb o6b*-}. =:3Gu== }=u`/u4qm9`v_8޹4|7ꯤp mU{{>Ld&3 B-fǂRT+nIJuq - |7 ٿ>¼w+r=N+>A/Eɻv@jU8;Tg'ȁ (5K~v^爄jph\J??XjzwlX|ލÜzO@;i1O$YtHC1UOk0q}>H}w; 3iܗ~OO\S߆ڥ#3Ϧ~L)$V&_ b}($ά$kR3(8 aPRD8ˤD(O.[9) `0ӎ0H"*@,VMF֏Ĺd'}~$s?}pzXe.6sm3ݜK-)TALӣaYYb,zl:q6 'jGD O  |9|)u_x6(R $2 f-Ul;AUU L*4To{!;pCxYkoJ8 Wk4OVٍoUC.!LPx(G3-~ Ja:MxXI$zɣk@_޹䩍LƱ'7z$8eytjG6y،zV*0 U@'{lx$(L0dSDHIXFb xv0s**VY]$ѣcMX]4ozU?0H=Wi %+*`E#XTUiIQ]|1ܗ:E pcMHoB "_Ƒqk]iӔ>{q| ) ~DSNt;f 5%hC vDK/U1Gy-BUy5y]<"'۽ Md/t\-]9v|-A<]Ivd;?LgW[B9ټ}/iɬvET6\kɋ%.<D_-rXZQ!@INX޽tZ>bhp+wSG;/UûGK: ֮7:KKږ.^Ր9.!OM1ćӇxO_%!fqQ<@Gz_ׁ!g>ڻE–$1=| 99p~ew9PVo˳++ ܢ;ы|OeN {Ik~npl2S5g2ܧG}tR<@1g5Ec:60<`%7|RC$h9!0,x-A2!z KFqE /^b@Ht bi'F~c9gv \j4Xc]zϣ6?s,Qy)k9O!١&@Ω"|m-"Im:jsq4o_9uV&Ma5(>wg̗ \X:XP}D%GEq 遰Tm$yrԖ> JDX"/$Ԭ%/a6qUR& &բQX\K.Rv D8PI2 Q3i@5^vٵ9  V8BӇ%L+y=+Rے@'H華rJLZujTa28x"؅d:N$w /HrD$*#l8*y'h pCu`23Ӭ4Ιe}>.ձ9?e *\8J%`^D:%<[ŮMa WMR2/QJTk{!׺̪J&ٻZ6*S04f6?]FVojԲj]㴅P3oj$,r\{cLx2Ytf,6WrX\f Qw+l;Wʹ6 2uoѧJۇMJ?W4tD(bPE03,yrKZ#WZRUP$#GpYY[gvu-5T7?k}[=uKdȥc?`FCe4dϳpUY TP-l"j 1bre-PJnV( /bo 0Cd;=a!Xp F`VD[TÆaQ]Gk^=~9VK\x^[ݽ]\Gc˔ggݴT=.ZƵegYz%hC3؝QŲѫ[ݻ]5Ǝ5ti>lQ7IěČc&0SDo7m/MT.n胃\?ZTBf^̇-5Vʌ| nYt/THN'A c(M0RGF8%Ed-;Z =;u?9gNӽ-;Su׍)[:0PtNÏTrq5ʢ&4{XV13{~gp߄~ L2~%wyсL$DYyuK°; 2)H<.I%sވb\'a%a3j@} R_ kSF ~Mt%LZvS sbf0;-#L";~Nvq\S3J9 3oN&h?E$~ktu?/_ݍO֜r=|'مv`Onz?]w9Oζ-*ؽ}%Q֕?w5|^A&H$zgq* t`TKFzWu9 _Uץm0r\r\fjL\b~=CԱ4Z|[e{hM.ǡ{Yִgʶ۫ $~M"V6?;Y:%=v?̛t;G_ru  |CnG͑7&<"PD Mcl TL$a2ϤSi;Usj 1aO0}!SBZ-H*|,SF*=˨Dsm|%29x>xۋU1~=৤ />@|܄"bTcB>s| Xٝ=l_׃>Z}7zR_=V9k;X}\=ry&ֈ$ex[=3da "h]za)x'+yb§< lC7@)1 _}PӨGZ5s렼aؘweoV]ZDyp %gw֡#OwLF_2'yܸ6]w0X[,>DO,Dr0'ad|!x\QH{^Km>Rvn63Wþ =ac;0-k} 2~ųsםyl#~1\ ϡ ^>~cB7=7IȠ|cB "_zW0JOPѤ]A:+!]o`K&DA ։Cn;d3:}cR3|,'b0AF<3N͹8z^Yg/~9]m3I*`MGjb'{|<#F>>Hpbɓlb#BIHeS<9r4vesf NRAQar=IT&#咸]7l&mmjd2嘇o/,{Ҟ,>Yp)B}&$/p37i0yy5KUP&m&Ilgi?9Aߏ#@XYQK#"hG P/(bOerL8!hlOn[قtA{c!i0 \!yX9LՃI |;4ՀSt/4Gځji]/d;|ߠ68;}_?ܼg\k7;Vͷ |n;˭^7dyBL2,ǘ!uV8e6ԳNaBΖ*Y.+&B f+`:C C1+ >Z: 3pAN7B_@{]@cOn9+,^ aF1Ә̍nm=FT^%6dQ܌mhݏAoMXN,(Ƴ=k> wZiGp #(D Ĉh^Ē\ 4i;| {L:PJ.S@%3lR%JU@ F#TCP*XdR`?l)drd*U&JىjhI`#d ZY% l0(8R4f4J*S+_h4#P5FtZkh͚?v=HP.SH5f_o9EJW TjyocI+yVz LP2eޒT(A~R}߫rV&Dp!QR{A$ߚL߂2*#\V|Bv! VB"?Tzj ^OݴnW-r/:cO*L3N'TCv+qYǡ:nG_`ѾQ3ꀨq`T= eSRӀ\cg|dk)Yܩ8b^3# >7 $ 7}cu{q{|>Ӌ%T$E?֘ H##;glήT]؎U%Uh,?+P=ݚS63KX'Hd/C6=ں0-R%Eɾgۏ!ϛ`(*ygc#`:@-s0M>$Q $?}d1p|  5MO7{Sh\r?koLt6r‘6G5hI&NVL3`M냩bD#jC"YKVBE3#MΉ)TLqaFmhu3fx9qX}< h0)_jN {hR{&N3]\bi57'N2@XzS1]OG8pOk5 H"zdfQO@&M !@.O0foz*b1 ;+&+R??ELb %_R"`O>)eq.Z J^ͪ7B_J πc$,z_"Z,@s;f;~x5|SkpgA[vecafV^{ۏ|L՗eXfl/b}{=P[z@zB_yߗC@Pzn29{؎KZ/󚄑c.J9R0]Od зьy6ΘvExu+'^xw` Akn@z{4zz(-?o>G=䓓>"FԇYԇ*Z7ҏo*eո_v}<9J6;g4 >|mM+.{8 {f0/MT[1e=X߸wݕDKK,wDmKjs%MSⶦҜuCW={vg@=,w/Xkn[کZ.Z:HLv큈I,jԗyLBP@"XIL&>zC>3N}< f#|jmH#g9tu`Z*;HGTUIі4?+K/^dJN!(r(3 lbfN/9q?PF=h; vL>B2yO`yMMμ6nڿqN=>ODh" 5_ȝlj&Fj‘dҀċz"ԢO}pM:$2J 95ZV  d2 y9;`p{#MC\fvQZE 9N`?DBk+y#Ej#![n^:Õa+%eFpq'x=:2[乍6nպ#+u:ᭋ5͚i0J3hה 3m$f3u> D *ĂQxgb%!j;&ݒc__Ob⣨w+$HZtf! 'Ɯ{>,#u4;JM+u}lZ7LPiGaŽC՟y+][8Pʮ-!ŃyN+uG}W$7)}t'Kh?z嗟T|"dVE{s(YQy򸧤9k!$u@9&Ж=&mb˝oowLIl-obL}%%Jݏf=)p^5YR zp}c.p46ZL b2ˈfcH>1ODPɁLǔ QzD94O&ɇ+Tx$ bOojiF*Ƭ, f- 74lutJv^e*b.N. ֠W E"u5`QKDhX]CfkԼۚ+,nuTGlηX lchu`<="#/w0 x:Lqtsxy_L$@F@NYxj1Dr|KF}(J&jEc^tO`qND\lioq#]֭*vp(o1ЎAk>Y_=dtOO~qrpU )SSwR豕[Kچg̙NlrkJyNֆ,`ȝe1FmF/trF\}pdgB Wt+S8(y9ZeɃ]Y@u՘}j ̄9O!]!w"(At|geP LDF"n#1G!bN]Xl2ScXihU<0xMƆp`n=kMS&S\̒Lוg^!M|mK~;stu|t1lT.v_L܃A}z$(i%!V7X' ["5]P%[D,d?QH1-PK*SC[WDn$,26䗙t&`R|qdB 9߱e#j4Ru4v_QF!,\9~h83xeZsjSQ0Z#J`,3Mn[ٜU2Uo6 /j@8B*bY 󁡏P{x(O8ȑ@gHH A#+tNK)V3lddhؑG(S!*F?CwY|{a]>|(=_" ]yy?'oDá(s8rW&nA6 ][>KU'} \n]"9ƕKy+B$0@(GrjBʿջU20ܸ8N) hJn"IA9*rDx8sڣQ&_g9+PKpm>8ϒl)kJϺpgpB_{mdZΒx!b: Fhbv#à]a#&y\d(Ëוl}4/\ݛ[ &U5Zp(?@Ίk<NJe|՚(?l͛Sv WGDm6|ɜrl6_^j+ ֤ d.N.7'7mך BrR6wD!D9i^jcRjK0rUU&3\\/d=n4v5=9{F8E.Po[`_/nfܸ5A|dC3jĦI~wL9ekV\ʬO1|}zf0vLXZž䋑3{aޅ{fq:Q7nҸnݽ'NHTsl\֜8MvJC&? OwMd6$8{x&htLg'sB|g!=q=n]?́n!Eݪ4?>dyܬ'7V?yh,9*n)Fsư_tܨo rԸK/}d=j$Y \t zd}jZl#]]z# .eO ~Qǔcf`aE3WWBp4#%70M`190.?Ci*Vq]EX4#d,-؟+7Tlw(t CxF`Y)wb3rJ>A&VE\.s&2j zҩ~H&r\.D lr>i|x%2u t;wE hr3a7@2&)tѶmǷEu(8WNbۃQ\ρ`\+nR k.Fcϕ///Kc"Ni^24#"K"ú!Oȧ+'x&*'0G Oѥ2\K&QzQc眅t.}f'Ebx ꫁@Β'hP! 0o]];y8spClD]H:Zx!4W\`;31e@t񘲉SqKx<]O:]pKz7q3;w ?q} wf{GL9d֬!&̄3Z'-%8WQ]:Cޛ@< } 3c@qL0gGKr$38~;Ы@|wYS 3V+3R45%Dw$Q{ ㅈYBAr=< OQOgb,xe(~֧U"ձ-Z J^ke}р]}@|`Rg//+AIY,,cV6C^KMFd@N }UT69[cRM52ydBH %C?&90"931˨94r>«!Y#)I :Ԯ_$ϳ{p0>L_5Q OGcJ7=:p'1HSJg&0,J:N%ۺC*ŔzLLzkD9qP=U&f3*g&KZ1ŌJڂ&A(Žy_Jzu0is c3w[Ft#;l`좉9?g#Mz4'&^hb* IY1BRi#wῒ2s633>%eɞjS8Pt?Dgpzx>Wv`ie\UᲪ} Cm4kZBΫfcu ]_:M&de96qѐ>*Q}ΛW->Qyݵ#v-Bޑ/ز^{ǝCFؓMn]$޵yCױ&|AW{{„}Uz 1I61g#&bMVLT~/N$ q!pl㩅 0ɂ9j&j :Dl^8RUTAC;uC.s݃.`EhLҴxmܢƸ$k?>{ܒl.ve)>BoZ//4%_H^5k:'ke2oFS9##EVf/F]'PNAVB@b8M`]ϸCkuPO1#~b C{LOhY4VJTv+gI{[ H%FJ̎bY$E:TsApDʷ(yn/ v2gFzv%ˋ\U3SCl<@! e:QlL#4~mỳHER9 '`hyըiI.٩pKt_VZL= y|f|; 輥& +L.gfnaƈb/NWa]!M鲛/ai3GQኧ 0|uQh+8B l!IQJ( LI3EHu `Y%>.hwt(bs>_WYWjTrmΝpQ^xpMLe?sdױF&w.N̛Y-c?5> טiTfӕ 5Zۦ_ŗJg(KRlt,q_>\[Z\RĶKQR ^"w.@ZR]ei"6 >˨2·sz"{!>RL2Ye8U}DxxbT0Zm\T ??"wHG3HKKJ랏;q|yy]-;dH#ӛ=^N |\@k<fLG@u]dz/Ɖ240n(z^taJP?W_ˁǭ F|Tx?0C%f-HPkqC#>gH{-n2PN=(zu\ AQ5VM#ݐZR^!P{GY1}@qq\Ht$#BrVf{#­lMK};rv{vvk}چkdUy鐀 #9xܼ:YCj9EOmrav 9e2PN&~T;D+lY=E=eZx$eq2/}W2G u8Jaߘ?zS;GK&1S |w~BO|$ M*kΓWxs GDP|Ky 4 4"afB"@.!l Q쌨 ~SL^[i]&Kq9m4祑<-0ä/k\\x+jں0CJb N1$"063f3hfwqL]̼0uTb-#2rM1"u*K 1 ]?)3JXӛϥzOW@́͢;g蝇>qyY_`_y7ԇ V>)69R*Rd[Ь?(M،coܱ[V]frIJ`uqM% ŭ 6ڝFFrB >m˜# />Քns_51X5me˶_ږ]mXK‘O/2SykX*O':m+!'Hhg$~8a:Ewe,uh{EA,h) 9y,7顅L2**_{ߜR9˟(iΞ{yN>X'WP?8.0.k2g/k`ǬUC![޲쑻ї% eNk[**OФ@ *)t-:5{^{¡3* 1ń@10 _ $^KZ)JSrX S`͝+wݳ@{Nc.@X .ĝ$1d(W,,>~tqAWNc*it:0i)ٲGGes-@1@6 iȰ+?. ;agjBdlذXR< ]+++*VYt]Olqoyg_*!LT#ZzQ!qG9`ไ*O#?|lf{Qta gл|=ۇef[OnqPt`{c43fT\wG³lEFf ?(`3x;(2of-z"sƑ@IX4XuEBi]1..F"L8'& I|iwh3MqΐWT6-UrWʤ8"~XRx8#'tdʌ[7@I~V}Ãzw/wz^/jf۠ [rLy5v5mZMݖU}þSج/)xi8h0v5Ae.ʏBAgSSz?ZGL=h7,aiCFMI5;QK>ٙ8ng@tbK~d ǜxl:PГI$>7̜'W&_Y[6yknW:_-)GUEHz,T yIݖn4oI\<"6|W ?_=򯇺k׬(R„'zRjNV_)UyOf-V*^a_?Mui/tS/jзy[Ecw0'֓B'>"]4^]g(6'q-wm3UTPk>i֗uX ֯DCP4n5Ӊdmmp:6jM LO:Mq: lcu8]ngN Rrr@cŵf$[b14dz<v B4 ?xȟ~7n $a4 ;f+ٞ݅`IlaF33L.a61c&ff/ a02g"1K-5ٴ#!?q^c!,+I!=y'B(->h*sЅ$XS%X` (fr,f֓ fԳ: (.|$b( Xj@)%.eOs_EU==}$d2I$CGHpDpSnPR@AW]pAQBgI@d^zϰS#!QtE:PgqYcb .fm@ nѓ؅ =t+zg%TZZ2B_isc lvt,E#i{F+CN}҇m@'pgNJȞ OfDVo_f6,KQ57 p)CwdF|zL*F#AøTLF4k4a %:fȥa-< 0)ͧOkFHa ] 48 VT} )hU'J޼ c)2Ml4Nf' 0+ sOЗ7/@ҟ<̒s[gDcEy 't 8eg6/A3 w%{C}sن'֊M/)I GFo?lFFNny ǰ _|@ϸ hD0WQrxL?`|Y LP(|Sn=4 ~TۗS7>&Sh1`Lef@eCP=MEiEs E7xI600ى䆍ųdq@=7YaڡkOlN_]k~e^3kc:~Gywǎŭhݻwl weme#Cwf8McshNË14d}zc#f8IBh ȷ!GTOóix?>w7ܷ4{{U;>dF#Q&m[Dj&EA2)aJL Bg&UfY):f3sه1DGD,=A#wʏpBYLu~EAjl0`&[x@m}E,~JZ´_H;[O}hؿr,M*yf,ͬ2znb`\Dg]ŝ"? <.yT4M&a SZs2jV Ӻ = '7D/^7ִ<:͛F~*7-țM4/nzcK's>A,-1=SW%7z0$fK/a-1xx Y=ֲ3x% Ļ[naᖻn-W.斗rBPx,l#M sŭ/攗c>\#>J$tSQ3D/Lu g1c㏏Z,cA@AcZObQFC,rc!"DPUl, 567BdaҀQr#*U ޢJ*R*^PJVAS{vl߿r,;?}3|=]t{mn{z{Iוߐ1c a! Re pUjLKLLs&rR0H'ʛo^YC!1$lW̕,8cO?`ZV9&bM7L('wwl۠# k'=*9a6ݗS{\#kF^oa6w%u0;55 &[[@fȏmns'D IYq׭o]9q zilzE> /vgV#(>?sj?ߐIȓrcRTb,Y V$Hm RxEG/GaL0 E 3QQs#^ʩM 53dEUI^^tëZ:bɊOj,6OnMFIc/k*XXRnkH4C­Wau#EU>45tZySʓ,ZNT%N$qN8?30/A~j vIS'bMz'׊bx#Agb9BKK (M_`xYf6IvguiUę/A7@-eԦ.X_ւ #\$HL3ZFEG:#3Q|hM2C]]JOUe_!<`0ߎ 1՝N\\@ӧ=#ҥ.P1땊n~d=Έ=p_K*qGЖ/wk _y*~?uH=4/ec|M_6{_/OK߾EmTh9#V4t_jKηCkZMk.(ͥ}ބ+Mw3T Sc#TRA+4[v ܨ"}.XĠo4Ӝ#M)${*~7=JA'I66&iO]t`{7GH!DEwRClc_cZ`{cZmpg_v-߼~q'zd[^`ԍ|G6u&`'p޽nMYr DNnn=*zcLaJyؿ@9$-5gBƔkiE"D߉0LS3\t8~gM3'IDRM'^#29(ab F R8F3Ӿ.͋g<8c1Y՛/ #x`~}) &c䭍`ƍh/g-MrN3l(m(c%oL-3{>g #H=^6(NN=P2*22-՘ t!|ۀ[O)7yܞZ϶.N{z7D w=17$یGp&~~[S>8)q[O#P|eq:bt'O[Rlr׊j 11 % 13 qu"6%{ u9-rMhGznfz%oy~oFG%&:K<8msleqIԞf{ФDG_, ݯ~|I{gCKsЩ,)t=]8^!y11|:¯ϫ[qBaס~agKE3c2BnAGD%zvu  _GmtP zdXZ->WjîI@}t?nf[Z'>ѸcF[$@m Y` "- ~AG֥ bN>T^y;1 s~GQ;m/]#vV|qs&w S W_`aga|E^ێ>q8>\l}Y[\ ;"L]<-36#>~Hس'{Jv]U!/+u`*Z G\:+S(FN]~,y 3/&^n ^OTFD!ձ/Ll<4c0a@wPWyA,I ?VY4SF>LbrzV$I^G+J0J~ƺS0܌ *4  0X!fE Bf@sW OW]~\$#4Sn}O\omO^jm-f“m/:[9cZg4g7/6SJ`J|w(a,gOPEBnDWRHElfLQ?)>:m!"ĿEj#R t!hoAab#:Z S8nlۜDky[bLt0@}~WAMkz;t=1[HC\3C")1H$}@0Lsr8.@*#xW}Fk! Hn y9O:B r (DE@0mT\bWlE)uNAI"IrIiמRW0Į<Ĝ_bd#۠7n/1n<~St3P8D, ~}-NG i4z[ ,סz9#)"QT"~юxhY(|,u%: nC$D5:-wEQb Τ(oV2kܸl8Ajp et RI:I)Sl*KӪ7*B& id^UP)h,la$bY |RA~aƪd*r)a=O32!`{YxH^g`ZȒNipZ&U60daMRȥ* IVg㒒DU?g}6udڮl9 I)DK rս ^k"{IcY.#$gA>U)Hi[e|WX&`80rBc- jnv i!$@^RJY]'seRYW_|lSe@04hMT7t.AmFBy6 +u|/a% I}e*;GŅ 47Ym1 5kS%ɘzYj/a^Vbbf>d՛ ̜"23M:T- "#cQYA<0ݽnʆB̆`>.NQQvNw6D};s+]Dw>ٴP@ E]¼Hk`jg ]ާ8V13h7Yt,趶c`|O;=`6GjyW6Tw-"E^N?[(}'o8^ >{HQ )n̦L&b[(OGa>GS)'eVUhW^W"@*4WLP!*&9fW!XH5ӣLIe"z)*fyRR(".=i^F`(?bn<<p5㳶 hC|5#--ݻ-GhPlΘmCC6EM*!Hg7QG~irPmV\J6jN|$#DІy,]"N_xF8bāiaJ8B@B0$<uJ%FwU霱Z:M>ïp?;Yᕸ_FJjĢDlDp#LG׆o*>#HD ϒguKmѦt#"}'iuBbq^+pL{#?Cԍ0QSlaF18xP06!A|M!vZq%Emc&7f3W3#^#N-DR ;+Ӿf*# t>3O1i"vqѵ"qEAjb_:ǵNݩԢYXXf}^oJ,05eUN?39y3sr&?n[5$TWyT6xbwx"w@4\ (BݤXX$H'??Y*%Kk3$-<+ V*6 {l'w`eLjJ Jn5JUږk,޴ N4{6{e@ <ύ菏K= zvh%2_K/328^A?.- l{?>|hڃ߰Xl7^ |~ ef}]TaH6PFI= =N\߬VK;#cU.Qe͎~M*J[muN}Cw0){,N<dG, <3}v7ٽ? 'pw997:|bx{`4zj`Z =-]%ZzݐsCQmA4+˵_/vrS!Z'C(8sTC:-97:0jfzqDO&PgНިsG R[AC 6&=[7=)@8)څфŋ#{([AN/s4УSB^:oIEiI;T$M蝚Sd" .\WEܒD=dٛLDo+* ­Sڦ#@F); ]<04SI1F@[7?j!;wE,Vd< j'nQ**CjB?mq2eۥ5GjKGaC wNRp744}sWNC/' 'p):ɎYH̃LSvr{t׍gdc'+Qt(|TUI%,?E#CS|^UXW 7EqGdkwE;![Y$\喲*޿œc%x; =2CGm^ ZmyQm_E%չ.)|]0 gmK{?o[-~.ycڰ48Xtx+嵅 lRI&0$;+jFtzv˳39NZG-=wn@t?knggߣt{tW \ 1 tEkQ`C#sP誀 ko-$/LE+&\U҄PnuK}E<־)fk6)wcUEn5nk:WqFӜPa*okT%ޮ/,\=aDBc )θ ~ 8YX-$#F痳Kd 3iEŠ-- >(Nr"]&bĆݥ++#GV"dĂ|sPZX1N  7Ưi|2_+z~_6lʹlKJB3SΫwG}`l^¦ L|0n#ےӜ)ꉱ=_Ҷ>D2"r]ڕN@ $GgZgz"?"=hHϚbq}fyE &Lؐ&th sBdYޯH]խ d-Q ҷw՝x0“$Rt}͝B3o0 4֣ ^iDx~j WmUПTMT8 (Դ({1[UrP|(,*#qJ϶,UӇsjA^RuJXF J\fO)uȕ$)R. eLKCnh]<;䍨L&a&nlp>TtF*0J_9Wzp#$/?A8y5kx})hqr`]NlAtj#_o>/+;?k7$AH@޹p!eh/> ˣ(5Z/ =x~wH4 [;ѕMSWW,<w>;  wE`2v) KT@AueE=$i)Q,چ~rg7n|v#Qq\U@a)SG;~J@1E DrƊAM%cst_x/CǏ۸qI陎* f<~(*ёdVN}V#&0jv@"a;摅h 13*@Q$+Ժ~Ə|ީr ˒R{oR`6̥擋l>YsD/_~(xSG~6&҄t>O0nɏfF"?7$7UwSQ,E$Մ \<DSNVTw̶/ЩG6.O9^W O|xlQ[~ BC!4-w@ѿ8:w`09SL"aRC%u{7\T.P/+%f31>~ u(%9 /Z 笠BЧ1>S 8*\ytbK#נ[Oh=!a-yduT ]~t}߬ 6e!2 _tGx lSb', 5A  / Xp9`j[^wP(]($VFJ5D2X]of&TJKdxdδy'웓-;zj涛&)yEurl#@=E/#Ō;K~C^PЫԪo?v|Y0A`.?[Og|Ʒ:~sW@剧IOۯ4ז(?3\RFt<>=rfwWm!ƅ$AK:!@fRMr? tQbNy_: ~~߷qo,ρDx"4sd~GݽOUx'+"]w6~?n_G<f< }'`58bCO'{pֶ5x8_‚g\wgt͞?~s1]KN7#@cN6-% ҄dO=.Q\f&*Aѷgv;Xyv*{lAd"> S(WسJӜ&8OSWe5컱Ϭȃ_WL<@iH|Cݙ!Ra+O}w K03YU!BD]h@NfQtGx`^ FMW,fHh&~'E-DUv bǢ/&]MkHZh$oQRl,*IM5@5Zcw],KxO.>9i׭Ó$rҔLdF.+-K+*6J"%7kںl ]};e=+՞K9sנ3 Ė;8ßrٔjұl cwު J&̞޻y}>Ն&dQi(TԴ{ƨd4c>9P\%X K+x-Ԩy m諳% ^6qjfڥI:mJP58{9'eYɭ3 X;MWܱß2h|5W;|V8'5jUValVqzAΘ'OgRH《6uHR ~ecϔid<<>*=휂Lܐ{,XH?A L(R(Z\CF I~cG_, &Y6jQy9ɹ@cD&^thi͉ +wv\QLKq-zXю:ƄK).̅[,s u4=Va\UOLagN4ح}4ہjB3ѹm,hPV" WDUu6?UcX}=ibx{`΅ WęRNCQ;t/6/$ZǮ_|QngyZwe `DФh+E Fn藁XY`d.6΍f_4yStЩ9vNf&,zK}3xD"&(WHJ~=)'7\tSfLE, <ryԀCTgY}AЬ,$/jxjͳIwwQ.CEP]▮EbꢦQF$;3Z) VLFr@4Qe)NZksFNdIPreoeE0inRod,3~$Ӛ1Ż׹f}$#r\mK/L8ޖCmεDZְ.t0 ? '^ɿ~V/q?F/e:\*lDq\'&N)6dT R|-U˶ *3!wۍR@=cFnhL: p<{l.aNll,LUbgQ#%3X&>3Qvh=ZҔFK]jƪ w8XOxѽG,P+4fޡvYyDn}x~Yn/Eta;<\R  _кBDNwĵsn;F3]޺atR%KS} 'P:j-k8rB)3.Q|zsSۃ /HߠƐ>O-trJbdoOv[e @ #gTJHLx'r]dGN 0 arúf#|! `i{kYU/o͒Ge?_29aH! x9q%1MZUZo$4G@L6ݞqT~;tnv+I!ed/ZJ?(壏@)p .O9 8D*ಀCޢT KJ;LjzRAB(5'ưMJJQ: XJ#E-QS)!{=ÉQgH7c (7?9z//|lC+p,]e%җY}{:2  Ҿm3"#x"8#*"kmuM=['o[1>Aԇr1 2P#f 0N5EsDxpn|d uJƏ:bH"&1mēHddN%]# *OudD*b[b:Qx^ \Q6N +!^N T_fP },1Ar Y3ѕGEnY9|mM ;/?faڦ/۟%- `{ ̴#V'iEi!& y&"qๆ4ܙSLŸ;pXNlv9XGLI,Ľ"ʍB\,Ɂ$B,*s!\1oE Zr;ЧzpJ00D4%8\HlDSFC$?u0JKBT[гxzӂZx "qtT9xQ+{ձD7O-, l}nYP;ƃjt?f>xc`d```ado󕁛.ڭgddq9@5 xc`d``cw?p22ESsxڍTjAytƋ!!J(Yĥ1 %B̪3%.Lꩮ>*Cw5 yT@(&YB p?H߽|ڣ5.{W?M3nj+6ss#ǻ'?;照,0MRsݑ~(].߁bA~_4Hy_zS ;TC.;iL%~W%&cZ W? 'O}w99nojdmp2 6ѲϚkY&ו7Ն+ܥ홨WtN4W]9.@ m厚%Ӧ_l^.-|Cy' O+ȭzs^싮HYVK~ r9r{zπ A+6w/ oqE| 댁ǤŨc&[ J'\]ZZڧ u&i= II99;Pb8me 4R"I*ksTٖ4xZyk+mLfV'=8=>ޔOedmcosddZmQǎ5;,Tu EgfLiaiB6KJrsY <#aCI"v7+n+ cwg9PNW-ګbe\>}<O& %Ba}?z?gPZ )&P>``@IáCCaÈ2xYrQQ@&l+emʚ*lJ]5T孎T?"EctǼZ1D gNW7v2CINNI:x}BtrFـk7ςffm\$$yy}NS(l)%Ui oBkh.b/.Zy_y**Gy I~ɢ 4]6y{F{pUMʯɮ(]nweCx=z7t2 Fwno{X=^-譌[fӠ5. w(wl}}~bQ.n^= |qTy}_iifՃ¡9'ý0؏Z4ǀkeZV Vj3=?#lz|Ǒ9/^q_B^r_Fp#WWQߍcה׃.63>V;һf7tt}ɞIكSSiŴ#c aSxMAɟվLҗ/^xc`d``jgdPg& fB0xڍQ=KA}w( buXX$`pI.$w1bkiim/BXvo\Yv̛7xw5y  ǐqICY~+]c`16@¸zTS6E-b>`×2ʳ)=Qs9UQ:ʩc_Roo_>&,U`dVkM\T^FVd 8,xVBݙQ!j·&vynrMM \'c\r&-zďt~W;x}WGݪ03ӮNQI-if]@Et1]Bet9]AWUt5]Cut=@7Mt3B-ljSdG}C[iH.hLmjnꡩY (bZeZUN#(z4=Kt=Lt'Ew=t/GSz*=NϠgҳz.=O/ҋz)^NWҫz-^Oo7қz+Nwһz/O҇(}>NOҧ,}>O_/҃%2}J_7-6}Kߣ#1~J?/+5~K#L'M3+q \Os+<ó B/KR/+JkZFo[ŷ]6>iͤo⁧f5'9,e[gAFFbkIDDyeh,% s%.nM2LLZD*mF/R;+ATXБDedO22eNpvr~I>δ=qF;tJ[Uٺ<0HTog6t )DۥKK*WKDybׄCIQ%BfF^JnLDomeSfʳv<äcr 1׆$ h͊[+|8{rjdž:$%(-sQs$>e9 0wݎx &iHo#Ql!2ת65r#::n [c:F(&v5p۝$t7Z&Ph tlN-w.$@ s0D2iTD,InwpMBڰor|m:yat~vtaj$M'ψ$'WU[ӔdrRTHā}]_UAV`Yfzǝ]ġ6Vܸ7pڎ#pIw7JbSV3Mvv[W&OcbW"j қ/ycIأBO޴@]  c>A"T*Zz,5kBW״+,\o9,5 <66rK8\%yqn1yTBO²kr(#Wa j-7ΒQKqڞp˟ hT璳&G_}tK9ř%y˫4ٓ,Ϧ-hy誢WbEm¦y =M54j Pf3ת'6*z:Y hX((Q0_ZhBb =UW \*pUXj@ԀQ˶9pBV'#eKnYme5&c:Vc:V'gsj4@ HU    +@VCK@ 2 ,Ӱ0 4Xb]ԡ:tQ.E/ DQoѬzՄFX -bEE EFahXD/ bBsiHBCА$4$HT4Ġ! 1hAC b4Ġ! 1h/]D h@׀Qנ^z 5נ^ׁ@w 5x]w 5x]w 5x]wmaҵޫ B t @kAkAkAk@ hDH^aVZp@Ńj (d= Z-o [-o [jZ<VO)hugo-0.68.3/examples/blog/static/fonts/fontawesome-webfont.woff2000066400000000000000000002021001363637351300246760ustar00rootroot00000000000000wOF2@*?FFTM `r 56$   ?webf[@֌nC˜tTLɡftȰq5?=ilґ\vl Tb 1fú7TQ D;:Ю1l׾jvenEߠk5>d7QlBa ux].WC$8v#y`F1aM8諠w=|'є0T|2/M%b tY$!ʐ5cb̚( &-A/mY /yo\Z= 5ck_n3㌾(WɃNag+O樴R'5=?mΩL :ދ*_Vz+zc1`Q#j/Z0-FibF"2ipÀF(2b~H]J]jݹFf-~ @ggB-Tx%pUume ';@7 t=pN/_U8 rsX=gׯHjcَܟdד_1l:1iITr>v{GbضT1*f-x-i{1h>(33!$:j~:ugv%ѽꄻ? d5+fUzҍXXOo | s&$y'x[`2(E_kbbp716;~vo[byݷKrfMB*Mۧm @ 3`,OmrFa0-P6Kt}>O`jT(aP GװSz=naY-fѠTWUV?](k=GƦW_e[K?j@eUw uNS3@}3AX?dz8iC/ɛJKE'&]=z_z;&K R∏Wk49 eb,g8{o>db7l1j|ʘUo#[U {37**Ef[D4GjAѢ ':ԅ8`WFckO.:q PiO,Vӫݽx3Kn5JjL {{^fy]O^AFі C0}XHny4tJc&&{ZsF|rXF5˺Pf5_jZkn( Qs<E':"`LG9kjSC6Aݢ1 &/ &c|n<؈>o^ ޮ)t8%iꪮ6̕4h\T˒)`$w_QK{x 0#́,]֭en%3jF* _|q2a#b{9vz2?.EX5x]U =ьnqlԔP!8` Z<. r+&ۇ:dOx1;! 0E[r'b>M1A;E5N6T!dHj9Mo2;Lڰ_"D<k<*-k"Z }m9(.{y̎2΂- R%hM%K3 hC>iV' ƫb':U됏T$aՠtZ,XW%7m]<t18fGHmeYI So[rYڌ\Ad)1ېOJoͺcQh!Si= -(LzKDC:Mc$“q־hW>KA@QEDtuqW|0QT"W|(aWm j 1!2H':I_f,CbjA\ΈLᔯ1 )Ha =N(U;qlqђd;h3`gkz"%(8XXЌJk_wo]Ӟ J8a46&033=9)v̞&JPVˢ0\q$HY1i9/i}4,rpջrWubiܝF# ]ڱ)b/5LN#'Ognx(aӑ%ct{&\`NQmЮTɽ}Hyɑ\._-kst*5$x)M/熡T=bq{:YDbBNfJ*9VDl0K LtNDy)M|nK<,*7+Iۚ٫ xA'zңc4EsRakszb)=m՜Ħ2ԃ~An4X;-Fpjd0M"M;p 0p/9iĠ|N:Ĺ EH=H}Ll@cOF =wAHKXE> b4a گs+BoӢwN޲ZCu^9|Bf6yN%.=3K$@媶$THMċ-EonW$F=fKQW(_|bA-qZ&猐[@EjC &>`Y:3JD8+g*ٕޤh2IY߽ ,&ʕ/xӫu b? F_)fGB ) i[yT6nbUO7l?bx5Rk/`C*g_N9 j=4ACCcs4No G2*8rJiOV?uVNoPCߗlIDֳt׹YZS5(F]y\._<.`9sJ]JOyQ WV2yy K}C^u0> E/{>W60@[`^ل S^G-u樱ycsiKnfl-4>wlKx-y f5,fTFd.fIjveY6J.is oUɾb)DO,|\)] xv:wƟaw cŢ0Bf}vp-Y"#1 2mU@Ε;T.yo]۔' mDZyaN;5H@VE>kv=nݠՅR~. .{>,G&^!>ӮK)\'K54-F{g:ABP*)Inj )H!E .#CncV>AU]=ZE߃aہf͓qzblj5;{|:͏|5mF% r HzX0Qh#πj5TxDDp^FOvRֆǟi!4&[~{"2+>U] ZuI4 qKt1rYxiMWt9ZVNo_~wР}^Pr:c^JqoKf=Y sr8(k'>Ձ :1ڠD:&vbyG(\컖Y8 &O裨4>;O]"x 6.B2FM8` ,lT!T9MUh!FAGuBc^/Ӧ*ijSN* @8\svq*1,9jD!nO_s=9w9&a>;g4)GRjM)V>5j wvz J*N=M)RQN2Dy}[ ՎN0A{cU@ˆULU$ȼ[+[ӤmՓ4:u2{wM${-Fzj&Mpםg q#"Z,ѣ2,CG]۫pkߩ< Wc~0VZRJ\W -JnC$ ~[\ˬɬrgz Stq|_ĨzR0gPzV-bU%;Lr@MuKR;2lFo׈^U7ϝ:5rJ|!!Mf0Ce7 {U!s ݩB  ~"B1q*Nj+7^7^&DCϞ>pB[i[IJ{pU[/T%po6Z#j'l2F ;xE}owsH%mOM%xB WbҸj0L@:I9pt ]xUT*g -r1[P|:$Go<65!#@` 'RîFӗm mӀߓ\ :Ȣxap(3ک4j(n{uY|bt)&8sU-?*l[G/Uqa ]A{ ,%7yz'Eo] 3El *k/^D/kuC *`NǓfvL퍝#_fFƳ.Fs]59V64601npX^ 2cDf g7øtp`HAkSb:T>3'յDsY]KIZ9vqKO+Iܿ\c1;i}ѥ!{lZ VZc *p22y@ %}_Z:oo&8CWFcqll1Pb6Kʷ#J`s$`.0(`nAi`>bC4d9AnCZFBW+vݻI* ܶ~O3>g.IT4 3*9K`"I};Ѹ0:qAmj U+OU:d3v-Ggšv&G7E,t'KJ(@[.1jh.'TjJh clt\[-le3`-cQŭ&QG' ,xjw1xo{2|I+ O~'3꽙G<]B65@Bz]2"_1*?91Rʄ"|rrIO5B/b}A ~S<}6/~Rdf6LIk)6gGӋ:\6u!=/02J"GxZ:Smy3R2ˑYdf_j7*i!E4ǥ?ԍD<! ]IZ&mO%v~\Mћg/SC(JLYŃoC:VǓA1yхgӮHx𢺥Z{ 6N\_V}y*]m/[h{EhwapЊW]7 2WxL"'jU$U~q9_.j dp ?T8 u*-/)HlYsluƱOZQ,p*e̙EZx,&8%Kcnjdwes?vs{-.A.w<!!X:U9~*x *TpO\G?^`<'߿*T!D{@اs$K(U,1jPL!- Ho%5çanоWwpحkd _yxhAMb M] ;Tn|D}Kqb:'A QrC&?ݬLC$|ƊLNieqƆpLQg;Nf^RUbz^>ždr,/vKO#V^bGqM^;v +5^5 S++f\߸ 7(x=ȵ!i*Tl +(@ӄX*2Bh*& ,vH/ P UQ pyn&VE=_Ya^Yj+J5u@>37W3%u9_3e<)0x6Fz UEXucxMi bo `لp UGj K嘢_-; Eb 8[t?lϙ;JRP ,z - 43œ=}l,u&P;,ɶG42h9ri l#36վ"K !N#gmRyw3wU v#B\^  ω`BU"^&f[qn4xso/FR^9P͐ 2A|mݥ|UϠi͏X^ʹq֓J˲~n&ki `;c@bJb2! ͅ M vQEs$9dzr{U942Iע 4( NDE"ԭl|-klWJ2C~it"#juGo跠|D<<?`FړU1CHY1F:S҉gȂ. 0؊|:DaN nLy⿛ޗNlڔ,KA0c)[RTIF|*$ '[IODf\~!"qݧ3k/JX0_!v |eZطe̕(2[yQh䀟NsLn+E.|,l##‚?cW)@) 9u{D_pnZzF7:`={u'uoZ?iЛy1cE6=(All{9}Nq jԉetJ3%N'+@wos-aeEn1B B'#<|W-6!~yx{iWiYNvM`/ =wrʢW~+cHžYM0w8)>{^?2hV0 =h w\y+r(je+Ȉ? 1@.\Q:"s?mCTaDUC KNjzOtq{Fa&)e07Rq&z]Rowht-u.ڷÔԴc$'$AQ7r7&gqcg/Z~o`6|.;mAr4T%5ڈ!h( ˤJL{5On#j4P nL|*IJ7ntH¸0`63QM`xb"NdqF?z4ҠcIu/dj!#`Ѕ=tßƵ8o<!TkWL$̇獐ίp5, wsi^qKPষɴ`hH si%}@NWtrƁCޏڨPP.A҇9;piZ]˨˛)뮜yFJJ-/)`/L~-Bt'Zgf:JMc{fș=T8=un'wنRix+hT6!eIa6Np? һK |NiͶ>A\}*n̨7,M%j\cǨ~U;<*+3:r Rz0; I`k~p!;^C*{LuG0zy K9bLXwm %V vB$yu|v$djgħ3gu 32rc[H 9A`po6%oZwCA߯Ib4gh7bo̧H7aI(E>742hRkyB Wi& Gx"a&NTPy@}j&Qt&SWQrI<9v1lY`)lĻ,,p7oc WWXg.05s5OӔ|JJYz'PE3Ut iuW569^#dZ&c/81>yaO虎kQeR`ӡ3QE,H=hGzX43UC|zRCth#l0Ra&b[{NItzvmˈ Pj1s &y~iwń59OjtDo;;j^mB75૴tsE9_ާXJCpM‡@eU7uyQ9@lOZEL|+,b&Ѣ vDy8܋;JБHA=^PO&@6,6s<. ߙ3F[P,B!G5R^5-ҾswR24!g֦vkіs{)whT0;j,RA}Srg,&Ζ(Z< #+ff52<|yuV+(KG@Ap!DgهI 'Zݦ+<i iyMUpbA:j`3vq?Ӆ"3 {4! D#qZ]Goy j)՘$li_>WGVa7<" ˲w|R o})h2۰JX-7GImJ;_۸h/$-{7mYufލ:HIbItxg/;%mpj%9b; xR 6GͶ! Đ~ΈHHcp~6rc=ԛlM jjS+-<#vf=**Nf["$a`K2RM{7܁4asp✅0n0FxLw[ 7&ߧ]|k NPx^,z,&XH8⎮#rj5?s)jiԑ$JP(uE0;9t-Y\nE4gGaxJ ]$9}#-U(.:➱:rrҠ!ItDWW*վZ /Q%&"4Α[e1uzo *$jB3sA0̔sƠ}& KI `Uzg"M=cT|-11k3Go冫*r{;CPhjNq=5Jhku1ٻr|vRqPƳ"|$Bt9nl{B_c;K _c&.t㛼xZiD*?rqy}WE.]1Ή^jh#1v30jHU nL V/ -r>eFHSRR}h'#lI\2W½_3W;F| m%vb\OqPoJ@h+%:#O;TTa*1761Ƅ,3v"Pǥ J!CC{5>cJFQ`@j8ۂd0m̟SRl(F \XO#cM֣Oc07Fʹ '=N IN;Tvx=|%A|NMHCQjR5n)StJpY:0>ϲEOnn|ȆƓo$ #!%.1D_YjXݷB=NsI+Q#Xtݰ BPv+3 & }Y6euzc?ejjb9ZsTb] bMI!1|M.Zdah2rG oJjzQ5=b%d4I<:SN#ǫ @4'0K"Ƹmt&dO9mΌ&u437;]?-H"*O1%43& Rr#]ddY/C/#o=EO|Crxצ +ZxXM bɅW9GݙPw ,Ox pcm.dH,T$Sa-t>K ~LiLvسx&&uYTyJ0R!0j{:$k(x{И48F#{qZYc0XCC:T`J EI#*Zl3ߟ$ɻO4Vq`AG7kuDWFnUuU"9S0&e#672OvZKF4Pmh^g];q߇:O7mYW\b1XH_ҭ7|&Fn.a,_6(j=p-jE ȸ^#qs<40."jǓ*g֣B+x޼?w&Z<=w5B9MOghׅ6_'^l _5mJ讼wP4 .]5BX jGvgѝed:O]Q`S9uNg>hb (ZVRjۡF[Z&H01`빬oE4OeE W#hE5NwCxwX^Z@z] Ͱ MvN?ӻ6!z0R:`݇p0v)VwdKxN:T4c~-٤ZJCyoT p: A]D$x"lŜ I_v&# Ֆo-'fG'*EvKܣو!ל{E G2ÊUtb-ܖ:6ӧN;bٟLm϶NV LZOGSy, ,b!Rkؗ_vD C+Kͨ(2a^/odnzN{L@ s-8?[hmIUC8V7CT gnRqjB ?iZb(؜D>c .mrk#hxASt;vs N<)ʁtb>ImNKTTŞ^V?_-Nw6ϔh㦤X,`$$n)]kpkR玟-ϒC:( 3mmhGڱA K۔6:GܖL m#Mi9r/E8Y3H?"sSGuTs=i*uۏmվQ̡7Sfpf#3CG_3&?aZF sⅰ^;ڒ\5Wj,pG :_^lsKgΎcqfc;Qc|3cWqh`Ǣ; *LETpwxXItZTp*PcЗs-uݥzjAՁm{P/sܸ?2L>2M&Q՘-Csh%%[od{+Z͠n8k'T;)v?.AC~.hu͜@X0  1;XY7Дhӎ%WF] D?=(;^F^ɡ)#j˯ "h &e>^E^^Ʋc(@<^4瞁$h">s\:$j+e1 ~< Z+';q҆tIn7ed ׇ ++bMMKe_ 7AJԨX>/?KZBH2kI$7wqoȭzn,N;L>euzJKۨ|77 ;I9۟${k:ٍsKZ6"O|ۄ- 8wr!0XŮh7t64vW u߼L;M)U~ZjDsYs!cw_};Q2뫮Bp bBQ*rEB!P`t>ߣ{`MW|&'f_W  .̭lT6͐jTK.#n2!+yww 眰eĩ׍Wa;Cp9TF 6 j*3ks[O|ixn|k* k/PU mȘqGs^g0L<Җ|42:c;}8RDKl+.G#񭬇O\ق`䝙<3NHM! z؍||Sh١ =P g&[+n- bmк@njư }RS5baA^ӐKFq?" q^7NXfRY[9m|Kso%R?8PZ)L&?Mu*k\F )Ļ>5 `{q4&dp ʆX&Sϩ{)_/r Z?O@C}Xx6dN6h޽m++P;[Q~$xiER!TB2j.rMVm,e]2X^[skp^75A&"LwMI1ǻCpAح%Ʃa]S&0s9Bs2f_t٩vEY{DY[Pe:Yr'~7躺S%xrɍıZG!1K.QsmtmskuӍ0At?~ߡBۙ,EqS5\=$dj ;ʒj[ Qg- {ʗ<2fDTpVǨk?t53\^6k=(`z*WY@e[q‡%΀HHuGwJ([_;@A]{/kI_KmsAk+bM{;ηla -||lhNeNL^tGTu|7B"*<Ũ2"6@spsS| 5R%J[{  [ݫ"էZB»?G_mU< s (K&ޡ юD vީU{ nZfLbAm&t E[W~bRQM˳I1[W)`->[DJŵ)9Mea]ݙzv\JVuȐppع\Rו@콅 9~?@Ν ?h&žy|,\Q”;VIY;yj<>el!Nv‡tj3 +(ךR(TIuG(@H#J/K!? V,Sh8*M&mҤEL9d>z`'O!.B!]SHp<)؍?,jӯ'wT_]Wh,Cl@7l OD&'H>*e) 3OK0Ty4 U@xSd0=B@YXe^>qg|]<6#,4-L6 5͵*C.T|/A_!sϒxgYNcx'7\.͠/p8NhcWG/O |% Bpg^`SE?e\`܅8cz? )Y\Hf"o@OjWgݧz#܌xMe i /YseU{`V\Ju=xz%67|ˆ 3{uCaf$X{a~ KU️Q _=cOb.=Opw2eFmhPwF!lmn ȱ}}T-텆1?Yٞ: 4QPst>I46g4SL{qe خUPUbL.:6G0mz+cFz{4f$vB!G>G囪sk eҦ@4#"?X,PeN }ROj·.ar%/:"Q:U35Pvët#>y{(ad)p"#IM .i\JrwVY*Y0ǃhj!ADm. _搻";ד(ˌQ"-nAgQ0w&Y:GMȲjpxUC A?OMyi8H1, *\mMaD|VcuSCWv1BV.: N3=16bRs[綬;i*1VQ pVнCJ>CnJ;ه҄~^TXP2R&{*U0T0?嫑#T ޲8y>,!p"wFflFf=jų֘DwFKCNt\[hKaؽ0FUxDGaAs.O<^9Iį6 \4;daH.dt%D86,S7_EdžHҾ7N7QKoBJFflJr vh4g(ƚYWG-&x vLOJ*!MӃ0Q8ZD'gVxx@GxBCU, +rKD)޹ퟩl:dWymκ;t`[!8AoY Z%92q x洇VS, ~Q &J uwN f!7R ngRjl+/^o_|[*M-K+r~|w:QˋJgn"$S鸛!TͰ;F`vݤm.!E&;Q4r *k!&D(?'jd <َW~ჺYņ,{OX7:*~URpNB̉>1ښE3rKߟyqpbtag=),o85ftzeVAB-05m38yC^`:ЕcCm)et5 5)xѤq ăi}7tBt97~>T-ϽXQJ܎7MZL5i5ŨrMgvxUVr|frh*ݖ'T":i#_dynjH O7yK aLqb^˲#L6Wɠ/o dzm凵TFV?L^(OD;WR^i|ʼj|xJL>zI¸xnkIgCe1S)ޫq &340Lh2A_o39b$~rQ*)(wkAS]@YJ :y[Wk{q:`9e Fj>;:Q_p_4B@\ K @P`hJmVPV2ghde[4 hW] KQ2&#ηV\ uh\Kͳ'ML/s)XyEUdv[Ѱe%.*]? 3x-|2SGp)*$+-NBs'-}~c4XK$I z>J@7qߒ<C1pmɳU1<P2$zkD-Nݭ3QS [7ӑ+=uH4'ߢqbצu ;)G)@}t= O,ox7!LtX ?sjp2o*VpڀtM6 ހUET-^ǁ^ U۰J7ꊼaǕB}J]p墀!e%;CDP>;g/goJ FF W5/탳g/;=APD!O]tTn7ODgy(&:POil8owLWXA?nNe{m4C\^Xb6T˓b4&tx8Ș=ҭҚ!lby,81Objw s _ yP8F(K>D`6f &v6: W!-+zlSbu3m;?E1cĖ}T&}&O0MgX6?:BY ΞE!o1.%RIoBu$[ZƳ- 0 UTi}1ݯO4sJ&/U/&jgZVh.#.H&kJ%e\){}d4kb\C(lzb_q?X;UY*,q+6~!.b"B][2u]2Op-sW83#2,>cƂL-=r-?gٕ9poX1sqfΧR*+?%4>VP$?{RlQPF",`?9 "oODJ` BO${QK~J%YVrTdL 4d,}\şP{ O$d,~־eXz!;cm顢`0 -$XKK1sиx<"5fRY $STcJÔ+uM1ś:o?۠REH3V=L(שX-8tϢ S%e72up(֚V2>uwO9}CyE핻!LJT6v&rAJ Lv4{zǰ޸O99n&<~ϑ'NB%摂kUק̤mu֘/BcTSjA!B-Ot&ՅTAkr,Qcyd!:p@xf8?WpsN66g`x [za{kz⪔ZVSz֮)*O 2+ W0hzH}X߉}#yx#SN -)Pm+7S_[}NFdòP]Ḱ^vu$ejz ۩.M>vz7`]Mݖ)-:~n?øl/yWUӒ }܍Οc]w%Qr)u vܫXq_vַ(+WڛUG]EJlʩk+'Ό3|,'f/^\̽Ŕ)j19k`Pid=~+ p[dQu!:}FGk`;>=vJmDvT~Z7\Jk+pf;ZAxYF\B VԲf`לtІQ>迃k5XV<\{ApWwrx#9Τ ;%)`ߨmO'^`fc,:@UJd VxV(V54$ X.㞚49Q#{-Ck, LRRѹ9d!Yo2xk݇&'q"}H#XJ  r=J2 -2/?d̙b]A۱5{p8>~golu`ӹuoMF073G J mqY0V@ܳv<9u@Xii,,bB54\IҸcdzXw?ɷV"4łXGrVW O#L-Υ =[o ?+(tJ~ޏ=LmKKVU0J'M6@/ _iee2ݥ6ax+nA^Yvj z H&#.Y*d :KuSuh5?,F0Ftֲ Ia>1[*F #S=q xΝ9B.@/#~G@ MF, *#ԯo _(mpxS":lei`^0 4> ܁ys>I-dCD.] 6aG1Jf55#լeg6.g#0ŕ=0p70FO_[^DT マL"DdNr.bxY˜z8JyJk{ǼۼtX^͝\Az̮Nր}ot7d5knh qcG aWdk4d&pi._[6YMȰas+`>d<e>d9rP{w;lȢLmW/B*+Z2:ЁkWK`;]/㤖$}~u1{T jM7{U%Ġ l|[v*kѽCRkÖ[Hr :,PqEC Mғvj[n˨p/SIlfGb!_tHbNQb$dӌ }R1K8pK.i zj#'Y$W{rzW'[$_§uciWF! wsxJY{QS]ˆc\x 3UlH9.g3Թ+{洐k-8x6іdZE<"J(r[rfѩ47r+; Hy0Jy G[b!98V8i6nM3;/,kG?Q[r\N(xWc)0%ِkjsrÌ4p ,:B/cMF :[Z z6>~oAa]B\x 4bG"tIФ7F4Kve"$\ I|'+S[^ 1?*N{xr]sH` ,cPJ_`dl2 Mօ- Q0zP0HZE\>5.r;4=P) }cL( &z;'{ BNg|X(iw`8}393:'5E^=:̵:ؙ<~DPqh8fMA7h֘;@: 0qY nnPᛢ`7ʝNfH!i F%dp82Ad4jLD(`5h5̻Ҥ].)NsyZtr@ [F0 DH" 0=q ѐb8H(R+W˿xn Π^1,b"U7l`dfLʌlȥԴWߏ ^"&6^5 iv:]A'-wtӢXO(>s~VߧMd2_ϭ韬P3= NdCN`2{PTjMjl_{(P{^`|A[ǝ([1f,B e E}-ɉh^vK#z+Qk)E5Ff[~PjcW@2H$FϷ%}G 1#LU yP롢.oW̕!p֬ތ 26.kNNƼWK_WwV&n1ZzpG^؅{H-'C|is\|:uG]P-nN,ݚسMj?HHH7feE V*u :.BS{vg%A਌7>9"EiIބV,?MJ"qXbo?Pz$$"G7n~lFˆJA{guՇinݵ#.X2$v&Ip'+ȱh8Evj5#Bh[RZO] f~q::4yP:&'jf|tAO|+d-i≮75 !bg אidrA5 ~JEF'ːWV)R;"S3g?QjDkF|v\ɖOf."h:yo.>sbqM$t\J6jg 7Go1d 9)lekVq6y.9L#=>{n .?Ɨeg/P00r^/ţ% ߪZ3M4%WJӿ>'+N(A\h*r6@ljD}t"$Hr|뜦ei^'P4 888IlkX$䲸wN3Y\m:m,`RԺ%˯]%WW#J|&)ZgxaU]0UD>o5HD2eE2Q$'+5z寁\$ȝΐ"(ӓE8{zX ko?o=g"H'SW ,7 =8mB-DDn ;7?~*__?`p[[󠼭nƴBqWrmN8YiL_W 8mÜT?wE"tFqv:ǹ$9}HUփ:GCBݖfTT6~3> Exc1v x}F0Y2ic5C,2i-6ؒ5T=rrpƵe$׫id_HkhQlnôdk( i 6FғɊLIA"&bcZt$3xL#Y+}mvϺMݡF3]F8se&6pW ,f$g \R֦9 єFD$nlT`01!1x(vHrtEj\,xZHGϊń>XPo::䂂-ckffjJ;SXmgN0I;p >j]TŊfqFC+|ǝ%}{9@GF!9 h+`:6>w4z1W?~a`5T™B8G-2w:v18ܙux@G o3˛ T>5vFPVOꭋgsz߄;;ɹxVo0>﷪ӉMq+~mP0vTwW!xA c%0iR%Йq)% cR;ɤL; @QP!2eq 7Z<s2fQ6x_iU>>SZ"e3.05e/$yS NJ}ۄ):c`01$N8f[>鬳:aٸq@xl6(3eAڙVL2ȼsqSr%l5`a`$+S* y:O$&H`4QQ V*U13SlYE1sxdf})AAbpځ >X Fne۷Gߊw][^ywE ëps (5tpL'9~*A:Cݖ Y4/'v \ѩ ^Ǐ(͛,.LO%[fd(G??<6J&IL fiw _SF5- XF&9͍ʓX Fgs-O&۪sl 7GQxlr`sTp5j:-E.2N\RaG0Hjn[N3"VG0XU:ߝ^CsRy]d WGW$$ӆI`g\l#~^@7V]ۿ_= Sx(}c<ڐdozqnkRlMJhH tϗE(2Tq5,rjd$R[UX^+󶠵N,3O)j$_)ڙD={Ҕ=+\ ՈYPVKYKunݝq|2fiG_W\,xM$ 毹.qѽ;VJ=NB d8YVM*iaJjt/w|dR^ۃ]])`yX4vM]Jx[8^Ebֳrӝ+ٔDJ} f#|5x- /dJ0Pce\Vif `G0DDutd]}-gvFnUO/]WSHVE҅dn1}R$. _%"C*$ɤ(Q->Q;wsi|oGu[G rihddO|25 Xk__?3mDVDz{2b✒=KO&Z_¯1y^a:%)͌Xe@e{K rO;v>++iş&, qx)ae\hJ{p0-xH~ETb?>.y{oXC4L&8Go&7dX[s>43\ :+7ehV:\@]%K\@ N] qsOߧjB1ޕ:dd1.R2׮ 0B994]2l]f`ق+*{0B_ 2Ď"B.w<*^ _q}+]wvS"Wy/! V!pGt,CT;|aSǙ3}""ة]ëu<ˮh"kdvc$Ïd*yhWi?nq&I԰H%0|J|˳UA^ULvaqqaX}$0&&"Nפ֒!n/?#m. ۫;E$ԜOFEݽ7:zaD\CζRv"oiy`>o<わd>oץ反7̄Őf@2+` ].XHl??qi^I q{ڎ:w.X9πHg{JiP K@5~qkY)̈́skHzd |w4S8[]^|u\pf ?H?2˿dp/?*z5:zbPD_➫?ws&tf;\?pBQ[}kñjswѰQa=`z/HDPcXv%d3nJOʀɳ DԖ?+*op_oE$Di߅ϭ]@nɗ墺g5*C9xaMBg8 8=p@BBp ž8%)m^Vo9fAv/fR\i=]i|.rY  b&nN(X[3c̝E: R+nOՆ %%A/w-)(H;I!lՒΘ6'QN?tYi_vmUG}U4 S^.֎p?c;a L(*g@\>w?\*zeJC#V(f-Q^> w*H =GM@H \37d0L\<? "p{i^d' x4eTp Yd !6թ㻨I`y*Ҁ(9!ylL%M*dxؠzVJKm$N%FD54\gJAMP~ǢZ,pV! gZuF NKuPNc2]*I GMu|uSn:?ix͈GcM.uҔU_}=ހ|SO:lY%!89ifͽ <ʡԃ??KިJBrO]K)JfEIug|,]Q?tW-Poje!2!@;2bDd  !#bϫ~>To-=?)22'dN}DZ'rqc3 ^k!QP,ݽ}rn<Eͽ P=kbJҎ-Hqe-I`ո֨ɫ)Dys}*t Lʹcg2Ɲ2w7ʩoΞ^e]2ObWʯҡANwmH'LE2͛#q3P+hVVSGPp[ $~nڢrZ%$%r 4++AyHC٦04 ͩ;ud=S3.!qwfV.EV`<:IfT!ۮJ+}ԪZe_/RD)=*qcɡb5P}Ry*f2)0Sl`~E!N!ޓgB\{fM):qlg@fv̀ISg&рtU ׹| Ev={ĞaaUJyևh%`WmTՙ;lPZqө奩i&E$z2-=&*`p ?2ҷ 'gl+%LN O&rҲ2i 'S4G0Lӿ wj7ӳl@:z4:2Dߺ2RR&wJXUvƛ|OZRƝxi76T\")`2LBl|Y0,O@DtbzGƘ*{˘LFWnqL)ʖJ8jz.8cՙni tT0~'vK&[]Z|(SۚJ3qQ,n&:,Cr'$חCY!B&>1Pr~eb}X|C} ]dF=a|ʅۅe}'N,XD % Ē-IN^Жhw;)/ަl7 C`c 3"YNfә yܢa$'G]K?]ѵEMΐ0D\`_DYU&GZTn>c*nԝAk}rp&]YoH\Y]qzMD5sNNCgf_&T:Uq1g xdJHQpP _]?Ѕå/,jY%"h!ralBE8,KxZ[.J"[%ffc՗7?ҤH^΋e`L_z{|L랮'ND{j!/ 5[\Do ?g*D[=^n=&(;FTʉe!0|Mstǖ] eN~4/ hZQݓݱo(SIiWRm1a8z=;sd3w4=KK^m^E4mfŗ*(\6ʴҷbAjP4\ "F#'"xB1{_jwe 29]5p-ri0QF| ̮MC˰ pύ^Un2Y%.aHp `ʋ{Yr"X4m| ʩgL̦{]պUf9rBЧd4 y;6lI쳡m/H0]8cs0uVFn3eݐn]$ S]*x#zhB?DͰEN 8 1=Bb&ipI!TVŹǙx]X1aya塑ڜ {JCgt2]h 24a܄6Pظ4lL.kUWzdֳ> Eupfyb4 gc6sEݕ a)S'1jt )MfcdkJ8q8/Z\k# /\I%,\p?Y&;5 vFO;R[n1|kDAnjt󞂹QYW0a9x=G-1oSE_r c@ ųN )f;bی0U!hgf)za@d 8d[Clil!(ߢc6Km6PnOv7ȡ`'c!^NUBeհ^Zr&iv87 ؆5tG,]ۀ kOjVKBdust--Tr;+!d8`u R-qO5NNEԒhX0N(@$nT͵{nL #ԭscfqɰ0D!^mSuAԎHc d& `I q Z + /^MrLxq .otI%WРRNH|-E$A{ ՛wf[I~N[ݶi䧊6] O 6擺Z[RkKR[Zn-rM9RazG*yؚ0dCSᕪҀ ah~2Dkb+A2![ƞlY638ޣk-*Ѡg;ZK80oz68Gu i1jnJgx~& _ع(IfȆ[GZ$3хkeQ99IsT-)Is ( Q)k˂/> SP߇У89l3(Nk|>ާםj imUlG./?nha{|Fe{؇>m㞷M?\i^I`ndNܠcя`17omm6ӟgƒ# A6|}X_ Ƌ{Gj7 SE3}wݔ{ %&)`XHпM%~Z70b? hp+ՔS/տS28b_*FOT,6aHlN&!3fFT[NWOղ;ծp."-0IE/IvJ*iq@Z)RP%iRj}HEbbtmY!c8O8,n)/3}brbce4dD8Ljy^u+pl d++,d?.v:#Pfk{ɚ{}S}~M3˛fW%9W2b G@8u0@TNYY@0앎0ug*K\ݹ?j=moߩ@>iڽ Ҝ( ݟ[O]y= Ϗf%ED{;L߻2%;3}D !wRuo>B=aJ8y!;O%q DH2 {yqIba|EHv.^j?"L5as eg2,p-LU%K=lcbԲ|;BzExV%ŅndA"Coma1B4EGzH@4O]x,@ M,]xOYtِ &&+-,87dAo$U(ԢSMEnjoIDtG;ݞw7ꔳ pіUG 9aY2Z*$L)\Pn֮4t$CQr&Z7$TɆ*d r,!  ޯR]%o^(]`/eN}D)dEO iR}$KV7cg,aql¼aݳLC]s8s++8Kf7}7WŊNQ*X1Ǝ&c| ٳPA,^ZU0vhQ~/Ӷgl->qA('/N]z50RfgȲxyv٤E~&g߆9zyyVc4X`@e6 ;I^۪ӯғ!SgO:͟r`RI*C'RS׮ݱ d. ,::sf&+5#Pz6r+y04g[Ff%gfKY"d~ TFyq5@ Vi]Jٮ#1˽VGs P+ Mjw;5Yb5hv{F&U7 'f߽˞D.MRRAq܅BL|S_9Kw$ycdQ-|x]>N!&*Ԭi Gz5k5H!ܢnܬz!3UU*N-`!Gnf-",8 hdBKqDQj ̞-`߇dۼA#A>q`2@&sKZ7-)E& ʖ+zVvdGHYunvf WROלsiP)HuYc;~`/MtPW7^zԄGQAct:;*̱ kY1cn[lh(me"N?'m7 nw *poHo3ytSS T^XsyG͊haT7H'~1‹B8 SWt_ ~SGM1'MM#;bzH>g[NOD_}O>VQ_σht#7G>8_BHm_:2(ZϰUcŷa4L#aՎ C{`h& ;į=y´/N^%+F4#vUTO7U*BMc-]HoۑV.m 9[-fW{&M@](@gI2dFDXXo*b* : LV_Œf>.Cv8> s%$iDMQk2a)DҠhބuu裘fL倥*Ba|7-Nt9Dxp>]_[4z%{.B倞PK+Kr\n ,bH_4McRF;X7Ē6IAZgEE0LPU0v$uUȉPlXl#G D'QKP'sb6 !Q/OCݬ# .6.ꇶ9eI|jq2Mu?̯9 8o5yKc!zjτINfUN1 =^3|dx?yb3O ݯ&H{:0ʾRkT!C-T01.өGI񭒧D-hi1`\֓!խv+F*Օk~: k3fjFT4/C33v⅂3)~7| 1W,䊖9W|fO3Y@¶y^zY!b/ Di4gf*0od~Pq*X,r$*V{.RPY2ybb'5lLXݝSٮF]HxV5L~x=1g*{Yod@9 ]"cRpB b|[*8ɫ, v$:{tZ[z@? ꝉ.j$7&OH//T>< DF][tO<4ⷫ&OhmF7 M'x8,Z1-1S~3$ۚ8 zH!nH!7 l{3k|=cK k> ]uܗ!5Vad!Eى<dŹeP#?D1F3ԢDz9;m'u]cw"#N:Kh61f竚UnIBO8 搣}}_|C,ߋ}aG%}?j| Lx;)X]38,OgwlN+Ʌה 2<n pvgGcϯ0gGG ); д]C ӹ3p/+o'F.R"Yj)}m!Ϊ܃Mܮ{%UW}kA%P!| H}``@.3deQ@tz0y-?b )'^a ^?K"&Zds}񖄸M21O.=ٕxfXo}M]|㧨À綶xj߫j9a_Dj%ID'hb*i.wMeo@w"M7G쪪ҰcQ?8Tk*M0ˤHXmP-Xꩋ֍ҭxZO_Х{|&ދ&?5g_*0)P+hwg.}s"S[=u}+X@)92 \m;JP&~ [I:O[UɴTE|̖H:-W4fDH1_Nwg1unfG) _?ABrrCt$cp4cO0qK;3Ih2dx 7jKl+u0΄!Pgcg0`QO;X7c?$rmAyђ2juuRcQҴ튎!izC=\ANQ;LP8SBX&w"e:^Ht#1}=o.V_QwKrIgKJ2Ii߮E!xyuX1T)=A~y?z[@:YM&Rie6</Z?r4`#w~;>%xaqe]fo&Lxj941g][l0VMQ\w3e+ܓsEٲq aȺB@DO[uȸ , s6zG-d.WFjÔ(IKh︗d5/b6ATg- 2 *دP'>[Jn';lclf3W~iP:8qCF]=>!#Qy8slM'GI/7ExՎ>,dgP-AZ#"%7<84 XT"~2B`(V,k(Wy0Tf2EujP׋DRۿ҂\MP:$BUu%4IxKkRtҩy{?9>hBkVQOL⑁p5q\*2|n_uƈwBy};҆3bo>tbu\9;+CW`rNs7d` \iv4jוg0MiBsABuh$S#9N= f5Q`N 5 Z^)]'~RM4& UHͷm;+鴊U2iw}oy׵IDkpd <} ^xveԾ2:\dH8E~~J>/FPֲ"kzx6/Mл'19/T RkSwpsq8A2OMq-2xO㼤^.; =eRϯʌ<?;BD%VIJ_0[Jp:^u]4ヒdڳG \UdHУXV?U\8h>½W[Z]")c9ny5JxՐugOݍ.xקU,hsӕ{=zU}o4U> q)>͵ 0PPS$!MaGi{O٘D^K}fuVGtvud~4:s8NjC}@衁ED!~(E闆-k!?z-u &C+-0õ\#~kFMmZIT\vzzM y1Z7Rjg[>P)/, 41.+j[^U$q`Satu|Y5n[ߡ?~6 aʞϯwŇ~?k@?pk@*LVRќ"a,ǟX5MHO-.^XZHTI<~/:Y-GrX;p9RMpTЃ5X:^Үjy.O!$` `Rxc8:>VK׍ʘy.\3]Of߶/)!;̹5|.]e6=lGmR-)Af&ZVkb)5ya%Hm-|lİrSՎBh?9frozؑ8%-DOBeoϤ¡#pϻ"b21i^e;M|OZxV,7!nnv ˖kӱ-?OZ_-?G߮k(ږ`bN'ܦ3{6~kcQtLNc])5  @ U`{!m6iF*[r9 $ޅ=lj:xo&y6]sPKeNטWe9Y˂D`y!PUT. }4]`u׺|f:eGhT$0>Xtr|+#Q_Y~fo8/ ltXޜ 1yM%IByM\X1{퇠=<.pOO(1r|Mvv6$1I**U2xV‡yrlޱ_;v6< pl #r^ 05縺nK:; i\SZX_.JOdBPp[Z)Hr7 L& mLpIf=[6a#{=it:݊נR;Td[F{MU-빷q#3ewC?E,5[gu(`ns_mx,%k\{.Z P`jL-&D"qLooX6AWㅚ4׺U@GN,56)-a Ӑ S-$i}){ %|}(>%4*΍/-4,sf.Xze$^BNRyu iXDܐ>HVʼ7ٕٙ8"_=ʼ/z$fAu]_UJ|7E[٠ x"> s_ rHKTinM=`.M]~(=mULÁcak!+aL[UNh, ^BzQ2=UwyԨqgbS³~?1q8\4iϡSa!?0_=>]ØKPI*d*/#n/vf=FMS)'^>k,8ߓ'tT"S핔WlBּvqySTyn!.1B76*|LMr25ey~$w!mdY3sL=[ˌqhjک:Wkip0f{[4fi5ΰc%JpijÇ£f{ic͹Cmuƭ*^o㓎،Nϝ12ϺMN ӥ\j_沄2~Yj&rSjy9]=ȭ% ScL^& Swo?IY)YE}m#luH!D{J+|dN,Cew̚^y0sN6 #g^۷9k+6e󸓉7/ mu) CqV1Cd21/( I, a|t (5M@4@e(VYĬJHҔ2#f #4i!P) hSV2:A:Q \֐@ ܨfp"IR/v1x umMֿ_Aj\Z)?b}Ѣ)WvƗLys涻3wn]emo~75-8]'EC઱y[| /ţlvlL'`kuʗxxoQPx}7;Cca?W( s*BMP:?05?SUt#qPU(d*1@!6 z* ;3">ch`xpg7'O5}@3d {u_ʢx?#ņUӉz)P~I%c[JGPFpZ1r׽dl @>( {D%nEǔFY[qkd͈Cݱ2-mԎDlشp۝(0;%O¨1Aם@Fg8XVi(rkxE| M ! 3`z>R* 8eJʊ dm{FӲ-S>,=B"V'GlB3k-L?gZg_:#sDEG,!#wtƐ8%:8B\F%h~fDxH|fŰjΏ?xT ,A@{7G|κf%ʘM!<|13֕Aaʐ$4OxeSg$B34剴+qZPle̯- 2XJ;M5b8 j݊rY[Z3a6aUnsqOcW mߏ<70;Z]@Z)D^iؖס2]= %N_A-iA ,,ہE³b4o@_^'+}58kO}3͙gm-5?;n4 YG7XUݖ5"ࠀ'q \8b!Fjd20ߊ_1YV1jub£>bP>=P !?$e\+ʩ KsV5VMa,۪׈S盤1rYHRTlϋ> n)x}z)zPe]@0&DrqR87¨@l^b<S(?to2Ik&c:"𻾛ƌ|zFN޳B**y emE)wEQ\grT -ˇSI£$LFbn,)P:yA"N $fk!҃x l +G \mNꮛs䏝i%rJWg q%=/sa2si' U+el(=ud6Ջ+VwTA_N랩—ZPNXF[Aqej ,9oFq +dvIɂqS#cvsQ{GZ몸`-PE4b!D#FӨi%JwP7DCX/]V\[AU~ pX:9E4A7⿚e77ГxZ>z7l М,;:VG@HOU;|Y?Ĩ_[zÆ)՛M6B|MB]\dEG 4 "1& & $.P0/`@Bt[̩$|/ |zXBp *|- ^ 2=Cºf+?HEx|??\M|wcauğ4ΆwnAWXSsx9Z9+! v HCz;[:y!3_#GJIR7w*[1C 43ȕv@n<k:gx>hzgpR H!hB KZ\t%J eH¡!AU.l {SY^cp woU¡lVhBp'~ռj<|5 GAF}KJMVމ8Տq@HҪ%@d+0=lFW AəBx $~}x'=/&ph7"1:!W< fOcQ\oDK\ިkbu0SF6DIXn񿨯X@N9ⰴeM:lC{%=\ЂN;ZQ|9עWhUSx*FUk@i$@z~)q=ngO4=|8>Ϛn~r Hu טR(m^/t<hjtdamG0+U d-Zlyf!)%e#{zrjXN4 hE=9{~t|7 :ٶeto.em%ow?g/-;1m8rqͼ%푸;d gYJDV<'oK!) JKIM - D,Tnm> k22]-|̿_qIdpYT[QP 4#b-Qo֧:~sK\4+ݴY')#mx!!;];]<%I9wpiaVT K}5 g"YY#;WO`#! Hy$`C#dr?  : 쟻CB񼕮+xۓ J#8O=s66Y߹UmbI)Lwr nT'|Mul*Z]ځd== 0yQYD+·}uA4.xAv x 'Ŀit"1--˘D%:,WQC#:-AML"7D 8{ifnʓE &|IX|*g mfsD[$ qL샞B;{`м 1]4C ǖZSwR"_>95(זfdgؼ̦"Ӄƾ?%5PO\#}C{! doApX! i0AP\hήy+ӌL(r؉\>OHNtSQy\r_PO`Iq Q os::7EEByסI~)ĝzժyx1`xlUi >ojk%\Н󬧓b,ʾۧ+[5s w{P3bUϮEU>z˝kdN؁PD^:"i2kkh[ 2f3n G+^ ;6ML<. d"Eu:]Uz]Tj-WRE0=,ӟ9!}Z kO)vzQըz&oMHpa}bRRZBmjvݮzMlIow;w<07gSnnyyɜkxNi3L`,,; d$N7oznj`̲;83o+* rK_H;Pf۴kaG߬Je{8a7/6$xƢSB G=LOWߍRx'{ ;sW.< ߵIR5{PĹkH=6OS$r\|N`k $`#5s@r4,a?P$ӯ8͢YQ*s_qx $'$:)wʼnKq<ȯÍ>ҒT{]"jr[*=U hP|2E$u3?w!$K$A [^Oq*ĴG+|HU~"r ^fEj,tG D{S ˑOF>rBSVmmC93S\OCWҒPXYJiUU˨!mܮ}23s6(֗'v͞Y#׉4`1IP %40•چ[S[@,~TqFVk#D-/\70=( $n<~"ζo5ۢ#LWibyڧ/#%ifw*Kj+ (nK'4X,/ĚgTskU;bzBѢPtm5~<:j Z|9܋a{qnנgM滚ߣo#2׸1yW}q@TF iv︿Xuk[63hl,V"e1ŸnH&Dh߾/δx_EHAD`3o`Ϟ[+w.Z*jC?Isffͱ<~#Έ݊̊;{/zB$]1.I~,dbEL`j1gՇ28!̢^waw641<=Ḧ́%c #9r{H#݌snW`lL<1^+nnБBnV#`uaP}˾4w/Sƹ!'Cx~9Onr`RuewxH3) "y1Xo7n<;Tp|oK:ZoPa]J.F}"wS=!kf1c*j<㑳!Ó bggDrYe}TYe {aq "c"< ?+vm8?3h~RFppˬ ֲWA%f.{s֗?)ut0~͓ȩ3gҸVJGPk~ xQ{6n30XMSjwikljp Oյ ݂wո0,~gpuU;gmY;kQᑿ@m8(e;$o>{}bF6]WE7eݯЏ :#Ӟ҈u97Ѳ7+/.鰊=@f-J8`|xu{a^c=ױ{&lvQÊm/V&wgo5 S=]$C}V8wF,>.yEG|ĩ펡ǭo>dDLTڠ#*#~vdPC1ru$$sF wO̪rvUXUsp RE@aӇ;8eV2G|H[*au}PGv98H.nU)Kٽ @ļ#_Fj}JX) 9I$xr~R[CATEg=n/?7h?j|=ȉΜ;Ӄrc#LWCU?t 'kftn{z 4`1J b GpYXŜ/`<5\,))%1ˆ4qs{<2@ P]i,3ػ(Pi zѴllD3-V}Nal%'EYcE&PxanP-P}\cjR14~ݥ] < K&xu&.;vq8&UXѿiM^63(pDP±E 0} y^%H~@HkeB^}oRregΔ cS#-}Y]2ALI(U 5QWW>( u/m> ݧ$1J:?oe!8x)<f K ?A8g+$J+ 8ݣO&ρX$$i귭u oʠ[ i&ޥdx, fdUZ+̅XmĬ;Kɩmr$NH]/F8(jN[~'C;oC)xkZ&=iO]85-oIpy`Tg|nEJeYXWMd=ab̐;奇J݇O) M prܜBu$'(d4~Ti~Q>cdpwI4JTEv)4Y}( q3 S_B {ܳz ;D],.`䃎ۆc 7>O\PܘCzEj"+vN}CwM7S˅PL[ X۵R֟~j 2jyH{١g͙KUk#̦{&D"rmaTdzF#i?wnNjM-JbX!7a &km6OLhd͝&" z /1|`AAepal:onRW.zޞ0f G&H9!ڜ)P mwk0hIS K|{#W`<M:v27OImNh$ejx !ξ2V&>I}"ܡ_1ї7v6]s\% cr&1鱥eMYIF`aK[f[V ̛o6A@ʊcJ*A-xa_۸z[7C9Uע&F]+P^+ $T7Uېf߆_&Տ[ux߾^wpRw5 ^39},??3Ь\ƺ3 eE Μ0*C,h={݈jo:LIZCVA8lyQ .wf܃#Z"@&[Pi9=9S%-;GnCkhaɓ-,C *acD*LRsJEo`LP!6g(ڇEDMZ¢JMbXhT20wJ-ƱŢv v>4? &!0NAϰok>v20A4ߩ޼zyX<_k1<;/5=1.BFP&m˨gwMTeg_!-83jd ((9!J_[x9I>u3=,">5AI \[a.b:w Sv#mW/;gJ<b(D()N Vj6f7RA7 'J ?\bm!fه:: |lڸ܈*dХW//&5Pǚ1(E %GF2vm~_ۮ]җ;>WxN캔kސfv+*Cq>*VhwS~UqEZ䀘bjG涶xej|ŘWj/duA@|lB+e'yП-횋\FP\W ^`nH~$'Iپ@ia2XjF5n(zHnlVVeh8ƙkQF$; al>g GÂ\#dkVAڂԁJ|aD<|S'L&ToѯcBL 1!t%aj<86nWDk)# ׇn*N?zmI޺|.Wȋe7f) z{/_3' 8oLwp<^d|o3ϫf IaN~r:h]ۮ|}m㌮B}qF<ɷcmV#ZBeoI_)m= f`R JA>v̤GW_Wx3^Si ʥ0{? \rsg*De3SbBHo_9G~xEKU^`m)7J.Lb0CO6uz),|ׯN87&9Wފ@qO,KChs2g4vSGh@~U~Ѭ_@ibfmo*J[7(@Y_#9 TOjkV۷b6QŁ"~avFߩ?3tr@.:WFb6 et?37w4H1.Ү iAkӭ7q|Ws< cu5|;ޕg k4b^-|6@/bI90}: ^ʈXOCHҰ[J̈́z:[2+wo >;,߶UzSzZm=|IeSQA=΢Kk?({}(ot4 HGQE~y„DRtU{;$W]ɰH&_D}au2cmAO@н9\Lh I&P{cLY`!ڲ"8舄Z9pb7sc_/5+3b;S>YO>B~ ҠϽC$na߂AzZ'wkmH;'<Ɖ3?/lTU\RѰq7<8Ted]~Z{ikcoEVLX`E:DS[] dMbDz/vu#i&,v62EP!|݁ DwVD'.c3eC[K}YT9"1&vEQȴָQ '*O5 t9`k" !;؃Q|Tx$/+_!Pb8>|7&aQdZv[X? g%v 9B؅ eʉS_XfLr:lX%nj́M;+)d)Kb DHƀ1%EGUFs{DҸQGy>sdF e͖5I_ V@ XMgjJ5ʭ:T^"4~/DL}y_d/7FUчdtvP#QN8=?Y܊3&/q+#MP}Zb:[6q(pN l{a;ı [˃~WoQ<7Q\Cmȅ bD:BR^BZZwHwh5RI͸oJ(lb)pS_JbKQސ9)aaHƖ*$>i|$AP`#}RT葌<"K´ue nZm6Q]z?7Ip~)~6eI4_nuHgHsH&)= ڧ4HLt+K HG&MV_~cbKhKbo6yOQAPW8~v]V}qVa߃S8ěV^4K!`cJWViD.3։xLMy^#P^46̩N&xZn<##AVUPۼ_3U$"zV@}Z2e"4ġXnjN]T43Ij Vj6rĮUIjk~#HiRFj*{8q(2/`1y5?\H}NP[N9Me~:-K8*+s)ZmRƘ]9m@Q18(NZ$Q{x^'\l5vs</3.TCe m$ko`$FcgY(cc6AzZJӷ$lN9}W!sߟ;ͳDKds,I24/GohT2,Q宋P8Aj&*pQƔ&rׄuzzhN(L˳2(78&{y}WzP1S(_HL5^k1(3$'(oٟt3z$ɲ_ϖr4(WX^VmP.__2,.mg6Ӗ<֒{곣('b?ۀ]l[W({ s@_ ?'q:-<3K8{+phiy_\j3Bs{Le9Zۍ\MVD=C˨{2/.GEΪht2 -dX>,&ɐɰi zbCû,̂IDP3|  3z5UC*jZ+Qт]XO5K؉OTZ10n!d|6Yz~Ո+rHq)K^| QmjL ,q+=(B@Qr802YJ=Ma,iуaŀeYJְ85d&6{VL „2.z~(N,/ʪnڮi^m?~!PD1X@$)+_`./LPNoر3-Vt=^!A1 )a9^%YQ50-q=?8I(i~yY8y?B0b8AR4r JjaZz~FqfyQVuv0Nnq^r +e; #($E3,/"D*+*F&Eu?( @,O *`./K2BRk:h2[6r{>?B0b8AR4r JjaZz~FqfyQVuv0Nnq^~`phxAdEtôl $jn>~0Nnq^~p I &'ʸJ 8I3yQVuv0Nnq^~  $ "L &H, JlTgƴ?_fv~JöP]Uo@~!v^5 u{_SbXs:'gwXJ/[\|jc!;5hMri HMʅ Ҹ |PZdRX 6&ZX;٭7HXBMgԂ&2MW~ HmYd^JX4g8ZkcS"^^Ec&[Z_.PI 6u؁gepI< [ߤk"@gcSmh֯^. z|=V7lj`3,?t)#Tp yMGG :pHWv].uNoD]b[˃F%%mz;_(=u$y$VC~POTJMh:A5h{ݰ,9W;N T|mcwI.*|bոT9rEa ЏtI1`UdKbj4ĭG1>)IMTDikS焎!j~BQ9BߋH¦ф$AqɭLi7MlPx7ߜW^Vl?PҲ #n XKIk/O5z͢Np4Xjrq.f±nVu+S@??KTcSd +]Goӫ?#(Xv%U~ǏБ.cZJkLthT/.&Lt]Gj(2=HS;$ ʱ&05e w^fiv!*H@Q빵o՛pK)n@qW"QT|GE}[O;af[mC4l),BD?+TVae]Ψ6j:Fuoz~Z] ~$lyy7FO}`/TNMU'H\:/[FQqUI7Df6XuANq]=ғÛ%$gcŤn=Ytt\!7}qԳ¾ +7O+2A 8 sѝI'9!]AOy_r[|ȧi?5BSTF)^b!j-4rMrDذ }pRa3"9[~4^c9PZ7"Le6:5m4 h;|/`I22TY ~/K,(´_܇I4^M== uBbxdگ#Pm Xbk u%sSo6޴@(XQMż!J\bgEJ,NB-/eMUk!#ܡxcEO7<5}H'mW) 6]ڥW0d:ͅw5Oqd>avUAшXlߌ#[6XȽ2sŦf^#o։ N(fhOYܪE/̇_9G1}[]l3mBQW,NHB*}d緰35@"@22W,~㖢ix߻_yV&x!TJy6yCK=cvu/$䡡>w}8 HB*͖yE:cNJ)u_bEKvP[$ZkKhc)pÖ!H5l [ְ%,@s_U{wT ,"""""BړIF!RJ)K jRv-:$Zk1c|3ɿ+]r؊lnT:hugo-0.68.3/examples/blog/static/fonts/glyphicons-halflings-regular.eot000066400000000000000000000472371363637351300262560ustar00rootroot00000000000000NAMLP',(GLYPHICONS HalflingsRegularxVersion 1.009;PS 001.009;hotconv 1.0.70;makeotf.lib2.5.583298GLYPHICONS Halflings RegularBSGPMMF٣(uʌ<0DB/X N CC^ rmR2skPJ"5+glW*iW/E4#ԣU~fUDĹJ1/!/s7k(hN8od$yq19@-HGS"Fjؠ6C3&W51BaQaRU/{*=@dh$1Tۗnc+cA Zɀ@Qcal2>Km' CHMĬfBX,Ype U*Ҕz miO1nE. hx!aC XTV‹ R%|IHP5"bN=r/_R_ %҄uzҘ52ġP)F7SqF{nia@Ds;}9⬥?ź R{Tk;޵ǜU\NZQ-^s7f 0S3A _n`W7Ppi!g/_pZ-=ץ~WZ#/4 KF` z0| Dѵ&däIÏ;M{'omm I !wi9|H:ۧ{~qO, L]&J09/9&Y 蓰{;'3`e@vHyDZ$3Dx28 W Cx5xwB`$C$'ElyhԀ DJ $(pQAA܉A@'$ hp0V0 `se$4$"t2=f4A{Tk0|rH`L&sh]A<`R'!1N;_t3# V *veF`E O${)W=p:F`22ړC^.ćG<.pNe2ִ+Ysl:˼ ܫu5tu^86ȄTmyQ%u~%~1rҘawߚ^_ZZa0!N`. uqYB\ᨀ[e:@J'Eہ,3ubj@pfeW9( ޅ=lG7gj SM609OˑlBa݁ <Bՙ(VRApf^+g9qMt]تpEr@]@VkV ud^X R@?EY2]#Ǽ4JK'dPC|mmn#$+48u'e&[n[L%{BCDL:^!bƙ:&g3-3ub iLZڂWFSId6.k5Pl77UzT:NN.")['|U"AIvwptdk9嫫9nDmq7I|6Kbc]MBABȪ_JT q  6@Fhd`GT:M7'L,IhFP ~j $¡„ 3hA-S^چ-%qe~Qqln"i&Qe?FlK"As(3Y;"Let'RzM1 0{=) K%$C 9M4c EotjVGD)l8,\w !%$3t TBzҴ iUJ[xgdBr$!eq"J> )\~3(^ R€8#>bHG'7_ fӫcκtDoAA߃(qB<``VΫ֘*buP4v@+.Qԥ$V@C0 RܐP[z:XH#e s>?EWO>@I$|si ES)0A?9ab,@K̩o&Q% ϞLu+ +H|Ɛ?NK4CnPt 'OT.j5Ĵ8vw֜I&+`yScaO[#gQd[KI矗`ČLP # )27aTi@c\ސ 0nCpߖ運4͵x*RzYbT[\kUvHʈqp঄IIŗ) bB XPNtz 2 I== ;}bqjiކa#" >11Ap1POOuxQ Fϲ(h݄O'MDxLK$ȵh& 14SirHJPtDM;rM+ *ؗ5u2$f3K %ѳb (@,2f,~"7R;E;HX(42Z'Tۿ2J+^!#oY~4-׃GW*!A0&8f{`W=DP8'= R g}iP>#4EBRY^4eN8V,[BĨD#X],LBsNC> +o^x jC.4Ya_{eA2=r+9POA!! }YPJeGn%x1/}RgHa ^3- 5 |qSaWK{ 1al`I1 Qf_yyCZ)L3X] W6@DMT<.uGK8DsбWr\7Z\V"ISd>CUjeD 3MtWcPӉ6#3QnቩJ\7#磱`؀K lV6 &T ~l. @61`! ` wYk/a0A¹ԁYhdxk:fEao̟^<IwYgq7s[ -y1ع5aMKאRBYFq}8*Nt'.YbZvK (]&ɜ(ՙ2:0 oΏхPKiBH4UX,[$ 0mXش f50VR 8%ާDtUs`-BPzPsvI8z-t1DiB "˶YTJ .?07jLN[2tĮ̎ #6?E׻:ɞY;A&qSIR)ss 9*x0Bj)mHAhyЏhMm&4Ŋ4 gV&tYOCS0Yd7MvNj)wA(o "͢[ E`7ezď-Q]6+Bca@^I:һ=sSnc 6 OB4LGpBq/>O pwj A*@JC[h&3B Qbϩ8 :%f~v/lS00a"B8(f uGoǚgyt_y~͔ %mL !I$Xt0~ePz]Ug Н=_?.j#+`li BM5 őGp7a ֒%Y[UG9@\bDY{{ED0 $Q+FvC`ݨ3Q E\uC9![$l 6DoDgG*+X!%#Cq ?8ZUB)U@opgީZq89|uccAќW;@">Ph_9}.6V/O:3}ZS {:~ykcO6;OB=bV. Rk o ^GV= }oI"+ ]wFzϷ`<30h3]Rf859s`KM8 XUq<\ZOssM&j&  .%PBL~^Gˈ3pD:Z<\ǠiW̆"(:zX~0PG]8RQMNTqfW~!0R%Ց0xvGFy/F-wu/*+ \8@6c<L;c[º nr QS'oQuT{qҐ_ͿSdA*ð:m8Yuz2PB Hh`lkpLLh cEb6eۏҋ ?!>| *=VK@rx0G`%ryr[6Y37 f**n%9df11ޢځ^'] Rq.,^%l e#wWs56!=!q[ %Ԯ]5^:m5)?V b|u7fw,:Ye R% [ o gFAzFPx{dxíw8ٔ{{L> d2CLL,L,(mS$=|%֝lu& ą83 N Xx \VnJ[)Iw/鹻 |GźYDH*Sp60cJ2@W%Ѧc_^$#*:G6n>D;~`9hXB UJB_вˈ%w'$v|#T<68KMϑ-5U+'B ĪNbJOv'|+*Mk(d }C˱@q&aR%} !VЃs3w2a2awHz/Q0F ]~;ä NDP mK3xke_ S!V&=v_PL9؃Yi NU_)J69f*S  17F|BR$y,Ʊ.&=uqsODBR=ɳeؽɇBH 2lu'h7^#S)Xi2..Pe/@FK$](%|2Y1pC8tI11N//+\pjdWmI=߽YZxMЉP81/ JG^U ,Pd1O^ypql2h$jvI%]V .'[+WU8[D,߻-=[ O wE)3J&dقݶR¡S\. 5J$I&oHȳ~ lz> Ux/Hu;?Gt{?;TH L|F8}{p:2t͆aѧp65Y"LD.rVS_ k]n&Hz~9æ p $4ق'{&M\ΰч!qi (.h' B T|{I6cL.빍iI꫿\!;g`1 j%C o3*60E؎]t.-%0 YK_nft] *VFCtJT+\WZ8gF^ ޞf 5I=#6.@2z;W`B/ęQghjyJNAX3, K66ڲM0T@O{4kj|"ftџۄU<-a5b)^R8:ilKa6@!]buvΏ$ oUœ~:.Lte JξP l$S[z~Rq39钺9Q/m"%ʤ7 5MKL鑧"IߏG XTގXLFݧV jp^/Mgۻ{w *9Oʈ<"aAq.M2@mp^'wߕmkxO8 $[&|YZy`2_|%r/J?QṈl3ÞKE$wvCh a@U1M%0?1* $GZ{!|ʿ$ە-٪Ev;͓:`Bl˸쌧ɬoQ0&,F?^s,ch˕$Ecl0w`⏺ň@/r^l8cT3k@JݔuP&ʪNdJjTKi *uX{tj~ɡ}i\BKenȵ|N u#]@lCZ$iPa㸩t04y20 s֪,Au!QBϖ^@Vsɑ\Za7쾉ш6-TrU u~1HJ(<αbRԖqi J?eG *jVħ ":Y);-Fd!HG~ux cb6m)&;0dU?8X~12ۼtIx5{(z '[ŃkZЅi,b1̇`(mHNeK/ [(#QGduT^m%!(7KgP=hϕkɐU+.[eC"GDΨ<*Ř 9&܂?)\<&Ŏ5 LJu@Y,냲ھ_w0^17p޻*>D8_)$UźR!jOF>{ t,-bP,m`D"/zA ͔إQZG&U]xejxLwv~=)@B6?!;53/ps@tOZS7ؙnlxZ?Zj a{6L41 2Qi&֥l]o=7ļ ofЖr MEV@H/aD٦HlK5)ŒZ OE3IG'г;D'zl(E$.ٜ-W R'\w+)w3꺾 @%R).~9;].šg+)%ȝk҉^NW>b1z:soD K2w[|>9vWMFu`axchիU`*ʆe]OV'6xd?H]_rA+zdFH ʋ<ǴkUsFzaH9-gvb=L/E).x9j%B)$AB t b.bAEZRbH(Jya9Wj0fF'Xz $DQ6q` o i={#4FYH@J3 3i~tYТhkHP17YD"pĦ;'16fpu>FoDQin̒- @P# hj ނŀfC 7°T5HVXpklĭ]yXr)?ͺBNJ B#9e&&_0=pZ6h) ̗a b=(p);.N,W^ *hԺCm}E7i6aIvͲxp*Ac#4N&`)ĉHWey7jloEh_n3 jp?4p2WE'kT_ &!ȖjVlHӻ_kɚʳaY s@[G"bYLܫXi Cq8&zVaY{#I@2m!d[1 AƢnKeם/>dmuX:xʷ\pNl+H+ctSǶC[~3e}6 \,Ʉ|Yݧv]'|&M2 ddsx-((76aXm=ӊQ<$Q†\ qiH阇i'i$"{S*VwF/tfQCWUZ{S;Nx}H&* 9׸qU1 a`(M-aG}n̽0 pmcn ɘ_\l} 9FvHþkJZNO mZQҤ aSf )QC+2 d[ H"t* c*bڢq,#S#u'Ҭ:4asCDMF|ɸm_1L]Y\*X>tgDd@&[)8;<{8<+VG\H^aae-4sJA \ hM[\`#pD5Z97g;BWmqTXX%0v&]E 4]FIJ&S_4R0D+meY gO+M{03v'ͅft:;ر Nn\ǔ^,)1laBZZ[  ZSUYh߆wS\/*?zQЋ`X4gr[CWG.Y0Q|RԃE[wy),ш$NK@c/b -#ZI G$ƗtmH#)XwPZAD|S ofTH)>M1b 7ɆSuq jK4[s xL Ǣ]5 !M!AdƧN><:ǻZ(8)e /W| bDDŃtT7rur0Ң`ܴh5 5S}4hrvalc!ZjB]xDbTxzYS6_)op>#@PS*bS\q ƋxYfQ><" Y6IEr_7Ұ VH!IrEL6!Nq"'daqMvA% v n.;A/2ʲa8D$GWv#̏ 9k'o؟o@ (]gk+}/ (nqK(f Ɵиp23YwpDdGq2$}KӯA"E&Ntg'Nes!Ю4qo}쿝S,ojr/s TMT&Qf\12h'&ctN'Tx7]2 ;G ʅ|T++:%/ 1T  ˀ<4͔˗ ,0~!WO' :suҦن(^ﮎ )7fmlҹ1ūtZh L0 6X"J҂ 49 ֩B}ԭ``Ӓ #Jn_F H|$OK=œi17o-Hqp[ɫ%%:Ɉi3۠G CLL4S:dBj|pYSDP>pv5KLe{t0yEND$*;z5NBIgn.N|׶nRaSZJcH mXek;_ 6,yb0#ZA e|wG U1lLD7ÄVqt[xuEQULPBlZSh.1Q0Uٱ8Rip;{H#GON!?t>Q |pkq!gT,j2sǍ4툊tjnƛ/IOE!ˋnF4M&1x$ew+vS  bm]e%8 P !s_06)Q2JB [t9'Ԝ,[fÆג]BB@r&Bs|Q gOC1J D&LJiC`A^#X8tH?daĖTSTaH0@U)^e}Jb7%ܔ%:ƿ@M+ysqL Y00ÔGD >ĩAW 2I:F 32ʠq:6S]K"g[ ϑHB5VEqLJX{CB!PIq9Llxʪ7>֤]@!@9H!pə$ ?)܎l/"́+@`}}:\ 8zQgS+򒤿C}R:HUF\Xg/AZ%c1wlETwX ZNhyf2D ø&vLq47z\iJyJ-kN3 -sJ5)V0N0d\ӛd0d-E[mf\UmxCR<(`ѕp4^!hQ `!l ~ƙ:JɠlW9˸ZXB=l)`jeVJUG!s1?Ƽ3Ê.}bIa6ʕ t?SxZJ'p i,.R2T`5-R BxrWH JPe#Bb|-[PEh‹(5Sfr/]IƊ dE#OS39ӻ]eۮɹ.9_beM9b#e(- 0Ra9"U,%~X܀z۽{'6[@t[W%* .d'vR {h!AedCE}x=E[|B$7J* B- ,=k7[_-I J5e̶{ ( ;WMw`~pAz 8f))(@ Īم<.a%N n@bz>%T*?lgbd<ĵw9Na8;<^*%y:tDҕZ<@0q4l\ 1`/$IJ ғsN);:A;)$ו Wwy%KrIv\bV\nd{6tv/~*O 7U>8rAC<jE-j牷xs)D1Ì/qp**̸$ّ,  Bȼpk MhpK7U]h&-$鎻Y;q6wzW˄֭AhD^R"s5fw +Q&/9ȂwNbz{Y> ]NEc,ߞ# BF:0/-EȾŒ׃F\I{tAZCORuk i)ytkdN&vA P{P'>xƆ`.%,;:Կ:aFoTQ}v#ףQk's~z5hMQʒY>CʍiUNF#J0uC8k! fv {E/IKIE> pyde ʾ=z:@7J|5g8x 3O 3H1؄F.yfzWIM j[.w%i?҆Uf|}@+[8k7CxSEOޯp$Q+:<]K3T-y[Nz;y-HZY^.M*'h8A.N2rLB 7:Or}CS˚S9Jq#WI}*8D!# g#Y>8` В ?a2H,^'?^nhOƒi<Ya2+6aFaMG-Gkè1TbL `*ـVX *xe§֊Z*c`VSbJU*6TK@zqPhg*ߔU(QU49L cM*TR!R,BȅE*C|TzpF@4*텰جXbL.T2y`Upb T,%@` #?@tGLŞS)ÿztϲFy׎ 14Lhfe(.)pK@\ Xe@TbvhD&0-IbD d@ZD1@ DyѧCN| 94Ӛ#Nc l;, `cX@(2$0 "@- $B@<$А8p7C b(@ PA@F 0tGORIJITySMW52\ToRKV0Ȏ( -$ !6wHGO r~e~/]V~/P~7SzKFv`;`9v# JBN,ӭ'`'`\LTApBs)r! ( i`hugo-0.68.3/examples/blog/static/fonts/glyphicons-halflings-regular.svg000066400000000000000000003243021363637351300262550ustar00rootroot00000000000000 hugo-0.68.3/examples/blog/static/fonts/glyphicons-halflings-regular.ttf000066400000000000000000001305341363637351300262550ustar00rootroot00000000000000pFFTMm*GDEFD OS/2gk8`cmapڭrcvt ( gaspglyf}]oheadM/6hhea D$hmtx `tlocao0maxpj name,post5 webfTPT=vuvs Z 2UKWN@ { , h, h@( + / _ "#%&&' ' )9IY`iy )9FIYiy !'9IY` * / _ "#%&&' ' 0@P`bp 0@HP`p !#0@P`fbߵiY!     |vpjdc]WQKED 5 *+  / / _ _  ""##%%&&&&' ' '' !& )009:@IDPYN``XbiYpyaku } )09@FHIPY`ipy !!#'09@IPY `` ((h ./<2<2/<2<23!%3#(@ (ddLL[27>32+&/#"&/.=/&6?#"&'&546?>;'.?654676X& j  j )"& j  j )L j )"& j  j )"& j LL#32!2#!+"&5!"&=463!46^^L^^p@LE32!2+!2++"&=!"&?>;5!"&?>;&'&6;22?69  x } x }  x } x v L   d    d  l d;2#4.#"!!!!32>53#"'.'#7367#73>76p<#4@9+820{dd 09B49@4#bkv$B dpd>uhi-K0! .O2d22dJtB+"0J+ku0wd/5dW%{L>G!2+!2++"&=!"&?>;5!"&?>;4632654&#^CjB0  0BjC x  x u x u@--@$?2O*$ $*P2@%d    d   BVT@L!2#!"&=46 %A+32!546;5467.=#"&=!54&'.467>=2cQQc22cQQc2A7 7AA7 7Ad[##[[##[dd76!' Pԇ $ op zy#%**%$ pdL #7!2"'&6&546 6'&4#!"&7622?62~   \l lL 7  &   l 2'7' & c_"fn &\`tfjpO32!546;! 22&&L%6.676.67646p'0SFO$WOHBXAO$WOHB"7Q)mr *`)nq&* )2"'#'".4>"2>4&ȶNN;)wdNNrVVVVNdy%:MNȶ[VVVdXD>.54>0{xuX6Cy>>xC8ZvxyDH-Sv@9yUUy9@vS-H^{62!2'%&7%&63 a o  ^{"62!2'%&7%&63#7'7#'JJN a o  d⋌&2##!"&=467%>="&=46X|>& f   f &>|.hK  ]  ]  Kh.| L#'+/37GKOSW!2#!"&54635)"3!2654&33535!3535!35!"3!2654&35!3535!35~  Ud  & sdd dd d  & d dd dL   ddd  ^ ddddddddddd  ^ dddddddddLL/?!2#!"&546)2#!"&546!2#!"&546)2#!"&5462pmppmpLpppp LL/?O_o32+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=462LppL/?O_32+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=462DDDLpp&,  62"'&4?622;;nnBB# "' "/&47 &4?62 62    ;    %I2"'#".4>"2>4&3232++"&=#"&=46;546ijMN,mwbMMoXXXX K  K K  KMbyl+MMijMXXX# K K  K K %52"'#".4>"2>4&!2#!"&=46ijMN,mwbMMoXXXXX^  Mbyl+MMijMXXX  -32+"&5465".5472>54&&dd[֛[ҧg|rr|p>ٸu֛[[u'>7xtrrtxd/?32+"&54632+"&54632+"&54632+"&=46  ޖ  ޖ  ޖ    ~ p     >     GO27'#"/&/&'7'&/&54?6?'6776?6"264X!)&1-=+PP08,2&+!)&1-<,P  P/:-1&+x~~~P09,1&+"(&1,=,QQ09-0&* !(&0-=,P~~~d!%)-1!2!2!5463!546!5#!"&53333333,);  ;),,;)D);dddddddd;)d KK d);ddd);;) dDDDD 62++"&5!+"&5#"&l`    j`  w  ? d3!#!"&5463#"&=X;),Rp);vLp02".4>"2>4&3232+"&546֛[[֛[[rrrr|2   [֛[[֛;rrr   2  ^  )#!3333))p,p,d/3232"'&6;4632#!"&546;2!546& & T2   2 >p  ^  12".4>"2>4&3232"'&6;46֛[[֛[[rrrr|  & [֛[[֛;rrr   12".4>"2>4&%++"&5#"&762֛[[֛[[rrrr   &[֛[[֛;rrr  9!2#!"&'&547>!";2;26?>;26'.    W & & W tW    >     '2".4>"2>4&&546֛[[֛[[rrrr[֛[[֛;rrr] $  (76#!"&?&#"2>53".4>32  mtrrr[֛[[u$  Lrrrtu֛[[֛[576#!"&?&#"#4>323#"'&5463!232>  ntr[u[u  h ntr$  Krtu֛[u֛[v h  Lr d/?O_o!2#!"&546!"3!2654&32+"&=463!2#!"&=4632+"&=463!2#!"&=4632+"&=463!2#!"&=4632+"&=463!2#!"&=46}    R 2  2   > 2  2   > 2  2   > 2  2   >   ~   R d 2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2 L#54&#!"#"3!2654&#!546;2uSRvd);;));;) SuvR;));;)X);dLL 732#462#".'.#"#"'&5>763276}2 d!C@1?*'),GUKx;(.9)-EgPL 3 0[;P$ 97W W!1A2+"&54. +"&54>32+"&546!32+"&546ޣc 2  2 c*  `  ct  ,rr  ,tޣ 4  4  G9%6'%&+"&546;2762"/"/&4?'&4?62A   Xx"xx"xx"ww".   ^ x"xx"ww"xx"r/%6'%&+"&546;2%3"/.7654'&6?6A    `Z  HN.   ^ d  g~jb1K3#"/.7654&'&6?6%6'%&+"&546;2%3"/.7654'&6?6 D@  *o;7 *    `Z  HN iT "ZG !   ^ d  g~j  !%-;?CGKO3#!#!#3!##5!!!!#53#533!3533##5#535#5!!#53#53#53!5!ddpddX,,ddddD dddd,D,ddddd dd,dddX d,,d,,ddd dddddd,dddddd  #7#3#3#3#3#3!5!#53#53#53ddddddd,,dddd,Pdd[[[[[   "'463&"260V C;S;;S;V0 ;;T;;  ! "'463!"/ &"260V 08D;S;;S;V0 V08;;T;;d&!2&54&#!"3!2#!"&54?6,9K@  D@   K|@  @  J  L !2 46 >>CEU!"3!26?6'.#"#!"&/.+";26=463!2;2654&!"3!26/.6D N9  >SV N N      & X & l l- p  v       dL!)13232#!"&546;>35"264$2"&48]4$);;));;) '3]dϾV<?!(% _5,Ry:" *28 T2*BBW-ޑY". BB % Zd'2;#!5>54.'52%32654.+32654&+50;*7Xml0 ); !9uc>--Ni*S>vPR}^3:R.CuN7Y3(;  G)IsC3[:+ 1aJ);4ePZo!56764.'&'5mSB ,J   95(1(aaR@ 9%/#4.+!52>5#"#!#3'3#72 &2p"& 2KK}}KK} dd R ,১ !%/#4.+!52>5#"#!5!'7!5L2 &2p"& 2C১  vdd  ,}KK}}KKL/?!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=462X LLddddddddL/?!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=46DLDLLddddddddL/?5463!2#!"&5463!2#!"&5463!2#!"&5463!2#!"&Xp LddddddddL/?!2#!"&=46!2#!"&=46!2#!"&=46!2#!"&=462LLLLLddddddddL/?O_o32+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=4632+"&=46)2#!"&=462ddA ddA ddA ddA LddddddddddddddddL#*:J!#;2+"&=46!2#!"&=465#535!2#!"&=46!2#!"&=46dddd ,XLdddd}KdKddddL#*:J32+"&=46#3!2#!"&=463#'7!2#!"&=46!2#!"&=462ddgdd /ȧ,XLddLdddK}}dddd!2#!"&546 K,,,,,,v,,,D,,L!2#!"&5467'2"&4,XJ*J%pNNpNL d>tNoOOo62.'&54>"264usFE66 !^Xm)!fhHuXyHÂ2".4>"֛[[֛[[Ktrr[֛[[֛oVrru5.54>6?6&'.'&76#&*IOWN>%3Vp}?T|J$?LWPI)(!1 )  HuwsuEG^F&:cYEvsxv!K:%A'# " A)Y l */7>%!2!"3!26=7#!"&546 7l l27);;));Ȼp87cs* s ;) );;)2cL6!#"3!2657#!"&546&'5&>75>^i4);;));ȹpS 9dTX .9I@F* L6;) );;)g  0!;bA4 L5!2!"3!26=7#!"&546 62"/&4?622^^  Ȫ   ȯ  ȭ   ȭ   L326'+"&546d0dLJJL#3266''+"&5462d00dLJJJJ3''&47660J*J36 &546.2   d32+"&546!32+"&546  dL#!"&5463!2L  346&5&5460d * ;O#72#"&5&5&5464646dd12N: 9  > =,L32+"&5&54646Rdd0L;;dH  #!"&762!2#!"&=46  *9HdduJ  u`((&;(J ' 7(a#aa32".4>#"#";;26=326=4&+54&֛[[֛[[}dd[֛[[֛dd2".4>!"3!26=4&֛[[֛[[E [֛[[֛~dd32".4>"'&"2?2?64/764/֛[[֛[[ xx  xx  xx  xx [֛[[֛ xx  xx  xx  xx  $2".4>'&"2764/&"֛[[֛[[Tw[֛[[֛1Uw;K2".4>";7>32";2>54.#";26=4&֛[[֛[[?2".4>#";26=4&#";#"3!26=4&+4&֛[[֛[[    KK  ^  K[֛[[֛V   2  2  2  /_3232++"&=.'#"&=46;>7546+"&=32+546;2>7#"&=46;. g  g g  g Df  fD Df  f g g  g g ͨ  fD Df  fD Df?2".4>"2>4&"/"/&4?'&4?62762֛[[֛[[rrrr@||@||@||@||[֛[[֛;rrrZ@||@||@||@||02".4>"2>4&"/&4?62762֛[[֛[[rrrrjjO[֛[[֛;rrr}jjO!2".4>"&32>54֛[[֛[[KtrAKihstr[֛[[֛;rtxiKA>rtsS6!2#!'&4' &F   &S &5!"&=463!46 &U & U ## ] #!+"&5!"&762   && ]32!2"'&63!46&# U & U # &] &5>746 ^$,[~UU & U #$DuMiqF +!2/"/&4?'&6!"&546762R,^j^!^j^^j^P,^j^IIgg+#!"&546762!2/"/&4?'&6j^^ ,^j^`j^,^^j^/2".4>#";2676&#";26=4&֛[[֛[[:#6#:1  [֛[[֛.   IUaho276?67632;2+"!#!54&+"&=46;2654?67>;26/.'&;26!"&5)#!  &0  =  2 pp 2  =   353  X  v  v !{,  2  ,ԯ  2 0y    r w  +I6.'&&&547>7>'.>7>&67>7>7>-BlabD8=3*U  :1'Ra\{%&=>8\tYR-!q[Fak[)ȕX1 "@&J<7_?3J5%#/D &/q!!6ROg58<'([@1%@_U2]rO.>7'&767>.'&'.'&>77>.'&>' '8GB    `H  >JS>H7 '+" NA 5M[`/Pg!;('2"&"IbYCe\D9$ 886#1%)*J7gG:    8G\au9hoK$]54<&"&5476&2>76&'&6?6&'&'.{nO9:On{{nO:9On{FZ  2Z__Z2  Z# %8-#,- "F-I\b\I*I\b\I--I\b\I*I\b\I9>||;7Es1$F^D10E^E$1u$/D0 "%,I';L!#7.54>327377>76&'&%7.5476&6?'&'.P[vY,9On{R=A &/l'PjR.Mv&  6QFZ  *HLh5)k|# %8- ,- "xatzbI\b\I-yRU4Zrnc1?1FrEs11) ]@ @] )1ES>L'+/37;?CGKOSW[_c3232!546;546;2!546#!"&5353353353353353533533533533535335335335335Rd22ddddddddddd|ddddddddd|ddddddddd2222pddddddddddddddddddddddddddddddw%7&=#!"&=46;3546'#"&=463!&=#'73546oXz#z*dXzdM*zL!2#!#"&546d);;)d);;L;));,;)X);dL ?32!546!32!546".5!2>&54=(LffL(, '6B6'p)IjV\>((>\VjI), +'%! !%'*L 'L'a'M 7 Maa'aQd_)!232"/&6;!%+!!"&5#"&?62**p&032!2#!!2+"&=!"&=#"&/#"&468^&d,!02**6%%+*2222 *L !53463!2!!P;),);DPdd);;)L 3463!2!!;),*:,P, pX);;)dDEk+32"/&6;#"&?62{**YDk&=!/&4?6!546X`)  )   !.#!"!"3!26=4&53353$`$-);;));;ddd-(d;)d);;)d);dddddL #12"&54%##"+"&'=454>;%".=4>7i**d]&/T7 " LRQ  )2( Jf,53232#"./.46;7>7'&6327"&)^Sz?vdjO9t\U>/ v?zS$2451 7F8%M)(  ()GM~ 1==7'''7'7'7'77 N괴N--N괴N-N--N괴N--N괴d!-=32!2+"&/#"&54?>335!7532+"&5462(<H(<,F=-7` 1dd>2vddQ,}Q,d-!2$'$(ddw} L 0<32#!+"&/&546;632+"&546!#35'!5X,<(<(21 `7-=|dd_dd22L!-d,Qv,Q($'$dd dԯ}wdO7G%6!2+#!"&5467!>;26&#!*.'&?'32+"&546dkn  T.TlnTj:d%8   VOddip &yLN(  % H YS(22S dO6F#!"&'#"&463!'&6?6*#!32!7%32+"&546n jUmlT.U  nJ   %&jPddO (SNLy& pd(Y aL7G2#!"&/&?>454&/!7%.!2#!"&=46ސNS( % p &y22SY( nTjkn  T.T8   Vd% dd-I!26=4&#!""&5&/&7>3!2766=467%'^ NLy& p  (S22(SYLddjTnlT.T  nk V   8%d%2".4>%&!"3!7%64֛[[֛[[  [֛[[֛9   &%2".4> 6=!26=4&#!54&֛[[֛[[%  [֛[[֛ &   %2".4>&";;265326֛[[֛[[K &   [֛[[֛@  %2".4>#"#"276&+4&֛[[֛[[  & [֛[[֛  2".4>%&277>7.'.'"'&65.'6.'&767>'&>7>7&72267.'4>&'?6.'.'>72>՛\\՛\\d+: =?1 " "/ ?9 #hu!$ 0 E.(,3)  (     *!A 7 ,8 !?*  \՛\\՛  ' "r"v G  .&* r$>   #1    %  *  '"  $  g2( % 67'"/&47&6PM<;+oX"O\e~Y+" n+We`#'7;!2#!"&=46#3!2#!"&=46!!!2#!"&=46!!d);;));;);;));; );;));;,;)d);;)d);dd;)d);;)d);dd;)d);;)d);dddL !2#!"&46!|;**Dd%32!2!5#!463!54635#!"&=);,); ;),;);));;)d;)pdd);d);dddD);;)+AW!2"/&546)2/"/&4?'&6#!"&54676276#!"&?'&4?622,^j^5,^j^/j^^^^j^j^,^j^&j^,^^^j#;CK2".4>"2>4&$2"&4$2#"'"&546?&542"&4$2"&4ݟ__ݠ^^oooo-- - L- 73H3)z - - - - _ݠ^^ݟWooo -!!- -! $33$ 1~ - - - -Z[%676&'&#"3276'.#"&477>32#"&'&6767632'."[v_"A0?! -  Y7J3$$ )G"#A.,= # (wnkV8@Fv"0DG([kPHNg8B*[eb2!5(7>B3$$' )M"#!7)/c# *xnfL@9NDH7!$W]B$&dXDD>.54>"".#"2>767>54&0{xuX6Cy>>xC8Zvxy#!?2-*!')-?"CoA23:+1! "3)@ +)?jDH-Sv@9yUUy9@vS-H-&65&&56&oM8J41<*.0(@  )*D*2Om9w.2&/7'/&477"/&4?BB8"._{iBBi BBBBBB7._BB^*k"5._{jBBFi BBBBBB77/_2#!"&54>!"264d:;));XV==V=.2G);;)3-D=V==V "/''!'&462*$3, #**#4$*' 2@K#.'#5&'.'3'.54>75>4.&ER<, 3'@" MOW(kVMbO/9X6FpH*M6&+  4C4%dfJ2#4.#"3#>36327#".'>7>'#53&'.>761T^'<;%T)-6"b "S5268 jt&'V7  0 $ݦ -$aPN(?",9J0* d2>2 ""   7Gd/9+DAL!X32"/&6;3+##"&?62*Ȗ*,|%#5##!32"/&6;3353!57#5!ddd,*dc,dd|ddd!%32"/&6;33!57#5!#5##!35*X,ddd,d,ddPdddL32"/&6;3##53#5#!35*Xdddd,d, dPddL32"/&6;3#5#!35##53*d,ddd, ddd32"/&6;3#53!5!!5!!5!*d,dpd , 32"/&6;3!5!!5!!5!#53* dpd,d, LL!2#!"&546!"3!2654&^pg );;));;Lp;) );;));LL+!2#!"&546!"3!2654&&546^pd );;));;oLp;) );;)); $  LL+!2#!"&546!"3!2654&!2"/&6^pg );;));; $ Lp;) );;));LL+!2#!"&546!"3!2654&#!"&?62^pg );;));; p $Lp;) );;));L5!2#!"&=463!2654&#!"&=46&=#"&=46;546&p);;)>DLpd;));d&  #%2"+'&7>?!"'&766763 ,  P'' K    S#  nnV/L5!2#!"3!2#!"&546&=#"&=46;546^>);;)pDLd;) );d&  1!2/"/&47'&6#"3!26=7#!"&5463!m)8m);;));Ȼp,pm)8m;) );;)֥#2".4>"2>4&2"&4ٝ]]ٝ]]qqqq{rrr]ٝ]]ٝGqqqsrrrL#3232"'&6;46!2!54635 ' gdV^|d22L# ++"&=#"&7>!2!54635Gz " 'gdM !d22LK" 62"'&4?62!2!54635qgdq#d22L #'762'&476#"&?'7!2!54635*MMК=gdML*Л:d22L#'/'7'&6"/&4?!2!54635^WЛԛL*MgdКԚPM*MXd22% ! q3gqdL+!#"&546;!3#53LDdddp,E/'&"!#"&546;!3#53"/&4?6262L_  Ȗdddj\jO)_ p,j[jO) >'.!#"&546;!3#53"/"/&4?'&4?62762Lg%dddFF))FF))gp,F))FF))F/!"!#"&546;!3#533232"/&6;546L dddd*p,/'&"!#"&546;!3#53++"&=#"&?62L*ndddd*pp,L !2!546#!"&5!52LPdL&}-1;&=!5!546#"&=46;#5376!!/&4#5;2+p/22ddpddd33*ȖdȖ*yddQ%6+"&5.546%2+"&5.54>323<>3234>^%"% "  d d 1t5gD >?1) A..@  ^  ^ dL3"!5265!3!52>54&/5!"!4"2pK Kp"2KKL8 88 %v% 88 x88 %v% 8LL  $(4!2#5'!7!!2#!"&546!55%!5#!!'!73wipdw%,);;));;),p,ddibbd;) );;));dfdd&767>".'.7.wfw3 .1LOefx;JwF2 1vev/ 5Cc;J|sU@L#A2/.=& &=>2#!"&=46754>ud?,  1;ftpR&mm&L!((" """" '$+  222/2 ! '!'3353353!2+!7#"&46!2!546L J LP*dd*22dL #"!4&#"!4&!46;2d);,;gd);,;;)d);L;));;)D););;)L%)!2#!"&546!#3!535#!#33||D| ,dddL| |||Dddd,ddd,L%)!2#!"&546!#5##3353#33||D| dddddddddL| |||Dddd,L#!2#!"&546!#3!!#3!!||D| ,,L| |||DdddL!2#!"&546!- ||D| ,L| |||D ,L )!2#!"&546!!!#";32654&#||D|dDd&96) )69&L| |||DdVAAT,TAAVL%)!2#!"&546!#3!535#!##53#53||D| ,ddddL| |||Dddd, d dL#'!2#!"&546!3!3##5335#53||D|DdXddd,ddL| |||Dp ddL"&!2#!"&546!#575#5!##53#53||D| d,ddddL| |||Dp2Ȗd d d %2".4>"2>4&!!!'57!۞^^۞^^qqqql,dd,^۞^^۞Lqqqddd '+2".4>"2>4&#'##!35۞^^۞^^qqqql2dddd,^۞^^۞Lqqqd2d2dddddA 62632+54&#!"#"&5467&54>3232"/&6;46n,,.xxPpVAbz  & AwasOEkdb  A32632&"#"&5467&54>++"&5#"&76762n,+.yxZ % OqVAb   AwaxchsOEkdc  dLm%5!33 33!#"!54&#Ԫ2dd,,Md22y7/2#"'2!54635#"&547.546324&546X^Y{;2 iJ7--7Ji/9iJqYZ=gJi22iJX5Jit'*BJb{"&'&7>2"3276767>/&'&"327>7>/&'&&"267"327>76&/&"327>76&/&oOOoSSoOOoS=y" $GF`   Pu "Q9   ccccVQ:   Pu "GF`   y" $ooSWWSo++oSWW"y  `FG # uP  :Q # cccc:Q # uP  $`FG # "y  d "!#5!!463!#53'353!"&5+, ?,dԢdu       d !! 463!#5##5#7!"&=)+5, ?,>dԪ |  ^G |d 77 P#3!#732!!34>3!!ddԢ!,d!s, d,+$d$+ppLL293232#!"&=46;54652#!"'74633!265#535d22s);;);)X>,>XL2dd2;));FD);>XXԢddL6=3232#!"&=46;54652#3#!"&54633!265#535d22s);!);;)X>,>XL2dd2;) $+;) );>XXԢd  #!"&762#";2676&35} ,, }@D:#6#:&77&P'L. dd LL/?O_o32+"&=4632+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=4632+"&=46!32+"&=46!32+"&=46                  L                  )33#!2!&/&63!5#5353!2+!7#"&46!2!546dd^>1B)(()B1>^dd> J LPdO7S33S7Odd|*dd*22+52#4!!2!'&63!&54!2+!%5#"&46!2!5460P9<:H)"Z" )HJLP;))%&!!&**22$.2"&432!65463!2+!7#"&46!2!546 jjj."+''+# J LPjjj9:LkkL:9r*dd*22,62"&5477'632!65463!2+!7#"&46!2!546X/[3oo"o"."+''+# J LPk6NooN>Qo 9:LkkL:9r*dd*22",!!.54>7!2+!7#"&46!2!546X,%??M<=BmJ J LP9fQ?HSTTvK~*dd*22)2!546754!2#3#3#3#!"&546/R;.6p6.d6\uSpSuu;)N\6226\N)G6.dddddSuuSSudLL/3!2#!"&546!2#!"/!"&4?!"&=46!'|  % XW & dDdL D 2  % XX %  2 dddL#-7!2#4&+"#4&+"#546!2!46+"&=!+"&= Sud;));d;));du);P;ddLuS);;));;)Su ;),); 2222  !&4762 !2!546 'YV/ |UYY(n0U22!/.#!"3!26=326!546;546;33232!'p'q*}20/222,2 "!#!5463!#5!#!"&5463!#5,  w,, v  w, O,T    dGFV32676'&7>++"&?+"'+"&?&/.=46;67'&6;6#";26=4&KjI C   )V=>8'"d 1*) "dT,| -otE  GAkI ! "% ,=?W7|&F@Je5&2WO_e_ 2  2 ~ $4<Rb%6%32!2&'&#!"&=46#";2654&'&"2647>?&/&6%?6'.'.. +jCHf7" *:>XXP* @--@- -?0 !3P/|)( )f!% =  &* x"62&CX>>X83 D-@--@ۂ # =I+E( //}X&+ 5!H d9Q`o322#+"&=#+"&=#"&=46;#"&=46;546;23546!2>574.#!2>574.#q Oh ..40:*"6-@# d   KK   d)  )k)  ) m!mJ.M-(2N-;]<* K  KK  K X K  KK  "p "),!2#!"&'.546"!7.# Vz$RR(z }VG+0 )IU!zV`3BBWwvXZ3Vz&--% ,(1#32#!"&546+"&=ۖgT)>)TH66g )TT)g6633#!"&546+"&=`T)>)TH66B)TT)g66 %'5754&>?' %5%Ndd/\^^<ǔȖ  (Abd 2"&4$2"&4$2"&4|XX|X|XX|X|XX|X X|XX|XX|XX|XX|XX|L2"&42"&42"&4|XX|XX|XX|XX|XX|XLX|XX|X|XX|X|XX|ddLL/!2#!"&=46!2#!"&=46!2#!"&=46}  J    J    J L  p  p  /3!2#!"&546!"3!2654&!2#!"&546!5^ );;)X);; G ;));;)X);d,dddL;!2+32+32+32#!"&46;5#"&46;5#"&46;5#"&46222222222222L********, *.62"&%#462"&%#46"&=32W??WW??||||||*(CBB||||԰||||ӐB76+2+"47&"+".543#"&'&676/!'.6E*  '?) T 0I' *L #3{,# n  6F82 *5#"#!#4.+3#525#"#5!2 &2p"& 2D d 2d  dd R , W 22 L 05"'./#!5"&?!##!"&=463!2E  1;E%= !'y,2 " # 22+."A2VddGJ!2#!"&546#"3!26=4&#"'&?!#"3!26=4&'"'&'#&#2LFF &  7 ? 9   9 gLR   2 2  2 2 $ #'!5!!2#!"&546)2#!"&546!PpmpG,Ld|pd,#'!2#!"&546!2#!"&546!!5!2pmpG,P| pd,dd'+!235463!23##!"&=##!"&546!2dddpdp,d ,'3#3!2#!"&546!!2#!"&546dddpG,|dpd, pdL'+32+!2#!"&5463!5#"&546;53!X|^d,Lpdpdd,'!#3!2#!"&546!!2#!"&546ddvpG,|dpd, p,0o #"&54632a5*A2~ 6'&4O**{))*2A~ !2"'&6d)***2,~o #!"&762{))*a**( 5-5!5!Lc d 1#3!35#5!34>;!5".5323!,P2 &d2"d& 2dd,dd  dd & ,L%1#4.+!52>5#"#!#3!35#5! 2 &d2p"d& 2 ,, dd & ,dd,ddfrJ32 +"'&476 0  ) J 00   >fJ32+"&7 &6S )  0 J ))   fJr"'&=46 4 ))  w  )  0f>J ' &=4762j  00  )  0  =:#463267>"&#""'./.>'&6|Vd&O "(P3G*+*3M, :I G79_7&%*>7F1 ||5KmCKG\JBktl$#?hI7 !2+&5#"&546!5X,p dddL!2%!#4675'=DXDd dQ,[u}4]ddMo__<vsvsQQ(dpEHEd{ d&ndd ddddd5d!u ,d;I]ddQEJadd9'dddd dy'dddddddd,d,A22>ff****NNNNNNNNNNNNNN"~Fn2b\r bb 6 ( L 0  X * ^ h(T*v 8|t*<6`R.j(h6h^2Dl.vb F !2!v!"@""##"#8#z##$$0$^$$%4%`%&&~&'P''(4(p())*&*J*+ +z,,h,,---.(.f..//F/~//0>0011`112$2^223"3>3h344`445,556>6|677N7788B889 9J99::l::;;<:>>?(?n??@H@@AA~BBBCCBCvCCDD`DDEZEFFtFFG6GvGGHH2HNHjHHII8I^IIJJ.JR@. j (|  L 8 x6 6   $ $4 $X | 0 www.glyphicons.comCopyright 2014 by Jan Kovarik. All rights reserved.GLYPHICONS HalflingsRegular1.009;UKWN;GLYPHICONSHalflings-RegularGLYPHICONS Halflings RegularVersion 1.009;PS 001.009;hotconv 1.0.70;makeotf.lib2.5.58329GLYPHICONSHalflings-RegularJan KovarikJan Kovarikwww.glyphicons.comwww.glyphicons.comwww.glyphicons.comWebfont 1.0Wed Oct 29 06:36:07 2014Font Squirrel2       !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~     glyph1glyph2uni00A0uni2000uni2001uni2002uni2003uni2004uni2005uni2006uni2007uni2008uni2009uni200Auni202Funi205FEurouni20BDuni231Buni25FCuni2601uni26FAuni2709uni270FuniE001uniE002uniE003uniE005uniE006uniE007uniE008uniE009uniE010uniE011uniE012uniE013uniE014uniE015uniE016uniE017uniE018uniE019uniE020uniE021uniE022uniE023uniE024uniE025uniE026uniE027uniE028uniE029uniE030uniE031uniE032uniE033uniE034uniE035uniE036uniE037uniE038uniE039uniE040uniE041uniE042uniE043uniE044uniE045uniE046uniE047uniE048uniE049uniE050uniE051uniE052uniE053uniE054uniE055uniE056uniE057uniE058uniE059uniE060uniE062uniE063uniE064uniE065uniE066uniE067uniE068uniE069uniE070uniE071uniE072uniE073uniE074uniE075uniE076uniE077uniE078uniE079uniE080uniE081uniE082uniE083uniE084uniE085uniE086uniE087uniE088uniE089uniE090uniE091uniE092uniE093uniE094uniE095uniE096uniE097uniE101uniE102uniE103uniE104uniE105uniE106uniE107uniE108uniE109uniE110uniE111uniE112uniE113uniE114uniE115uniE116uniE117uniE118uniE119uniE120uniE121uniE122uniE123uniE124uniE125uniE126uniE127uniE128uniE129uniE130uniE131uniE132uniE133uniE134uniE135uniE136uniE137uniE138uniE139uniE140uniE141uniE142uniE143uniE144uniE145uniE146uniE148uniE149uniE150uniE151uniE152uniE153uniE154uniE155uniE156uniE157uniE158uniE159uniE160uniE161uniE162uniE163uniE164uniE165uniE166uniE167uniE168uniE169uniE170uniE171uniE172uniE173uniE174uniE175uniE176uniE177uniE178uniE179uniE180uniE181uniE182uniE183uniE184uniE185uniE186uniE187uniE188uniE189uniE190uniE191uniE192uniE193uniE194uniE195uniE197uniE198uniE199uniE200uniE201uniE202uniE203uniE204uniE205uniE206uniE209uniE210uniE211uniE212uniE213uniE214uniE215uniE216uniE218uniE219uniE221uniE223uniE224uniE225uniE226uniE227uniE230uniE231uniE232uniE233uniE234uniE235uniE236uniE237uniE238uniE239uniE240uniE241uniE242uniE243uniE244uniE245uniE246uniE247uniE248uniE249uniE250uniE251uniE252uniE253uniE254uniE255uniE256uniE257uniE258uniE259uniE260uniF8FFu1F511u1F6AATPhugo-0.68.3/examples/blog/static/fonts/glyphicons-halflings-regular.woff000066400000000000000000000556001363637351300264210ustar00rootroot00000000000000wOFF[\FFTMXm*GDEFt DOS/2E`gkcmaprڭcvt (gaspglyfM}]oheadQ46M/hheaQ$ DhmtxROt `locaS`'0omaxpU jnameU,postWH- Ѻ5webf[xTP=vuvsxc`d``b `b`d`d,`HJxc`fft! B3.a0b ?@u" @aF$% 1 x?hSAiSm߽44,qPK q XE](2 .ԩ] "ED i]DԡZJ\8wwV"FpUԯ.Χ(gK4O n;NR{g`'!PMUHEՠJʫ*Yq9c<U9!QIYׅ-KC+ դU)Q94JYp]Nq9.qyVV n)9[{vVכ־FWb++{>׍a|*gQ,K<'W@Ex̢D&Ud# & x Mx2c 5*.lN/h]GtT(xŽ |յ0>wm#Ye[%Y-YR'rYjD% ,@BKZjHڤ@b-R+nhK~룼$;h^fܹsn{ι ˴0 kb8Fd:%Lה"1AՔ AY>,ؔ#pZ4؟5made ?Ȝy=I:C D(nIxL .1!P'JDtHj@L4Ph' )b)vHX,f1c\'cGu>1 ~t?!xT_q?qBF#L%Dћ"?Yǯj??8>NSkemAYDb4 J);@jP$ 'qh8`;aX6CF*dYc"'?hLV㗌,>ce3eVh =C~xC\((qb@ 4xK&hׁ 4\2DZ6N1|-;j Yu@jѫxi䊧mK ٍDEwq3̷.cAw@4t.gkgr{~Wl~{lW2} 276a2\6oz@$HSH gbtX70Ktc1,7B oLƏ66[,%iZ ,l>TpKSGg\> #A#3Eyk6v;u3!ZI8Mk?8CWq{`C*h>H1_skh)ojOO' !~dXgB(0< kOYxeƧĭ5k =d ϧ> +tC-o Ǫ/_koܶs+fOztpu7-}d9 se \9.H4!0S\ ʱk2"?ip7\2zlްt=W\!KyOXimUnov 6: 2 LZkAA^qCޔ &PaFI0>&Q #FQl> A·q*OȦ_@27l,sf 6p7ܩ?M1vA2]$j";vlk~va0gjzRD:gc6yw%g(þ#'uB#=_@?>FVb0a!aL4tXv:Fh9j^xތz}Wn}7}jΚiHitKSaXEEbbBQ1ftxFȮ -"dqA\~F`6i䁕+ Ԣ^Ȳ}ש׆k&Ĺ<- \;g1>w00v^x 7l#Ot^5+xe.^]׼G8^ m(t1 sbfJ %<4H@e8C,5<(kc5YIA]|ךl6+=HVcbKՋB6i4 #_|&>NvQk#pW=u7HɰR$ [5싙 g %19}&@$&l=1RI}9#ςz??1z&ı_ac|PI[:u;l->k4GYm|Zw }HnR=-B ~m.ِ .Mz^,0%8EG**|sg|ozO֬0sz.WN^ yHk<v3t{8-|' ea~H94xA-@y bT4@0b#]DDljDSio:AgSP z:;-|yH"r {B{\5RLi6AAtM]taRKC!1CgC샂 +1EG!Xzٛnzv@x-#i^x*$)W=O\f[WX~V? `Lei::v4$?=Ra#c]8YFJb&'{%LCE Cf]^$/fߪM;À; 6CXV#X~ F< :vCcyBpLv1Fv#9 /8VF01_K?x>}#G7т\Wp!.@bwɡ+{o#ԍPQҮnī66 cZD(. u;nM}?vtxF{+` ="rPπlDV̶?Z@H䰅][35%O )\^ Z;>Ftf-IzӮ yu1uo<:oa:uqwykk ⋜}0?jvX+}VG$s ?26YI5c$Cfb!X*|F^$p7p55߶6[mjgl>* KO& 8ܝ:ǰokKm~oS-*4E}P/% k:e"1AJCAX8= LŢ>ܱav{|K.3 :\Bxwbeb>1ۿvH?f58 %6$ɲ'pL^HXbpIVqnA8Kg'i!UzSEI5N=hpV?(E Vr?޴7Vڋɿ.O;p 4NRZm.O> MuL'j5`;MtAQܶMyV<` $m)yڳXDa:݁q1JFq15-l\3~X-2pFDe/f!2i:=h{%{t^ *PBͽ]YD3jd *w|GLϽ}ˑk7Ç=06oz*zo1~Jw00SePw%#@BJB %+ ';%!& )Hq 7fqH.!Eǎf,9՚$9 H{~i Z)O|!"D.KQ a2 %2Wɂ\{*B{7,9.'ew U^W&$r9rcGBwll<ʷSQゅh! iѨvJ :Y?#_m4q[ },EA{VПP|Dg?9MId?{)/ /\[ Jҏ[f4G>QK^ m O -7w]„<U3jƏ,:Yq~0/mŵ@CCFq{,Θ쬷ΘQSo lsɿh?A2q`5Z&*X1L5:6ς+O]uej%?ۼ&aW?{2[}W?JbΙk-\b7sIkf&Λfx~nO-9V ~cW"ȗy)b\)2MrWf;MU7'[-c/.ؾuMl&.9) G!!W* 60Cф#qrqOKZOWq,8́/XpTȑg<>¤)[J8o` ;S\S%h~p|J˾F~K=E0NQX*8;D7Q1QC% *Eyy} UG?>I`>'6<+3IVgϮyOQ$WBvH v[Ϗ 2+ 'ø6N߆<ɕ 2S娚9X1\┣df>B~-t>W]pPrZ['+ƌl9]8qC!' @AAOuШ !?M\JMͭfǞ)ߕ=w?AN>¼}jQ<ǏpǠ^(}1+2q F4RiHďITr8^!gm>'ڸhE`s̊ol!(9~ o%#)~ƃj$@ՔLpGOa{߿fé)zؔY<~^cs潺ݴNRURTY%8Ks3qd]^QTb' zx)HFҩPmUZjQ&XƁo<0jYGz]$8c&hyݼwΞ{9^sf߹m[vӣ!(ZAsۧyB8RiԣBg6{UmtyW!bpǮd n/ŷʼ@v/%cxEn:4Y²,yZ-krcH&^ȩC'Ȯ'^T5r)((IJU&#݌! +YM.JEX^|Lw@ھZsgY洺\xԟxyLCyo?eV"_[Q/5Y|qI/\9diEBh$v wOL fpa ,?HgHf2RbL v >USo^1/,ēvcYGmŨ~Amz ?/40yj̸pk2H eERb/"M 75ul[drC&Y͐&I `!>p;J-b--.VM4>Fj/5σt5}>C*<'d?,cdGf2ҁ0w6Lh"fKζp;ǿ϶Pdc1EOi%Ř(DCWV2I)TiMFTz0U S7V mBW6;nYZUzSTg>(hF"޽T뽷R]L۶|Lx[s,'NU|E<4)Rp*vU#g*gjə*=~܃ASēA JHw3@NurbwȀʌx}[`7ZtPlh L.)NU}kq'vFQr׷{ˤS]ZL(@*Sf^+uPe_k#.8ɂ%ՠ,@TKх t`ߑXAD;b|pA7}q2 @Y`~iԬK0jY( R~^ҧ8>=F"˜A[DqvQCX|ZsO \/f.F;kPbdz7ԐeͶ-6bybaWjnh7YLF!4wssFCnh_0> MZ nC *#5/OUN\(3o@[7`Mg8xge;f\y|f֤ޑ]i5q5q&>'353kYꭑ=W7+΋yxIeOYǏs(p6[B/t爁*̠-n: <Ц) +ް~q_}oxt>LV FG@d9[2?2ȳ8笞={fgcsCmre#E>45qo:JX^ioP,xf:/yn9VѥS7=u-\%KϦUv,ⳀZ=vkN*+_.ڊ֞iڃ=w @lmr>Oo,VԲɝz &:'45!9pI 0@I[PU""sInvR>A9t$3/|k8yiE c8E!Q\ۂ} %Af4s*A8A΀>D=5uwjnG z?2Q/I=fH4n]澀YmG"2PEHfvZn<šPiA_q/PDտ $$~%NyhrOdM\-m(@\#ƼNJO>a+ uJ*(%¢FPJW,$))} B\_wV] 0TOCÊQ}5{Ho*;;葞rǨMc54S : M7(kY:z`gp Jstˉv'eG^~iD16dA @'N ֭N.?f…1bzJD V o@7R@6<%IF0mj= [}Nۊ57pyv4@<mЭ9Tp?R70қQG[jzib~/)wC? רa-/Cn.ĕH j63pKrhXIƎj o19 f\~:-ѓK47BY̆y%DC~em@]%rs4T G-Ug>HOpVB]{9&^6|m _PLLI7ǒi "'T }? 4|[Fǭtu/_y;Z?HK0Wzc#)~.rĥ+B&JG0[.ΡrOk;VCoX K۝S߳rt:zX\xmJhxNh5 K`;ydp.Ec4XD<-llip.^p: u/.Y[rl_4kz$~Dq]7/T_<菵4K$Ɩ &w S7|K^7MsMGhw㢴0]?fja5aiЦ6C2no• f=)d^v qNcԎl=u]?;f-E~nv}5%Oջd덿=Z%v  nKu ̓*J#1hu1Hr o}SZu=w;nϗU `FȶEn?߫k&l9YdgA8NSGD09MAK{ހK3݊[_]%W4zۈu9\~n3~zir X3k`Psn=m]ԃJksT9deYN`}/]U#b;Rt,lh*#JB+ (iGx\}~IֳFv@Tu֭J @-LwzYgw`wx-(d٢]F3_XcYmQԃWb-F K5d-0b球—֨T+_Zxcj*`}|x~LF*S*oMتAT1p71?R t>R'"Ey)oP7%$rv QeE+nzlVlFrkt''?R'ZCEIKy ga0^}pE;Kq{T/?i"%1ޒb-Ծqƛ˵+ 8]rIڣV{dȪ͜\AQvOS]0.NX9svb?OE~FPU}o[YKrA̓U%7Dw q b/h AhPbQؓJB8I ?I%=XtO;(PhLd S 'hݱ>|TV?,O"\`7.2>D fmg;-C'u, zA`-ټ$x vck2[xp\cbl΀ihsivaÛM,gĨlMz7JvˑVRWϋNo4(-XB^Cl&Vnnn D4[k6N&}f3YQw@$U$(Ǫo:-ZG#&/} ?N}ƥ7A!MhW>?iXprA١b?uϱι-h6;SB#/@ѿJ !%Q)Dq:{JI^ޑˡPY7UG(h?HmъvREH=N`P)QG9FMSMG@2E$Q $s~TkN"9Ն8cF^"?+G٠ ^*gUlFVxUpoC.XCƵ׵͉qK[k[K(l; ӡn%^Rj,$) 1n.G:Cf(,;ĴR—F_~^;իD;6|/jGGSSGGӎļDzbR/X?Up14u$`[ߜH477I~~Irߙs#6+heW6@wK̸h6, 1C"=meA =@z sls];kklr^"s青>&Մ-[{JiҴ9[ݵȩ-]dޢc An۹g}ꒇ6hTɖ?3s^kLcY 1Zn[bݴE߆դwk3f> fMDՠaD ~}&@5u gnOȢ<'` &bӬ-6;X"d*awYvtLXָkUߩa=HR_@+j2T*£%/͸oƤy 19/7 ~7_o+$DүsIH:r yiF:v(dO":omdM8 ;Z9uʩHCg\K/*ԙg*-I_ERqR'[f?GUAovb A$e]/Կo?|ԐQm4G7G833+ 74z*)$݋JpDNj5pqeDf/>%gW{U:g,nlU\t'%E}͝uCꘒܻߺp}U+^b'o(5gVBIOEm>5yzg}AP-P/ޫ6)x5/t;1p1L9Aܳ|)X]mkFEH/4}:,oLMo6]YM50u[yҫfVh?E-A_i﫝j . 6|5`#Z-svfqӟs͚>w7C{ A]Bz,iH'dv?`E x,mz`F[2avhp%(̒ʂ5Ԧ;Gюh\y";|"ٝʖrxzsPHCTvP$ly}iyhvMCr)#x-.(t%fu€(ۅeUUo pqeˡ啗syi Xk`>X@2P. 2͌>n|,/4} ?A&Jr+ɐCV]{Z0- A= F$+%UZyޗٲR B)wT8(aRΣ*-sr5v !^tZ:/K,'F  9=G<Cu"$-FS2(F 0Q+Xw,]=bh[qBQI ;)"Ō926r?}lV =b[j4AzKkQ?T[%$KQ-l_@l/ &;차Dr?P_dE1~z^I~breufP/պ# E+S\G-R4 SSV俑; *`G*5'dL ~ 5Fhb` ꁜ4[b$~GNAX$~ }[W}_z×6m&~O%j/r&|_Sy<-*Lϛ,JQzͤ𫷣|V|GVW~z  HE YnH4r7P?99ߡ|O-5 %4 dzO/4L_PsT>LQD( J8F+)jCb Mu2Xc8$t}&@Qr-֤U_o6q7P1ˤ+rc6I \ (*v24Uc(A ̣93]z;0'=*,e56Va,qh*P@wȬG/Oj|FIm #Pz;Jwʎ}< z Tt~`ȱGP%;? 5((u# vՊI#9,?Gb4K]Qgԟ]E[ phʯG+`Ęp?@>!}" ҽr=CD5 62ZY? iA T(E UJu;"}պ#LcӗVWO&CIԙu8*烞QaQ^*z(L|Jӏ^fp104~CUx*rV*N9π׳Pūsp_L3Z"}&rO|l~kC/Wj><SxMbSg(]J(Z#x\$OC68-f:{Sҳ蚨o4:)Wb"uiuh~d%BAM sWH.gv%4v+=¿ SGϋjWHWu>[B{[uɶs;laziW߭\zC|\fte&ߕ+Bk/t  CM /@S>Tm G`v`?G(,zb" eAAi7QR<"iX:I܋(aV;4R]}^1vԵ7=p|[Jοeµ{)e#ief0KJq"*F#(GjJFhX#шݍk5ERP΋ ^pCeoe:{6۬5͝sƙ8X K6V[=}V+hͧJlZZ5W;TeV-@HID<͙[)֐l^bXeNN"K]@b?.HH gzXaْA}MOeXHNrڟW;htgttOyu3=*פؿCFGsh9JͽZ-k]L-~hii.49Qr5I,Vݓ^jf_},Q6?5NV ޞˍYٜN%ezqƨ>Z Nt1 a %= yhޙ HJZ? hvrk@mY`^insF\*|Lz!/?)(0 MS4(ȗh{-'ho7cCҞ?6'|ubգ@!bÙf{tz1UA?=@ t%䕉iu[ NiD GT@:p<(cXUm2ϱ7zOM^FϴYUfwGs#t:/~Os]Fݑ((^?L$Sʽ WzT>m'_d:5Lh;H7WgzgZZb3{2d5Jj9c+\vqzDbbƶg "l@צpQBbS Q>+d p%}L!cdwHopx(Tpxp#:dvQ qdAQFdLKmPR pU?l zg-jPbGaR&^q>u8p&Ӯф `MGSܵaoWܛZaâٟݰV5Rs2NX qGB OKg BW)Sg\ӡl]z<߲o-_- AKMqӭ!æSigy۰]K;ST'kPqee7cZT{~*7b\H?jٵl3P оwT2jY;)l DueytOTjöUHXgɬ,WϢ^u![]vF| QGh`(# R'5XDQqM6gc'bu:'H( ?yյ6~.e[n *UyZst9R!GMM$xz$]{L<}4JZ~MVՕhy >@u +]2FqO8jѥWCQqrw.䄫ޥ\_y\On)IKGRHŁqI. d+u@ϴ kŤ}9Tv6*xge7?ì}S-AU OMlJ pժݧYwhi6\fAZc,rjFTMj8kO51TqW_n`7%KWsd0:`OXs$4?:SI1W-Pr}² 9.&P^f 8(WI``@5a}ziV pPԽ+:d\j"=aj)W$q{͜p)V|7hj$L֡9\ځn[ k{lG.m m~TEbȭm` wnyP&:PLJY_pNWzVS׃]7Ed%i癬| EWM7r HB6`UGZ 9N2l2ɅHY(ŗiwݓ[`cZR;Yz=TrvH9c. ֲG6*p΅'[:/ҪXCYхMt-']n,{@ cObIN.xN F9뛝NK[Xr=Wm ݏƦY+?sJgXuP%ȗV^[ W;W xvi/XS3ȼ2ԩZ f2/y?8M@Q*˄CXk?MzTy?ZYu׳)]͕1-a7j~ .d  'VztXK2k̹d?zzK.>,BZ`q'kHqy5j>a\C#H;#p7l4} IR7ފ0$=V#_.vs{g>h!Ab/p7=zmi%͟3)^Oj<_UNY63dsIr8EjU* 33|v ;OB@,,\cwd}6k.ukF9'26D]exGJK.׽}S$@ t";2ɩ*41_x7QbjX9Q;#{9eI -奐br B<9dpzIVQ:l+si #=T+R(MDC$ a̱ ONgj19gqXk}FdcG,&..^ɷwwc>E_]3U|t{Jf窂u_.\*W=}lNo+^Ṿ vP>~sTjWz~_ogS}-DTd -TAaYf3,PATcm ռ4g}mE$BwŪ8>9JW⁩O/9PJCXA{,@c,tEJTj98Q& HPl~K%ƞ1ѻ -eD zxNXuz.9}Mc&:Z5ә8% յսmomCB:l8~ܦEjTYHYvnV^IN]]ŽCXkg#s cSB$Ý=$k}cG&/z}_v6<7IVGGg*l\RXST)šE%Yu~Q~>XЅ`9Wk*@_ՊpM]0*%a3X팁KM|{FԔ 췾d7[nlͬD@m8e cż#gHdd@~.jllɛeRcxE(( Km¼GXA7S@[l.%գnMDs]n_Q 5i?zGTG3T@e i,r O2<l+/,%m ۚXn|E]lí[m<|#z+5 7&\5S-{AE^tK M^rq]FmC%2vJ)W-}OM"`9l+=%"T'8zH3QҐѩYP~VزNi 7ۛ ?w1xc`d```d?oAePBYt?;"@.Hc xc`d`` &]aA_x}SJAS<` b)6 >@D"X\o!ι{,_oggg #JVYp>uC4&*<=$g9W@.0q- ;:pt"HUe5 Vg([Ax9!޴EMߗ4N&ӞwjtԞeσLp>w>Gpfz`|^aż>)o oMg+RmRq,RJ1XTN7t{IE\F8U mb:fN&j9Yxc``ЂM /^0Kؘژ0=avcca>bĒIJk ."/ I888qqpnǥ5w)^-8 ||||[5? JPKLpPa) "Z"WDmDWc3K O~/cLuNN+9K8;99/p>"k676-nܷ0h8)iʋK+s9@.xڭNAwh /"TD#J$rqr|!'O3XFާ0wY 1fg;73;3xE0C q=qX4GA$x ZB8ڃ Dw!IaSX w.0?oN؍gڍ@\A`sb k`sݡ},0Ya DȵȵMyFMvYdS20~>/qJG i<#c0C~G9ee Kvв[ڷ{&V(Ө1j1MZqr7,gKܥX0QY{ MYжz=a:[jEݢ BZZ=ns`+ȍxmUSgFB]9I$uw-J;mPwwwwwwwwlޕ]<3)e׿7R^ VV_@$zГ^З~g`0m[czf`(3233 23s2s32  eD*954XXeXX14i++ kk [[ ۲3Qfvd ;1qgg& nLdOboa_c@`PpHhXxNDNdNarsgrgsrsrs rsWrWs rs7r7s rswrwsrOO // oo __ ?? f,˺eݳYϬW;MelP68s䘉GE{RαM 7nܺp;ڛZ[ݛƵ? ѵֵykx~yj?\3V+wE5=QMjzTӣ(vN؉k/셽d/Kd/Kdbbbbbbbbbbjjjjjjjjjj/r{^n/+v ;NaS)ԼffffffffnnnnnnnnnnaaaaaaaChQN-ܩ?C?C?C?C?݇C}>t݇C}C?C?C?C?vNjHMp[qn???????>>=<<<<<:::::::U>::::::::=;;;;;;;;;;;;}VhSoTPhugo-0.68.3/examples/blog/static/fonts/glyphicons-halflings-regular.woff2000066400000000000000000000431541363637351300265040ustar00rootroot00000000000000wOF2Fl\F M?FFTM `r $e6$t 0 "Q?webfe5옏@? t,3+2q FYO&>bm5ZH$Y{H jd Չ %٧y"+@]e{vNc)n?~?萤h_&iѝ?>^K v-cۍ12Ky,'n(3EwiB& Tlh0M҆dYrﲬnti]yurVXsjgMnәHW r2>iT`V7R(+o6'cB4ι㿚T ]a[Qd<3wq8,rTI80>E?*E痦#7'S ocʷ_7&#*+)+4aA6cy٣f(bF$;{ YA1vP-tG"Cf- WԙuKְK#*K< (Z`٫ [%YT{%Ɋ$s{oջvt"p4`ߩϤ}o `'ne> G5sz_N PKӦvmU ɾ{z"3`l W#Ԑ^@+,ckoAOpnuzzJ)Υ1}O=xR`J`qUs/+kv1xljlEl\nDƶVjg{Zdz7 5!xm5o[u&1ڂHBkAqrR (\gh7Ҋy=HZUPh$8RgzgͭN:1u$܅>R]"f7 K^'3+E/^YU5]NB.ʋ8+͏8,|{M|Aua|a˅՝% lKGP,Nukc8mX@d̘?Y&{?P(G]Or-\LF9,&y8r3ܟ?p>~sDz1?\U5q=tzԒ&Znj%mM"}tkDwh-=mB76&:һqt" 1:Еu;"K_/Jdc0l0'^B8VCzg[ ;d Ybȃuu;@*}y| .'C>\g=9VŐ[o|g^ >d 9 *E|A*M[[*mOQz?Pn?R)YoT&[U*5S MB [ oYDh{,}1f?NN ]O/^;\J BEsJrĚ'g/B%o Cn7:|yKt&$s|wP\i]$Z@+ Հ90x]r%+RUEm+ܰ;wu9/I77զQlu\yWN)8ܰvY*umm( fEG8 j#IRz #q߷ )Y$ Лc_%m-{!0-` ;公hyV]Hv! ta\K[1{"j 6@3T0%Θ"ԙZIGS.ΣpӬS1eٓ؛ Yv8d\BlSR)ӆ {Iӆ%>0Ўڦ\'cg2%4QD 0͒3B"MՎ&ۊhIڧRgME I(5UD] }b8$8>X h"l΀j.%ۀHH- Iݸ#1C4Y7YݖV o>P]6O47f ~AJdYF€.oy) 8l 22e1H[t@!ȅ 2\@5ٓ%Zkޒa@.`n3OFR(󅥶ZkLkF HWjY I5*6eSbk.5F,.N0ԙ|V||~N( 4],Jp|~xeA5/ڻSvy?'_v|rXHQēB@= XB94TBBcHP+_YH#$`FB;+BPR4̼ t:t"ZEJ^!XǓq4_dTW(5܀IUŇAz@U6n.WGXHRK&'swMjʎ<3)`#F@  F Ԣvob$x +u&}|X&[٪8F-E&/>/G.az^/})'x$O=<zoA9M؝&~3r3g'8ң\-MDzk5A G9|1-! 87[,mRu|57 =X,aJ^tN4\fЄ]AzH^7F&k"LU>}>rBX(ۂT% JdhKPKTFaA3HHC[r;ad54 lLkjG{8h~ fR@9wB0 zS'a7@@Nƹlbj3hNXF/es'DsQjw}Jz^:V.:ڋ{ͼ(ȲBɦx<Db#"S{PHuN/{r6;wUsPО p8+6g_2lΡ6H džH: dBtGNmx@j |{s9=wR/oDJs5z>;'xEq^r^=G?9AA_K%Dɮ:uikjkIeG՝#*)jm|t}`JZ؈H=4{g߁)qXMA,H71V"o,Y#hݨS_;a_ԗZ^cn4HE?} ȝ٤=}BWvުUehGF;@2S@f n2#fY:]JyH]-G׌wgv'|0e _7Ґn+fٸY<( ?y%wm+j&&!c^u'b&hm6¤*2 ?AIƲ5FWؙ[ƜBUzIE!m:xheǮnz|]% mrUFگ1 };!n F&gP;&$$F).tBQ3(C=Xes;iي@~NΡE SRh\BeobTnΒju g@'qQ딎nx.u6bVU& ];!C_  5*zɺmRQuqPZ0}mn^nOrT:U'h0nZp^R|DF_b\@mDE8{oGM᠜q}Sd C,iܚE/Ë[d8],MCI_u,]Vc"pg@`"y),;B^el2'.(Ęy>-|hw;jՍiԽ_o|!@)ɢ=̌SPz*!z})|ƧT}jEtCZný*՞4ۆ׽[ 9Юݓz`Wmeo|j8j59@.EV/ZW@|f_\"${v/;a:Sei3TG*]ơ/h2C32$1}DNXt?Fϝ~n,Pj9.>ף{ 9EN-v|3hCиE XT;P$=J-gݕigz~q(A<:h193N̽Q}CLWߧ׎~ b"|4u}cy62[ \d,ҎճbkD%0Tx{=;Է(i LS13Nh/6?'E^~P{sZZKĞB{Dt&z)Uoa5Q3ȗr~ F]$<tm(} MB@[GxFh8#},#u Laz(Qh4%xm`Uչ.Ev1a4_'/[d{FxI59 D<&8VEFg 芘#I䟍2S_]QqAn_Q>bޘ4g-0&E#ci8 vR/4rP7KsOWN3ՏvE\bqQ5ZڽVy5]h/ i)-/kNю#e)"P {KSQx>a&, _g-mc<n]Ч-52cz 7d PzVOPvfR Rఓ9Z -dC`,at=k?v4#P Bإ/[s.-bH)ɺz '}׶w!rXZ .:Vn;->: 6rUcs4kVW{#5ߑ0B`ܝ0u".QdB0Cr]#Q9lqN^ֳh~NU\ 16 ~SnTl\THҲڛ-~G~)$oQ7-C}q%/avO|[q4~Bc-$N76w{V餃.&(o*n NeRi4!3R"4nbm-y[X."!QKE\N4gՠםaNp >k)90BZBs yrer)vDtrv\v[>rJm a̼~uՏ>rMZcB<`)\yt|ۍr'<>[Îh7Z8caI! p⢟̮,G k5@`iw nО8pv *'O A[.rhT pR?+;\*HsLqUf:ql-ć *6!h+ˬ{h- jgkMMP#:}{/VŶC]옙&[W$ګ^#4fWa\ 5躺M[6)T3~ :. Z`si(RQ|/` il^L#f-;-C;_*{@EMCooÂ_7TrqzF%ׯ|UEƫUs^ݜv{fQ<ĐVPTfͦ?mpP*&QG{cJEPe2)xP0AMɪZHj"׻"AC+zqmVzᖞU%C:@1W [y)J@ob% jA>)Nǀi$At`>?f0gH36p6D|M 4N 4JJڃ jƇ\ p38Я6pV?:$sDNƹ2n,HO\[ոK-)W~im?T:޺UeY-#dJe)Z5?$\dW<,Ɇ;ط5SոTT̄f(PYv=Q ~DX*8辩s- ˨΀55 XRl QC l|5{ӦT\t꼕+en۸Psl3UO[ZS3*,:ÛZLS'̵**@ı~xgno2- WV;pZ9?~$6҄xJ>\QA_Cihbl] 64*A˯ɰqX7YX.-ոaɇVhiKgqNRĆN(r']%٘@3̀jZJ.;nm,S0xͻOF33ҧ<$'GE+}'1f3y5/&Z\RB7dm]8\3߂Ȫ@oT3eu^W@e7l!B,s1$Z&?dC (YЦSm>J"&pt܈P㇄BF4G5 t^Ć$j-a㠍g^ʐCAsT=kTS,|r9IBϘЬ'vGA@thQNj&T=xt;2]P|T- LÞe1ݽWZŚ*MrH5?=o"9K5='k-*AE| qҔ_?\7%|M6f++S*}W_]3fmܮ˳m w!.R#鬪;qq71$•ݙկ_iK&JάMemV5P0> Q5WHIh&4ҍIlE7}sm[cȾ|d^ %Uv1D>.T7*=tZ_㟾1Х:=0pZ6ҋNt(uƝ; B]$kڌ.{F*/UZN砦|oqKG;^侞9NexK \wh~ZpHb䉸 [k8k.bX.QXpxYa^"#Bwnbum5F~>8bN:p4 [gv^ BFUz)?60F8/2C8>N8G%l%5FH{46h4%# 7x oN t\'Ȩ E0#jNãVӹd?WlcW žֵu-}22EN}#䵵2H^a3rqs-S3&f퇣fwl.=W8,cHjcTWנs90ZDMC2ZMdjt"8:g{.Ʊ1Fb618"yԦ> W9 V `jT򔔑r,ni d qN .g+ S Q KaB?_QE rjh>Eӛ;C׭7^q `Ue#-;oJċԝ>) ;Jg׭9R;OgiI7}8Kہqjeؓ+ٗ'nϷk3eFρ0V#pMAzb^PVu~1uғwn ^.II_vdW[Q,+Lbćq 9V} ΏVw4qU3&jıHYb ttT7ρarBwP9?)uT/aA19kM \Psq+=[5͔?9W+^o^E8s)f 2aQxi& NE>"^Naa;f9]NE& t^CLz'e8ZRs&67_ãcyJ1 @TZ?SD2 |POӌ\dR7zH9iQ#zrc.4GR4qx<2~Xhnੳ2auBNC+kX0 aj5n>މe3vާ<>_ uH:XR%~9!4oѼ38? 1d#A&{A!i6 /Xa㇤=W;|) g~ ?*悽 }ڧKt>5|E.A Q6 (6 6є7<9_C f1Ўi8, V4$uti,.`v6r P gFBɎ t C3; ,oÂx| /KMp1S_X.fV#U>Ȓ#B] AIVoІϵGTV1nr+OXS% ³fOZ[_9P߰ {Gln%#hdwH= ye/W>,IP,*MV~ºK&eċM콣=)qFS"GTF*LX,h[wweWQEx ?{^چExhiׂJH|^͓e*^Я.uxEb#;ԝ<]z]\wNhochqE=4Q17W̓lÕ6᧿HE_̣qy YR۫9~l4sVy`Uߛ,#_u+DeM~hq벇#Yz$; 5ͯ9$ z> *jO$$O/xRtf-}*oɦ|3M;xިUl/.~XǎY4x3&x";$KI5dڭ ~w[M9O%4Q}S^t@w[Y;-s;bwH-* imI-1e/~TNN.p)H$W~ƦO (9, ]gM6r+#%/swA$q4O> d9}+$s?0a,>yڈs<=,c_*\D}2MT8/4g'ڦ8'}"C*\9#Y>z$7c[s|"$} ymzQx 5%o$jkp)x-:И|?ofgFr2SZq}q o,wyOgCF1l'L5T33yM92"s5uD6-JUbs O)wR -2/5frϛf@=BFCB&'F}@&yubC?'S49+ÓCIî+f/RU C Fu:C*} T:}{ݽⲷue[!>? ڸ"M 8gz0\HkZ:h~@+#N fjyio!B R'5>`[!T`mC Iѝ}n >W!M}Uav43)!kcȂm? dwv!ה;Xϡۨ}8vt"Ӽ# kvXJ[l[ZݙMÀXC3l[ TaVjʻѬ"œ t:(<cZveQTqHi{銀Q埓'ÖiP■mKAIBF =Tᅽ(&TS?/؁A:ַОV(@wFa^]o]*99Ri_2vM`Pf{QYH#V7v7Ұq>@~uɘ׆Ax/xB3Ġtyb0nG` EDٍA: PwI7nW2ED}.(h"U]9Ih_V@GZ0C pb :L 3tN*N 2!3 Cayn.ɋW`̳}QBCi 8*{57O#aTBUoi0 _^ ChrU}~rL 1z>..=%GG o EuPPsؘ޸8Pu&;*|i&Pbțh;[|y*cVhҼ(~_AqU2GIQ3`^v=@K'ЇZ#4sJ=:sY sڥbyj S_E܃"@~>86#y[cSŬ#SJGZyvvSя扝pwaT/, 9'Jkv%%.~o[ 衧RBjSȀ*$'腁pçSu +9\_f+8u\,tpэkخJ0h(]NQvW7 86:ݣ WcY_i>"R(e]6RA%U6&F]7@̳k3X h?KQ2Bk[?..KKAb65ke+]FeWHU0Oק5 e3Hco>l]02cH9{Z {sO!A,7?ŷ3w俎A Fj8B&8U$G$Y5FL5n1> q2.6e +@/kb{(7i={l͍݂濦81g(%h/EfMҍt5̼vgo ~ਜ਼WKi父UأݖwRSEFT% `=|*=1*SX^w)lfQH(YSSˌK1W]f7ך^&p@T'.%3 5zaTf6A5LX̡|L-ηTg{A)F."hjA;.~o% G#}&]׾c`ChH9xnNY lc\+v\EƧ1D9KX)2b.NWQש$/|6tð32ԛ72иyu0e)Nuh'd~xY ># b"k3 :9v$ПC:)H> զz;ed\jmfOa%9cKxۥ!k%HDn{Y"{n_} )9= _/Z(>lYVgQ#߭:Qbw$zwٮ#U?|Ghz{o$wϜ)|Vh? ZV7%Go/׆E"KӲlp76-z !l4n>$\zV?szqejQ]m^=^ !lHB4sL i9}2^K5OB)O v^~݀xrm\K&G^5CL}&FB]Kn3|sGjykObsܽaW?R6Jfh2 lBS\=jV*Y^˺^E)*\ rr(a@6nԌ?}dLgIvqNcaƮkmLcA!hdVwc=憖s_:җsLg>1*4-%&0Ub)Eܬ*b51 ++;<`!qfM*,[/GK+{,>CLR%%c~'EGAG=h䟔8:IDN)W̻AF)ucw'qhXèL@a~6Pc2L"A2bU & 9A#QLO:E9kfKFb93tL$cˬpLz5dp۰>$`.~X=?NͰ/LPNo0p b8AR4r Jj} Ӳ04ˋquۏAFP 'HfXDIVTM7Lv\(N,/ʪnڮi^m?~ QU Ӳ04ˋquۏb$tV&gϖr> 2)) { throw new Error('Bootstrap\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3') } }(jQuery); /* ======================================================================== * Bootstrap: transition.js v3.3.6 * http://getbootstrap.com/javascript/#transitions * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/) // ============================================================ function transitionEnd() { var el = document.createElement('bootstrap') var transEndEventNames = { WebkitTransition : 'webkitTransitionEnd', MozTransition : 'transitionend', OTransition : 'oTransitionEnd otransitionend', transition : 'transitionend' } for (var name in transEndEventNames) { if (el.style[name] !== undefined) { return { end: transEndEventNames[name] } } } return false // explicit for ie8 ( ._.) } // http://blog.alexmaccaw.com/css-transitions $.fn.emulateTransitionEnd = function (duration) { var called = false var $el = this $(this).one('bsTransitionEnd', function () { called = true }) var callback = function () { if (!called) $($el).trigger($.support.transition.end) } setTimeout(callback, duration) return this } $(function () { $.support.transition = transitionEnd() if (!$.support.transition) return $.event.special.bsTransitionEnd = { bindType: $.support.transition.end, delegateType: $.support.transition.end, handle: function (e) { if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments) } } }) }(jQuery); /* ======================================================================== * Bootstrap: alert.js v3.3.6 * http://getbootstrap.com/javascript/#alerts * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // ALERT CLASS DEFINITION // ====================== var dismiss = '[data-dismiss="alert"]' var Alert = function (el) { $(el).on('click', dismiss, this.close) } Alert.VERSION = '3.3.6' Alert.TRANSITION_DURATION = 150 Alert.prototype.close = function (e) { var $this = $(this) var selector = $this.attr('data-target') if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } var $parent = $(selector) if (e) e.preventDefault() if (!$parent.length) { $parent = $this.closest('.alert') } $parent.trigger(e = $.Event('close.bs.alert')) if (e.isDefaultPrevented()) return $parent.removeClass('in') function removeElement() { // detach from parent, fire event then clean up data $parent.detach().trigger('closed.bs.alert').remove() } $.support.transition && $parent.hasClass('fade') ? $parent .one('bsTransitionEnd', removeElement) .emulateTransitionEnd(Alert.TRANSITION_DURATION) : removeElement() } // ALERT PLUGIN DEFINITION // ======================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.alert') if (!data) $this.data('bs.alert', (data = new Alert(this))) if (typeof option == 'string') data[option].call($this) }) } var old = $.fn.alert $.fn.alert = Plugin $.fn.alert.Constructor = Alert // ALERT NO CONFLICT // ================= $.fn.alert.noConflict = function () { $.fn.alert = old return this } // ALERT DATA-API // ============== $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close) }(jQuery); /* ======================================================================== * Bootstrap: button.js v3.3.6 * http://getbootstrap.com/javascript/#buttons * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // BUTTON PUBLIC CLASS DEFINITION // ============================== var Button = function (element, options) { this.$element = $(element) this.options = $.extend({}, Button.DEFAULTS, options) this.isLoading = false } Button.VERSION = '3.3.6' Button.DEFAULTS = { loadingText: 'loading...' } Button.prototype.setState = function (state) { var d = 'disabled' var $el = this.$element var val = $el.is('input') ? 'val' : 'html' var data = $el.data() state += 'Text' if (data.resetText == null) $el.data('resetText', $el[val]()) // push to event loop to allow forms to submit setTimeout($.proxy(function () { $el[val](data[state] == null ? this.options[state] : data[state]) if (state == 'loadingText') { this.isLoading = true $el.addClass(d).attr(d, d) } else if (this.isLoading) { this.isLoading = false $el.removeClass(d).removeAttr(d) } }, this), 0) } Button.prototype.toggle = function () { var changed = true var $parent = this.$element.closest('[data-toggle="buttons"]') if ($parent.length) { var $input = this.$element.find('input') if ($input.prop('type') == 'radio') { if ($input.prop('checked')) changed = false $parent.find('.active').removeClass('active') this.$element.addClass('active') } else if ($input.prop('type') == 'checkbox') { if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false this.$element.toggleClass('active') } $input.prop('checked', this.$element.hasClass('active')) if (changed) $input.trigger('change') } else { this.$element.attr('aria-pressed', !this.$element.hasClass('active')) this.$element.toggleClass('active') } } // BUTTON PLUGIN DEFINITION // ======================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.button') var options = typeof option == 'object' && option if (!data) $this.data('bs.button', (data = new Button(this, options))) if (option == 'toggle') data.toggle() else if (option) data.setState(option) }) } var old = $.fn.button $.fn.button = Plugin $.fn.button.Constructor = Button // BUTTON NO CONFLICT // ================== $.fn.button.noConflict = function () { $.fn.button = old return this } // BUTTON DATA-API // =============== $(document) .on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) { var $btn = $(e.target) if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') Plugin.call($btn, 'toggle') if (!($(e.target).is('input[type="radio"]') || $(e.target).is('input[type="checkbox"]'))) e.preventDefault() }) .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) { $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type)) }) }(jQuery); /* ======================================================================== * Bootstrap: carousel.js v3.3.6 * http://getbootstrap.com/javascript/#carousel * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // CAROUSEL CLASS DEFINITION // ========================= var Carousel = function (element, options) { this.$element = $(element) this.$indicators = this.$element.find('.carousel-indicators') this.options = options this.paused = null this.sliding = null this.interval = null this.$active = null this.$items = null this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this)) this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element .on('mouseenter.bs.carousel', $.proxy(this.pause, this)) .on('mouseleave.bs.carousel', $.proxy(this.cycle, this)) } Carousel.VERSION = '3.3.6' Carousel.TRANSITION_DURATION = 600 Carousel.DEFAULTS = { interval: 5000, pause: 'hover', wrap: true, keyboard: true } Carousel.prototype.keydown = function (e) { if (/input|textarea/i.test(e.target.tagName)) return switch (e.which) { case 37: this.prev(); break case 39: this.next(); break default: return } e.preventDefault() } Carousel.prototype.cycle = function (e) { e || (this.paused = false) this.interval && clearInterval(this.interval) this.options.interval && !this.paused && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) return this } Carousel.prototype.getItemIndex = function (item) { this.$items = item.parent().children('.item') return this.$items.index(item || this.$active) } Carousel.prototype.getItemForDirection = function (direction, active) { var activeIndex = this.getItemIndex(active) var willWrap = (direction == 'prev' && activeIndex === 0) || (direction == 'next' && activeIndex == (this.$items.length - 1)) if (willWrap && !this.options.wrap) return active var delta = direction == 'prev' ? -1 : 1 var itemIndex = (activeIndex + delta) % this.$items.length return this.$items.eq(itemIndex) } Carousel.prototype.to = function (pos) { var that = this var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active')) if (pos > (this.$items.length - 1) || pos < 0) return if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid" if (activeIndex == pos) return this.pause().cycle() return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos)) } Carousel.prototype.pause = function (e) { e || (this.paused = true) if (this.$element.find('.next, .prev').length && $.support.transition) { this.$element.trigger($.support.transition.end) this.cycle(true) } this.interval = clearInterval(this.interval) return this } Carousel.prototype.next = function () { if (this.sliding) return return this.slide('next') } Carousel.prototype.prev = function () { if (this.sliding) return return this.slide('prev') } Carousel.prototype.slide = function (type, next) { var $active = this.$element.find('.item.active') var $next = next || this.getItemForDirection(type, $active) var isCycling = this.interval var direction = type == 'next' ? 'left' : 'right' var that = this if ($next.hasClass('active')) return (this.sliding = false) var relatedTarget = $next[0] var slideEvent = $.Event('slide.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) this.$element.trigger(slideEvent) if (slideEvent.isDefaultPrevented()) return this.sliding = true isCycling && this.pause() if (this.$indicators.length) { this.$indicators.find('.active').removeClass('active') var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]) $nextIndicator && $nextIndicator.addClass('active') } var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid" if ($.support.transition && this.$element.hasClass('slide')) { $next.addClass(type) $next[0].offsetWidth // force reflow $active.addClass(direction) $next.addClass(direction) $active .one('bsTransitionEnd', function () { $next.removeClass([type, direction].join(' ')).addClass('active') $active.removeClass(['active', direction].join(' ')) that.sliding = false setTimeout(function () { that.$element.trigger(slidEvent) }, 0) }) .emulateTransitionEnd(Carousel.TRANSITION_DURATION) } else { $active.removeClass('active') $next.addClass('active') this.sliding = false this.$element.trigger(slidEvent) } isCycling && this.cycle() return this } // CAROUSEL PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.carousel') var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option) var action = typeof option == 'string' ? option : options.slide if (!data) $this.data('bs.carousel', (data = new Carousel(this, options))) if (typeof option == 'number') data.to(option) else if (action) data[action]() else if (options.interval) data.pause().cycle() }) } var old = $.fn.carousel $.fn.carousel = Plugin $.fn.carousel.Constructor = Carousel // CAROUSEL NO CONFLICT // ==================== $.fn.carousel.noConflict = function () { $.fn.carousel = old return this } // CAROUSEL DATA-API // ================= var clickHandler = function (e) { var href var $this = $(this) var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7 if (!$target.hasClass('carousel')) return var options = $.extend({}, $target.data(), $this.data()) var slideIndex = $this.attr('data-slide-to') if (slideIndex) options.interval = false Plugin.call($target, options) if (slideIndex) { $target.data('bs.carousel').to(slideIndex) } e.preventDefault() } $(document) .on('click.bs.carousel.data-api', '[data-slide]', clickHandler) .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler) $(window).on('load', function () { $('[data-ride="carousel"]').each(function () { var $carousel = $(this) Plugin.call($carousel, $carousel.data()) }) }) }(jQuery); /* ======================================================================== * Bootstrap: collapse.js v3.3.6 * http://getbootstrap.com/javascript/#collapse * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // COLLAPSE PUBLIC CLASS DEFINITION // ================================ var Collapse = function (element, options) { this.$element = $(element) this.options = $.extend({}, Collapse.DEFAULTS, options) this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' + '[data-toggle="collapse"][data-target="#' + element.id + '"]') this.transitioning = null if (this.options.parent) { this.$parent = this.getParent() } else { this.addAriaAndCollapsedClass(this.$element, this.$trigger) } if (this.options.toggle) this.toggle() } Collapse.VERSION = '3.3.6' Collapse.TRANSITION_DURATION = 350 Collapse.DEFAULTS = { toggle: true } Collapse.prototype.dimension = function () { var hasWidth = this.$element.hasClass('width') return hasWidth ? 'width' : 'height' } Collapse.prototype.show = function () { if (this.transitioning || this.$element.hasClass('in')) return var activesData var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing') if (actives && actives.length) { activesData = actives.data('bs.collapse') if (activesData && activesData.transitioning) return } var startEvent = $.Event('show.bs.collapse') this.$element.trigger(startEvent) if (startEvent.isDefaultPrevented()) return if (actives && actives.length) { Plugin.call(actives, 'hide') activesData || actives.data('bs.collapse', null) } var dimension = this.dimension() this.$element .removeClass('collapse') .addClass('collapsing')[dimension](0) .attr('aria-expanded', true) this.$trigger .removeClass('collapsed') .attr('aria-expanded', true) this.transitioning = 1 var complete = function () { this.$element .removeClass('collapsing') .addClass('collapse in')[dimension]('') this.transitioning = 0 this.$element .trigger('shown.bs.collapse') } if (!$.support.transition) return complete.call(this) var scrollSize = $.camelCase(['scroll', dimension].join('-')) this.$element .one('bsTransitionEnd', $.proxy(complete, this)) .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize]) } Collapse.prototype.hide = function () { if (this.transitioning || !this.$element.hasClass('in')) return var startEvent = $.Event('hide.bs.collapse') this.$element.trigger(startEvent) if (startEvent.isDefaultPrevented()) return var dimension = this.dimension() this.$element[dimension](this.$element[dimension]())[0].offsetHeight this.$element .addClass('collapsing') .removeClass('collapse in') .attr('aria-expanded', false) this.$trigger .addClass('collapsed') .attr('aria-expanded', false) this.transitioning = 1 var complete = function () { this.transitioning = 0 this.$element .removeClass('collapsing') .addClass('collapse') .trigger('hidden.bs.collapse') } if (!$.support.transition) return complete.call(this) this.$element [dimension](0) .one('bsTransitionEnd', $.proxy(complete, this)) .emulateTransitionEnd(Collapse.TRANSITION_DURATION) } Collapse.prototype.toggle = function () { this[this.$element.hasClass('in') ? 'hide' : 'show']() } Collapse.prototype.getParent = function () { return $(this.options.parent) .find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]') .each($.proxy(function (i, element) { var $element = $(element) this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element) }, this)) .end() } Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) { var isOpen = $element.hasClass('in') $element.attr('aria-expanded', isOpen) $trigger .toggleClass('collapsed', !isOpen) .attr('aria-expanded', isOpen) } function getTargetFromTrigger($trigger) { var href var target = $trigger.attr('data-target') || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7 return $(target) } // COLLAPSE PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.collapse') var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option) if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false if (!data) $this.data('bs.collapse', (data = new Collapse(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.collapse $.fn.collapse = Plugin $.fn.collapse.Constructor = Collapse // COLLAPSE NO CONFLICT // ==================== $.fn.collapse.noConflict = function () { $.fn.collapse = old return this } // COLLAPSE DATA-API // ================= $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) { var $this = $(this) if (!$this.attr('data-target')) e.preventDefault() var $target = getTargetFromTrigger($this) var data = $target.data('bs.collapse') var option = data ? 'toggle' : $this.data() Plugin.call($target, option) }) }(jQuery); /* ======================================================================== * Bootstrap: dropdown.js v3.3.6 * http://getbootstrap.com/javascript/#dropdowns * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // DROPDOWN CLASS DEFINITION // ========================= var backdrop = '.dropdown-backdrop' var toggle = '[data-toggle="dropdown"]' var Dropdown = function (element) { $(element).on('click.bs.dropdown', this.toggle) } Dropdown.VERSION = '3.3.6' function getParent($this) { var selector = $this.attr('data-target') if (!selector) { selector = $this.attr('href') selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } var $parent = selector && $(selector) return $parent && $parent.length ? $parent : $this.parent() } function clearMenus(e) { if (e && e.which === 3) return $(backdrop).remove() $(toggle).each(function () { var $this = $(this) var $parent = getParent($this) var relatedTarget = { relatedTarget: this } if (!$parent.hasClass('open')) return if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget)) if (e.isDefaultPrevented()) return $this.attr('aria-expanded', 'false') $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget)) }) } Dropdown.prototype.toggle = function (e) { var $this = $(this) if ($this.is('.disabled, :disabled')) return var $parent = getParent($this) var isActive = $parent.hasClass('open') clearMenus() if (!isActive) { if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) { // if mobile we use a backdrop because click events don't delegate $(document.createElement('div')) .addClass('dropdown-backdrop') .insertAfter($(this)) .on('click', clearMenus) } var relatedTarget = { relatedTarget: this } $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget)) if (e.isDefaultPrevented()) return $this .trigger('focus') .attr('aria-expanded', 'true') $parent .toggleClass('open') .trigger($.Event('shown.bs.dropdown', relatedTarget)) } return false } Dropdown.prototype.keydown = function (e) { if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return var $this = $(this) e.preventDefault() e.stopPropagation() if ($this.is('.disabled, :disabled')) return var $parent = getParent($this) var isActive = $parent.hasClass('open') if (!isActive && e.which != 27 || isActive && e.which == 27) { if (e.which == 27) $parent.find(toggle).trigger('focus') return $this.trigger('click') } var desc = ' li:not(.disabled):visible a' var $items = $parent.find('.dropdown-menu' + desc) if (!$items.length) return var index = $items.index(e.target) if (e.which == 38 && index > 0) index-- // up if (e.which == 40 && index < $items.length - 1) index++ // down if (!~index) index = 0 $items.eq(index).trigger('focus') } // DROPDOWN PLUGIN DEFINITION // ========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.dropdown') if (!data) $this.data('bs.dropdown', (data = new Dropdown(this))) if (typeof option == 'string') data[option].call($this) }) } var old = $.fn.dropdown $.fn.dropdown = Plugin $.fn.dropdown.Constructor = Dropdown // DROPDOWN NO CONFLICT // ==================== $.fn.dropdown.noConflict = function () { $.fn.dropdown = old return this } // APPLY TO STANDARD DROPDOWN ELEMENTS // =================================== $(document) .on('click.bs.dropdown.data-api', clearMenus) .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle) .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown) .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown) }(jQuery); /* ======================================================================== * Bootstrap: modal.js v3.3.6 * http://getbootstrap.com/javascript/#modals * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // MODAL CLASS DEFINITION // ====================== var Modal = function (element, options) { this.options = options this.$body = $(document.body) this.$element = $(element) this.$dialog = this.$element.find('.modal-dialog') this.$backdrop = null this.isShown = null this.originalBodyPad = null this.scrollbarWidth = 0 this.ignoreBackdropClick = false if (this.options.remote) { this.$element .find('.modal-content') .load(this.options.remote, $.proxy(function () { this.$element.trigger('loaded.bs.modal') }, this)) } } Modal.VERSION = '3.3.6' Modal.TRANSITION_DURATION = 300 Modal.BACKDROP_TRANSITION_DURATION = 150 Modal.DEFAULTS = { backdrop: true, keyboard: true, show: true } Modal.prototype.toggle = function (_relatedTarget) { return this.isShown ? this.hide() : this.show(_relatedTarget) } Modal.prototype.show = function (_relatedTarget) { var that = this var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget }) this.$element.trigger(e) if (this.isShown || e.isDefaultPrevented()) return this.isShown = true this.checkScrollbar() this.setScrollbar() this.$body.addClass('modal-open') this.escape() this.resize() this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this)) this.$dialog.on('mousedown.dismiss.bs.modal', function () { that.$element.one('mouseup.dismiss.bs.modal', function (e) { if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true }) }) this.backdrop(function () { var transition = $.support.transition && that.$element.hasClass('fade') if (!that.$element.parent().length) { that.$element.appendTo(that.$body) // don't move modals dom position } that.$element .show() .scrollTop(0) that.adjustDialog() if (transition) { that.$element[0].offsetWidth // force reflow } that.$element.addClass('in') that.enforceFocus() var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget }) transition ? that.$dialog // wait for modal to slide in .one('bsTransitionEnd', function () { that.$element.trigger('focus').trigger(e) }) .emulateTransitionEnd(Modal.TRANSITION_DURATION) : that.$element.trigger('focus').trigger(e) }) } Modal.prototype.hide = function (e) { if (e) e.preventDefault() e = $.Event('hide.bs.modal') this.$element.trigger(e) if (!this.isShown || e.isDefaultPrevented()) return this.isShown = false this.escape() this.resize() $(document).off('focusin.bs.modal') this.$element .removeClass('in') .off('click.dismiss.bs.modal') .off('mouseup.dismiss.bs.modal') this.$dialog.off('mousedown.dismiss.bs.modal') $.support.transition && this.$element.hasClass('fade') ? this.$element .one('bsTransitionEnd', $.proxy(this.hideModal, this)) .emulateTransitionEnd(Modal.TRANSITION_DURATION) : this.hideModal() } Modal.prototype.enforceFocus = function () { $(document) .off('focusin.bs.modal') // guard against infinite focus loop .on('focusin.bs.modal', $.proxy(function (e) { if (this.$element[0] !== e.target && !this.$element.has(e.target).length) { this.$element.trigger('focus') } }, this)) } Modal.prototype.escape = function () { if (this.isShown && this.options.keyboard) { this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) { e.which == 27 && this.hide() }, this)) } else if (!this.isShown) { this.$element.off('keydown.dismiss.bs.modal') } } Modal.prototype.resize = function () { if (this.isShown) { $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this)) } else { $(window).off('resize.bs.modal') } } Modal.prototype.hideModal = function () { var that = this this.$element.hide() this.backdrop(function () { that.$body.removeClass('modal-open') that.resetAdjustments() that.resetScrollbar() that.$element.trigger('hidden.bs.modal') }) } Modal.prototype.removeBackdrop = function () { this.$backdrop && this.$backdrop.remove() this.$backdrop = null } Modal.prototype.backdrop = function (callback) { var that = this var animate = this.$element.hasClass('fade') ? 'fade' : '' if (this.isShown && this.options.backdrop) { var doAnimate = $.support.transition && animate this.$backdrop = $(document.createElement('div')) .addClass('modal-backdrop ' + animate) .appendTo(this.$body) this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) { if (this.ignoreBackdropClick) { this.ignoreBackdropClick = false return } if (e.target !== e.currentTarget) return this.options.backdrop == 'static' ? this.$element[0].focus() : this.hide() }, this)) if (doAnimate) this.$backdrop[0].offsetWidth // force reflow this.$backdrop.addClass('in') if (!callback) return doAnimate ? this.$backdrop .one('bsTransitionEnd', callback) .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : callback() } else if (!this.isShown && this.$backdrop) { this.$backdrop.removeClass('in') var callbackRemove = function () { that.removeBackdrop() callback && callback() } $.support.transition && this.$element.hasClass('fade') ? this.$backdrop .one('bsTransitionEnd', callbackRemove) .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) : callbackRemove() } else if (callback) { callback() } } // these following methods are used to handle overflowing modals Modal.prototype.handleUpdate = function () { this.adjustDialog() } Modal.prototype.adjustDialog = function () { var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight this.$element.css({ paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '', paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : '' }) } Modal.prototype.resetAdjustments = function () { this.$element.css({ paddingLeft: '', paddingRight: '' }) } Modal.prototype.checkScrollbar = function () { var fullWindowWidth = window.innerWidth if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8 var documentElementRect = document.documentElement.getBoundingClientRect() fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left) } this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth this.scrollbarWidth = this.measureScrollbar() } Modal.prototype.setScrollbar = function () { var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10) this.originalBodyPad = document.body.style.paddingRight || '' if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth) } Modal.prototype.resetScrollbar = function () { this.$body.css('padding-right', this.originalBodyPad) } Modal.prototype.measureScrollbar = function () { // thx walsh var scrollDiv = document.createElement('div') scrollDiv.className = 'modal-scrollbar-measure' this.$body.append(scrollDiv) var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth this.$body[0].removeChild(scrollDiv) return scrollbarWidth } // MODAL PLUGIN DEFINITION // ======================= function Plugin(option, _relatedTarget) { return this.each(function () { var $this = $(this) var data = $this.data('bs.modal') var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option) if (!data) $this.data('bs.modal', (data = new Modal(this, options))) if (typeof option == 'string') data[option](_relatedTarget) else if (options.show) data.show(_relatedTarget) }) } var old = $.fn.modal $.fn.modal = Plugin $.fn.modal.Constructor = Modal // MODAL NO CONFLICT // ================= $.fn.modal.noConflict = function () { $.fn.modal = old return this } // MODAL DATA-API // ============== $(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) { var $this = $(this) var href = $this.attr('href') var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7 var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data()) if ($this.is('a')) e.preventDefault() $target.one('show.bs.modal', function (showEvent) { if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown $target.one('hidden.bs.modal', function () { $this.is(':visible') && $this.trigger('focus') }) }) Plugin.call($target, option, this) }) }(jQuery); /* ======================================================================== * Bootstrap: tooltip.js v3.3.6 * http://getbootstrap.com/javascript/#tooltip * Inspired by the original jQuery.tipsy by Jason Frame * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // TOOLTIP PUBLIC CLASS DEFINITION // =============================== var Tooltip = function (element, options) { this.type = null this.options = null this.enabled = null this.timeout = null this.hoverState = null this.$element = null this.inState = null this.init('tooltip', element, options) } Tooltip.VERSION = '3.3.6' Tooltip.TRANSITION_DURATION = 150 Tooltip.DEFAULTS = { animation: true, placement: 'top', selector: false, template: '', trigger: 'hover focus', title: '', delay: 0, html: false, container: false, viewport: { selector: 'body', padding: 0 } } Tooltip.prototype.init = function (type, element, options) { this.enabled = true this.type = type this.$element = $(element) this.options = this.getOptions(options) this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport)) this.inState = { click: false, hover: false, focus: false } if (this.$element[0] instanceof document.constructor && !this.options.selector) { throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!') } var triggers = this.options.trigger.split(' ') for (var i = triggers.length; i--;) { var trigger = triggers[i] if (trigger == 'click') { this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) } else if (trigger != 'manual') { var eventIn = trigger == 'hover' ? 'mouseenter' : 'focusin' var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout' this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) } } this.options.selector ? (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : this.fixTitle() } Tooltip.prototype.getDefaults = function () { return Tooltip.DEFAULTS } Tooltip.prototype.getOptions = function (options) { options = $.extend({}, this.getDefaults(), this.$element.data(), options) if (options.delay && typeof options.delay == 'number') { options.delay = { show: options.delay, hide: options.delay } } return options } Tooltip.prototype.getDelegateOptions = function () { var options = {} var defaults = this.getDefaults() this._options && $.each(this._options, function (key, value) { if (defaults[key] != value) options[key] = value }) return options } Tooltip.prototype.enter = function (obj) { var self = obj instanceof this.constructor ? obj : $(obj.currentTarget).data('bs.' + this.type) if (!self) { self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) $(obj.currentTarget).data('bs.' + this.type, self) } if (obj instanceof $.Event) { self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true } if (self.tip().hasClass('in') || self.hoverState == 'in') { self.hoverState = 'in' return } clearTimeout(self.timeout) self.hoverState = 'in' if (!self.options.delay || !self.options.delay.show) return self.show() self.timeout = setTimeout(function () { if (self.hoverState == 'in') self.show() }, self.options.delay.show) } Tooltip.prototype.isInStateTrue = function () { for (var key in this.inState) { if (this.inState[key]) return true } return false } Tooltip.prototype.leave = function (obj) { var self = obj instanceof this.constructor ? obj : $(obj.currentTarget).data('bs.' + this.type) if (!self) { self = new this.constructor(obj.currentTarget, this.getDelegateOptions()) $(obj.currentTarget).data('bs.' + this.type, self) } if (obj instanceof $.Event) { self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false } if (self.isInStateTrue()) return clearTimeout(self.timeout) self.hoverState = 'out' if (!self.options.delay || !self.options.delay.hide) return self.hide() self.timeout = setTimeout(function () { if (self.hoverState == 'out') self.hide() }, self.options.delay.hide) } Tooltip.prototype.show = function () { var e = $.Event('show.bs.' + this.type) if (this.hasContent() && this.enabled) { this.$element.trigger(e) var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0]) if (e.isDefaultPrevented() || !inDom) return var that = this var $tip = this.tip() var tipId = this.getUID(this.type) this.setContent() $tip.attr('id', tipId) this.$element.attr('aria-describedby', tipId) if (this.options.animation) $tip.addClass('fade') var placement = typeof this.options.placement == 'function' ? this.options.placement.call(this, $tip[0], this.$element[0]) : this.options.placement var autoToken = /\s?auto?\s?/i var autoPlace = autoToken.test(placement) if (autoPlace) placement = placement.replace(autoToken, '') || 'top' $tip .detach() .css({ top: 0, left: 0, display: 'block' }) .addClass(placement) .data('bs.' + this.type, this) this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) this.$element.trigger('inserted.bs.' + this.type) var pos = this.getPosition() var actualWidth = $tip[0].offsetWidth var actualHeight = $tip[0].offsetHeight if (autoPlace) { var orgPlacement = placement var viewportDim = this.getPosition(this.$viewport) placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top' : placement == 'top' && pos.top - actualHeight < viewportDim.top ? 'bottom' : placement == 'right' && pos.right + actualWidth > viewportDim.width ? 'left' : placement == 'left' && pos.left - actualWidth < viewportDim.left ? 'right' : placement $tip .removeClass(orgPlacement) .addClass(placement) } var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight) this.applyPlacement(calculatedOffset, placement) var complete = function () { var prevHoverState = that.hoverState that.$element.trigger('shown.bs.' + that.type) that.hoverState = null if (prevHoverState == 'out') that.leave(that) } $.support.transition && this.$tip.hasClass('fade') ? $tip .one('bsTransitionEnd', complete) .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : complete() } } Tooltip.prototype.applyPlacement = function (offset, placement) { var $tip = this.tip() var width = $tip[0].offsetWidth var height = $tip[0].offsetHeight // manually read margins because getBoundingClientRect includes difference var marginTop = parseInt($tip.css('margin-top'), 10) var marginLeft = parseInt($tip.css('margin-left'), 10) // we must check for NaN for ie 8/9 if (isNaN(marginTop)) marginTop = 0 if (isNaN(marginLeft)) marginLeft = 0 offset.top += marginTop offset.left += marginLeft // $.fn.offset doesn't round pixel values // so we use setOffset directly with our own function B-0 $.offset.setOffset($tip[0], $.extend({ using: function (props) { $tip.css({ top: Math.round(props.top), left: Math.round(props.left) }) } }, offset), 0) $tip.addClass('in') // check to see if placing tip in new offset caused the tip to resize itself var actualWidth = $tip[0].offsetWidth var actualHeight = $tip[0].offsetHeight if (placement == 'top' && actualHeight != height) { offset.top = offset.top + height - actualHeight } var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight) if (delta.left) offset.left += delta.left else offset.top += delta.top var isVertical = /top|bottom/.test(placement) var arrowDelta = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight' $tip.offset(offset) this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical) } Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) { this.arrow() .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%') .css(isVertical ? 'top' : 'left', '') } Tooltip.prototype.setContent = function () { var $tip = this.tip() var title = this.getTitle() $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) $tip.removeClass('fade in top bottom left right') } Tooltip.prototype.hide = function (callback) { var that = this var $tip = $(this.$tip) var e = $.Event('hide.bs.' + this.type) function complete() { if (that.hoverState != 'in') $tip.detach() that.$element .removeAttr('aria-describedby') .trigger('hidden.bs.' + that.type) callback && callback() } this.$element.trigger(e) if (e.isDefaultPrevented()) return $tip.removeClass('in') $.support.transition && $tip.hasClass('fade') ? $tip .one('bsTransitionEnd', complete) .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) : complete() this.hoverState = null return this } Tooltip.prototype.fixTitle = function () { var $e = this.$element if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') { $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') } } Tooltip.prototype.hasContent = function () { return this.getTitle() } Tooltip.prototype.getPosition = function ($element) { $element = $element || this.$element var el = $element[0] var isBody = el.tagName == 'BODY' var elRect = el.getBoundingClientRect() if (elRect.width == null) { // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093 elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top }) } var elOffset = isBody ? { top: 0, left: 0 } : $element.offset() var scroll = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() } var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null return $.extend({}, elRect, scroll, outerDims, elOffset) } Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) { return placement == 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } : placement == 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } : placement == 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } : /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } } Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) { var delta = { top: 0, left: 0 } if (!this.$viewport) return delta var viewportPadding = this.options.viewport && this.options.viewport.padding || 0 var viewportDimensions = this.getPosition(this.$viewport) if (/right|left/.test(placement)) { var topEdgeOffset = pos.top - viewportPadding - viewportDimensions.scroll var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight if (topEdgeOffset < viewportDimensions.top) { // top overflow delta.top = viewportDimensions.top - topEdgeOffset } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset } } else { var leftEdgeOffset = pos.left - viewportPadding var rightEdgeOffset = pos.left + viewportPadding + actualWidth if (leftEdgeOffset < viewportDimensions.left) { // left overflow delta.left = viewportDimensions.left - leftEdgeOffset } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset } } return delta } Tooltip.prototype.getTitle = function () { var title var $e = this.$element var o = this.options title = $e.attr('data-original-title') || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) return title } Tooltip.prototype.getUID = function (prefix) { do prefix += ~~(Math.random() * 1000000) while (document.getElementById(prefix)) return prefix } Tooltip.prototype.tip = function () { if (!this.$tip) { this.$tip = $(this.options.template) if (this.$tip.length != 1) { throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!') } } return this.$tip } Tooltip.prototype.arrow = function () { return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')) } Tooltip.prototype.enable = function () { this.enabled = true } Tooltip.prototype.disable = function () { this.enabled = false } Tooltip.prototype.toggleEnabled = function () { this.enabled = !this.enabled } Tooltip.prototype.toggle = function (e) { var self = this if (e) { self = $(e.currentTarget).data('bs.' + this.type) if (!self) { self = new this.constructor(e.currentTarget, this.getDelegateOptions()) $(e.currentTarget).data('bs.' + this.type, self) } } if (e) { self.inState.click = !self.inState.click if (self.isInStateTrue()) self.enter(self) else self.leave(self) } else { self.tip().hasClass('in') ? self.leave(self) : self.enter(self) } } Tooltip.prototype.destroy = function () { var that = this clearTimeout(this.timeout) this.hide(function () { that.$element.off('.' + that.type).removeData('bs.' + that.type) if (that.$tip) { that.$tip.detach() } that.$tip = null that.$arrow = null that.$viewport = null }) } // TOOLTIP PLUGIN DEFINITION // ========================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.tooltip') var options = typeof option == 'object' && option if (!data && /destroy|hide/.test(option)) return if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.tooltip $.fn.tooltip = Plugin $.fn.tooltip.Constructor = Tooltip // TOOLTIP NO CONFLICT // =================== $.fn.tooltip.noConflict = function () { $.fn.tooltip = old return this } }(jQuery); /* ======================================================================== * Bootstrap: popover.js v3.3.6 * http://getbootstrap.com/javascript/#popovers * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // POPOVER PUBLIC CLASS DEFINITION // =============================== var Popover = function (element, options) { this.init('popover', element, options) } if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js') Popover.VERSION = '3.3.6' Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, { placement: 'right', trigger: 'click', content: '', template: '' }) // NOTE: POPOVER EXTENDS tooltip.js // ================================ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype) Popover.prototype.constructor = Popover Popover.prototype.getDefaults = function () { return Popover.DEFAULTS } Popover.prototype.setContent = function () { var $tip = this.tip() var title = this.getTitle() var content = this.getContent() $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text' ](content) $tip.removeClass('fade top bottom left right in') // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do // this manually by checking the contents. if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide() } Popover.prototype.hasContent = function () { return this.getTitle() || this.getContent() } Popover.prototype.getContent = function () { var $e = this.$element var o = this.options return $e.attr('data-content') || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) } Popover.prototype.arrow = function () { return (this.$arrow = this.$arrow || this.tip().find('.arrow')) } // POPOVER PLUGIN DEFINITION // ========================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.popover') var options = typeof option == 'object' && option if (!data && /destroy|hide/.test(option)) return if (!data) $this.data('bs.popover', (data = new Popover(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.popover $.fn.popover = Plugin $.fn.popover.Constructor = Popover // POPOVER NO CONFLICT // =================== $.fn.popover.noConflict = function () { $.fn.popover = old return this } }(jQuery); /* ======================================================================== * Bootstrap: scrollspy.js v3.3.6 * http://getbootstrap.com/javascript/#scrollspy * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // SCROLLSPY CLASS DEFINITION // ========================== function ScrollSpy(element, options) { this.$body = $(document.body) this.$scrollElement = $(element).is(document.body) ? $(window) : $(element) this.options = $.extend({}, ScrollSpy.DEFAULTS, options) this.selector = (this.options.target || '') + ' .nav li > a' this.offsets = [] this.targets = [] this.activeTarget = null this.scrollHeight = 0 this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this)) this.refresh() this.process() } ScrollSpy.VERSION = '3.3.6' ScrollSpy.DEFAULTS = { offset: 10 } ScrollSpy.prototype.getScrollHeight = function () { return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight) } ScrollSpy.prototype.refresh = function () { var that = this var offsetMethod = 'offset' var offsetBase = 0 this.offsets = [] this.targets = [] this.scrollHeight = this.getScrollHeight() if (!$.isWindow(this.$scrollElement[0])) { offsetMethod = 'position' offsetBase = this.$scrollElement.scrollTop() } this.$body .find(this.selector) .map(function () { var $el = $(this) var href = $el.data('target') || $el.attr('href') var $href = /^#./.test(href) && $(href) return ($href && $href.length && $href.is(':visible') && [[$href[offsetMethod]().top + offsetBase, href]]) || null }) .sort(function (a, b) { return a[0] - b[0] }) .each(function () { that.offsets.push(this[0]) that.targets.push(this[1]) }) } ScrollSpy.prototype.process = function () { var scrollTop = this.$scrollElement.scrollTop() + this.options.offset var scrollHeight = this.getScrollHeight() var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height() var offsets = this.offsets var targets = this.targets var activeTarget = this.activeTarget var i if (this.scrollHeight != scrollHeight) { this.refresh() } if (scrollTop >= maxScroll) { return activeTarget != (i = targets[targets.length - 1]) && this.activate(i) } if (activeTarget && scrollTop < offsets[0]) { this.activeTarget = null return this.clear() } for (i = offsets.length; i--;) { activeTarget != targets[i] && scrollTop >= offsets[i] && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1]) && this.activate(targets[i]) } } ScrollSpy.prototype.activate = function (target) { this.activeTarget = target this.clear() var selector = this.selector + '[data-target="' + target + '"],' + this.selector + '[href="' + target + '"]' var active = $(selector) .parents('li') .addClass('active') if (active.parent('.dropdown-menu').length) { active = active .closest('li.dropdown') .addClass('active') } active.trigger('activate.bs.scrollspy') } ScrollSpy.prototype.clear = function () { $(this.selector) .parentsUntil(this.options.target, '.active') .removeClass('active') } // SCROLLSPY PLUGIN DEFINITION // =========================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.scrollspy') var options = typeof option == 'object' && option if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.scrollspy $.fn.scrollspy = Plugin $.fn.scrollspy.Constructor = ScrollSpy // SCROLLSPY NO CONFLICT // ===================== $.fn.scrollspy.noConflict = function () { $.fn.scrollspy = old return this } // SCROLLSPY DATA-API // ================== $(window).on('load.bs.scrollspy.data-api', function () { $('[data-spy="scroll"]').each(function () { var $spy = $(this) Plugin.call($spy, $spy.data()) }) }) }(jQuery); /* ======================================================================== * Bootstrap: tab.js v3.3.6 * http://getbootstrap.com/javascript/#tabs * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // TAB CLASS DEFINITION // ==================== var Tab = function (element) { // jscs:disable requireDollarBeforejQueryAssignment this.element = $(element) // jscs:enable requireDollarBeforejQueryAssignment } Tab.VERSION = '3.3.6' Tab.TRANSITION_DURATION = 150 Tab.prototype.show = function () { var $this = this.element var $ul = $this.closest('ul:not(.dropdown-menu)') var selector = $this.data('target') if (!selector) { selector = $this.attr('href') selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7 } if ($this.parent('li').hasClass('active')) return var $previous = $ul.find('.active:last a') var hideEvent = $.Event('hide.bs.tab', { relatedTarget: $this[0] }) var showEvent = $.Event('show.bs.tab', { relatedTarget: $previous[0] }) $previous.trigger(hideEvent) $this.trigger(showEvent) if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return var $target = $(selector) this.activate($this.closest('li'), $ul) this.activate($target, $target.parent(), function () { $previous.trigger({ type: 'hidden.bs.tab', relatedTarget: $this[0] }) $this.trigger({ type: 'shown.bs.tab', relatedTarget: $previous[0] }) }) } Tab.prototype.activate = function (element, container, callback) { var $active = container.find('> .active') var transition = callback && $.support.transition && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length) function next() { $active .removeClass('active') .find('> .dropdown-menu > .active') .removeClass('active') .end() .find('[data-toggle="tab"]') .attr('aria-expanded', false) element .addClass('active') .find('[data-toggle="tab"]') .attr('aria-expanded', true) if (transition) { element[0].offsetWidth // reflow for transition element.addClass('in') } else { element.removeClass('fade') } if (element.parent('.dropdown-menu').length) { element .closest('li.dropdown') .addClass('active') .end() .find('[data-toggle="tab"]') .attr('aria-expanded', true) } callback && callback() } $active.length && transition ? $active .one('bsTransitionEnd', next) .emulateTransitionEnd(Tab.TRANSITION_DURATION) : next() $active.removeClass('in') } // TAB PLUGIN DEFINITION // ===================== function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.tab') if (!data) $this.data('bs.tab', (data = new Tab(this))) if (typeof option == 'string') data[option]() }) } var old = $.fn.tab $.fn.tab = Plugin $.fn.tab.Constructor = Tab // TAB NO CONFLICT // =============== $.fn.tab.noConflict = function () { $.fn.tab = old return this } // TAB DATA-API // ============ var clickHandler = function (e) { e.preventDefault() Plugin.call($(this), 'show') } $(document) .on('click.bs.tab.data-api', '[data-toggle="tab"]', clickHandler) .on('click.bs.tab.data-api', '[data-toggle="pill"]', clickHandler) }(jQuery); /* ======================================================================== * Bootstrap: affix.js v3.3.6 * http://getbootstrap.com/javascript/#affix * ======================================================================== * Copyright 2011-2015 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) * ======================================================================== */ +function ($) { 'use strict'; // AFFIX CLASS DEFINITION // ====================== var Affix = function (element, options) { this.options = $.extend({}, Affix.DEFAULTS, options) this.$target = $(this.options.target) .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this)) .on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this)) this.$element = $(element) this.affixed = null this.unpin = null this.pinnedOffset = null this.checkPosition() } Affix.VERSION = '3.3.6' Affix.RESET = 'affix affix-top affix-bottom' Affix.DEFAULTS = { offset: 0, target: window } Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) { var scrollTop = this.$target.scrollTop() var position = this.$element.offset() var targetHeight = this.$target.height() if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false if (this.affixed == 'bottom') { if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom' return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom' } var initializing = this.affixed == null var colliderTop = initializing ? scrollTop : position.top var colliderHeight = initializing ? targetHeight : height if (offsetTop != null && scrollTop <= offsetTop) return 'top' if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom' return false } Affix.prototype.getPinnedOffset = function () { if (this.pinnedOffset) return this.pinnedOffset this.$element.removeClass(Affix.RESET).addClass('affix') var scrollTop = this.$target.scrollTop() var position = this.$element.offset() return (this.pinnedOffset = position.top - scrollTop) } Affix.prototype.checkPositionWithEventLoop = function () { setTimeout($.proxy(this.checkPosition, this), 1) } Affix.prototype.checkPosition = function () { if (!this.$element.is(':visible')) return var height = this.$element.height() var offset = this.options.offset var offsetTop = offset.top var offsetBottom = offset.bottom var scrollHeight = Math.max($(document).height(), $(document.body).height()) if (typeof offset != 'object') offsetBottom = offsetTop = offset if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element) if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element) var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom) if (this.affixed != affix) { if (this.unpin != null) this.$element.css('top', '') var affixType = 'affix' + (affix ? '-' + affix : '') var e = $.Event(affixType + '.bs.affix') this.$element.trigger(e) if (e.isDefaultPrevented()) return this.affixed = affix this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null this.$element .removeClass(Affix.RESET) .addClass(affixType) .trigger(affixType.replace('affix', 'affixed') + '.bs.affix') } if (affix == 'bottom') { this.$element.offset({ top: scrollHeight - height - offsetBottom }) } } // AFFIX PLUGIN DEFINITION // ======================= function Plugin(option) { return this.each(function () { var $this = $(this) var data = $this.data('bs.affix') var options = typeof option == 'object' && option if (!data) $this.data('bs.affix', (data = new Affix(this, options))) if (typeof option == 'string') data[option]() }) } var old = $.fn.affix $.fn.affix = Plugin $.fn.affix.Constructor = Affix // AFFIX NO CONFLICT // ================= $.fn.affix.noConflict = function () { $.fn.affix = old return this } // AFFIX DATA-API // ============== $(window).on('load', function () { $('[data-spy="affix"]').each(function () { var $spy = $(this) var data = $spy.data() data.offset = data.offset || {} if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom if (data.offsetTop != null) data.offset.top = data.offsetTop Plugin.call($spy, data) }) }) }(jQuery); hugo-0.68.3/examples/blog/static/js/jquery-1.11.3.min.js000066400000000000000000002733251363637351300224220ustar00rootroot00000000000000/*! jQuery v1.11.3 | (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="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,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=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.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},m.extend=m.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||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},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=r(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(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[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=r(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&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=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);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(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&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.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?m.extend(a,d):d}},e={};return d.pipe=d.then,m.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&&m.isFunction(a.promise)?e:0,g=1===f?a:m.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]&&m.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;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.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.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.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 m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;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},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML="
    a",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!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(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/\s*$/g,ra={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:k.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?""!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(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=wa(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=wa(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?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(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,m.cleanData(ua(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,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m(".*?\n", }, // set class { `{{< youtube w7Ft2ymGmfc video>}}`, "(?s)\n
    .*?.*?
    \n", }, // set class and autoplay (using named params) { `{{< youtube id="w7Ft2ymGmfc" class="video" autoplay="true" >}}`, "(?s)\n
    .*?.*?
    ", }, } { var ( cfg, fs = newTestCfg() th = newTestHelper(cfg, fs, t) ) writeSource(t, fs, filepath.Join("content", "simple.md"), fmt.Sprintf(`--- title: Shorty --- %s`, this.in)) writeSource(t, fs, filepath.Join("layouts", "_default", "single.html"), `{{ .Content }}`) buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{}) th.assertFileContentRegexp(filepath.Join("public", "simple", "index.html"), this.expected) } } func TestShortcodeVimeo(t *testing.T) { t.Parallel() for _, this := range []struct { in, expected string }{ { `{{< vimeo 146022717 >}}`, "(?s)\n
    .*?.*?
    \n", }, // set class { `{{< vimeo 146022717 video >}}`, "(?s)\n
    .*?.*?
    \n", }, // set vimeo title { `{{< vimeo 146022717 video my-title >}}`, "(?s)\n
    .*?.*?
    \n", }, // set class (using named params) { `{{< vimeo id="146022717" class="video" >}}`, "(?s)^
    .*?.*?
    ", }, // set vimeo title (using named params) { `{{< vimeo id="146022717" class="video" title="my vimeo video" >}}`, "(?s)^
    .*?.*?
    ", }, } { var ( cfg, fs = newTestCfg() th = newTestHelper(cfg, fs, t) ) writeSource(t, fs, filepath.Join("content", "simple.md"), fmt.Sprintf(`--- title: Shorty --- %s`, this.in)) writeSource(t, fs, filepath.Join("layouts", "_default", "single.html"), `{{ .Content }}`) buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{}) th.assertFileContentRegexp(filepath.Join("public", "simple", "index.html"), this.expected) } } func TestShortcodeGist(t *testing.T) { t.Parallel() for _, this := range []struct { in, expected string }{ { `{{< gist spf13 7896402 >}}`, "(?s)^", }, { `{{< gist spf13 7896402 "img.html" >}}`, "(?s)^", }, } { var ( cfg, fs = newTestCfg() th = newTestHelper(cfg, fs, t) ) writeSource(t, fs, filepath.Join("content", "simple.md"), fmt.Sprintf(`--- title: Shorty --- %s`, this.in)) writeSource(t, fs, filepath.Join("layouts", "_default", "single.html"), `{{ .Content }}`) buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg}, BuildCfg{}) th.assertFileContentRegexp(filepath.Join("public", "simple", "index.html"), this.expected) } } func TestShortcodeTweet(t *testing.T) { t.Parallel() for i, this := range []struct { privacy map[string]interface{} in, resp, expected string }{ { map[string]interface{}{ "twitter": map[string]interface{}{ "simple": true, }, }, `{{< tweet 666616452582129664 >}}`, `{"url":"https:\/\/twitter.com\/spf13\/status\/666616452582129664","author_name":"Steve Francia","author_url":"https:\/\/twitter.com\/spf13","html":"\u003Cblockquote class=\"twitter-tweet\"\u003E\u003Cp lang=\"en\" dir=\"ltr\"\u003EHugo 0.15 will have 30%+ faster render times thanks to this commit \u003Ca href=\"https:\/\/t.co\/FfzhM8bNhT\"\u003Ehttps:\/\/t.co\/FfzhM8bNhT\u003C\/a\u003E \u003Ca href=\"https:\/\/twitter.com\/hashtag\/gohugo?src=hash\"\u003E#gohugo\u003C\/a\u003E \u003Ca href=\"https:\/\/twitter.com\/hashtag\/golang?src=hash\"\u003E#golang\u003C\/a\u003E \u003Ca href=\"https:\/\/t.co\/ITbMNU2BUf\"\u003Ehttps:\/\/t.co\/ITbMNU2BUf\u003C\/a\u003E\u003C\/p\u003E— Steve Francia (@spf13) \u003Ca href=\"https:\/\/twitter.com\/spf13\/status\/666616452582129664\"\u003ENovember 17, 2015\u003C\/a\u003E\u003C\/blockquote\u003E\n\u003Cscript async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"\u003E\u003C\/script\u003E","width":550,"height":null,"type":"rich","cache_age":"3153600000","provider_name":"Twitter","provider_url":"https:\/\/twitter.com","version":"1.0"}`, `.twitter-tweet a`, }, { map[string]interface{}{ "twitter": map[string]interface{}{ "simple": false, }, }, `{{< tweet 666616452582129664 >}}`, `{"url":"https:\/\/twitter.com\/spf13\/status\/666616452582129664","author_name":"Steve Francia","author_url":"https:\/\/twitter.com\/spf13","html":"\u003Cblockquote class=\"twitter-tweet\"\u003E\u003Cp lang=\"en\" dir=\"ltr\"\u003EHugo 0.15 will have 30%+ faster render times thanks to this commit \u003Ca href=\"https:\/\/t.co\/FfzhM8bNhT\"\u003Ehttps:\/\/t.co\/FfzhM8bNhT\u003C\/a\u003E \u003Ca href=\"https:\/\/twitter.com\/hashtag\/gohugo?src=hash\"\u003E#gohugo\u003C\/a\u003E \u003Ca href=\"https:\/\/twitter.com\/hashtag\/golang?src=hash\"\u003E#golang\u003C\/a\u003E \u003Ca href=\"https:\/\/t.co\/ITbMNU2BUf\"\u003Ehttps:\/\/t.co\/ITbMNU2BUf\u003C\/a\u003E\u003C\/p\u003E— Steve Francia (@spf13) \u003Ca href=\"https:\/\/twitter.com\/spf13\/status\/666616452582129664\"\u003ENovember 17, 2015\u003C\/a\u003E\u003C\/blockquote\u003E\n\u003Cscript async src=\"\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"\u003E\u003C\/script\u003E","width":550,"height":null,"type":"rich","cache_age":"3153600000","provider_name":"Twitter","provider_url":"https:\/\/twitter.com","version":"1.0"}`, `(?s)^.*?`, }, } { // overload getJSON to return mock API response from Twitter tweetFuncMap := template.FuncMap{ "getJSON": func(urlParts ...interface{}) interface{} { var v interface{} err := json.Unmarshal([]byte(this.resp), &v) if err != nil { t.Fatalf("[%d] unexpected error in json.Unmarshal: %s", i, err) return err } return v }, } var ( cfg, fs = newTestCfg() th = newTestHelper(cfg, fs, t) ) cfg.Set("privacy", this.privacy) writeSource(t, fs, filepath.Join("content", "simple.md"), fmt.Sprintf(`--- title: Shorty --- %s`, this.in)) writeSource(t, fs, filepath.Join("layouts", "_default", "single.html"), `{{ .Content }}`) buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg, OverloadedTemplateFuncs: tweetFuncMap}, BuildCfg{}) th.assertFileContentRegexp(filepath.Join("public", "simple", "index.html"), this.expected) } } func TestShortcodeInstagram(t *testing.T) { t.Parallel() for i, this := range []struct { in, hidecaption, resp, expected string }{ { `{{< instagram BMokmydjG-M >}}`, `0`, `{"provider_url": "https://www.instagram.com", "media_id": "1380514280986406796_25025320", "author_name": "instagram", "height": null, "thumbnail_url": "https://scontent-amt2-1.cdninstagram.com/t51.2885-15/s640x640/sh0.08/e35/15048135_1880160212214218_7827880881132929024_n.jpg?ig_cache_key=MTM4MDUxNDI4MDk4NjQwNjc5Ng%3D%3D.2", "thumbnail_width": 640, "thumbnail_height": 640, "provider_name": "Instagram", "title": "Today, we\u2019re introducing a few new tools to help you make your story even more fun: Boomerang and mentions. We\u2019re also starting to test links inside some stories.\nBoomerang lets you turn everyday moments into something fun and unexpected. Now you can easily take a Boomerang right inside Instagram. Swipe right from your feed to open the stories camera. A new format picker under the record button lets you select \u201cBoomerang\u201d mode.\nYou can also now share who you\u2019re with or who you\u2019re thinking of by mentioning them in your story. When you add text to your story, type \u201c@\u201d followed by a username and select the person you\u2019d like to mention. Their username will appear underlined in your story. And when someone taps the mention, they'll see a pop-up that takes them to that profile.\nYou may begin to spot \u201cSee More\u201d links at the bottom of some stories. This is a test that lets verified accounts add links so it\u2019s easy to learn more. From your favorite chefs\u2019 recipes to articles from top journalists or concert dates from the musicians you love, tap \u201cSee More\u201d or swipe up to view the link right inside the app.\nTo learn more about today\u2019s updates, check out help.instagram.com.\nThese updates for Instagram Stories are available as part of Instagram version 9.7 available for iOS in the Apple App Store, for Android in Google Play and for Windows 10 in the Windows Store.", "html": "\u003cblockquote class=\"instagram-media\" data-instgrm-captioned data-instgrm-version=\"7\" style=\" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);\"\u003e\u003cdiv style=\"padding:8px;\"\u003e \u003cdiv style=\" background:#F8F8F8; line-height:0; margin-top:40px; padding:50.0% 0; text-align:center; width:100%;\"\u003e \u003cdiv style=\" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5/P8/t9FuRVCRmU73JWlzosgSIIZURCjo/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqjrTY0L8fxCxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;\"\u003e\u003c/div\u003e\u003c/div\u003e \u003cp style=\" margin:8px 0 0 0; padding:0 4px;\"\u003e \u003ca href=\"https://www.instagram.com/p/BMokmydjG-M/\" style=\" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;\" target=\"_blank\"\u003eToday, we\u2019re introducing a few new tools to help you make your story even more fun: Boomerang and mentions. We\u2019re also starting to test links inside some stories. Boomerang lets you turn everyday moments into something fun and unexpected. Now you can easily take a Boomerang right inside Instagram. Swipe right from your feed to open the stories camera. A new format picker under the record button lets you select \u201cBoomerang\u201d mode. You can also now share who you\u2019re with or who you\u2019re thinking of by mentioning them in your story. When you add text to your story, type \u201c@\u201d followed by a username and select the person you\u2019d like to mention. Their username will appear underlined in your story. And when someone taps the mention, they\u0026#39;ll see a pop-up that takes them to that profile. You may begin to spot \u201cSee More\u201d links at the bottom of some stories. This is a test that lets verified accounts add links so it\u2019s easy to learn more. From your favorite chefs\u2019 recipes to articles from top journalists or concert dates from the musicians you love, tap \u201cSee More\u201d or swipe up to view the link right inside the app. To learn more about today\u2019s updates, check out help.instagram.com. These updates for Instagram Stories are available as part of Instagram version 9.7 available for iOS in the Apple App Store, for Android in Google Play and for Windows 10 in the Windows Store.\u003c/a\u003e\u003c/p\u003e \u003cp style=\" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;\"\u003eA photo posted by Instagram (@instagram) on \u003ctime style=\" font-family:Arial,sans-serif; font-size:14px; line-height:17px;\" datetime=\"2016-11-10T15:02:28+00:00\"\u003eNov 10, 2016 at 7:02am PST\u003c/time\u003e\u003c/p\u003e\u003c/div\u003e\u003c/blockquote\u003e\n\u003cscript async defer src=\"//platform.instagram.com/en_US/embeds.js\"\u003e\u003c/script\u003e", "width": 658, "version": "1.0", "author_url": "https://www.instagram.com/instagram", "author_id": 25025320, "type": "rich"}`, `(?s)
    `, }, { `{{< instagram BMokmydjG-M hidecaption >}}`, `1`, `{"provider_url": "https://www.instagram.com", "media_id": "1380514280986406796_25025320", "author_name": "instagram", "height": null, "thumbnail_url": "https://scontent-amt2-1.cdninstagram.com/t51.2885-15/s640x640/sh0.08/e35/15048135_1880160212214218_7827880881132929024_n.jpg?ig_cache_key=MTM4MDUxNDI4MDk4NjQwNjc5Ng%3D%3D.2", "thumbnail_width": 640, "thumbnail_height": 640, "provider_name": "Instagram", "title": "Today, we\u2019re introducing a few new tools to help you make your story even more fun: Boomerang and mentions. We\u2019re also starting to test links inside some stories.\nBoomerang lets you turn everyday moments into something fun and unexpected. Now you can easily take a Boomerang right inside Instagram. Swipe right from your feed to open the stories camera. A new format picker under the record button lets you select \u201cBoomerang\u201d mode.\nYou can also now share who you\u2019re with or who you\u2019re thinking of by mentioning them in your story. When you add text to your story, type \u201c@\u201d followed by a username and select the person you\u2019d like to mention. Their username will appear underlined in your story. And when someone taps the mention, they'll see a pop-up that takes them to that profile.\nYou may begin to spot \u201cSee More\u201d links at the bottom of some stories. This is a test that lets verified accounts add links so it\u2019s easy to learn more. From your favorite chefs\u2019 recipes to articles from top journalists or concert dates from the musicians you love, tap \u201cSee More\u201d or swipe up to view the link right inside the app.\nTo learn more about today\u2019s updates, check out help.instagram.com.\nThese updates for Instagram Stories are available as part of Instagram version 9.7 available for iOS in the Apple App Store, for Android in Google Play and for Windows 10 in the Windows Store.", "html": "\u003cblockquote class=\"instagram-media\" data-instgrm-version=\"7\" style=\" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);\"\u003e\u003cdiv style=\"padding:8px;\"\u003e \u003cdiv style=\" background:#F8F8F8; line-height:0; margin-top:40px; padding:50.0% 0; text-align:center; width:100%;\"\u003e \u003cdiv style=\" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5/P8/t9FuRVCRmU73JWlzosgSIIZURCjo/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqjrTY0L8fxCxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;\"\u003e\u003c/div\u003e\u003c/div\u003e\u003cp style=\" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;\"\u003e\u003ca href=\"https://www.instagram.com/p/BMokmydjG-M/\" style=\" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;\" target=\"_blank\"\u003eA photo posted by Instagram (@instagram)\u003c/a\u003e on \u003ctime style=\" font-family:Arial,sans-serif; font-size:14px; line-height:17px;\" datetime=\"2016-11-10T15:02:28+00:00\"\u003eNov 10, 2016 at 7:02am PST\u003c/time\u003e\u003c/p\u003e\u003c/div\u003e\u003c/blockquote\u003e\n\u003cscript async defer src=\"//platform.instagram.com/en_US/embeds.js\"\u003e\u003c/script\u003e", "width": 658, "version": "1.0", "author_url": "https://www.instagram.com/instagram", "author_id": 25025320, "type": "rich"}`, `(?s)
    `, }, } { // overload getJSON to return mock API response from Instagram instagramFuncMap := template.FuncMap{ "getJSON": func(urlParts ...string) interface{} { var v interface{} err := json.Unmarshal([]byte(this.resp), &v) if err != nil { t.Fatalf("[%d] unexpected error in json.Unmarshal: %s", i, err) return err } return v }, } var ( cfg, fs = newTestCfg() th = newTestHelper(cfg, fs, t) ) writeSource(t, fs, filepath.Join("content", "simple.md"), fmt.Sprintf(`--- title: Shorty --- %s`, this.in)) writeSource(t, fs, filepath.Join("layouts", "_default", "single.html"), `{{ .Content | safeHTML }}`) buildSingleSite(t, deps.DepsCfg{Fs: fs, Cfg: cfg, OverloadedTemplateFuncs: instagramFuncMap}, BuildCfg{}) th.assertFileContentRegexp(filepath.Join("public", "simple", "index.html"), this.expected) } } hugo-0.68.3/hugolib/embedded_templates_test.go000066400000000000000000000067641363637351300214270ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package hugolib import ( "testing" qt "github.com/frankban/quicktest" ) // Just some simple test of the embedded templates to avoid // https://github.com/gohugoio/hugo/issues/4757 and similar. // TODO(bep) fix me https://github.com/gohugoio/hugo/issues/5926 func _TestEmbeddedTemplates(t *testing.T) { t.Parallel() c := qt.New(t) c.Assert(true, qt.Equals, true) home := []string{"index.html", ` GA: {{ template "_internal/google_analytics.html" . }} GA async: {{ template "_internal/google_analytics_async.html" . }} Disqus: {{ template "_internal/disqus.html" . }} `} b := newTestSitesBuilder(t) b.WithSimpleConfigFile().WithTemplatesAdded(home...) b.Build(BuildCfg{}) // Gheck GA regular and async b.AssertFileContent("public/index.html", "'anonymizeIp', true", "'script','https://www.google-analytics.com/analytics.js','ga');\n\tga('create', 'ga_id', 'auto')", "`, ``, or `` (case-insensitive; it need not match the start tag). 2. **Start condition:** line begins with the string ``. 3. **Start condition:** line begins with the string ``. 4. **Start condition:** line begins with the string ``. 5. **Start condition:** line begins with the string ``. 6. **Start condition:** line begins the string `<` or ``, or the string `/>`.\ **End condition:** line is followed by a [blank line]. 7. **Start condition:** line begins with a complete [open tag] (with any [tag name] other than `script`, `style`, or `pre`) or a complete [closing tag], followed only by [whitespace] or the end of the line.\ **End condition:** line is followed by a [blank line]. HTML blocks continue until they are closed by their appropriate [end condition], or the last line of the document or other [container block](#container-blocks). This means any HTML **within an HTML block** that might otherwise be recognised as a start condition will be ignored by the parser and passed through as-is, without changing the parser's state. For instance, `
    ` within a HTML block started by `
    ` will not affect the parser state; as the HTML block was started in by start condition 6, it will end at any blank line. This can be surprising: ```````````````````````````````` example
    **Hello**,
    
    _world_.
    
    .
    **Hello**,
    

    world.

    ```````````````````````````````` In this case, the HTML block is terminated by the newline — the `**Hello**` text remains verbatim — and regular parsing resumes, with a paragraph, emphasised `world` and inline and block HTML following. All types of [HTML blocks] except type 7 may interrupt a paragraph. Blocks of type 7 may not interrupt a paragraph. (This restriction is intended to prevent unwanted interpretation of long tags inside a wrapped paragraph as starting HTML blocks.) Some simple examples follow. Here are some basic HTML blocks of type 6: ```````````````````````````````` example
    hi
    okay. .
    hi

    okay.

    ```````````````````````````````` ```````````````````````````````` example *foo* ```````````````````````````````` Here we have two HTML blocks with a Markdown paragraph between them: ```````````````````````````````` example
    *Markdown*
    .

    Markdown

    ```````````````````````````````` The tag on the first line can be partial, as long as it is split where there would be whitespace: ```````````````````````````````` example
    .
    ```````````````````````````````` ```````````````````````````````` example
    .
    ```````````````````````````````` An open tag need not be closed: ```````````````````````````````` example
    *foo* *bar* .
    *foo*

    bar

    ```````````````````````````````` A partial tag need not even be completed (garbage in, garbage out): ```````````````````````````````` example
    . ```````````````````````````````` ```````````````````````````````` example
    foo
    .
    foo
    ```````````````````````````````` Everything until the next blank line or end of document gets included in the HTML block. So, in the following example, what looks like a Markdown code block is actually part of the HTML block, which continues until a blank line or the end of the document is reached: ```````````````````````````````` example
    ``` c int x = 33; ``` .
    ``` c int x = 33; ``` ```````````````````````````````` To start an [HTML block] with a tag that is *not* in the list of block-level tags in (6), you must put the tag by itself on the first line (and it must be complete): ```````````````````````````````` example *bar* . *bar* ```````````````````````````````` In type 7 blocks, the [tag name] can be anything: ```````````````````````````````` example *bar* . *bar* ```````````````````````````````` ```````````````````````````````` example *bar* . *bar* ```````````````````````````````` ```````````````````````````````` example *bar* . *bar* ```````````````````````````````` These rules are designed to allow us to work with tags that can function as either block-level or inline-level tags. The `` tag is a nice example. We can surround content with `` tags in three different ways. In this case, we get a raw HTML block, because the `` tag is on a line by itself: ```````````````````````````````` example *foo* . *foo* ```````````````````````````````` In this case, we get a raw HTML block that just includes the `` tag (because it ends with the following blank line). So the contents get interpreted as CommonMark: ```````````````````````````````` example *foo* .

    foo

    ```````````````````````````````` Finally, in this case, the `` tags are interpreted as [raw HTML] *inside* the CommonMark paragraph. (Because the tag is not on a line by itself, we get inline HTML rather than an [HTML block].) ```````````````````````````````` example *foo* .

    foo

    ```````````````````````````````` HTML tags designed to contain literal content (`script`, `style`, `pre`), comments, processing instructions, and declarations are treated somewhat differently. Instead of ending at the first blank line, these blocks end at the first line containing a corresponding end tag. As a result, these blocks can contain blank lines: A pre tag (type 1): ```````````````````````````````` example
    
    import Text.HTML.TagSoup
    
    main :: IO ()
    main = print $ parseTags tags
    
    okay .
    
    import Text.HTML.TagSoup
    
    main :: IO ()
    main = print $ parseTags tags
    

    okay

    ```````````````````````````````` A script tag (type 1): ```````````````````````````````` example okay .

    okay

    ```````````````````````````````` A style tag (type 1): ```````````````````````````````` example okay .

    okay

    ```````````````````````````````` If there is no matching end tag, the block will end at the end of the document (or the enclosing [block quote][block quotes] or [list item][list items]): ```````````````````````````````` example *foo* .

    foo

    ```````````````````````````````` ```````````````````````````````` example *bar* *baz* . *bar*

    baz

    ```````````````````````````````` Note that anything on the last line after the end tag will be included in the [HTML block]: ```````````````````````````````` example 1. *bar* . 1. *bar* ```````````````````````````````` A comment (type 2): ```````````````````````````````` example okay .

    okay

    ```````````````````````````````` A processing instruction (type 3): ```````````````````````````````` example '; ?> okay . '; ?>

    okay

    ```````````````````````````````` A declaration (type 4): ```````````````````````````````` example . ```````````````````````````````` CDATA (type 5): ```````````````````````````````` example okay .

    okay

    ```````````````````````````````` The opening tag can be indented 1-3 spaces, but not 4: ```````````````````````````````` example .
    <!-- foo -->
    
    ```````````````````````````````` ```````````````````````````````` example
    .
    <div>
    
    ```````````````````````````````` An HTML block of types 1--6 can interrupt a paragraph, and need not be preceded by a blank line. ```````````````````````````````` example Foo
    bar
    .

    Foo

    bar
    ```````````````````````````````` However, a following blank line is needed, except at the end of a document, and except for blocks of types 1--5, [above][HTML block]: ```````````````````````````````` example
    bar
    *foo* .
    bar
    *foo* ```````````````````````````````` HTML blocks of type 7 cannot interrupt a paragraph: ```````````````````````````````` example Foo baz .

    Foo baz

    ```````````````````````````````` This rule differs from John Gruber's original Markdown syntax specification, which says: > The only restrictions are that block-level HTML elements — > e.g. `
    `, ``, `
    `, `

    `, etc. — must be separated from > surrounding content by blank lines, and the start and end tags of the > block should not be indented with tabs or spaces. In some ways Gruber's rule is more restrictive than the one given here: - It requires that an HTML block be preceded by a blank line. - It does not allow the start tag to be indented. - It requires a matching end tag, which it also does not allow to be indented. Most Markdown implementations (including some of Gruber's own) do not respect all of these restrictions. There is one respect, however, in which Gruber's rule is more liberal than the one given here, since it allows blank lines to occur inside an HTML block. There are two reasons for disallowing them here. First, it removes the need to parse balanced tags, which is expensive and can require backtracking from the end of the document if no matching end tag is found. Second, it provides a very simple and flexible way of including Markdown content inside HTML tags: simply separate the Markdown from the HTML using blank lines: Compare: ```````````````````````````````` example

    *Emphasized* text.
    .

    Emphasized text.

    ```````````````````````````````` ```````````````````````````````` example
    *Emphasized* text.
    .
    *Emphasized* text.
    ```````````````````````````````` Some Markdown implementations have adopted a convention of interpreting content inside tags as text if the open tag has the attribute `markdown=1`. The rule given above seems a simpler and more elegant way of achieving the same expressive power, which is also much simpler to parse. The main potential drawback is that one can no longer paste HTML blocks into Markdown documents with 100% reliability. However, *in most cases* this will work fine, because the blank lines in HTML are usually followed by HTML block tags. For example: ```````````````````````````````` example
    Hi
    .
    Hi
    ```````````````````````````````` There are problems, however, if the inner tags are indented *and* separated by spaces, as then they will be interpreted as an indented code block: ```````````````````````````````` example
    Hi
    .
    <td>
      Hi
    </td>
    
    ```````````````````````````````` Fortunately, blank lines are usually not necessary and can be deleted. The exception is inside `
    ` tags, but as described
    [above][HTML blocks], raw HTML blocks starting with `
    `
    *can* contain blank lines.
    
    ## Link reference definitions
    
    A [link reference definition](@)
    consists of a [link label], indented up to three spaces, followed
    by a colon (`:`), optional [whitespace] (including up to one
    [line ending]), a [link destination],
    optional [whitespace] (including up to one
    [line ending]), and an optional [link
    title], which if it is present must be separated
    from the [link destination] by [whitespace].
    No further [non-whitespace characters] may occur on the line.
    
    A [link reference definition]
    does not correspond to a structural element of a document.  Instead, it
    defines a label which can be used in [reference links]
    and reference-style [images] elsewhere in the document.  [Link
    reference definitions] can come either before or after the links that use
    them.
    
    ```````````````````````````````` example
    [foo]: /url "title"
    
    [foo]
    .
    

    foo

    ```````````````````````````````` ```````````````````````````````` example [foo]: /url 'the title' [foo] .

    foo

    ```````````````````````````````` ```````````````````````````````` example [Foo*bar\]]:my_(url) 'title (with parens)' [Foo*bar\]] .

    Foo*bar]

    ```````````````````````````````` ```````````````````````````````` example [Foo bar]: 'title' [Foo bar] .

    Foo bar

    ```````````````````````````````` The title may extend over multiple lines: ```````````````````````````````` example [foo]: /url ' title line1 line2 ' [foo] .

    foo

    ```````````````````````````````` However, it may not contain a [blank line]: ```````````````````````````````` example [foo]: /url 'title with blank line' [foo] .

    [foo]: /url 'title

    with blank line'

    [foo]

    ```````````````````````````````` The title may be omitted: ```````````````````````````````` example [foo]: /url [foo] .

    foo

    ```````````````````````````````` The link destination may not be omitted: ```````````````````````````````` example [foo]: [foo] .

    [foo]:

    [foo]

    ```````````````````````````````` However, an empty link destination may be specified using angle brackets: ```````````````````````````````` example [foo]: <> [foo] .

    foo

    ```````````````````````````````` The title must be separated from the link destination by whitespace: ```````````````````````````````` example [foo]: (baz) [foo] .

    [foo]: (baz)

    [foo]

    ```````````````````````````````` Both title and destination can contain backslash escapes and literal backslashes: ```````````````````````````````` example [foo]: /url\bar\*baz "foo\"bar\baz" [foo] .

    foo

    ```````````````````````````````` A link can come before its corresponding definition: ```````````````````````````````` example [foo] [foo]: url .

    foo

    ```````````````````````````````` If there are several matching definitions, the first one takes precedence: ```````````````````````````````` example [foo] [foo]: first [foo]: second .

    foo

    ```````````````````````````````` As noted in the section on [Links], matching of labels is case-insensitive (see [matches]). ```````````````````````````````` example [FOO]: /url [Foo] .

    Foo

    ```````````````````````````````` ```````````````````````````````` example [ΑΓΩ]: /φου [αγω] .

    αγω

    ```````````````````````````````` Here is a link reference definition with no corresponding link. It contributes nothing to the document. ```````````````````````````````` example [foo]: /url . ```````````````````````````````` Here is another one: ```````````````````````````````` example [ foo ]: /url bar .

    bar

    ```````````````````````````````` This is not a link reference definition, because there are [non-whitespace characters] after the title: ```````````````````````````````` example [foo]: /url "title" ok .

    [foo]: /url "title" ok

    ```````````````````````````````` This is a link reference definition, but it has no title: ```````````````````````````````` example [foo]: /url "title" ok .

    "title" ok

    ```````````````````````````````` This is not a link reference definition, because it is indented four spaces: ```````````````````````````````` example [foo]: /url "title" [foo] .
    [foo]: /url "title"
    

    [foo]

    ```````````````````````````````` This is not a link reference definition, because it occurs inside a code block: ```````````````````````````````` example ``` [foo]: /url ``` [foo] .
    [foo]: /url
    

    [foo]

    ```````````````````````````````` A [link reference definition] cannot interrupt a paragraph. ```````````````````````````````` example Foo [bar]: /baz [bar] .

    Foo [bar]: /baz

    [bar]

    ```````````````````````````````` However, it can directly follow other block elements, such as headings and thematic breaks, and it need not be followed by a blank line. ```````````````````````````````` example # [Foo] [foo]: /url > bar .

    Foo

    bar

    ```````````````````````````````` ```````````````````````````````` example [foo]: /url bar === [foo] .

    bar

    foo

    ```````````````````````````````` ```````````````````````````````` example [foo]: /url === [foo] .

    === foo

    ```````````````````````````````` Several [link reference definitions] can occur one after another, without intervening blank lines. ```````````````````````````````` example [foo]: /foo-url "foo" [bar]: /bar-url "bar" [baz]: /baz-url [foo], [bar], [baz] .

    foo, bar, baz

    ```````````````````````````````` [Link reference definitions] can occur inside block containers, like lists and block quotations. They affect the entire document, not just the container in which they are defined: ```````````````````````````````` example [foo] > [foo]: /url .

    foo

    ```````````````````````````````` Whether something is a [link reference definition] is independent of whether the link reference it defines is used in the document. Thus, for example, the following document contains just a link reference definition, and no visible content: ```````````````````````````````` example [foo]: /url . ```````````````````````````````` ## Paragraphs A sequence of non-blank lines that cannot be interpreted as other kinds of blocks forms a [paragraph](@). The contents of the paragraph are the result of parsing the paragraph's raw content as inlines. The paragraph's raw content is formed by concatenating the lines and removing initial and final [whitespace]. A simple example with two paragraphs: ```````````````````````````````` example aaa bbb .

    aaa

    bbb

    ```````````````````````````````` Paragraphs can contain multiple lines, but no blank lines: ```````````````````````````````` example aaa bbb ccc ddd .

    aaa bbb

    ccc ddd

    ```````````````````````````````` Multiple blank lines between paragraph have no effect: ```````````````````````````````` example aaa bbb .

    aaa

    bbb

    ```````````````````````````````` Leading spaces are skipped: ```````````````````````````````` example aaa bbb .

    aaa bbb

    ```````````````````````````````` Lines after the first may be indented any amount, since indented code blocks cannot interrupt paragraphs. ```````````````````````````````` example aaa bbb ccc .

    aaa bbb ccc

    ```````````````````````````````` However, the first line may be indented at most three spaces, or an indented code block will be triggered: ```````````````````````````````` example aaa bbb .

    aaa bbb

    ```````````````````````````````` ```````````````````````````````` example aaa bbb .
    aaa
    

    bbb

    ```````````````````````````````` Final spaces are stripped before inline parsing, so a paragraph that ends with two or more spaces will not end with a [hard line break]: ```````````````````````````````` example aaa bbb .

    aaa
    bbb

    ```````````````````````````````` ## Blank lines [Blank lines] between block-level elements are ignored, except for the role they play in determining whether a [list] is [tight] or [loose]. Blank lines at the beginning and end of the document are also ignored. ```````````````````````````````` example aaa # aaa .

    aaa

    aaa

    ```````````````````````````````` # Container blocks A [container block](#container-blocks) is a block that has other blocks as its contents. There are two basic kinds of container blocks: [block quotes] and [list items]. [Lists] are meta-containers for [list items]. We define the syntax for container blocks recursively. The general form of the definition is: > If X is a sequence of blocks, then the result of > transforming X in such-and-such a way is a container of type Y > with these blocks as its content. So, we explain what counts as a block quote or list item by explaining how these can be *generated* from their contents. This should suffice to define the syntax, although it does not give a recipe for *parsing* these constructions. (A recipe is provided below in the section entitled [A parsing strategy](#appendix-a-parsing-strategy).) ## Block quotes A [block quote marker](@) consists of 0-3 spaces of initial indent, plus (a) the character `>` together with a following space, or (b) a single character `>` not followed by a space. The following rules define [block quotes]: 1. **Basic case.** If a string of lines *Ls* constitute a sequence of blocks *Bs*, then the result of prepending a [block quote marker] to the beginning of each line in *Ls* is a [block quote](#block-quotes) containing *Bs*. 2. **Laziness.** If a string of lines *Ls* constitute a [block quote](#block-quotes) with contents *Bs*, then the result of deleting the initial [block quote marker] from one or more lines in which the next [non-whitespace character] after the [block quote marker] is [paragraph continuation text] is a block quote with *Bs* as its content. [Paragraph continuation text](@) is text that will be parsed as part of the content of a paragraph, but does not occur at the beginning of the paragraph. 3. **Consecutiveness.** A document cannot contain two [block quotes] in a row unless there is a [blank line] between them. Nothing else counts as a [block quote](#block-quotes). Here is a simple example: ```````````````````````````````` example > # Foo > bar > baz .

    Foo

    bar baz

    ```````````````````````````````` The spaces after the `>` characters can be omitted: ```````````````````````````````` example ># Foo >bar > baz .

    Foo

    bar baz

    ```````````````````````````````` The `>` characters can be indented 1-3 spaces: ```````````````````````````````` example > # Foo > bar > baz .

    Foo

    bar baz

    ```````````````````````````````` Four spaces gives us a code block: ```````````````````````````````` example > # Foo > bar > baz .
    > # Foo
    > bar
    > baz
    
    ```````````````````````````````` The Laziness clause allows us to omit the `>` before [paragraph continuation text]: ```````````````````````````````` example > # Foo > bar baz .

    Foo

    bar baz

    ```````````````````````````````` A block quote can contain some lazy and some non-lazy continuation lines: ```````````````````````````````` example > bar baz > foo .

    bar baz foo

    ```````````````````````````````` Laziness only applies to lines that would have been continuations of paragraphs had they been prepended with [block quote markers]. For example, the `> ` cannot be omitted in the second line of ``` markdown > foo > --- ``` without changing the meaning: ```````````````````````````````` example > foo --- .

    foo


    ```````````````````````````````` Similarly, if we omit the `> ` in the second line of ``` markdown > - foo > - bar ``` then the block quote ends after the first line: ```````````````````````````````` example > - foo - bar .
    • foo
    • bar
    ```````````````````````````````` For the same reason, we can't omit the `> ` in front of subsequent lines of an indented or fenced code block: ```````````````````````````````` example > foo bar .
    foo
    
    bar
    
    ```````````````````````````````` ```````````````````````````````` example > ``` foo ``` .

    foo

    ```````````````````````````````` Note that in the following case, we have a [lazy continuation line]: ```````````````````````````````` example > foo - bar .

    foo - bar

    ```````````````````````````````` To see why, note that in ```markdown > foo > - bar ``` the `- bar` is indented too far to start a list, and can't be an indented code block because indented code blocks cannot interrupt paragraphs, so it is [paragraph continuation text]. A block quote can be empty: ```````````````````````````````` example > .
    ```````````````````````````````` ```````````````````````````````` example > > > .
    ```````````````````````````````` A block quote can have initial or final blank lines: ```````````````````````````````` example > > foo > .

    foo

    ```````````````````````````````` A blank line always separates block quotes: ```````````````````````````````` example > foo > bar .

    foo

    bar

    ```````````````````````````````` (Most current Markdown implementations, including John Gruber's original `Markdown.pl`, will parse this example as a single block quote with two paragraphs. But it seems better to allow the author to decide whether two block quotes or one are wanted.) Consecutiveness means that if we put these block quotes together, we get a single block quote: ```````````````````````````````` example > foo > bar .

    foo bar

    ```````````````````````````````` To get a block quote with two paragraphs, use: ```````````````````````````````` example > foo > > bar .

    foo

    bar

    ```````````````````````````````` Block quotes can interrupt paragraphs: ```````````````````````````````` example foo > bar .

    foo

    bar

    ```````````````````````````````` In general, blank lines are not needed before or after block quotes: ```````````````````````````````` example > aaa *** > bbb .

    aaa


    bbb

    ```````````````````````````````` However, because of laziness, a blank line is needed between a block quote and a following paragraph: ```````````````````````````````` example > bar baz .

    bar baz

    ```````````````````````````````` ```````````````````````````````` example > bar baz .

    bar

    baz

    ```````````````````````````````` ```````````````````````````````` example > bar > baz .

    bar

    baz

    ```````````````````````````````` It is a consequence of the Laziness rule that any number of initial `>`s may be omitted on a continuation line of a nested block quote: ```````````````````````````````` example > > > foo bar .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example >>> foo > bar >>baz .

    foo bar baz

    ```````````````````````````````` When including an indented code block in a block quote, remember that the [block quote marker] includes both the `>` and a following space. So *five spaces* are needed after the `>`: ```````````````````````````````` example > code > not code .
    code
    

    not code

    ```````````````````````````````` ## List items A [list marker](@) is a [bullet list marker] or an [ordered list marker]. A [bullet list marker](@) is a `-`, `+`, or `*` character. An [ordered list marker](@) is a sequence of 1--9 arabic digits (`0-9`), followed by either a `.` character or a `)` character. (The reason for the length limit is that with 10 digits we start seeing integer overflows in some browsers.) The following rules define [list items]: 1. **Basic case.** If a sequence of lines *Ls* constitute a sequence of blocks *Bs* starting with a [non-whitespace character], and *M* is a list marker of width *W* followed by 1 ≤ *N* ≤ 4 spaces, then the result of prepending *M* and the following spaces to the first line of *Ls*, and indenting subsequent lines of *Ls* by *W + N* spaces, is a list item with *Bs* as its contents. The type of the list item (bullet or ordered) is determined by the type of its list marker. If the list item is ordered, then it is also assigned a start number, based on the ordered list marker. Exceptions: 1. When the first list item in a [list] interrupts a paragraph---that is, when it starts on a line that would otherwise count as [paragraph continuation text]---then (a) the lines *Ls* must not begin with a blank line, and (b) if the list item is ordered, the start number must be 1. 2. If any line is a [thematic break][thematic breaks] then that line is not a list item. For example, let *Ls* be the lines ```````````````````````````````` example A paragraph with two lines. indented code > A block quote. .

    A paragraph with two lines.

    indented code
    

    A block quote.

    ```````````````````````````````` And let *M* be the marker `1.`, and *N* = 2. Then rule #1 says that the following is an ordered list item with start number 1, and the same contents as *Ls*: ```````````````````````````````` example 1. A paragraph with two lines. indented code > A block quote. .
    1. A paragraph with two lines.

      indented code
      

      A block quote.

    ```````````````````````````````` The most important thing to notice is that the position of the text after the list marker determines how much indentation is needed in subsequent blocks in the list item. If the list marker takes up two spaces, and there are three spaces between the list marker and the next [non-whitespace character], then blocks must be indented five spaces in order to fall under the list item. Here are some examples showing how far content must be indented to be put under the list item: ```````````````````````````````` example - one two .
    • one

    two

    ```````````````````````````````` ```````````````````````````````` example - one two .
    • one

      two

    ```````````````````````````````` ```````````````````````````````` example - one two .
    • one
     two
    
    ```````````````````````````````` ```````````````````````````````` example - one two .
    • one

      two

    ```````````````````````````````` It is tempting to think of this in terms of columns: the continuation blocks must be indented at least to the column of the first [non-whitespace character] after the list marker. However, that is not quite right. The spaces after the list marker determine how much relative indentation is needed. Which column this indentation reaches will depend on how the list item is embedded in other constructions, as shown by this example: ```````````````````````````````` example > > 1. one >> >> two .
    1. one

      two

    ```````````````````````````````` Here `two` occurs in the same column as the list marker `1.`, but is actually contained in the list item, because there is sufficient indentation after the last containing blockquote marker. The converse is also possible. In the following example, the word `two` occurs far to the right of the initial text of the list item, `one`, but it is not considered part of the list item, because it is not indented far enough past the blockquote marker: ```````````````````````````````` example >>- one >> > > two .
    • one

    two

    ```````````````````````````````` Note that at least one space is needed between the list marker and any following content, so these are not list items: ```````````````````````````````` example -one 2.two .

    -one

    2.two

    ```````````````````````````````` A list item may contain blocks that are separated by more than one blank line. ```````````````````````````````` example - foo bar .
    • foo

      bar

    ```````````````````````````````` A list item may contain any kind of block: ```````````````````````````````` example 1. foo ``` bar ``` baz > bam .
    1. foo

      bar
      

      baz

      bam

    ```````````````````````````````` A list item that contains an indented code block will preserve empty lines within the code block verbatim. ```````````````````````````````` example - Foo bar baz .
    • Foo

      bar
      
      
      baz
      
    ```````````````````````````````` Note that ordered list start numbers must be nine digits or less: ```````````````````````````````` example 123456789. ok .
    1. ok
    ```````````````````````````````` ```````````````````````````````` example 1234567890. not ok .

    1234567890. not ok

    ```````````````````````````````` A start number may begin with 0s: ```````````````````````````````` example 0. ok .
    1. ok
    ```````````````````````````````` ```````````````````````````````` example 003. ok .
    1. ok
    ```````````````````````````````` A start number may not be negative: ```````````````````````````````` example -1. not ok .

    -1. not ok

    ```````````````````````````````` 2. **Item starting with indented code.** If a sequence of lines *Ls* constitute a sequence of blocks *Bs* starting with an indented code block, and *M* is a list marker of width *W* followed by one space, then the result of prepending *M* and the following space to the first line of *Ls*, and indenting subsequent lines of *Ls* by *W + 1* spaces, is a list item with *Bs* as its contents. If a line is empty, then it need not be indented. The type of the list item (bullet or ordered) is determined by the type of its list marker. If the list item is ordered, then it is also assigned a start number, based on the ordered list marker. An indented code block will have to be indented four spaces beyond the edge of the region where text will be included in the list item. In the following case that is 6 spaces: ```````````````````````````````` example - foo bar .
    • foo

      bar
      
    ```````````````````````````````` And in this case it is 11 spaces: ```````````````````````````````` example 10. foo bar .
    1. foo

      bar
      
    ```````````````````````````````` If the *first* block in the list item is an indented code block, then by rule #2, the contents must be indented *one* space after the list marker: ```````````````````````````````` example indented code paragraph more code .
    indented code
    

    paragraph

    more code
    
    ```````````````````````````````` ```````````````````````````````` example 1. indented code paragraph more code .
    1. indented code
      

      paragraph

      more code
      
    ```````````````````````````````` Note that an additional space indent is interpreted as space inside the code block: ```````````````````````````````` example 1. indented code paragraph more code .
    1.  indented code
      

      paragraph

      more code
      
    ```````````````````````````````` Note that rules #1 and #2 only apply to two cases: (a) cases in which the lines to be included in a list item begin with a [non-whitespace character], and (b) cases in which they begin with an indented code block. In a case like the following, where the first block begins with a three-space indent, the rules do not allow us to form a list item by indenting the whole thing and prepending a list marker: ```````````````````````````````` example foo bar .

    foo

    bar

    ```````````````````````````````` ```````````````````````````````` example - foo bar .
    • foo

    bar

    ```````````````````````````````` This is not a significant restriction, because when a block begins with 1-3 spaces indent, the indentation can always be removed without a change in interpretation, allowing rule #1 to be applied. So, in the above case: ```````````````````````````````` example - foo bar .
    • foo

      bar

    ```````````````````````````````` 3. **Item starting with a blank line.** If a sequence of lines *Ls* starting with a single [blank line] constitute a (possibly empty) sequence of blocks *Bs*, not separated from each other by more than one blank line, and *M* is a list marker of width *W*, then the result of prepending *M* to the first line of *Ls*, and indenting subsequent lines of *Ls* by *W + 1* spaces, is a list item with *Bs* as its contents. If a line is empty, then it need not be indented. The type of the list item (bullet or ordered) is determined by the type of its list marker. If the list item is ordered, then it is also assigned a start number, based on the ordered list marker. Here are some list items that start with a blank line but are not empty: ```````````````````````````````` example - foo - ``` bar ``` - baz .
    • foo
    • bar
      
    • baz
      
    ```````````````````````````````` When the list item starts with a blank line, the number of spaces following the list marker doesn't change the required indentation: ```````````````````````````````` example - foo .
    • foo
    ```````````````````````````````` A list item can begin with at most one blank line. In the following example, `foo` is not part of the list item: ```````````````````````````````` example - foo .

    foo

    ```````````````````````````````` Here is an empty bullet list item: ```````````````````````````````` example - foo - - bar .
    • foo
    • bar
    ```````````````````````````````` It does not matter whether there are spaces following the [list marker]: ```````````````````````````````` example - foo - - bar .
    • foo
    • bar
    ```````````````````````````````` Here is an empty ordered list item: ```````````````````````````````` example 1. foo 2. 3. bar .
    1. foo
    2. bar
    ```````````````````````````````` A list may start or end with an empty list item: ```````````````````````````````` example * .
    ```````````````````````````````` However, an empty list item cannot interrupt a paragraph: ```````````````````````````````` example foo * foo 1. .

    foo *

    foo 1.

    ```````````````````````````````` 4. **Indentation.** If a sequence of lines *Ls* constitutes a list item according to rule #1, #2, or #3, then the result of indenting each line of *Ls* by 1-3 spaces (the same for each line) also constitutes a list item with the same contents and attributes. If a line is empty, then it need not be indented. Indented one space: ```````````````````````````````` example 1. A paragraph with two lines. indented code > A block quote. .
    1. A paragraph with two lines.

      indented code
      

      A block quote.

    ```````````````````````````````` Indented two spaces: ```````````````````````````````` example 1. A paragraph with two lines. indented code > A block quote. .
    1. A paragraph with two lines.

      indented code
      

      A block quote.

    ```````````````````````````````` Indented three spaces: ```````````````````````````````` example 1. A paragraph with two lines. indented code > A block quote. .
    1. A paragraph with two lines.

      indented code
      

      A block quote.

    ```````````````````````````````` Four spaces indent gives a code block: ```````````````````````````````` example 1. A paragraph with two lines. indented code > A block quote. .
    1.  A paragraph
        with two lines.
    
            indented code
    
        > A block quote.
    
    ```````````````````````````````` 5. **Laziness.** If a string of lines *Ls* constitute a [list item](#list-items) with contents *Bs*, then the result of deleting some or all of the indentation from one or more lines in which the next [non-whitespace character] after the indentation is [paragraph continuation text] is a list item with the same contents and attributes. The unindented lines are called [lazy continuation line](@)s. Here is an example with [lazy continuation lines]: ```````````````````````````````` example 1. A paragraph with two lines. indented code > A block quote. .
    1. A paragraph with two lines.

      indented code
      

      A block quote.

    ```````````````````````````````` Indentation can be partially deleted: ```````````````````````````````` example 1. A paragraph with two lines. .
    1. A paragraph with two lines.
    ```````````````````````````````` These examples show how laziness can work in nested structures: ```````````````````````````````` example > 1. > Blockquote continued here. .
    1. Blockquote continued here.

    ```````````````````````````````` ```````````````````````````````` example > 1. > Blockquote > continued here. .
    1. Blockquote continued here.

    ```````````````````````````````` 6. **That's all.** Nothing that is not counted as a list item by rules #1--5 counts as a [list item](#list-items). The rules for sublists follow from the general rules [above][List items]. A sublist must be indented the same number of spaces a paragraph would need to be in order to be included in the list item. So, in this case we need two spaces indent: ```````````````````````````````` example - foo - bar - baz - boo .
    • foo
      • bar
        • baz
          • boo
    ```````````````````````````````` One is not enough: ```````````````````````````````` example - foo - bar - baz - boo .
    • foo
    • bar
    • baz
    • boo
    ```````````````````````````````` Here we need four, because the list marker is wider: ```````````````````````````````` example 10) foo - bar .
    1. foo
      • bar
    ```````````````````````````````` Three is not enough: ```````````````````````````````` example 10) foo - bar .
    1. foo
    • bar
    ```````````````````````````````` A list may be the first block in a list item: ```````````````````````````````` example - - foo .
      • foo
    ```````````````````````````````` ```````````````````````````````` example 1. - 2. foo .
        1. foo
    ```````````````````````````````` A list item can contain a heading: ```````````````````````````````` example - # Foo - Bar --- baz .
    • Foo

    • Bar

      baz
    ```````````````````````````````` ### Motivation John Gruber's Markdown spec says the following about list items: 1. "List markers typically start at the left margin, but may be indented by up to three spaces. List markers must be followed by one or more spaces or a tab." 2. "To make lists look nice, you can wrap items with hanging indents.... But if you don't want to, you don't have to." 3. "List items may consist of multiple paragraphs. Each subsequent paragraph in a list item must be indented by either 4 spaces or one tab." 4. "It looks nice if you indent every line of the subsequent paragraphs, but here again, Markdown will allow you to be lazy." 5. "To put a blockquote within a list item, the blockquote's `>` delimiters need to be indented." 6. "To put a code block within a list item, the code block needs to be indented twice — 8 spaces or two tabs." These rules specify that a paragraph under a list item must be indented four spaces (presumably, from the left margin, rather than the start of the list marker, but this is not said), and that code under a list item must be indented eight spaces instead of the usual four. They also say that a block quote must be indented, but not by how much; however, the example given has four spaces indentation. Although nothing is said about other kinds of block-level content, it is certainly reasonable to infer that *all* block elements under a list item, including other lists, must be indented four spaces. This principle has been called the *four-space rule*. The four-space rule is clear and principled, and if the reference implementation `Markdown.pl` had followed it, it probably would have become the standard. However, `Markdown.pl` allowed paragraphs and sublists to start with only two spaces indentation, at least on the outer level. Worse, its behavior was inconsistent: a sublist of an outer-level list needed two spaces indentation, but a sublist of this sublist needed three spaces. It is not surprising, then, that different implementations of Markdown have developed very different rules for determining what comes under a list item. (Pandoc and python-Markdown, for example, stuck with Gruber's syntax description and the four-space rule, while discount, redcarpet, marked, PHP Markdown, and others followed `Markdown.pl`'s behavior more closely.) Unfortunately, given the divergences between implementations, there is no way to give a spec for list items that will be guaranteed not to break any existing documents. However, the spec given here should correctly handle lists formatted with either the four-space rule or the more forgiving `Markdown.pl` behavior, provided they are laid out in a way that is natural for a human to read. The strategy here is to let the width and indentation of the list marker determine the indentation necessary for blocks to fall under the list item, rather than having a fixed and arbitrary number. The writer can think of the body of the list item as a unit which gets indented to the right enough to fit the list marker (and any indentation on the list marker). (The laziness rule, #5, then allows continuation lines to be unindented if needed.) This rule is superior, we claim, to any rule requiring a fixed level of indentation from the margin. The four-space rule is clear but unnatural. It is quite unintuitive that ``` markdown - foo bar - baz ``` should be parsed as two lists with an intervening paragraph, ``` html
    • foo

    bar

    • baz
    ``` as the four-space rule demands, rather than a single list, ``` html
    • foo

      bar

      • baz
    ``` The choice of four spaces is arbitrary. It can be learned, but it is not likely to be guessed, and it trips up beginners regularly. Would it help to adopt a two-space rule? The problem is that such a rule, together with the rule allowing 1--3 spaces indentation of the initial list marker, allows text that is indented *less than* the original list marker to be included in the list item. For example, `Markdown.pl` parses ``` markdown - one two ``` as a single list item, with `two` a continuation paragraph: ``` html
    • one

      two

    ``` and similarly ``` markdown > - one > > two ``` as ``` html
    • one

      two

    ``` This is extremely unintuitive. Rather than requiring a fixed indent from the margin, we could require a fixed indent (say, two spaces, or even one space) from the list marker (which may itself be indented). This proposal would remove the last anomaly discussed. Unlike the spec presented above, it would count the following as a list item with a subparagraph, even though the paragraph `bar` is not indented as far as the first paragraph `foo`: ``` markdown 10. foo bar ``` Arguably this text does read like a list item with `bar` as a subparagraph, which may count in favor of the proposal. However, on this proposal indented code would have to be indented six spaces after the list marker. And this would break a lot of existing Markdown, which has the pattern: ``` markdown 1. foo indented code ``` where the code is indented eight spaces. The spec above, by contrast, will parse this text as expected, since the code block's indentation is measured from the beginning of `foo`. The one case that needs special treatment is a list item that *starts* with indented code. How much indentation is required in that case, since we don't have a "first paragraph" to measure from? Rule #2 simply stipulates that in such cases, we require one space indentation from the list marker (and then the normal four spaces for the indented code). This will match the four-space rule in cases where the list marker plus its initial indentation takes four spaces (a common case), but diverge in other cases. ## Lists A [list](@) is a sequence of one or more list items [of the same type]. The list items may be separated by any number of blank lines. Two list items are [of the same type](@) if they begin with a [list marker] of the same type. Two list markers are of the same type if (a) they are bullet list markers using the same character (`-`, `+`, or `*`) or (b) they are ordered list numbers with the same delimiter (either `.` or `)`). A list is an [ordered list](@) if its constituent list items begin with [ordered list markers], and a [bullet list](@) if its constituent list items begin with [bullet list markers]. The [start number](@) of an [ordered list] is determined by the list number of its initial list item. The numbers of subsequent list items are disregarded. A list is [loose](@) if any of its constituent list items are separated by blank lines, or if any of its constituent list items directly contain two block-level elements with a blank line between them. Otherwise a list is [tight](@). (The difference in HTML output is that paragraphs in a loose list are wrapped in `

    ` tags, while paragraphs in a tight list are not.) Changing the bullet or ordered list delimiter starts a new list: ```````````````````````````````` example - foo - bar + baz .

    • foo
    • bar
    • baz
    ```````````````````````````````` ```````````````````````````````` example 1. foo 2. bar 3) baz .
    1. foo
    2. bar
    1. baz
    ```````````````````````````````` In CommonMark, a list can interrupt a paragraph. That is, no blank line is needed to separate a paragraph from a following list: ```````````````````````````````` example Foo - bar - baz .

    Foo

    • bar
    • baz
    ```````````````````````````````` `Markdown.pl` does not allow this, through fear of triggering a list via a numeral in a hard-wrapped line: ``` markdown The number of windows in my house is 14. The number of doors is 6. ``` Oddly, though, `Markdown.pl` *does* allow a blockquote to interrupt a paragraph, even though the same considerations might apply. In CommonMark, we do allow lists to interrupt paragraphs, for two reasons. First, it is natural and not uncommon for people to start lists without blank lines: ``` markdown I need to buy - new shoes - a coat - a plane ticket ``` Second, we are attracted to a > [principle of uniformity](@): > if a chunk of text has a certain > meaning, it will continue to have the same meaning when put into a > container block (such as a list item or blockquote). (Indeed, the spec for [list items] and [block quotes] presupposes this principle.) This principle implies that if ``` markdown * I need to buy - new shoes - a coat - a plane ticket ``` is a list item containing a paragraph followed by a nested sublist, as all Markdown implementations agree it is (though the paragraph may be rendered without `

    ` tags, since the list is "tight"), then ``` markdown I need to buy - new shoes - a coat - a plane ticket ``` by itself should be a paragraph followed by a nested sublist. Since it is well established Markdown practice to allow lists to interrupt paragraphs inside list items, the [principle of uniformity] requires us to allow this outside list items as well. ([reStructuredText](http://docutils.sourceforge.net/rst.html) takes a different approach, requiring blank lines before lists even inside other list items.) In order to solve of unwanted lists in paragraphs with hard-wrapped numerals, we allow only lists starting with `1` to interrupt paragraphs. Thus, ```````````````````````````````` example The number of windows in my house is 14. The number of doors is 6. .

    The number of windows in my house is 14. The number of doors is 6.

    ```````````````````````````````` We may still get an unintended result in cases like ```````````````````````````````` example The number of windows in my house is 1. The number of doors is 6. .

    The number of windows in my house is

    1. The number of doors is 6.
    ```````````````````````````````` but this rule should prevent most spurious list captures. There can be any number of blank lines between items: ```````````````````````````````` example - foo - bar - baz .
    • foo

    • bar

    • baz

    ```````````````````````````````` ```````````````````````````````` example - foo - bar - baz bim .
    • foo
      • bar
        • baz

          bim

    ```````````````````````````````` To separate consecutive lists of the same type, or to separate a list from an indented code block that would otherwise be parsed as a subparagraph of the final list item, you can insert a blank HTML comment: ```````````````````````````````` example - foo - bar - baz - bim .
    • foo
    • bar
    • baz
    • bim
    ```````````````````````````````` ```````````````````````````````` example - foo notcode - foo code .
    • foo

      notcode

    • foo

    code
    
    ```````````````````````````````` List items need not be indented to the same level. The following list items will be treated as items at the same list level, since none is indented enough to belong to the previous list item: ```````````````````````````````` example - a - b - c - d - e - f - g .
    • a
    • b
    • c
    • d
    • e
    • f
    • g
    ```````````````````````````````` ```````````````````````````````` example 1. a 2. b 3. c .
    1. a

    2. b

    3. c

    ```````````````````````````````` Note, however, that list items may not be indented more than three spaces. Here `- e` is treated as a paragraph continuation line, because it is indented more than three spaces: ```````````````````````````````` example - a - b - c - d - e .
    • a
    • b
    • c
    • d - e
    ```````````````````````````````` And here, `3. c` is treated as in indented code block, because it is indented four spaces and preceded by a blank line. ```````````````````````````````` example 1. a 2. b 3. c .
    1. a

    2. b

    3. c
    
    ```````````````````````````````` This is a loose list, because there is a blank line between two of the list items: ```````````````````````````````` example - a - b - c .
    • a

    • b

    • c

    ```````````````````````````````` So is this, with a empty second item: ```````````````````````````````` example * a * * c .
    • a

    • c

    ```````````````````````````````` These are loose lists, even though there is no space between the items, because one of the items directly contains two block-level elements with a blank line between them: ```````````````````````````````` example - a - b c - d .
    • a

    • b

      c

    • d

    ```````````````````````````````` ```````````````````````````````` example - a - b [ref]: /url - d .
    • a

    • b

    • d

    ```````````````````````````````` This is a tight list, because the blank lines are in a code block: ```````````````````````````````` example - a - ``` b ``` - c .
    • a
    • b
      
      
      
    • c
    ```````````````````````````````` This is a tight list, because the blank line is between two paragraphs of a sublist. So the sublist is loose while the outer list is tight: ```````````````````````````````` example - a - b c - d .
    • a
      • b

        c

    • d
    ```````````````````````````````` This is a tight list, because the blank line is inside the block quote: ```````````````````````````````` example * a > b > * c .
    • a

      b

    • c
    ```````````````````````````````` This list is tight, because the consecutive block elements are not separated by blank lines: ```````````````````````````````` example - a > b ``` c ``` - d .
    • a

      b

      c
      
    • d
    ```````````````````````````````` A single-paragraph list is tight: ```````````````````````````````` example - a .
    • a
    ```````````````````````````````` ```````````````````````````````` example - a - b .
    • a
      • b
    ```````````````````````````````` This list is loose, because of the blank line between the two block elements in the list item: ```````````````````````````````` example 1. ``` foo ``` bar .
    1. foo
      

      bar

    ```````````````````````````````` Here the outer list is loose, the inner list tight: ```````````````````````````````` example * foo * bar baz .
    • foo

      • bar

      baz

    ```````````````````````````````` ```````````````````````````````` example - a - b - c - d - e - f .
    • a

      • b
      • c
    • d

      • e
      • f
    ```````````````````````````````` # Inlines Inlines are parsed sequentially from the beginning of the character stream to the end (left to right, in left-to-right languages). Thus, for example, in ```````````````````````````````` example `hi`lo` .

    hilo`

    ```````````````````````````````` `hi` is parsed as code, leaving the backtick at the end as a literal backtick. ## Backslash escapes Any ASCII punctuation character may be backslash-escaped: ```````````````````````````````` example \!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\`\{\|\}\~ .

    !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

    ```````````````````````````````` Backslashes before other characters are treated as literal backslashes: ```````````````````````````````` example \→\A\a\ \3\φ\« .

    \→\A\a\ \3\φ\«

    ```````````````````````````````` Escaped characters are treated as regular characters and do not have their usual Markdown meanings: ```````````````````````````````` example \*not emphasized* \
    not a tag \[not a link](/foo) \`not code` 1\. not a list \* not a list \# not a heading \[foo]: /url "not a reference" \ö not a character entity .

    *not emphasized* <br/> not a tag [not a link](/foo) `not code` 1. not a list * not a list # not a heading [foo]: /url "not a reference" &ouml; not a character entity

    ```````````````````````````````` If a backslash is itself escaped, the following character is not: ```````````````````````````````` example \\*emphasis* .

    \emphasis

    ```````````````````````````````` A backslash at the end of the line is a [hard line break]: ```````````````````````````````` example foo\ bar .

    foo
    bar

    ```````````````````````````````` Backslash escapes do not work in code blocks, code spans, autolinks, or raw HTML: ```````````````````````````````` example `` \[\` `` .

    \[\`

    ```````````````````````````````` ```````````````````````````````` example \[\] .
    \[\]
    
    ```````````````````````````````` ```````````````````````````````` example ~~~ \[\] ~~~ .
    \[\]
    
    ```````````````````````````````` ```````````````````````````````` example .

    http://example.com?find=\*

    ```````````````````````````````` ```````````````````````````````` example . ```````````````````````````````` But they work in all other contexts, including URLs and link titles, link references, and [info strings] in [fenced code blocks]: ```````````````````````````````` example [foo](/bar\* "ti\*tle") .

    foo

    ```````````````````````````````` ```````````````````````````````` example [foo] [foo]: /bar\* "ti\*tle" .

    foo

    ```````````````````````````````` ```````````````````````````````` example ``` foo\+bar foo ``` .
    foo
    
    ```````````````````````````````` ## Entity and numeric character references Valid HTML entity references and numeric character references can be used in place of the corresponding Unicode character, with the following exceptions: - Entity and character references are not recognized in code blocks and code spans. - Entity and character references cannot stand in place of special characters that define structural elements in CommonMark. For example, although `*` can be used in place of a literal `*` character, `*` cannot replace `*` in emphasis delimiters, bullet list markers, or thematic breaks. Conforming CommonMark parsers need not store information about whether a particular character was represented in the source using a Unicode character or an entity reference. [Entity references](@) consist of `&` + any of the valid HTML5 entity names + `;`. The document is used as an authoritative source for the valid entity references and their corresponding code points. ```````````````````````````````` example   & © Æ Ď ¾ ℋ ⅆ ∲ ≧̸ .

      & © Æ Ď ¾ ℋ ⅆ ∲ ≧̸

    ```````````````````````````````` [Decimal numeric character references](@) consist of `&#` + a string of 1--7 arabic digits + `;`. A numeric character reference is parsed as the corresponding Unicode character. Invalid Unicode code points will be replaced by the REPLACEMENT CHARACTER (`U+FFFD`). For security reasons, the code point `U+0000` will also be replaced by `U+FFFD`. ```````````````````````````````` example # Ӓ Ϡ � .

    # Ӓ Ϡ �

    ```````````````````````````````` [Hexadecimal numeric character references](@) consist of `&#` + either `X` or `x` + a string of 1-6 hexadecimal digits + `;`. They too are parsed as the corresponding Unicode character (this time specified with a hexadecimal numeral instead of decimal). ```````````````````````````````` example " ആ ಫ .

    " ആ ಫ

    ```````````````````````````````` Here are some nonentities: ```````````````````````````````` example   &x; &#; &#x; � &#abcdef0; &ThisIsNotDefined; &hi?; .

    &nbsp &x; &#; &#x; &#87654321; &#abcdef0; &ThisIsNotDefined; &hi?;

    ```````````````````````````````` Although HTML5 does accept some entity references without a trailing semicolon (such as `©`), these are not recognized here, because it makes the grammar too ambiguous: ```````````````````````````````` example © .

    &copy

    ```````````````````````````````` Strings that are not on the list of HTML5 named entities are not recognized as entity references either: ```````````````````````````````` example &MadeUpEntity; .

    &MadeUpEntity;

    ```````````````````````````````` Entity and numeric character references are recognized in any context besides code spans or code blocks, including URLs, [link titles], and [fenced code block][] [info strings]: ```````````````````````````````` example . ```````````````````````````````` ```````````````````````````````` example [foo](/föö "föö") .

    foo

    ```````````````````````````````` ```````````````````````````````` example [foo] [foo]: /föö "föö" .

    foo

    ```````````````````````````````` ```````````````````````````````` example ``` föö foo ``` .
    foo
    
    ```````````````````````````````` Entity and numeric character references are treated as literal text in code spans and code blocks: ```````````````````````````````` example `föö` .

    f&ouml;&ouml;

    ```````````````````````````````` ```````````````````````````````` example föfö .
    f&ouml;f&ouml;
    
    ```````````````````````````````` Entity and numeric character references cannot be used in place of symbols indicating structure in CommonMark documents. ```````````````````````````````` example *foo* *foo* .

    *foo* foo

    ```````````````````````````````` ```````````````````````````````` example * foo * foo .

    * foo

    • foo
    ```````````````````````````````` ```````````````````````````````` example foo bar .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example foo .

    →foo

    ```````````````````````````````` ```````````````````````````````` example [a](url "tit") .

    [a](url "tit")

    ```````````````````````````````` ## Code spans A [backtick string](@) is a string of one or more backtick characters (`` ` ``) that is neither preceded nor followed by a backtick. A [code span](@) begins with a backtick string and ends with a backtick string of equal length. The contents of the code span are the characters between the two backtick strings, normalized in the following ways: - First, [line endings] are converted to [spaces]. - If the resulting string both begins *and* ends with a [space] character, but does not consist entirely of [space] characters, a single [space] character is removed from the front and back. This allows you to include code that begins or ends with backtick characters, which must be separated by whitespace from the opening or closing backtick strings. This is a simple code span: ```````````````````````````````` example `foo` .

    foo

    ```````````````````````````````` Here two backticks are used, because the code contains a backtick. This example also illustrates stripping of a single leading and trailing space: ```````````````````````````````` example `` foo ` bar `` .

    foo ` bar

    ```````````````````````````````` This example shows the motivation for stripping leading and trailing spaces: ```````````````````````````````` example ` `` ` .

    ``

    ```````````````````````````````` Note that only *one* space is stripped: ```````````````````````````````` example ` `` ` .

    ``

    ```````````````````````````````` The stripping only happens if the space is on both sides of the string: ```````````````````````````````` example ` a` .

    a

    ```````````````````````````````` Only [spaces], and not [unicode whitespace] in general, are stripped in this way: ```````````````````````````````` example ` b ` .

     b 

    ```````````````````````````````` No stripping occurs if the code span contains only spaces: ```````````````````````````````` example ` ` ` ` .

     

    ```````````````````````````````` [Line endings] are treated like spaces: ```````````````````````````````` example `` foo bar baz `` .

    foo bar baz

    ```````````````````````````````` ```````````````````````````````` example `` foo `` .

    foo

    ```````````````````````````````` Interior spaces are not collapsed: ```````````````````````````````` example `foo bar baz` .

    foo bar baz

    ```````````````````````````````` Note that browsers will typically collapse consecutive spaces when rendering `` elements, so it is recommended that the following CSS be used: code{white-space: pre-wrap;} Note that backslash escapes do not work in code spans. All backslashes are treated literally: ```````````````````````````````` example `foo\`bar` .

    foo\bar`

    ```````````````````````````````` Backslash escapes are never needed, because one can always choose a string of *n* backtick characters as delimiters, where the code does not contain any strings of exactly *n* backtick characters. ```````````````````````````````` example ``foo`bar`` .

    foo`bar

    ```````````````````````````````` ```````````````````````````````` example ` foo `` bar ` .

    foo `` bar

    ```````````````````````````````` Code span backticks have higher precedence than any other inline constructs except HTML tags and autolinks. Thus, for example, this is not parsed as emphasized text, since the second `*` is part of a code span: ```````````````````````````````` example *foo`*` .

    *foo*

    ```````````````````````````````` And this is not parsed as a link: ```````````````````````````````` example [not a `link](/foo`) .

    [not a link](/foo)

    ```````````````````````````````` Code spans, HTML tags, and autolinks have the same precedence. Thus, this is code: ```````````````````````````````` example `` .

    <a href="">`

    ```````````````````````````````` But this is an HTML tag: ```````````````````````````````` example
    ` .

    `

    ```````````````````````````````` And this is code: ```````````````````````````````` example `` .

    <http://foo.bar.baz>`

    ```````````````````````````````` But this is an autolink: ```````````````````````````````` example ` .

    http://foo.bar.`baz`

    ```````````````````````````````` When a backtick string is not closed by a matching backtick string, we just have literal backticks: ```````````````````````````````` example ```foo`` .

    ```foo``

    ```````````````````````````````` ```````````````````````````````` example `foo .

    `foo

    ```````````````````````````````` The following case also illustrates the need for opening and closing backtick strings to be equal in length: ```````````````````````````````` example `foo``bar`` .

    `foobar

    ```````````````````````````````` ## Emphasis and strong emphasis John Gruber's original [Markdown syntax description](http://daringfireball.net/projects/markdown/syntax#em) says: > Markdown treats asterisks (`*`) and underscores (`_`) as indicators of > emphasis. Text wrapped with one `*` or `_` will be wrapped with an HTML > `` tag; double `*`'s or `_`'s will be wrapped with an HTML `` > tag. This is enough for most users, but these rules leave much undecided, especially when it comes to nested emphasis. The original `Markdown.pl` test suite makes it clear that triple `***` and `___` delimiters can be used for strong emphasis, and most implementations have also allowed the following patterns: ``` markdown ***strong emph*** ***strong** in emph* ***emph* in strong** **in strong *emph*** *in emph **strong*** ``` The following patterns are less widely supported, but the intent is clear and they are useful (especially in contexts like bibliography entries): ``` markdown *emph *with emph* in it* **strong **with strong** in it** ``` Many implementations have also restricted intraword emphasis to the `*` forms, to avoid unwanted emphasis in words containing internal underscores. (It is best practice to put these in code spans, but users often do not.) ``` markdown internal emphasis: foo*bar*baz no emphasis: foo_bar_baz ``` The rules given below capture all of these patterns, while allowing for efficient parsing strategies that do not backtrack. First, some definitions. A [delimiter run](@) is either a sequence of one or more `*` characters that is not preceded or followed by a non-backslash-escaped `*` character, or a sequence of one or more `_` characters that is not preceded or followed by a non-backslash-escaped `_` character. A [left-flanking delimiter run](@) is a [delimiter run] that is (1) not followed by [Unicode whitespace], and either (2a) not followed by a [punctuation character], or (2b) followed by a [punctuation character] and preceded by [Unicode whitespace] or a [punctuation character]. For purposes of this definition, the beginning and the end of the line count as Unicode whitespace. A [right-flanking delimiter run](@) is a [delimiter run] that is (1) not preceded by [Unicode whitespace], and either (2a) not preceded by a [punctuation character], or (2b) preceded by a [punctuation character] and followed by [Unicode whitespace] or a [punctuation character]. For purposes of this definition, the beginning and the end of the line count as Unicode whitespace. Here are some examples of delimiter runs. - left-flanking but not right-flanking: ``` ***abc _abc **"abc" _"abc" ``` - right-flanking but not left-flanking: ``` abc*** abc_ "abc"** "abc"_ ``` - Both left and right-flanking: ``` abc***def "abc"_"def" ``` - Neither left nor right-flanking: ``` abc *** def a _ b ``` (The idea of distinguishing left-flanking and right-flanking delimiter runs based on the character before and the character after comes from Roopesh Chander's [vfmd](http://www.vfmd.org/vfmd-spec/specification/#procedure-for-identifying-emphasis-tags). vfmd uses the terminology "emphasis indicator string" instead of "delimiter run," and its rules for distinguishing left- and right-flanking runs are a bit more complex than the ones given here.) The following rules define emphasis and strong emphasis: 1. A single `*` character [can open emphasis](@) iff (if and only if) it is part of a [left-flanking delimiter run]. 2. A single `_` character [can open emphasis] iff it is part of a [left-flanking delimiter run] and either (a) not part of a [right-flanking delimiter run] or (b) part of a [right-flanking delimiter run] preceded by punctuation. 3. A single `*` character [can close emphasis](@) iff it is part of a [right-flanking delimiter run]. 4. A single `_` character [can close emphasis] iff it is part of a [right-flanking delimiter run] and either (a) not part of a [left-flanking delimiter run] or (b) part of a [left-flanking delimiter run] followed by punctuation. 5. A double `**` [can open strong emphasis](@) iff it is part of a [left-flanking delimiter run]. 6. A double `__` [can open strong emphasis] iff it is part of a [left-flanking delimiter run] and either (a) not part of a [right-flanking delimiter run] or (b) part of a [right-flanking delimiter run] preceded by punctuation. 7. A double `**` [can close strong emphasis](@) iff it is part of a [right-flanking delimiter run]. 8. A double `__` [can close strong emphasis] iff it is part of a [right-flanking delimiter run] and either (a) not part of a [left-flanking delimiter run] or (b) part of a [left-flanking delimiter run] followed by punctuation. 9. Emphasis begins with a delimiter that [can open emphasis] and ends with a delimiter that [can close emphasis], and that uses the same character (`_` or `*`) as the opening delimiter. The opening and closing delimiters must belong to separate [delimiter runs]. If one of the delimiters can both open and close emphasis, then the sum of the lengths of the delimiter runs containing the opening and closing delimiters must not be a multiple of 3 unless both lengths are multiples of 3. 10. Strong emphasis begins with a delimiter that [can open strong emphasis] and ends with a delimiter that [can close strong emphasis], and that uses the same character (`_` or `*`) as the opening delimiter. The opening and closing delimiters must belong to separate [delimiter runs]. If one of the delimiters can both open and close strong emphasis, then the sum of the lengths of the delimiter runs containing the opening and closing delimiters must not be a multiple of 3 unless both lengths are multiples of 3. 11. A literal `*` character cannot occur at the beginning or end of `*`-delimited emphasis or `**`-delimited strong emphasis, unless it is backslash-escaped. 12. A literal `_` character cannot occur at the beginning or end of `_`-delimited emphasis or `__`-delimited strong emphasis, unless it is backslash-escaped. Where rules 1--12 above are compatible with multiple parsings, the following principles resolve ambiguity: 13. The number of nestings should be minimized. Thus, for example, an interpretation `...` is always preferred to `...`. 14. An interpretation `...` is always preferred to `...`. 15. When two potential emphasis or strong emphasis spans overlap, so that the second begins before the first ends and ends after the first ends, the first takes precedence. Thus, for example, `*foo _bar* baz_` is parsed as `foo _bar baz_` rather than `*foo bar* baz`. 16. When there are two potential emphasis or strong emphasis spans with the same closing delimiter, the shorter one (the one that opens later) takes precedence. Thus, for example, `**foo **bar baz**` is parsed as `**foo bar baz` rather than `foo **bar baz`. 17. Inline code spans, links, images, and HTML tags group more tightly than emphasis. So, when there is a choice between an interpretation that contains one of these elements and one that does not, the former always wins. Thus, for example, `*[foo*](bar)` is parsed as `*foo*` rather than as `[foo](bar)`. These rules can be illustrated through a series of examples. Rule 1: ```````````````````````````````` example *foo bar* .

    foo bar

    ```````````````````````````````` This is not emphasis, because the opening `*` is followed by whitespace, and hence not part of a [left-flanking delimiter run]: ```````````````````````````````` example a * foo bar* .

    a * foo bar*

    ```````````````````````````````` This is not emphasis, because the opening `*` is preceded by an alphanumeric and followed by punctuation, and hence not part of a [left-flanking delimiter run]: ```````````````````````````````` example a*"foo"* .

    a*"foo"*

    ```````````````````````````````` Unicode nonbreaking spaces count as whitespace, too: ```````````````````````````````` example * a * .

    * a *

    ```````````````````````````````` Intraword emphasis with `*` is permitted: ```````````````````````````````` example foo*bar* .

    foobar

    ```````````````````````````````` ```````````````````````````````` example 5*6*78 .

    5678

    ```````````````````````````````` Rule 2: ```````````````````````````````` example _foo bar_ .

    foo bar

    ```````````````````````````````` This is not emphasis, because the opening `_` is followed by whitespace: ```````````````````````````````` example _ foo bar_ .

    _ foo bar_

    ```````````````````````````````` This is not emphasis, because the opening `_` is preceded by an alphanumeric and followed by punctuation: ```````````````````````````````` example a_"foo"_ .

    a_"foo"_

    ```````````````````````````````` Emphasis with `_` is not allowed inside words: ```````````````````````````````` example foo_bar_ .

    foo_bar_

    ```````````````````````````````` ```````````````````````````````` example 5_6_78 .

    5_6_78

    ```````````````````````````````` ```````````````````````````````` example пристаням_стремятся_ .

    пристаням_стремятся_

    ```````````````````````````````` Here `_` does not generate emphasis, because the first delimiter run is right-flanking and the second left-flanking: ```````````````````````````````` example aa_"bb"_cc .

    aa_"bb"_cc

    ```````````````````````````````` This is emphasis, even though the opening delimiter is both left- and right-flanking, because it is preceded by punctuation: ```````````````````````````````` example foo-_(bar)_ .

    foo-(bar)

    ```````````````````````````````` Rule 3: This is not emphasis, because the closing delimiter does not match the opening delimiter: ```````````````````````````````` example _foo* .

    _foo*

    ```````````````````````````````` This is not emphasis, because the closing `*` is preceded by whitespace: ```````````````````````````````` example *foo bar * .

    *foo bar *

    ```````````````````````````````` A newline also counts as whitespace: ```````````````````````````````` example *foo bar * .

    *foo bar *

    ```````````````````````````````` This is not emphasis, because the second `*` is preceded by punctuation and followed by an alphanumeric (hence it is not part of a [right-flanking delimiter run]: ```````````````````````````````` example *(*foo) .

    *(*foo)

    ```````````````````````````````` The point of this restriction is more easily appreciated with this example: ```````````````````````````````` example *(*foo*)* .

    (foo)

    ```````````````````````````````` Intraword emphasis with `*` is allowed: ```````````````````````````````` example *foo*bar .

    foobar

    ```````````````````````````````` Rule 4: This is not emphasis, because the closing `_` is preceded by whitespace: ```````````````````````````````` example _foo bar _ .

    _foo bar _

    ```````````````````````````````` This is not emphasis, because the second `_` is preceded by punctuation and followed by an alphanumeric: ```````````````````````````````` example _(_foo) .

    _(_foo)

    ```````````````````````````````` This is emphasis within emphasis: ```````````````````````````````` example _(_foo_)_ .

    (foo)

    ```````````````````````````````` Intraword emphasis is disallowed for `_`: ```````````````````````````````` example _foo_bar .

    _foo_bar

    ```````````````````````````````` ```````````````````````````````` example _пристаням_стремятся .

    _пристаням_стремятся

    ```````````````````````````````` ```````````````````````````````` example _foo_bar_baz_ .

    foo_bar_baz

    ```````````````````````````````` This is emphasis, even though the closing delimiter is both left- and right-flanking, because it is followed by punctuation: ```````````````````````````````` example _(bar)_. .

    (bar).

    ```````````````````````````````` Rule 5: ```````````````````````````````` example **foo bar** .

    foo bar

    ```````````````````````````````` This is not strong emphasis, because the opening delimiter is followed by whitespace: ```````````````````````````````` example ** foo bar** .

    ** foo bar**

    ```````````````````````````````` This is not strong emphasis, because the opening `**` is preceded by an alphanumeric and followed by punctuation, and hence not part of a [left-flanking delimiter run]: ```````````````````````````````` example a**"foo"** .

    a**"foo"**

    ```````````````````````````````` Intraword strong emphasis with `**` is permitted: ```````````````````````````````` example foo**bar** .

    foobar

    ```````````````````````````````` Rule 6: ```````````````````````````````` example __foo bar__ .

    foo bar

    ```````````````````````````````` This is not strong emphasis, because the opening delimiter is followed by whitespace: ```````````````````````````````` example __ foo bar__ .

    __ foo bar__

    ```````````````````````````````` A newline counts as whitespace: ```````````````````````````````` example __ foo bar__ .

    __ foo bar__

    ```````````````````````````````` This is not strong emphasis, because the opening `__` is preceded by an alphanumeric and followed by punctuation: ```````````````````````````````` example a__"foo"__ .

    a__"foo"__

    ```````````````````````````````` Intraword strong emphasis is forbidden with `__`: ```````````````````````````````` example foo__bar__ .

    foo__bar__

    ```````````````````````````````` ```````````````````````````````` example 5__6__78 .

    5__6__78

    ```````````````````````````````` ```````````````````````````````` example пристаням__стремятся__ .

    пристаням__стремятся__

    ```````````````````````````````` ```````````````````````````````` example __foo, __bar__, baz__ .

    foo, bar, baz

    ```````````````````````````````` This is strong emphasis, even though the opening delimiter is both left- and right-flanking, because it is preceded by punctuation: ```````````````````````````````` example foo-__(bar)__ .

    foo-(bar)

    ```````````````````````````````` Rule 7: This is not strong emphasis, because the closing delimiter is preceded by whitespace: ```````````````````````````````` example **foo bar ** .

    **foo bar **

    ```````````````````````````````` (Nor can it be interpreted as an emphasized `*foo bar *`, because of Rule 11.) This is not strong emphasis, because the second `**` is preceded by punctuation and followed by an alphanumeric: ```````````````````````````````` example **(**foo) .

    **(**foo)

    ```````````````````````````````` The point of this restriction is more easily appreciated with these examples: ```````````````````````````````` example *(**foo**)* .

    (foo)

    ```````````````````````````````` ```````````````````````````````` example **Gomphocarpus (*Gomphocarpus physocarpus*, syn. *Asclepias physocarpa*)** .

    Gomphocarpus (Gomphocarpus physocarpus, syn. Asclepias physocarpa)

    ```````````````````````````````` ```````````````````````````````` example **foo "*bar*" foo** .

    foo "bar" foo

    ```````````````````````````````` Intraword emphasis: ```````````````````````````````` example **foo**bar .

    foobar

    ```````````````````````````````` Rule 8: This is not strong emphasis, because the closing delimiter is preceded by whitespace: ```````````````````````````````` example __foo bar __ .

    __foo bar __

    ```````````````````````````````` This is not strong emphasis, because the second `__` is preceded by punctuation and followed by an alphanumeric: ```````````````````````````````` example __(__foo) .

    __(__foo)

    ```````````````````````````````` The point of this restriction is more easily appreciated with this example: ```````````````````````````````` example _(__foo__)_ .

    (foo)

    ```````````````````````````````` Intraword strong emphasis is forbidden with `__`: ```````````````````````````````` example __foo__bar .

    __foo__bar

    ```````````````````````````````` ```````````````````````````````` example __пристаням__стремятся .

    __пристаням__стремятся

    ```````````````````````````````` ```````````````````````````````` example __foo__bar__baz__ .

    foo__bar__baz

    ```````````````````````````````` This is strong emphasis, even though the closing delimiter is both left- and right-flanking, because it is followed by punctuation: ```````````````````````````````` example __(bar)__. .

    (bar).

    ```````````````````````````````` Rule 9: Any nonempty sequence of inline elements can be the contents of an emphasized span. ```````````````````````````````` example *foo [bar](/url)* .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example *foo bar* .

    foo bar

    ```````````````````````````````` In particular, emphasis and strong emphasis can be nested inside emphasis: ```````````````````````````````` example _foo __bar__ baz_ .

    foo bar baz

    ```````````````````````````````` ```````````````````````````````` example _foo _bar_ baz_ .

    foo bar baz

    ```````````````````````````````` ```````````````````````````````` example __foo_ bar_ .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example *foo *bar** .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example *foo **bar** baz* .

    foo bar baz

    ```````````````````````````````` ```````````````````````````````` example *foo**bar**baz* .

    foobarbaz

    ```````````````````````````````` Note that in the preceding case, the interpretation ``` markdown

    foobarbaz

    ``` is precluded by the condition that a delimiter that can both open and close (like the `*` after `foo`) cannot form emphasis if the sum of the lengths of the delimiter runs containing the opening and closing delimiters is a multiple of 3 unless both lengths are multiples of 3. For the same reason, we don't get two consecutive emphasis sections in this example: ```````````````````````````````` example *foo**bar* .

    foo**bar

    ```````````````````````````````` The same condition ensures that the following cases are all strong emphasis nested inside emphasis, even when the interior spaces are omitted: ```````````````````````````````` example ***foo** bar* .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example *foo **bar*** .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example *foo**bar*** .

    foobar

    ```````````````````````````````` When the lengths of the interior closing and opening delimiter runs are *both* multiples of 3, though, they can match to create emphasis: ```````````````````````````````` example foo***bar***baz .

    foobarbaz

    ```````````````````````````````` ```````````````````````````````` example foo******bar*********baz .

    foobar***baz

    ```````````````````````````````` Indefinite levels of nesting are possible: ```````````````````````````````` example *foo **bar *baz* bim** bop* .

    foo bar baz bim bop

    ```````````````````````````````` ```````````````````````````````` example *foo [*bar*](/url)* .

    foo bar

    ```````````````````````````````` There can be no empty emphasis or strong emphasis: ```````````````````````````````` example ** is not an empty emphasis .

    ** is not an empty emphasis

    ```````````````````````````````` ```````````````````````````````` example **** is not an empty strong emphasis .

    **** is not an empty strong emphasis

    ```````````````````````````````` Rule 10: Any nonempty sequence of inline elements can be the contents of an strongly emphasized span. ```````````````````````````````` example **foo [bar](/url)** .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example **foo bar** .

    foo bar

    ```````````````````````````````` In particular, emphasis and strong emphasis can be nested inside strong emphasis: ```````````````````````````````` example __foo _bar_ baz__ .

    foo bar baz

    ```````````````````````````````` ```````````````````````````````` example __foo __bar__ baz__ .

    foo bar baz

    ```````````````````````````````` ```````````````````````````````` example ____foo__ bar__ .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example **foo **bar**** .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example **foo *bar* baz** .

    foo bar baz

    ```````````````````````````````` ```````````````````````````````` example **foo*bar*baz** .

    foobarbaz

    ```````````````````````````````` ```````````````````````````````` example ***foo* bar** .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example **foo *bar*** .

    foo bar

    ```````````````````````````````` Indefinite levels of nesting are possible: ```````````````````````````````` example **foo *bar **baz** bim* bop** .

    foo bar baz bim bop

    ```````````````````````````````` ```````````````````````````````` example **foo [*bar*](/url)** .

    foo bar

    ```````````````````````````````` There can be no empty emphasis or strong emphasis: ```````````````````````````````` example __ is not an empty emphasis .

    __ is not an empty emphasis

    ```````````````````````````````` ```````````````````````````````` example ____ is not an empty strong emphasis .

    ____ is not an empty strong emphasis

    ```````````````````````````````` Rule 11: ```````````````````````````````` example foo *** .

    foo ***

    ```````````````````````````````` ```````````````````````````````` example foo *\** .

    foo *

    ```````````````````````````````` ```````````````````````````````` example foo *_* .

    foo _

    ```````````````````````````````` ```````````````````````````````` example foo ***** .

    foo *****

    ```````````````````````````````` ```````````````````````````````` example foo **\*** .

    foo *

    ```````````````````````````````` ```````````````````````````````` example foo **_** .

    foo _

    ```````````````````````````````` Note that when delimiters do not match evenly, Rule 11 determines that the excess literal `*` characters will appear outside of the emphasis, rather than inside it: ```````````````````````````````` example **foo* .

    *foo

    ```````````````````````````````` ```````````````````````````````` example *foo** .

    foo*

    ```````````````````````````````` ```````````````````````````````` example ***foo** .

    *foo

    ```````````````````````````````` ```````````````````````````````` example ****foo* .

    ***foo

    ```````````````````````````````` ```````````````````````````````` example **foo*** .

    foo*

    ```````````````````````````````` ```````````````````````````````` example *foo**** .

    foo***

    ```````````````````````````````` Rule 12: ```````````````````````````````` example foo ___ .

    foo ___

    ```````````````````````````````` ```````````````````````````````` example foo _\__ .

    foo _

    ```````````````````````````````` ```````````````````````````````` example foo _*_ .

    foo *

    ```````````````````````````````` ```````````````````````````````` example foo _____ .

    foo _____

    ```````````````````````````````` ```````````````````````````````` example foo __\___ .

    foo _

    ```````````````````````````````` ```````````````````````````````` example foo __*__ .

    foo *

    ```````````````````````````````` ```````````````````````````````` example __foo_ .

    _foo

    ```````````````````````````````` Note that when delimiters do not match evenly, Rule 12 determines that the excess literal `_` characters will appear outside of the emphasis, rather than inside it: ```````````````````````````````` example _foo__ .

    foo_

    ```````````````````````````````` ```````````````````````````````` example ___foo__ .

    _foo

    ```````````````````````````````` ```````````````````````````````` example ____foo_ .

    ___foo

    ```````````````````````````````` ```````````````````````````````` example __foo___ .

    foo_

    ```````````````````````````````` ```````````````````````````````` example _foo____ .

    foo___

    ```````````````````````````````` Rule 13 implies that if you want emphasis nested directly inside emphasis, you must use different delimiters: ```````````````````````````````` example **foo** .

    foo

    ```````````````````````````````` ```````````````````````````````` example *_foo_* .

    foo

    ```````````````````````````````` ```````````````````````````````` example __foo__ .

    foo

    ```````````````````````````````` ```````````````````````````````` example _*foo*_ .

    foo

    ```````````````````````````````` However, strong emphasis within strong emphasis is possible without switching delimiters: ```````````````````````````````` example ****foo**** .

    foo

    ```````````````````````````````` ```````````````````````````````` example ____foo____ .

    foo

    ```````````````````````````````` Rule 13 can be applied to arbitrarily long sequences of delimiters: ```````````````````````````````` example ******foo****** .

    foo

    ```````````````````````````````` Rule 14: ```````````````````````````````` example ***foo*** .

    foo

    ```````````````````````````````` ```````````````````````````````` example _____foo_____ .

    foo

    ```````````````````````````````` Rule 15: ```````````````````````````````` example *foo _bar* baz_ .

    foo _bar baz_

    ```````````````````````````````` ```````````````````````````````` example *foo __bar *baz bim__ bam* .

    foo bar *baz bim bam

    ```````````````````````````````` Rule 16: ```````````````````````````````` example **foo **bar baz** .

    **foo bar baz

    ```````````````````````````````` ```````````````````````````````` example *foo *bar baz* .

    *foo bar baz

    ```````````````````````````````` Rule 17: ```````````````````````````````` example *[bar*](/url) .

    *bar*

    ```````````````````````````````` ```````````````````````````````` example _foo [bar_](/url) .

    _foo bar_

    ```````````````````````````````` ```````````````````````````````` example * .

    *

    ```````````````````````````````` ```````````````````````````````` example ** .

    **

    ```````````````````````````````` ```````````````````````````````` example __ .

    __

    ```````````````````````````````` ```````````````````````````````` example *a `*`* .

    a *

    ```````````````````````````````` ```````````````````````````````` example _a `_`_ .

    a _

    ```````````````````````````````` ```````````````````````````````` example **a .

    **ahttp://foo.bar/?q=**

    ```````````````````````````````` ```````````````````````````````` example __a .

    __ahttp://foo.bar/?q=__

    ```````````````````````````````` ## Links A link contains [link text] (the visible text), a [link destination] (the URI that is the link destination), and optionally a [link title]. There are two basic kinds of links in Markdown. In [inline links] the destination and title are given immediately after the link text. In [reference links] the destination and title are defined elsewhere in the document. A [link text](@) consists of a sequence of zero or more inline elements enclosed by square brackets (`[` and `]`). The following rules apply: - Links may not contain other links, at any level of nesting. If multiple otherwise valid link definitions appear nested inside each other, the inner-most definition is used. - Brackets are allowed in the [link text] only if (a) they are backslash-escaped or (b) they appear as a matched pair of brackets, with an open bracket `[`, a sequence of zero or more inlines, and a close bracket `]`. - Backtick [code spans], [autolinks], and raw [HTML tags] bind more tightly than the brackets in link text. Thus, for example, `` [foo`]` `` could not be a link text, since the second `]` is part of a code span. - The brackets in link text bind more tightly than markers for [emphasis and strong emphasis]. Thus, for example, `*[foo*](url)` is a link. A [link destination](@) consists of either - a sequence of zero or more characters between an opening `<` and a closing `>` that contains no line breaks or unescaped `<` or `>` characters, or - a nonempty sequence of characters that does not start with `<`, does not include ASCII space or control characters, and includes parentheses only if (a) they are backslash-escaped or (b) they are part of a balanced pair of unescaped parentheses. (Implementations may impose limits on parentheses nesting to avoid performance issues, but at least three levels of nesting should be supported.) A [link title](@) consists of either - a sequence of zero or more characters between straight double-quote characters (`"`), including a `"` character only if it is backslash-escaped, or - a sequence of zero or more characters between straight single-quote characters (`'`), including a `'` character only if it is backslash-escaped, or - a sequence of zero or more characters between matching parentheses (`(...)`), including a `(` or `)` character only if it is backslash-escaped. Although [link titles] may span multiple lines, they may not contain a [blank line]. An [inline link](@) consists of a [link text] followed immediately by a left parenthesis `(`, optional [whitespace], an optional [link destination], an optional [link title] separated from the link destination by [whitespace], optional [whitespace], and a right parenthesis `)`. The link's text consists of the inlines contained in the [link text] (excluding the enclosing square brackets). The link's URI consists of the link destination, excluding enclosing `<...>` if present, with backslash-escapes in effect as described above. The link's title consists of the link title, excluding its enclosing delimiters, with backslash-escapes in effect as described above. Here is a simple inline link: ```````````````````````````````` example [link](/uri "title") .

    link

    ```````````````````````````````` The title may be omitted: ```````````````````````````````` example [link](/uri) .

    link

    ```````````````````````````````` Both the title and the destination may be omitted: ```````````````````````````````` example [link]() .

    link

    ```````````````````````````````` ```````````````````````````````` example [link](<>) .

    link

    ```````````````````````````````` The destination can only contain spaces if it is enclosed in pointy brackets: ```````````````````````````````` example [link](/my uri) .

    [link](/my uri)

    ```````````````````````````````` ```````````````````````````````` example [link](
    ) .

    link

    ```````````````````````````````` The destination cannot contain line breaks, even if enclosed in pointy brackets: ```````````````````````````````` example [link](foo bar) .

    [link](foo bar)

    ```````````````````````````````` ```````````````````````````````` example [link]() .

    [link]()

    ```````````````````````````````` The destination can contain `)` if it is enclosed in pointy brackets: ```````````````````````````````` example [a]() .

    a

    ```````````````````````````````` Pointy brackets that enclose links must be unescaped: ```````````````````````````````` example [link]() .

    [link](<foo>)

    ```````````````````````````````` These are not links, because the opening pointy bracket is not matched properly: ```````````````````````````````` example [a]( [a](c) .

    [a](<b)c [a](<b)c> [a](c)

    ```````````````````````````````` Parentheses inside the link destination may be escaped: ```````````````````````````````` example [link](\(foo\)) .

    link

    ```````````````````````````````` Any number of parentheses are allowed without escaping, as long as they are balanced: ```````````````````````````````` example [link](foo(and(bar))) .

    link

    ```````````````````````````````` However, if you have unbalanced parentheses, you need to escape or use the `<...>` form: ```````````````````````````````` example [link](foo\(and\(bar\)) .

    link

    ```````````````````````````````` ```````````````````````````````` example [link]() .

    link

    ```````````````````````````````` Parentheses and other symbols can also be escaped, as usual in Markdown: ```````````````````````````````` example [link](foo\)\:) .

    link

    ```````````````````````````````` A link can contain fragment identifiers and queries: ```````````````````````````````` example [link](#fragment) [link](http://example.com#fragment) [link](http://example.com?foo=3#frag) .

    link

    link

    link

    ```````````````````````````````` Note that a backslash before a non-escapable character is just a backslash: ```````````````````````````````` example [link](foo\bar) .

    link

    ```````````````````````````````` URL-escaping should be left alone inside the destination, as all URL-escaped characters are also valid URL characters. Entity and numerical character references in the destination will be parsed into the corresponding Unicode code points, as usual. These may be optionally URL-escaped when written as HTML, but this spec does not enforce any particular policy for rendering URLs in HTML or other formats. Renderers may make different decisions about how to escape or normalize URLs in the output. ```````````````````````````````` example [link](foo%20bä) .

    link

    ```````````````````````````````` Note that, because titles can often be parsed as destinations, if you try to omit the destination and keep the title, you'll get unexpected results: ```````````````````````````````` example [link]("title") .

    link

    ```````````````````````````````` Titles may be in single quotes, double quotes, or parentheses: ```````````````````````````````` example [link](/url "title") [link](/url 'title') [link](/url (title)) .

    link link link

    ```````````````````````````````` Backslash escapes and entity and numeric character references may be used in titles: ```````````````````````````````` example [link](/url "title \""") .

    link

    ```````````````````````````````` Titles must be separated from the link using a [whitespace]. Other [Unicode whitespace] like non-breaking space doesn't work. ```````````````````````````````` example [link](/url "title") .

    link

    ```````````````````````````````` Nested balanced quotes are not allowed without escaping: ```````````````````````````````` example [link](/url "title "and" title") .

    [link](/url "title "and" title")

    ```````````````````````````````` But it is easy to work around this by using a different quote type: ```````````````````````````````` example [link](/url 'title "and" title') .

    link

    ```````````````````````````````` (Note: `Markdown.pl` did allow double quotes inside a double-quoted title, and its test suite included a test demonstrating this. But it is hard to see a good rationale for the extra complexity this brings, since there are already many ways---backslash escaping, entity and numeric character references, or using a different quote type for the enclosing title---to write titles containing double quotes. `Markdown.pl`'s handling of titles has a number of other strange features. For example, it allows single-quoted titles in inline links, but not reference links. And, in reference links but not inline links, it allows a title to begin with `"` and end with `)`. `Markdown.pl` 1.0.1 even allows titles with no closing quotation mark, though 1.0.2b8 does not. It seems preferable to adopt a simple, rational rule that works the same way in inline links and link reference definitions.) [Whitespace] is allowed around the destination and title: ```````````````````````````````` example [link]( /uri "title" ) .

    link

    ```````````````````````````````` But it is not allowed between the link text and the following parenthesis: ```````````````````````````````` example [link] (/uri) .

    [link] (/uri)

    ```````````````````````````````` The link text may contain balanced brackets, but not unbalanced ones, unless they are escaped: ```````````````````````````````` example [link [foo [bar]]](/uri) .

    link [foo [bar]]

    ```````````````````````````````` ```````````````````````````````` example [link] bar](/uri) .

    [link] bar](/uri)

    ```````````````````````````````` ```````````````````````````````` example [link [bar](/uri) .

    [link bar

    ```````````````````````````````` ```````````````````````````````` example [link \[bar](/uri) .

    link [bar

    ```````````````````````````````` The link text may contain inline content: ```````````````````````````````` example [link *foo **bar** `#`*](/uri) .

    link foo bar #

    ```````````````````````````````` ```````````````````````````````` example [![moon](moon.jpg)](/uri) .

    moon

    ```````````````````````````````` However, links may not contain other links, at any level of nesting. ```````````````````````````````` example [foo [bar](/uri)](/uri) .

    [foo bar](/uri)

    ```````````````````````````````` ```````````````````````````````` example [foo *[bar [baz](/uri)](/uri)*](/uri) .

    [foo [bar baz](/uri)](/uri)

    ```````````````````````````````` ```````````````````````````````` example ![[[foo](uri1)](uri2)](uri3) .

    [foo](uri2)

    ```````````````````````````````` These cases illustrate the precedence of link text grouping over emphasis grouping: ```````````````````````````````` example *[foo*](/uri) .

    *foo*

    ```````````````````````````````` ```````````````````````````````` example [foo *bar](baz*) .

    foo *bar

    ```````````````````````````````` Note that brackets that *aren't* part of links do not take precedence: ```````````````````````````````` example *foo [bar* baz] .

    foo [bar baz]

    ```````````````````````````````` These cases illustrate the precedence of HTML tags, code spans, and autolinks over link grouping: ```````````````````````````````` example [foo .

    [foo

    ```````````````````````````````` ```````````````````````````````` example [foo`](/uri)` .

    [foo](/uri)

    ```````````````````````````````` ```````````````````````````````` example [foo .

    [foohttp://example.com/?search=](uri)

    ```````````````````````````````` There are three kinds of [reference link](@)s: [full](#full-reference-link), [collapsed](#collapsed-reference-link), and [shortcut](#shortcut-reference-link). A [full reference link](@) consists of a [link text] immediately followed by a [link label] that [matches] a [link reference definition] elsewhere in the document. A [link label](@) begins with a left bracket (`[`) and ends with the first right bracket (`]`) that is not backslash-escaped. Between these brackets there must be at least one [non-whitespace character]. Unescaped square bracket characters are not allowed inside the opening and closing square brackets of [link labels]. A link label can have at most 999 characters inside the square brackets. One label [matches](@) another just in case their normalized forms are equal. To normalize a label, strip off the opening and closing brackets, perform the *Unicode case fold*, strip leading and trailing [whitespace] and collapse consecutive internal [whitespace] to a single space. If there are multiple matching reference link definitions, the one that comes first in the document is used. (It is desirable in such cases to emit a warning.) The contents of the first link label are parsed as inlines, which are used as the link's text. The link's URI and title are provided by the matching [link reference definition]. Here is a simple example: ```````````````````````````````` example [foo][bar] [bar]: /url "title" .

    foo

    ```````````````````````````````` The rules for the [link text] are the same as with [inline links]. Thus: The link text may contain balanced brackets, but not unbalanced ones, unless they are escaped: ```````````````````````````````` example [link [foo [bar]]][ref] [ref]: /uri .

    link [foo [bar]]

    ```````````````````````````````` ```````````````````````````````` example [link \[bar][ref] [ref]: /uri .

    link [bar

    ```````````````````````````````` The link text may contain inline content: ```````````````````````````````` example [link *foo **bar** `#`*][ref] [ref]: /uri .

    link foo bar #

    ```````````````````````````````` ```````````````````````````````` example [![moon](moon.jpg)][ref] [ref]: /uri .

    moon

    ```````````````````````````````` However, links may not contain other links, at any level of nesting. ```````````````````````````````` example [foo [bar](/uri)][ref] [ref]: /uri .

    [foo bar]ref

    ```````````````````````````````` ```````````````````````````````` example [foo *bar [baz][ref]*][ref] [ref]: /uri .

    [foo bar baz]ref

    ```````````````````````````````` (In the examples above, we have two [shortcut reference links] instead of one [full reference link].) The following cases illustrate the precedence of link text grouping over emphasis grouping: ```````````````````````````````` example *[foo*][ref] [ref]: /uri .

    *foo*

    ```````````````````````````````` ```````````````````````````````` example [foo *bar][ref] [ref]: /uri .

    foo *bar

    ```````````````````````````````` These cases illustrate the precedence of HTML tags, code spans, and autolinks over link grouping: ```````````````````````````````` example [foo [ref]: /uri .

    [foo

    ```````````````````````````````` ```````````````````````````````` example [foo`][ref]` [ref]: /uri .

    [foo][ref]

    ```````````````````````````````` ```````````````````````````````` example [foo [ref]: /uri .

    [foohttp://example.com/?search=][ref]

    ```````````````````````````````` Matching is case-insensitive: ```````````````````````````````` example [foo][BaR] [bar]: /url "title" .

    foo

    ```````````````````````````````` Unicode case fold is used: ```````````````````````````````` example [Толпой][Толпой] is a Russian word. [ТОЛПОЙ]: /url .

    Толпой is a Russian word.

    ```````````````````````````````` Consecutive internal [whitespace] is treated as one space for purposes of determining matching: ```````````````````````````````` example [Foo bar]: /url [Baz][Foo bar] .

    Baz

    ```````````````````````````````` No [whitespace] is allowed between the [link text] and the [link label]: ```````````````````````````````` example [foo] [bar] [bar]: /url "title" .

    [foo] bar

    ```````````````````````````````` ```````````````````````````````` example [foo] [bar] [bar]: /url "title" .

    [foo] bar

    ```````````````````````````````` This is a departure from John Gruber's original Markdown syntax description, which explicitly allows whitespace between the link text and the link label. It brings reference links in line with [inline links], which (according to both original Markdown and this spec) cannot have whitespace after the link text. More importantly, it prevents inadvertent capture of consecutive [shortcut reference links]. If whitespace is allowed between the link text and the link label, then in the following we will have a single reference link, not two shortcut reference links, as intended: ``` markdown [foo] [bar] [foo]: /url1 [bar]: /url2 ``` (Note that [shortcut reference links] were introduced by Gruber himself in a beta version of `Markdown.pl`, but never included in the official syntax description. Without shortcut reference links, it is harmless to allow space between the link text and link label; but once shortcut references are introduced, it is too dangerous to allow this, as it frequently leads to unintended results.) When there are multiple matching [link reference definitions], the first is used: ```````````````````````````````` example [foo]: /url1 [foo]: /url2 [bar][foo] .

    bar

    ```````````````````````````````` Note that matching is performed on normalized strings, not parsed inline content. So the following does not match, even though the labels define equivalent inline content: ```````````````````````````````` example [bar][foo\!] [foo!]: /url .

    [bar][foo!]

    ```````````````````````````````` [Link labels] cannot contain brackets, unless they are backslash-escaped: ```````````````````````````````` example [foo][ref[] [ref[]: /uri .

    [foo][ref[]

    [ref[]: /uri

    ```````````````````````````````` ```````````````````````````````` example [foo][ref[bar]] [ref[bar]]: /uri .

    [foo][ref[bar]]

    [ref[bar]]: /uri

    ```````````````````````````````` ```````````````````````````````` example [[[foo]]] [[[foo]]]: /url .

    [[[foo]]]

    [[[foo]]]: /url

    ```````````````````````````````` ```````````````````````````````` example [foo][ref\[] [ref\[]: /uri .

    foo

    ```````````````````````````````` Note that in this example `]` is not backslash-escaped: ```````````````````````````````` example [bar\\]: /uri [bar\\] .

    bar\

    ```````````````````````````````` A [link label] must contain at least one [non-whitespace character]: ```````````````````````````````` example [] []: /uri .

    []

    []: /uri

    ```````````````````````````````` ```````````````````````````````` example [ ] [ ]: /uri .

    [ ]

    [ ]: /uri

    ```````````````````````````````` A [collapsed reference link](@) consists of a [link label] that [matches] a [link reference definition] elsewhere in the document, followed by the string `[]`. The contents of the first link label are parsed as inlines, which are used as the link's text. The link's URI and title are provided by the matching reference link definition. Thus, `[foo][]` is equivalent to `[foo][foo]`. ```````````````````````````````` example [foo][] [foo]: /url "title" .

    foo

    ```````````````````````````````` ```````````````````````````````` example [*foo* bar][] [*foo* bar]: /url "title" .

    foo bar

    ```````````````````````````````` The link labels are case-insensitive: ```````````````````````````````` example [Foo][] [foo]: /url "title" .

    Foo

    ```````````````````````````````` As with full reference links, [whitespace] is not allowed between the two sets of brackets: ```````````````````````````````` example [foo] [] [foo]: /url "title" .

    foo []

    ```````````````````````````````` A [shortcut reference link](@) consists of a [link label] that [matches] a [link reference definition] elsewhere in the document and is not followed by `[]` or a link label. The contents of the first link label are parsed as inlines, which are used as the link's text. The link's URI and title are provided by the matching link reference definition. Thus, `[foo]` is equivalent to `[foo][]`. ```````````````````````````````` example [foo] [foo]: /url "title" .

    foo

    ```````````````````````````````` ```````````````````````````````` example [*foo* bar] [*foo* bar]: /url "title" .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example [[*foo* bar]] [*foo* bar]: /url "title" .

    [foo bar]

    ```````````````````````````````` ```````````````````````````````` example [[bar [foo] [foo]: /url .

    [[bar foo

    ```````````````````````````````` The link labels are case-insensitive: ```````````````````````````````` example [Foo] [foo]: /url "title" .

    Foo

    ```````````````````````````````` A space after the link text should be preserved: ```````````````````````````````` example [foo] bar [foo]: /url .

    foo bar

    ```````````````````````````````` If you just want bracketed text, you can backslash-escape the opening bracket to avoid links: ```````````````````````````````` example \[foo] [foo]: /url "title" .

    [foo]

    ```````````````````````````````` Note that this is a link, because a link label ends with the first following closing bracket: ```````````````````````````````` example [foo*]: /url *[foo*] .

    *foo*

    ```````````````````````````````` Full and compact references take precedence over shortcut references: ```````````````````````````````` example [foo][bar] [foo]: /url1 [bar]: /url2 .

    foo

    ```````````````````````````````` ```````````````````````````````` example [foo][] [foo]: /url1 .

    foo

    ```````````````````````````````` Inline links also take precedence: ```````````````````````````````` example [foo]() [foo]: /url1 .

    foo

    ```````````````````````````````` ```````````````````````````````` example [foo](not a link) [foo]: /url1 .

    foo(not a link)

    ```````````````````````````````` In the following case `[bar][baz]` is parsed as a reference, `[foo]` as normal text: ```````````````````````````````` example [foo][bar][baz] [baz]: /url .

    [foo]bar

    ```````````````````````````````` Here, though, `[foo][bar]` is parsed as a reference, since `[bar]` is defined: ```````````````````````````````` example [foo][bar][baz] [baz]: /url1 [bar]: /url2 .

    foobaz

    ```````````````````````````````` Here `[foo]` is not parsed as a shortcut reference, because it is followed by a link label (even though `[bar]` is not defined): ```````````````````````````````` example [foo][bar][baz] [baz]: /url1 [foo]: /url2 .

    [foo]bar

    ```````````````````````````````` ## Images Syntax for images is like the syntax for links, with one difference. Instead of [link text], we have an [image description](@). The rules for this are the same as for [link text], except that (a) an image description starts with `![` rather than `[`, and (b) an image description may contain links. An image description has inline elements as its contents. When an image is rendered to HTML, this is standardly used as the image's `alt` attribute. ```````````````````````````````` example ![foo](/url "title") .

    foo

    ```````````````````````````````` ```````````````````````````````` example ![foo *bar*] [foo *bar*]: train.jpg "train & tracks" .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example ![foo ![bar](/url)](/url2) .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example ![foo [bar](/url)](/url2) .

    foo bar

    ```````````````````````````````` Though this spec is concerned with parsing, not rendering, it is recommended that in rendering to HTML, only the plain string content of the [image description] be used. Note that in the above example, the alt attribute's value is `foo bar`, not `foo [bar](/url)` or `foo bar`. Only the plain string content is rendered, without formatting. ```````````````````````````````` example ![foo *bar*][] [foo *bar*]: train.jpg "train & tracks" .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example ![foo *bar*][foobar] [FOOBAR]: train.jpg "train & tracks" .

    foo bar

    ```````````````````````````````` ```````````````````````````````` example ![foo](train.jpg) .

    foo

    ```````````````````````````````` ```````````````````````````````` example My ![foo bar](/path/to/train.jpg "title" ) .

    My foo bar

    ```````````````````````````````` ```````````````````````````````` example ![foo]() .

    foo

    ```````````````````````````````` ```````````````````````````````` example ![](/url) .

    ```````````````````````````````` Reference-style: ```````````````````````````````` example ![foo][bar] [bar]: /url .

    foo

    ```````````````````````````````` ```````````````````````````````` example ![foo][bar] [BAR]: /url .

    foo

    ```````````````````````````````` Collapsed: ```````````````````````````````` example ![foo][] [foo]: /url "title" .

    foo

    ```````````````````````````````` ```````````````````````````````` example ![*foo* bar][] [*foo* bar]: /url "title" .

    foo bar

    ```````````````````````````````` The labels are case-insensitive: ```````````````````````````````` example ![Foo][] [foo]: /url "title" .

    Foo

    ```````````````````````````````` As with reference links, [whitespace] is not allowed between the two sets of brackets: ```````````````````````````````` example ![foo] [] [foo]: /url "title" .

    foo []

    ```````````````````````````````` Shortcut: ```````````````````````````````` example ![foo] [foo]: /url "title" .

    foo

    ```````````````````````````````` ```````````````````````````````` example ![*foo* bar] [*foo* bar]: /url "title" .

    foo bar

    ```````````````````````````````` Note that link labels cannot contain unescaped brackets: ```````````````````````````````` example ![[foo]] [[foo]]: /url "title" .

    ![[foo]]

    [[foo]]: /url "title"

    ```````````````````````````````` The link labels are case-insensitive: ```````````````````````````````` example ![Foo] [foo]: /url "title" .

    Foo

    ```````````````````````````````` If you just want a literal `!` followed by bracketed text, you can backslash-escape the opening `[`: ```````````````````````````````` example !\[foo] [foo]: /url "title" .

    ![foo]

    ```````````````````````````````` If you want a link after a literal `!`, backslash-escape the `!`: ```````````````````````````````` example \![foo] [foo]: /url "title" .

    !foo

    ```````````````````````````````` ## Autolinks [Autolink](@)s are absolute URIs and email addresses inside `<` and `>`. They are parsed as links, with the URL or email address as the link label. A [URI autolink](@) consists of `<`, followed by an [absolute URI] followed by `>`. It is parsed as a link to the URI, with the URI as the link's label. An [absolute URI](@), for these purposes, consists of a [scheme] followed by a colon (`:`) followed by zero or more characters other than ASCII [whitespace] and control characters, `<`, and `>`. If the URI includes these characters, they must be percent-encoded (e.g. `%20` for a space). For purposes of this spec, a [scheme](@) is any sequence of 2--32 characters beginning with an ASCII letter and followed by any combination of ASCII letters, digits, or the symbols plus ("+"), period ("."), or hyphen ("-"). Here are some valid autolinks: ```````````````````````````````` example .

    http://foo.bar.baz

    ```````````````````````````````` ```````````````````````````````` example .

    http://foo.bar.baz/test?q=hello&id=22&boolean

    ```````````````````````````````` ```````````````````````````````` example .

    irc://foo.bar:2233/baz

    ```````````````````````````````` Uppercase is also fine: ```````````````````````````````` example .

    MAILTO:FOO@BAR.BAZ

    ```````````````````````````````` Note that many strings that count as [absolute URIs] for purposes of this spec are not valid URIs, because their schemes are not registered or because of other problems with their syntax: ```````````````````````````````` example .

    a+b+c:d

    ```````````````````````````````` ```````````````````````````````` example .

    made-up-scheme://foo,bar

    ```````````````````````````````` ```````````````````````````````` example .

    http://../

    ```````````````````````````````` ```````````````````````````````` example .

    localhost:5001/foo

    ```````````````````````````````` Spaces are not allowed in autolinks: ```````````````````````````````` example .

    <http://foo.bar/baz bim>

    ```````````````````````````````` Backslash-escapes do not work inside autolinks: ```````````````````````````````` example .

    http://example.com/\[\

    ```````````````````````````````` An [email autolink](@) consists of `<`, followed by an [email address], followed by `>`. The link's label is the email address, and the URL is `mailto:` followed by the email address. An [email address](@), for these purposes, is anything that matches the [non-normative regex from the HTML5 spec](https://html.spec.whatwg.org/multipage/forms.html#e-mail-state-(type=email)): /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])? (?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ Examples of email autolinks: ```````````````````````````````` example .

    foo@bar.example.com

    ```````````````````````````````` ```````````````````````````````` example .

    foo+special@Bar.baz-bar0.com

    ```````````````````````````````` Backslash-escapes do not work inside email autolinks: ```````````````````````````````` example .

    <foo+@bar.example.com>

    ```````````````````````````````` These are not autolinks: ```````````````````````````````` example <> .

    <>

    ```````````````````````````````` ```````````````````````````````` example < http://foo.bar > .

    < http://foo.bar >

    ```````````````````````````````` ```````````````````````````````` example .

    <m:abc>

    ```````````````````````````````` ```````````````````````````````` example .

    <foo.bar.baz>

    ```````````````````````````````` ```````````````````````````````` example http://example.com .

    http://example.com

    ```````````````````````````````` ```````````````````````````````` example foo@bar.example.com .

    foo@bar.example.com

    ```````````````````````````````` ## Raw HTML Text between `<` and `>` that looks like an HTML tag is parsed as a raw HTML tag and will be rendered in HTML without escaping. Tag and attribute names are not limited to current HTML tags, so custom tags (and even, say, DocBook tags) may be used. Here is the grammar for tags: A [tag name](@) consists of an ASCII letter followed by zero or more ASCII letters, digits, or hyphens (`-`). An [attribute](@) consists of [whitespace], an [attribute name], and an optional [attribute value specification]. An [attribute name](@) consists of an ASCII letter, `_`, or `:`, followed by zero or more ASCII letters, digits, `_`, `.`, `:`, or `-`. (Note: This is the XML specification restricted to ASCII. HTML5 is laxer.) An [attribute value specification](@) consists of optional [whitespace], a `=` character, optional [whitespace], and an [attribute value]. An [attribute value](@) consists of an [unquoted attribute value], a [single-quoted attribute value], or a [double-quoted attribute value]. An [unquoted attribute value](@) is a nonempty string of characters not including [whitespace], `"`, `'`, `=`, `<`, `>`, or `` ` ``. A [single-quoted attribute value](@) consists of `'`, zero or more characters not including `'`, and a final `'`. A [double-quoted attribute value](@) consists of `"`, zero or more characters not including `"`, and a final `"`. An [open tag](@) consists of a `<` character, a [tag name], zero or more [attributes], optional [whitespace], an optional `/` character, and a `>` character. A [closing tag](@) consists of the string ``. An [HTML comment](@) consists of ``, where *text* does not start with `>` or `->`, does not end with `-`, and does not contain `--`. (See the [HTML5 spec](http://www.w3.org/TR/html5/syntax.html#comments).) A [processing instruction](@) consists of the string ``, and the string `?>`. A [declaration](@) consists of the string ``, and the character `>`. A [CDATA section](@) consists of the string ``, and the string `]]>`. An [HTML tag](@) consists of an [open tag], a [closing tag], an [HTML comment], a [processing instruction], a [declaration], or a [CDATA section]. Here are some simple open tags: ```````````````````````````````` example .

    ```````````````````````````````` Empty elements: ```````````````````````````````` example .

    ```````````````````````````````` [Whitespace] is allowed: ```````````````````````````````` example .

    ```````````````````````````````` With attributes: ```````````````````````````````` example .

    ```````````````````````````````` Custom tag names can be used: ```````````````````````````````` example Foo .

    Foo

    ```````````````````````````````` Illegal tag names, not parsed as HTML: ```````````````````````````````` example <33> <__> .

    <33> <__>

    ```````````````````````````````` Illegal attribute names: ```````````````````````````````` example
    .

    <a h*#ref="hi">

    ```````````````````````````````` Illegal attribute values: ```````````````````````````````` example
    .

    </a href="foo">

    ```````````````````````````````` Comments: ```````````````````````````````` example foo .

    foo

    ```````````````````````````````` ```````````````````````````````` example foo .

    foo <!-- not a comment -- two hyphens -->

    ```````````````````````````````` Not comments: ```````````````````````````````` example foo foo --> foo .

    foo <!--> foo -->

    foo <!-- foo--->

    ```````````````````````````````` Processing instructions: ```````````````````````````````` example foo .

    foo

    ```````````````````````````````` Declarations: ```````````````````````````````` example foo .

    foo

    ```````````````````````````````` CDATA sections: ```````````````````````````````` example foo &<]]> .

    foo &<]]>

    ```````````````````````````````` Entity and numeric character references are preserved in HTML attributes: ```````````````````````````````` example foo
    .

    foo

    ```````````````````````````````` Backslash escapes do not work in HTML attributes: ```````````````````````````````` example foo .

    foo

    ```````````````````````````````` ```````````````````````````````` example .

    <a href=""">

    ```````````````````````````````` ## Hard line breaks A line break (not in a code span or HTML tag) that is preceded by two or more spaces and does not occur at the end of a block is parsed as a [hard line break](@) (rendered in HTML as a `
    ` tag): ```````````````````````````````` example foo baz .

    foo
    baz

    ```````````````````````````````` For a more visible alternative, a backslash before the [line ending] may be used instead of two spaces: ```````````````````````````````` example foo\ baz .

    foo
    baz

    ```````````````````````````````` More than two spaces can be used: ```````````````````````````````` example foo baz .

    foo
    baz

    ```````````````````````````````` Leading spaces at the beginning of the next line are ignored: ```````````````````````````````` example foo bar .

    foo
    bar

    ```````````````````````````````` ```````````````````````````````` example foo\ bar .

    foo
    bar

    ```````````````````````````````` Line breaks can occur inside emphasis, links, and other constructs that allow inline content: ```````````````````````````````` example *foo bar* .

    foo
    bar

    ```````````````````````````````` ```````````````````````````````` example *foo\ bar* .

    foo
    bar

    ```````````````````````````````` Line breaks do not occur inside code spans ```````````````````````````````` example `code span` .

    code span

    ```````````````````````````````` ```````````````````````````````` example `code\ span` .

    code\ span

    ```````````````````````````````` or HTML tags: ```````````````````````````````` example
    .

    ```````````````````````````````` ```````````````````````````````` example .

    ```````````````````````````````` Hard line breaks are for separating inline content within a block. Neither syntax for hard line breaks works at the end of a paragraph or other block element: ```````````````````````````````` example foo\ .

    foo\

    ```````````````````````````````` ```````````````````````````````` example foo .

    foo

    ```````````````````````````````` ```````````````````````````````` example ### foo\ .

    foo\

    ```````````````````````````````` ```````````````````````````````` example ### foo .

    foo

    ```````````````````````````````` ## Soft line breaks A regular line break (not in a code span or HTML tag) that is not preceded by two or more spaces or a backslash is parsed as a [softbreak](@). (A softbreak may be rendered in HTML either as a [line ending] or as a space. The result will be the same in browsers. In the examples here, a [line ending] will be used.) ```````````````````````````````` example foo baz .

    foo baz

    ```````````````````````````````` Spaces at the end of the line and beginning of the next line are removed: ```````````````````````````````` example foo baz .

    foo baz

    ```````````````````````````````` A conforming parser may render a soft line break in HTML either as a line break or as a space. A renderer may also provide an option to render soft line breaks as hard line breaks. ## Textual content Any characters not given an interpretation by the above rules will be parsed as plain textual content. ```````````````````````````````` example hello $.;'there .

    hello $.;'there

    ```````````````````````````````` ```````````````````````````````` example Foo χρῆν .

    Foo χρῆν

    ```````````````````````````````` Internal spaces are preserved verbatim: ```````````````````````````````` example Multiple spaces .

    Multiple spaces

    ```````````````````````````````` # Appendix: A parsing strategy In this appendix we describe some features of the parsing strategy used in the CommonMark reference implementations. ## Overview Parsing has two phases: 1. In the first phase, lines of input are consumed and the block structure of the document---its division into paragraphs, block quotes, list items, and so on---is constructed. Text is assigned to these blocks but not parsed. Link reference definitions are parsed and a map of links is constructed. 2. In the second phase, the raw text contents of paragraphs and headings are parsed into sequences of Markdown inline elements (strings, code spans, links, emphasis, and so on), using the map of link references constructed in phase 1. At each point in processing, the document is represented as a tree of **blocks**. The root of the tree is a `document` block. The `document` may have any number of other blocks as **children**. These children may, in turn, have other blocks as children. The last child of a block is normally considered **open**, meaning that subsequent lines of input can alter its contents. (Blocks that are not open are **closed**.) Here, for example, is a possible document tree, with the open blocks marked by arrows: ``` tree -> document -> block_quote paragraph "Lorem ipsum dolor\nsit amet." -> list (type=bullet tight=true bullet_char=-) list_item paragraph "Qui *quodsi iracundia*" -> list_item -> paragraph "aliquando id" ``` ## Phase 1: block structure Each line that is processed has an effect on this tree. The line is analyzed and, depending on its contents, the document may be altered in one or more of the following ways: 1. One or more open blocks may be closed. 2. One or more new blocks may be created as children of the last open block. 3. Text may be added to the last (deepest) open block remaining on the tree. Once a line has been incorporated into the tree in this way, it can be discarded, so input can be read in a stream. For each line, we follow this procedure: 1. First we iterate through the open blocks, starting with the root document, and descending through last children down to the last open block. Each block imposes a condition that the line must satisfy if the block is to remain open. For example, a block quote requires a `>` character. A paragraph requires a non-blank line. In this phase we may match all or just some of the open blocks. But we cannot close unmatched blocks yet, because we may have a [lazy continuation line]. 2. Next, after consuming the continuation markers for existing blocks, we look for new block starts (e.g. `>` for a block quote). If we encounter a new block start, we close any blocks unmatched in step 1 before creating the new block as a child of the last matched block. 3. Finally, we look at the remainder of the line (after block markers like `>`, list markers, and indentation have been consumed). This is text that can be incorporated into the last open block (a paragraph, code block, heading, or raw HTML). Setext headings are formed when we see a line of a paragraph that is a [setext heading underline]. Reference link definitions are detected when a paragraph is closed; the accumulated text lines are parsed to see if they begin with one or more reference link definitions. Any remainder becomes a normal paragraph. We can see how this works by considering how the tree above is generated by four lines of Markdown: ``` markdown > Lorem ipsum dolor sit amet. > - Qui *quodsi iracundia* > - aliquando id ``` At the outset, our document model is just ``` tree -> document ``` The first line of our text, ``` markdown > Lorem ipsum dolor ``` causes a `block_quote` block to be created as a child of our open `document` block, and a `paragraph` block as a child of the `block_quote`. Then the text is added to the last open block, the `paragraph`: ``` tree -> document -> block_quote -> paragraph "Lorem ipsum dolor" ``` The next line, ``` markdown sit amet. ``` is a "lazy continuation" of the open `paragraph`, so it gets added to the paragraph's text: ``` tree -> document -> block_quote -> paragraph "Lorem ipsum dolor\nsit amet." ``` The third line, ``` markdown > - Qui *quodsi iracundia* ``` causes the `paragraph` block to be closed, and a new `list` block opened as a child of the `block_quote`. A `list_item` is also added as a child of the `list`, and a `paragraph` as a child of the `list_item`. The text is then added to the new `paragraph`: ``` tree -> document -> block_quote paragraph "Lorem ipsum dolor\nsit amet." -> list (type=bullet tight=true bullet_char=-) -> list_item -> paragraph "Qui *quodsi iracundia*" ``` The fourth line, ``` markdown > - aliquando id ``` causes the `list_item` (and its child the `paragraph`) to be closed, and a new `list_item` opened up as child of the `list`. A `paragraph` is added as a child of the new `list_item`, to contain the text. We thus obtain the final tree: ``` tree -> document -> block_quote paragraph "Lorem ipsum dolor\nsit amet." -> list (type=bullet tight=true bullet_char=-) list_item paragraph "Qui *quodsi iracundia*" -> list_item -> paragraph "aliquando id" ``` ## Phase 2: inline structure Once all of the input has been parsed, all open blocks are closed. We then "walk the tree," visiting every node, and parse raw string contents of paragraphs and headings as inlines. At this point we have seen all the link reference definitions, so we can resolve reference links as we go. ``` tree document block_quote paragraph str "Lorem ipsum dolor" softbreak str "sit amet." list (type=bullet tight=true bullet_char=-) list_item paragraph str "Qui " emph str "quodsi iracundia" list_item paragraph str "aliquando id" ``` Notice how the [line ending] in the first paragraph has been parsed as a `softbreak`, and the asterisks in the first list item have become an `emph`. ### An algorithm for parsing nested emphasis and links By far the trickiest part of inline parsing is handling emphasis, strong emphasis, links, and images. This is done using the following algorithm. When we're parsing inlines and we hit either - a run of `*` or `_` characters, or - a `[` or `![` we insert a text node with these symbols as its literal content, and we add a pointer to this text node to the [delimiter stack](@). The [delimiter stack] is a doubly linked list. Each element contains a pointer to a text node, plus information about - the type of delimiter (`[`, `![`, `*`, `_`) - the number of delimiters, - whether the delimiter is "active" (all are active to start), and - whether the delimiter is a potential opener, a potential closer, or both (which depends on what sort of characters precede and follow the delimiters). When we hit a `]` character, we call the *look for link or image* procedure (see below). When we hit the end of the input, we call the *process emphasis* procedure (see below), with `stack_bottom` = NULL. #### *look for link or image* Starting at the top of the delimiter stack, we look backwards through the stack for an opening `[` or `![` delimiter. - If we don't find one, we return a literal text node `]`. - If we do find one, but it's not *active*, we remove the inactive delimiter from the stack, and return a literal text node `]`. - If we find one and it's active, then we parse ahead to see if we have an inline link/image, reference link/image, compact reference link/image, or shortcut reference link/image. + If we don't, then we remove the opening delimiter from the delimiter stack and return a literal text node `]`. + If we do, then * We return a link or image node whose children are the inlines after the text node pointed to by the opening delimiter. * We run *process emphasis* on these inlines, with the `[` opener as `stack_bottom`. * We remove the opening delimiter. * If we have a link (and not an image), we also set all `[` delimiters before the opening delimiter to *inactive*. (This will prevent us from getting links within links.) #### *process emphasis* Parameter `stack_bottom` sets a lower bound to how far we descend in the [delimiter stack]. If it is NULL, we can go all the way to the bottom. Otherwise, we stop before visiting `stack_bottom`. Let `current_position` point to the element on the [delimiter stack] just above `stack_bottom` (or the first element if `stack_bottom` is NULL). We keep track of the `openers_bottom` for each delimiter type (`*`, `_`) and each length of the closing delimiter run (modulo 3). Initialize this to `stack_bottom`. Then we repeat the following until we run out of potential closers: - Move `current_position` forward in the delimiter stack (if needed) until we find the first potential closer with delimiter `*` or `_`. (This will be the potential closer closest to the beginning of the input -- the first one in parse order.) - Now, look back in the stack (staying above `stack_bottom` and the `openers_bottom` for this delimiter type) for the first matching potential opener ("matching" means same delimiter). - If one is found: + Figure out whether we have emphasis or strong emphasis: if both closer and opener spans have length >= 2, we have strong, otherwise regular. + Insert an emph or strong emph node accordingly, after the text node corresponding to the opener. + Remove any delimiters between the opener and closer from the delimiter stack. + Remove 1 (for regular emph) or 2 (for strong emph) delimiters from the opening and closing text nodes. If they become empty as a result, remove them and remove the corresponding element of the delimiter stack. If the closing node is removed, reset `current_position` to the next element in the stack. - If none is found: + Set `openers_bottom` to the element before `current_position`. (We know that there are no openers for this kind of closer up to and including this point, so this puts a lower bound on future searches.) + If the closer at `current_position` is not a potential opener, remove it from the delimiter stack (since we know it can't be a closer either). + Advance `current_position` to the next element in the stack. After we're done, we remove all delimiters above `stack_bottom` from the delimiter stack. hugo-0.68.3/hugolib/testhelpers_test.go000066400000000000000000000633721363637351300201600ustar00rootroot00000000000000package hugolib import ( "image/jpeg" "io" "math/rand" "path/filepath" "runtime" "strconv" "testing" "time" "unicode/utf8" "github.com/gohugoio/hugo/htesting" "github.com/gohugoio/hugo/output" "github.com/gohugoio/hugo/parser/metadecoders" "github.com/google/go-cmp/cmp" "github.com/gohugoio/hugo/parser" "github.com/pkg/errors" "bytes" "fmt" "regexp" "strings" "text/template" "github.com/fsnotify/fsnotify" "github.com/gohugoio/hugo/common/herrors" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/resources/page" "github.com/sanity-io/litter" "github.com/spf13/afero" "github.com/spf13/cast" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/tpl" "github.com/spf13/viper" "os" "github.com/gohugoio/hugo/resources/resource" qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/hugofs" ) var ( deepEqualsPages = qt.CmpEquals(cmp.Comparer(func(p1, p2 *pageState) bool { return p1 == p2 })) deepEqualsOutputFormats = qt.CmpEquals(cmp.Comparer(func(o1, o2 output.Format) bool { return o1.Name == o2.Name && o1.MediaType.Type() == o2.MediaType.Type() })) ) type sitesBuilder struct { Cfg config.Provider environ []string Fs *hugofs.Fs T testing.TB depsCfg deps.DepsCfg *qt.C logger *loggers.Logger rnd *rand.Rand dumper litter.Options // Used to test partial rebuilds. changedFiles []string removedFiles []string // Aka the Hugo server mode. running bool H *HugoSites theme string // Default toml configFormat string configFileSet bool viperSet bool // Default is empty. // TODO(bep) revisit this and consider always setting it to something. // Consider this in relation to using the BaseFs.PublishFs to all publishing. workingDir string addNothing bool // Base data/content contentFilePairs []filenameContent templateFilePairs []filenameContent i18nFilePairs []filenameContent dataFilePairs []filenameContent // Additional data/content. // As in "use the base, but add these on top". contentFilePairsAdded []filenameContent templateFilePairsAdded []filenameContent i18nFilePairsAdded []filenameContent dataFilePairsAdded []filenameContent } type filenameContent struct { filename string content string } func newTestSitesBuilder(t testing.TB) *sitesBuilder { v := viper.New() fs := hugofs.NewMem(v) litterOptions := litter.Options{ HidePrivateFields: true, StripPackageNames: true, Separator: " ", } return &sitesBuilder{T: t, C: qt.New(t), Fs: fs, configFormat: "toml", dumper: litterOptions, rnd: rand.New(rand.NewSource(time.Now().Unix()))} } func newTestSitesBuilderFromDepsCfg(t testing.TB, d deps.DepsCfg) *sitesBuilder { c := qt.New(t) litterOptions := litter.Options{ HidePrivateFields: true, StripPackageNames: true, Separator: " ", } b := &sitesBuilder{T: t, C: c, depsCfg: d, Fs: d.Fs, dumper: litterOptions, rnd: rand.New(rand.NewSource(time.Now().Unix()))} workingDir := d.Cfg.GetString("workingDir") b.WithWorkingDir(workingDir) return b.WithViper(d.Cfg.(*viper.Viper)) } func (s *sitesBuilder) Running() *sitesBuilder { s.running = true return s } func (s *sitesBuilder) WithNothingAdded() *sitesBuilder { s.addNothing = true return s } func (s *sitesBuilder) WithLogger(logger *loggers.Logger) *sitesBuilder { s.logger = logger return s } func (s *sitesBuilder) WithWorkingDir(dir string) *sitesBuilder { s.workingDir = filepath.FromSlash(dir) return s } func (s *sitesBuilder) WithEnviron(env ...string) *sitesBuilder { for i := 0; i < len(env); i += 2 { s.environ = append(s.environ, fmt.Sprintf("%s=%s", env[i], env[i+1])) } return s } func (s *sitesBuilder) WithConfigTemplate(data interface{}, format, configTemplate string) *sitesBuilder { s.T.Helper() if format == "" { format = "toml" } templ, err := template.New("test").Parse(configTemplate) if err != nil { s.Fatalf("Template parse failed: %s", err) } var b bytes.Buffer templ.Execute(&b, data) return s.WithConfigFile(format, b.String()) } func (s *sitesBuilder) WithViper(v *viper.Viper) *sitesBuilder { s.T.Helper() if s.configFileSet { s.T.Fatal("WithViper: use Viper or config.toml, not both") } defer func() { s.viperSet = true }() // Write to a config file to make sure the tests follow the same code path. var buff bytes.Buffer m := v.AllSettings() s.Assert(parser.InterfaceToConfig(m, metadecoders.TOML, &buff), qt.IsNil) return s.WithConfigFile("toml", buff.String()) } func (s *sitesBuilder) WithConfigFile(format, conf string) *sitesBuilder { s.T.Helper() if s.viperSet { s.T.Fatal("WithConfigFile: use Viper or config.toml, not both") } s.configFileSet = true filename := s.absFilename("config." + format) writeSource(s.T, s.Fs, filename, conf) s.configFormat = format return s } func (s *sitesBuilder) WithThemeConfigFile(format, conf string) *sitesBuilder { s.T.Helper() if s.theme == "" { s.theme = "test-theme" } filename := filepath.Join("themes", s.theme, "config."+format) writeSource(s.T, s.Fs, s.absFilename(filename), conf) return s } func (s *sitesBuilder) WithSourceFile(filenameContent ...string) *sitesBuilder { s.T.Helper() for i := 0; i < len(filenameContent); i += 2 { writeSource(s.T, s.Fs, s.absFilename(filenameContent[i]), filenameContent[i+1]) } return s } func (s *sitesBuilder) absFilename(filename string) string { filename = filepath.FromSlash(filename) if filepath.IsAbs(filename) { return filename } if s.workingDir != "" && !strings.HasPrefix(filename, s.workingDir) { filename = filepath.Join(s.workingDir, filename) } return filename } const commonConfigSections = ` [services] [services.disqus] shortname = "disqus_shortname" [services.googleAnalytics] id = "ga_id" [privacy] [privacy.disqus] disable = false [privacy.googleAnalytics] respectDoNotTrack = true anonymizeIP = true [privacy.instagram] simple = true [privacy.twitter] enableDNT = true [privacy.vimeo] disable = false [privacy.youtube] disable = false privacyEnhanced = true ` func (s *sitesBuilder) WithSimpleConfigFile() *sitesBuilder { s.T.Helper() return s.WithSimpleConfigFileAndBaseURL("http://example.com/") } func (s *sitesBuilder) WithSimpleConfigFileAndBaseURL(baseURL string) *sitesBuilder { s.T.Helper() config := fmt.Sprintf("baseURL = %q", baseURL) config = config + commonConfigSections return s.WithConfigFile("toml", config) } func (s *sitesBuilder) WithDefaultMultiSiteConfig() *sitesBuilder { var defaultMultiSiteConfig = ` baseURL = "http://example.com/blog" paginate = 1 disablePathToLower = true defaultContentLanguage = "en" defaultContentLanguageInSubdir = true [permalinks] other = "/somewhere/else/:filename" [blackfriday] angledQuotes = true [Taxonomies] tag = "tags" [Languages] [Languages.en] weight = 10 title = "In English" languageName = "English" [Languages.en.blackfriday] angledQuotes = false [[Languages.en.menu.main]] url = "/" name = "Home" weight = 0 [Languages.fr] weight = 20 title = "Le Français" languageName = "Français" [Languages.fr.Taxonomies] plaque = "plaques" [Languages.nn] weight = 30 title = "På nynorsk" languageName = "Nynorsk" paginatePath = "side" [Languages.nn.Taxonomies] lag = "lag" [[Languages.nn.menu.main]] url = "/" name = "Heim" weight = 1 [Languages.nb] weight = 40 title = "På bokmål" languageName = "Bokmål" paginatePath = "side" [Languages.nb.Taxonomies] lag = "lag" ` + commonConfigSections return s.WithConfigFile("toml", defaultMultiSiteConfig) } func (s *sitesBuilder) WithSunset(in string) { // Write a real image into one of the bundle above. src, err := os.Open(filepath.FromSlash("testdata/sunset.jpg")) s.Assert(err, qt.IsNil) out, err := s.Fs.Source.Create(filepath.FromSlash(filepath.Join(s.workingDir, in))) s.Assert(err, qt.IsNil) _, err = io.Copy(out, src) s.Assert(err, qt.IsNil) out.Close() src.Close() } func (s *sitesBuilder) createFilenameContent(pairs []string) []filenameContent { var slice []filenameContent s.appendFilenameContent(&slice, pairs...) return slice } func (s *sitesBuilder) appendFilenameContent(slice *[]filenameContent, pairs ...string) { if len(pairs)%2 != 0 { panic("file content mismatch") } for i := 0; i < len(pairs); i += 2 { c := filenameContent{ filename: pairs[i], content: pairs[i+1], } *slice = append(*slice, c) } } func (s *sitesBuilder) WithContent(filenameContent ...string) *sitesBuilder { s.appendFilenameContent(&s.contentFilePairs, filenameContent...) return s } func (s *sitesBuilder) WithContentAdded(filenameContent ...string) *sitesBuilder { s.appendFilenameContent(&s.contentFilePairsAdded, filenameContent...) return s } func (s *sitesBuilder) WithTemplates(filenameContent ...string) *sitesBuilder { s.appendFilenameContent(&s.templateFilePairs, filenameContent...) return s } func (s *sitesBuilder) WithTemplatesAdded(filenameContent ...string) *sitesBuilder { s.appendFilenameContent(&s.templateFilePairsAdded, filenameContent...) return s } func (s *sitesBuilder) WithData(filenameContent ...string) *sitesBuilder { s.appendFilenameContent(&s.dataFilePairs, filenameContent...) return s } func (s *sitesBuilder) WithDataAdded(filenameContent ...string) *sitesBuilder { s.appendFilenameContent(&s.dataFilePairsAdded, filenameContent...) return s } func (s *sitesBuilder) WithI18n(filenameContent ...string) *sitesBuilder { s.appendFilenameContent(&s.i18nFilePairs, filenameContent...) return s } func (s *sitesBuilder) WithI18nAdded(filenameContent ...string) *sitesBuilder { s.appendFilenameContent(&s.i18nFilePairsAdded, filenameContent...) return s } func (s *sitesBuilder) EditFiles(filenameContent ...string) *sitesBuilder { for i := 0; i < len(filenameContent); i += 2 { filename, content := filepath.FromSlash(filenameContent[i]), filenameContent[i+1] absFilename := s.absFilename(filename) s.changedFiles = append(s.changedFiles, absFilename) writeSource(s.T, s.Fs, absFilename, content) } return s } func (s *sitesBuilder) RemoveFiles(filenames ...string) *sitesBuilder { for _, filename := range filenames { absFilename := s.absFilename(filename) s.removedFiles = append(s.removedFiles, absFilename) s.Assert(s.Fs.Source.Remove(absFilename), qt.IsNil) } return s } func (s *sitesBuilder) writeFilePairs(folder string, files []filenameContent) *sitesBuilder { // We have had some "filesystem ordering" bugs that we have not discovered in // our tests running with the in memory filesystem. // That file system is backed by a map so not sure how this helps, but some // randomness in tests doesn't hurt. // TODO(bep) this turns out to be more confusing than helpful. //s.rnd.Shuffle(len(files), func(i, j int) { files[i], files[j] = files[j], files[i] }) for _, fc := range files { target := folder // TODO(bep) clean up this magic. if strings.HasPrefix(fc.filename, folder) { target = "" } if s.workingDir != "" { target = filepath.Join(s.workingDir, target) } writeSource(s.T, s.Fs, filepath.Join(target, fc.filename), fc.content) } return s } func (s *sitesBuilder) CreateSites() *sitesBuilder { if err := s.CreateSitesE(); err != nil { herrors.PrintStackTraceFromErr(err) s.Fatalf("Failed to create sites: %s", err) } return s } func (s *sitesBuilder) LoadConfig() error { if !s.configFileSet { s.WithSimpleConfigFile() } cfg, _, err := LoadConfig(ConfigSourceDescriptor{ WorkingDir: s.workingDir, Fs: s.Fs.Source, Logger: s.logger, Environ: s.environ, Filename: "config." + s.configFormat}, func(cfg config.Provider) error { return nil }) if err != nil { return err } s.Cfg = cfg return nil } func (s *sitesBuilder) CreateSitesE() error { if !s.addNothing { if _, ok := s.Fs.Source.(*afero.OsFs); ok { for _, dir := range []string{ "content/sect", "layouts/_default", "layouts/_default/_markup", "layouts/partials", "layouts/shortcodes", "data", "i18n", } { if err := os.MkdirAll(filepath.Join(s.workingDir, dir), 0777); err != nil { return errors.Wrapf(err, "failed to create %q", dir) } } } s.addDefaults() s.writeFilePairs("content", s.contentFilePairsAdded) s.writeFilePairs("layouts", s.templateFilePairsAdded) s.writeFilePairs("data", s.dataFilePairsAdded) s.writeFilePairs("i18n", s.i18nFilePairsAdded) s.writeFilePairs("i18n", s.i18nFilePairs) s.writeFilePairs("data", s.dataFilePairs) s.writeFilePairs("content", s.contentFilePairs) s.writeFilePairs("layouts", s.templateFilePairs) } if err := s.LoadConfig(); err != nil { return errors.Wrap(err, "failed to load config") } s.Fs.Destination = hugofs.NewCreateCountingFs(s.Fs.Destination) depsCfg := s.depsCfg depsCfg.Fs = s.Fs depsCfg.Cfg = s.Cfg depsCfg.Logger = s.logger depsCfg.Running = s.running sites, err := NewHugoSites(depsCfg) if err != nil { return errors.Wrap(err, "failed to create sites") } s.H = sites return nil } func (s *sitesBuilder) BuildE(cfg BuildCfg) error { if s.H == nil { s.CreateSites() } return s.H.Build(cfg) } func (s *sitesBuilder) Build(cfg BuildCfg) *sitesBuilder { s.T.Helper() return s.build(cfg, false) } func (s *sitesBuilder) BuildFail(cfg BuildCfg) *sitesBuilder { s.T.Helper() return s.build(cfg, true) } func (s *sitesBuilder) changeEvents() []fsnotify.Event { var events []fsnotify.Event for _, v := range s.changedFiles { events = append(events, fsnotify.Event{ Name: v, Op: fsnotify.Write, }) } for _, v := range s.removedFiles { events = append(events, fsnotify.Event{ Name: v, Op: fsnotify.Remove, }) } return events } func (s *sitesBuilder) build(cfg BuildCfg, shouldFail bool) *sitesBuilder { s.Helper() defer func() { s.changedFiles = nil }() if s.H == nil { s.CreateSites() } err := s.H.Build(cfg, s.changeEvents()...) if err == nil { logErrorCount := s.H.NumLogErrors() if logErrorCount > 0 { err = fmt.Errorf("logged %d errors", logErrorCount) } } if err != nil && !shouldFail { herrors.PrintStackTraceFromErr(err) s.Fatalf("Build failed: %s", err) } else if err == nil && shouldFail { s.Fatalf("Expected error") } return s } func (s *sitesBuilder) addDefaults() { var ( contentTemplate = `--- title: doc1 weight: 1 tags: - tag1 date: "2018-02-28" --- # doc1 *some "content"* {{< shortcode >}} {{< lingo >}} ` defaultContent = []string{ "content/sect/doc1.en.md", contentTemplate, "content/sect/doc1.fr.md", contentTemplate, "content/sect/doc1.nb.md", contentTemplate, "content/sect/doc1.nn.md", contentTemplate, } listTemplateCommon = "{{ $p := .Paginator }}{{ $p.PageNumber }}|{{ .Title }}|{{ i18n \"hello\" }}|{{ .Permalink }}|Pager: {{ template \"_internal/pagination.html\" . }}|Kind: {{ .Kind }}|Content: {{ .Content }}|Len Pages: {{ len .Pages }}|Len RegularPages: {{ len .RegularPages }}| HasParent: {{ if .Parent }}YES{{ else }}NO{{ end }}" defaultTemplates = []string{ "_default/single.html", "Single: {{ .Title }}|{{ i18n \"hello\" }}|{{.Language.Lang}}|RelPermalink: {{ .RelPermalink }}|Permalink: {{ .Permalink }}|{{ .Content }}|Resources: {{ range .Resources }}{{ .MediaType }}: {{ .RelPermalink}} -- {{ end }}|Summary: {{ .Summary }}|Truncated: {{ .Truncated }}|Parent: {{ .Parent.Title }}", "_default/list.html", "List Page " + listTemplateCommon, "index.html", "{{ $p := .Paginator }}Default Home Page {{ $p.PageNumber }}: {{ .Title }}|{{ .IsHome }}|{{ i18n \"hello\" }}|{{ .Permalink }}|{{ .Site.Data.hugo.slogan }}|String Resource: {{ ( \"Hugo Pipes\" | resources.FromString \"text/pipes.txt\").RelPermalink }}", "index.fr.html", "{{ $p := .Paginator }}French Home Page {{ $p.PageNumber }}: {{ .Title }}|{{ .IsHome }}|{{ i18n \"hello\" }}|{{ .Permalink }}|{{ .Site.Data.hugo.slogan }}|String Resource: {{ ( \"Hugo Pipes\" | resources.FromString \"text/pipes.txt\").RelPermalink }}", "_default/terms.html", "Taxonomy Term Page " + listTemplateCommon, "_default/taxonomy.html", "Taxonomy List Page " + listTemplateCommon, // Shortcodes "shortcodes/shortcode.html", "Shortcode: {{ i18n \"hello\" }}", // A shortcode in multiple languages "shortcodes/lingo.html", "LingoDefault", "shortcodes/lingo.fr.html", "LingoFrench", // Special templates "404.html", "404|{{ .Lang }}|{{ .Title }}", "robots.txt", "robots|{{ .Lang }}|{{ .Title }}", } defaultI18n = []string{ "en.yaml", ` hello: other: "Hello" `, "fr.yaml", ` hello: other: "Bonjour" `, } defaultData = []string{ "hugo.toml", "slogan = \"Hugo Rocks!\"", } ) if len(s.contentFilePairs) == 0 { s.writeFilePairs("content", s.createFilenameContent(defaultContent)) } if len(s.templateFilePairs) == 0 { s.writeFilePairs("layouts", s.createFilenameContent(defaultTemplates)) } if len(s.dataFilePairs) == 0 { s.writeFilePairs("data", s.createFilenameContent(defaultData)) } if len(s.i18nFilePairs) == 0 { s.writeFilePairs("i18n", s.createFilenameContent(defaultI18n)) } } func (s *sitesBuilder) Fatalf(format string, args ...interface{}) { s.T.Helper() s.T.Fatalf(format, args...) } func (s *sitesBuilder) AssertFileContentFn(filename string, f func(s string) bool) { s.T.Helper() content := s.FileContent(filename) if !f(content) { s.Fatalf("Assert failed for %q in content\n%s", filename, content) } } func (s *sitesBuilder) AssertHome(matches ...string) { s.AssertFileContent("public/index.html", matches...) } func (s *sitesBuilder) AssertFileContent(filename string, matches ...string) { s.T.Helper() content := s.FileContent(filename) for _, m := range matches { lines := strings.Split(m, "\n") for _, match := range lines { match = strings.TrimSpace(match) if match == "" { continue } if !strings.Contains(content, match) { s.Fatalf("No match for %q in content for %s\n%s\n%q", match, filename, content, content) } } } } func (s *sitesBuilder) AssertImage(width, height int, filename string) { filename = filepath.Join(s.workingDir, filename) f, err := s.Fs.Destination.Open(filename) s.Assert(err, qt.IsNil) defer f.Close() cfg, err := jpeg.DecodeConfig(f) s.Assert(err, qt.IsNil) s.Assert(cfg.Width, qt.Equals, width) s.Assert(cfg.Height, qt.Equals, height) } func (s *sitesBuilder) AssertNoDuplicateWrites() { s.Helper() d := s.Fs.Destination.(hugofs.DuplicatesReporter) s.Assert(d.ReportDuplicates(), qt.Equals, "") } func (s *sitesBuilder) FileContent(filename string) string { s.T.Helper() filename = filepath.FromSlash(filename) if !strings.HasPrefix(filename, s.workingDir) { filename = filepath.Join(s.workingDir, filename) } return readDestination(s.T, s.Fs, filename) } func (s *sitesBuilder) AssertObject(expected string, object interface{}) { s.T.Helper() got := s.dumper.Sdump(object) expected = strings.TrimSpace(expected) if expected != got { fmt.Println(got) diff := htesting.DiffStrings(expected, got) s.Fatalf("diff:\n%s\nexpected\n%s\ngot\n%s", diff, expected, got) } } func (s *sitesBuilder) AssertFileContentRe(filename string, matches ...string) { content := readDestination(s.T, s.Fs, filename) for _, match := range matches { r := regexp.MustCompile("(?s)" + match) if !r.MatchString(content) { s.Fatalf("No match for %q in content for %s\n%q", match, filename, content) } } } func (s *sitesBuilder) CheckExists(filename string) bool { return destinationExists(s.Fs, filepath.Clean(filename)) } func (s *sitesBuilder) GetPage(ref string) page.Page { p, err := s.H.Sites[0].getPageNew(nil, ref) s.Assert(err, qt.IsNil) return p } func (s *sitesBuilder) GetPageRel(p page.Page, ref string) page.Page { p, err := s.H.Sites[0].getPageNew(p, ref) s.Assert(err, qt.IsNil) return p } func newTestHelper(cfg config.Provider, fs *hugofs.Fs, t testing.TB) testHelper { return testHelper{ Cfg: cfg, Fs: fs, C: qt.New(t), } } type testHelper struct { Cfg config.Provider Fs *hugofs.Fs *qt.C } func (th testHelper) assertFileContent(filename string, matches ...string) { th.Helper() filename = th.replaceDefaultContentLanguageValue(filename) content := readDestination(th, th.Fs, filename) for _, match := range matches { match = th.replaceDefaultContentLanguageValue(match) th.Assert(strings.Contains(content, match), qt.Equals, true, qt.Commentf(match+" not in: \n"+content)) } } func (th testHelper) assertFileContentRegexp(filename string, matches ...string) { filename = th.replaceDefaultContentLanguageValue(filename) content := readDestination(th, th.Fs, filename) for _, match := range matches { match = th.replaceDefaultContentLanguageValue(match) r := regexp.MustCompile(match) matches := r.MatchString(content) if !matches { fmt.Println(match+":\n", content) } th.Assert(matches, qt.Equals, true) } } func (th testHelper) assertFileNotExist(filename string) { exists, err := helpers.Exists(filename, th.Fs.Destination) th.Assert(err, qt.IsNil) th.Assert(exists, qt.Equals, false) } func (th testHelper) replaceDefaultContentLanguageValue(value string) string { defaultInSubDir := th.Cfg.GetBool("defaultContentLanguageInSubDir") replace := th.Cfg.GetString("defaultContentLanguage") + "/" if !defaultInSubDir { value = strings.Replace(value, replace, "", 1) } return value } func loadTestConfig(fs afero.Fs, withConfig ...func(cfg config.Provider) error) (*viper.Viper, error) { v, _, err := LoadConfig(ConfigSourceDescriptor{Fs: fs}, withConfig...) return v, err } func newTestCfgBasic() (*viper.Viper, *hugofs.Fs) { mm := afero.NewMemMapFs() v := viper.New() v.Set("defaultContentLanguageInSubdir", true) fs := hugofs.NewFrom(hugofs.NewBaseFileDecorator(mm), v) return v, fs } func newTestCfg(withConfig ...func(cfg config.Provider) error) (*viper.Viper, *hugofs.Fs) { mm := afero.NewMemMapFs() v, err := loadTestConfig(mm, func(cfg config.Provider) error { // Default is false, but true is easier to use as default in tests cfg.Set("defaultContentLanguageInSubdir", true) for _, w := range withConfig { w(cfg) } return nil }) if err != nil && err != ErrNoConfigFile { panic(err) } fs := hugofs.NewFrom(hugofs.NewBaseFileDecorator(mm), v) return v, fs } func newTestSitesFromConfig(t testing.TB, afs afero.Fs, tomlConfig string, layoutPathContentPairs ...string) (testHelper, *HugoSites) { if len(layoutPathContentPairs)%2 != 0 { t.Fatalf("Layouts must be provided in pairs") } c := qt.New(t) writeToFs(t, afs, filepath.Join("content", ".gitkeep"), "") writeToFs(t, afs, "config.toml", tomlConfig) cfg, err := LoadConfigDefault(afs) c.Assert(err, qt.IsNil) fs := hugofs.NewFrom(afs, cfg) th := newTestHelper(cfg, fs, t) for i := 0; i < len(layoutPathContentPairs); i += 2 { writeSource(t, fs, layoutPathContentPairs[i], layoutPathContentPairs[i+1]) } h, err := NewHugoSites(deps.DepsCfg{Fs: fs, Cfg: cfg}) c.Assert(err, qt.IsNil) return th, h } func createWithTemplateFromNameValues(additionalTemplates ...string) func(templ tpl.TemplateManager) error { return func(templ tpl.TemplateManager) error { for i := 0; i < len(additionalTemplates); i += 2 { err := templ.AddTemplate(additionalTemplates[i], additionalTemplates[i+1]) if err != nil { return err } } return nil } } // TODO(bep) replace these with the builder func buildSingleSite(t testing.TB, depsCfg deps.DepsCfg, buildCfg BuildCfg) *Site { t.Helper() return buildSingleSiteExpected(t, false, false, depsCfg, buildCfg) } func buildSingleSiteExpected(t testing.TB, expectSiteInitEror, expectBuildError bool, depsCfg deps.DepsCfg, buildCfg BuildCfg) *Site { t.Helper() b := newTestSitesBuilderFromDepsCfg(t, depsCfg).WithNothingAdded() err := b.CreateSitesE() if expectSiteInitEror { b.Assert(err, qt.Not(qt.IsNil)) return nil } else { b.Assert(err, qt.IsNil) } h := b.H b.Assert(len(h.Sites), qt.Equals, 1) if expectBuildError { b.Assert(h.Build(buildCfg), qt.Not(qt.IsNil)) return nil } b.Assert(h.Build(buildCfg), qt.IsNil) return h.Sites[0] } func writeSourcesToSource(t *testing.T, base string, fs *hugofs.Fs, sources ...[2]string) { for _, src := range sources { writeSource(t, fs, filepath.Join(base, src[0]), src[1]) } } func getPage(in page.Page, ref string) page.Page { p, err := in.GetPage(ref) if err != nil { panic(err) } return p } func content(c resource.ContentProvider) string { cc, err := c.Content() if err != nil { panic(err) } ccs, err := cast.ToStringE(cc) if err != nil { panic(err) } return ccs } func dumpPages(pages ...page.Page) { fmt.Println("---------") for _, p := range pages { var meta interface{} if p.File() != nil && p.File().FileInfo() != nil { meta = p.File().FileInfo().Meta() } fmt.Printf("Kind: %s Title: %-10s RelPermalink: %-10s Path: %-10s sections: %s Lang: %s Meta: %v\n", p.Kind(), p.Title(), p.RelPermalink(), p.Path(), p.SectionsPath(), p.Lang(), meta) } } func dumpSPages(pages ...*pageState) { for i, p := range pages { fmt.Printf("%d: Kind: %s Title: %-10s RelPermalink: %-10s Path: %-10s sections: %s\n", i+1, p.Kind(), p.Title(), p.RelPermalink(), p.Path(), p.SectionsPath()) } } func printStringIndexes(s string) { lines := strings.Split(s, "\n") i := 0 for _, line := range lines { for _, r := range line { fmt.Printf("%-3s", strconv.Itoa(i)) i += utf8.RuneLen(r) } i++ fmt.Println() for _, r := range line { fmt.Printf("%-3s", string(r)) } fmt.Println() } } func isCI() bool { return (os.Getenv("CI") != "" || os.Getenv("CI_LOCAL") != "") && os.Getenv("CIRCLE_BRANCH") == "" } // See https://github.com/golang/go/issues/19280 // Not in use. var parallelEnabled = true func parallel(t *testing.T) { if parallelEnabled { t.Parallel() } } func skipSymlink(t *testing.T) { if runtime.GOOS == "windows" && os.Getenv("CI") == "" { t.Skip("skip symlink test on local Windows (needs admin)") } } func captureStderr(f func() error) (string, error) { old := os.Stderr r, w, _ := os.Pipe() os.Stderr = w err := f() w.Close() os.Stderr = old var buf bytes.Buffer io.Copy(&buf, r) return buf.String(), err } hugo-0.68.3/hugolib/testsite/000077500000000000000000000000001363637351300160615ustar00rootroot00000000000000hugo-0.68.3/hugolib/testsite/.gitignore000066400000000000000000000000131363637351300200430ustar00rootroot00000000000000config.tomlhugo-0.68.3/hugolib/testsite/content/000077500000000000000000000000001363637351300175335ustar00rootroot00000000000000hugo-0.68.3/hugolib/testsite/content/first-post.md000066400000000000000000000000621363637351300221650ustar00rootroot00000000000000--- title: "My First Post" lastmod: 2018-02-28 ---hugo-0.68.3/hugolib/testsite/content_nn/000077500000000000000000000000001363637351300202265ustar00rootroot00000000000000hugo-0.68.3/hugolib/testsite/content_nn/first-post.md000066400000000000000000000000641363637351300226620ustar00rootroot00000000000000--- title: "Min første dag" lastmod: 1972-02-28 ---hugo-0.68.3/hugolib/translations.go000066400000000000000000000030441363637351300172660ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package hugolib import ( "github.com/gohugoio/hugo/resources/page" ) func pagesToTranslationsMap(sites []*Site) map[string]page.Pages { out := make(map[string]page.Pages) for _, s := range sites { s.pageMap.pageTrees.Walk(func(ss string, n *contentNode) bool { p := n.p // TranslationKey is implemented for all page types. base := p.TranslationKey() pageTranslations, found := out[base] if !found { pageTranslations = make(page.Pages, 0) } pageTranslations = append(pageTranslations, p) out[base] = pageTranslations return false }) } return out } func assignTranslationsToPages(allTranslations map[string]page.Pages, sites []*Site) { for _, s := range sites { s.pageMap.pageTrees.Walk(func(ss string, n *contentNode) bool { p := n.p base := p.TranslationKey() translations, found := allTranslations[base] if !found { return false } p.setTranslations(translations) return false }) } } hugo-0.68.3/identity/000077500000000000000000000000001363637351300144155ustar00rootroot00000000000000hugo-0.68.3/identity/identity.go000066400000000000000000000054341363637351300166030ustar00rootroot00000000000000package identity import ( "path/filepath" "strings" "sync" ) // NewIdentityManager creates a new Manager starting at id. func NewManager(id Provider) Manager { return &identityManager{ Provider: id, ids: Identities{id.GetIdentity(): id}, } } // NewPathIdentity creates a new Identity with the two identifiers // type and path. func NewPathIdentity(typ, pat string) PathIdentity { pat = strings.ToLower(strings.TrimPrefix(filepath.ToSlash(pat), "/")) return PathIdentity{Type: typ, Path: pat} } // Identities stores identity providers. type Identities map[Identity]Provider func (ids Identities) search(depth int, id Identity) Provider { if v, found := ids[id.GetIdentity()]; found { return v } depth++ // There may be infinite recursion in templates. if depth > 100 { // Bail out. return nil } for _, v := range ids { switch t := v.(type) { case IdentitiesProvider: if nested := t.GetIdentities().search(depth, id); nested != nil { return nested } } } return nil } // IdentitiesProvider provides all Identities. type IdentitiesProvider interface { GetIdentities() Identities } // Identity represents an thing that can provide an identify. This can be // any Go type, but the Identity returned by GetIdentify must be hashable. type Identity interface { Provider Name() string } // Manager manages identities, and is itself a Provider of Identity. type Manager interface { IdentitiesProvider Provider Add(ids ...Provider) Search(id Identity) Provider Reset() } // A PathIdentity is a common identity identified by a type and a path, e.g. "layouts" and "_default/single.html". type PathIdentity struct { Type string Path string } // GetIdentity returns itself. func (id PathIdentity) GetIdentity() Identity { return id } // Name returns the Path. func (id PathIdentity) Name() string { return id.Path } // A KeyValueIdentity a general purpose identity. type KeyValueIdentity struct { Key string Value string } // GetIdentity returns itself. func (id KeyValueIdentity) GetIdentity() Identity { return id } // Name returns the Key. func (id KeyValueIdentity) Name() string { return id.Key } // Provider provides the hashable Identity. type Provider interface { GetIdentity() Identity } type identityManager struct { sync.Mutex Provider ids Identities } func (im *identityManager) Add(ids ...Provider) { im.Lock() for _, id := range ids { im.ids[id.GetIdentity()] = id } im.Unlock() } func (im *identityManager) Reset() { im.Lock() id := im.GetIdentity() im.ids = Identities{id.GetIdentity(): id} im.Unlock() } func (im *identityManager) GetIdentities() Identities { im.Lock() defer im.Unlock() return im.ids } func (im *identityManager) Search(id Identity) Provider { im.Lock() defer im.Unlock() return im.ids.search(0, id.GetIdentity()) } hugo-0.68.3/identity/identity_test.go000066400000000000000000000021051363637351300176320ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package identity import ( "testing" qt "github.com/frankban/quicktest" ) func TestIdentityManager(t *testing.T) { c := qt.New(t) id1 := testIdentity{name: "id1"} im := NewManager(id1) c.Assert(im.Search(id1).GetIdentity(), qt.Equals, id1) c.Assert(im.Search(testIdentity{name: "notfound"}), qt.Equals, nil) } type testIdentity struct { name string } func (id testIdentity) GetIdentity() Identity { return id } func (id testIdentity) Name() string { return id.name } hugo-0.68.3/langs/000077500000000000000000000000001363637351300136705ustar00rootroot00000000000000hugo-0.68.3/langs/config.go000066400000000000000000000131301363637351300154620ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package langs import ( "fmt" "path/filepath" "sort" "strings" "github.com/gohugoio/hugo/common/maps" "github.com/spf13/cast" "github.com/pkg/errors" "github.com/gohugoio/hugo/config" ) type LanguagesConfig struct { Languages Languages Multihost bool DefaultContentLanguageInSubdir bool } func LoadLanguageSettings(cfg config.Provider, oldLangs Languages) (c LanguagesConfig, err error) { defaultLang := cfg.GetString("defaultContentLanguage") if defaultLang == "" { defaultLang = "en" cfg.Set("defaultContentLanguage", defaultLang) } var languages map[string]interface{} languagesFromConfig := cfg.GetStringMap("languages") disableLanguages := cfg.GetStringSlice("disableLanguages") if len(disableLanguages) == 0 { languages = languagesFromConfig } else { languages = make(map[string]interface{}) for k, v := range languagesFromConfig { for _, disabled := range disableLanguages { if disabled == defaultLang { return c, fmt.Errorf("cannot disable default language %q", defaultLang) } if strings.EqualFold(k, disabled) { v.(map[string]interface{})["disabled"] = true break } } languages[k] = v } } var languages2 Languages if len(languages) == 0 { languages2 = append(languages2, NewDefaultLanguage(cfg)) } else { languages2, err = toSortedLanguages(cfg, languages) if err != nil { return c, errors.Wrap(err, "Failed to parse multilingual config") } } if oldLangs != nil { // When in multihost mode, the languages are mapped to a server, so // some structural language changes will need a restart of the dev server. // The validation below isn't complete, but should cover the most // important cases. var invalid bool if languages2.IsMultihost() != oldLangs.IsMultihost() { invalid = true } else { if languages2.IsMultihost() && len(languages2) != len(oldLangs) { invalid = true } } if invalid { return c, errors.New("language change needing a server restart detected") } if languages2.IsMultihost() { // We need to transfer any server baseURL to the new language for i, ol := range oldLangs { nl := languages2[i] nl.Set("baseURL", ol.GetString("baseURL")) } } } // The defaultContentLanguage is something the user has to decide, but it needs // to match a language in the language definition list. langExists := false for _, lang := range languages2 { if lang.Lang == defaultLang { langExists = true break } } if !langExists { return c, fmt.Errorf("site config value %q for defaultContentLanguage does not match any language definition", defaultLang) } c.Languages = languages2 c.Multihost = languages2.IsMultihost() c.DefaultContentLanguageInSubdir = c.Multihost sortedDefaultFirst := make(Languages, len(c.Languages)) for i, v := range c.Languages { sortedDefaultFirst[i] = v } sort.Slice(sortedDefaultFirst, func(i, j int) bool { li, lj := sortedDefaultFirst[i], sortedDefaultFirst[j] if li.Lang == defaultLang { return true } if lj.Lang == defaultLang { return false } return i < j }) cfg.Set("languagesSorted", c.Languages) cfg.Set("languagesSortedDefaultFirst", sortedDefaultFirst) cfg.Set("multilingual", len(languages2) > 1) multihost := c.Multihost if multihost { cfg.Set("defaultContentLanguageInSubdir", true) cfg.Set("multihost", true) } if multihost { // The baseURL may be provided at the language level. If that is true, // then every language must have a baseURL. In this case we always render // to a language sub folder, which is then stripped from all the Permalink URLs etc. for _, l := range languages2 { burl := l.GetLocal("baseURL") if burl == nil { return c, errors.New("baseURL must be set on all or none of the languages") } } } return c, nil } func toSortedLanguages(cfg config.Provider, l map[string]interface{}) (Languages, error) { languages := make(Languages, len(l)) i := 0 for lang, langConf := range l { langsMap, err := maps.ToStringMapE(langConf) if err != nil { return nil, fmt.Errorf("Language config is not a map: %T", langConf) } language := NewLanguage(lang, cfg) for loki, v := range langsMap { switch loki { case "title": language.Title = cast.ToString(v) case "languagename": language.LanguageName = cast.ToString(v) case "languagedirection": language.LanguageDirection = cast.ToString(v) case "weight": language.Weight = cast.ToInt(v) case "contentdir": language.ContentDir = filepath.Clean(cast.ToString(v)) case "disabled": language.Disabled = cast.ToBool(v) case "params": m := maps.ToStringMap(v) // Needed for case insensitive fetching of params values maps.ToLower(m) for k, vv := range m { language.SetParam(k, vv) } } // Put all into the Params map language.SetParam(loki, v) // Also set it in the configuration map (for baseURL etc.) language.Set(loki, v) } languages[i] = language i++ } sort.Sort(languages) return languages, nil } hugo-0.68.3/langs/i18n/000077500000000000000000000000001363637351300144475ustar00rootroot00000000000000hugo-0.68.3/langs/i18n/i18n.go000066400000000000000000000077241363637351300155670ustar00rootroot00000000000000// Copyright 2017 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package i18n import ( "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/helpers" "github.com/nicksnyder/go-i18n/i18n/bundle" "github.com/nicksnyder/go-i18n/i18n/translation" ) var ( i18nWarningLogger = helpers.NewDistinctFeedbackLogger() ) // Translator handles i18n translations. type Translator struct { translateFuncs map[string]bundle.TranslateFunc cfg config.Provider logger *loggers.Logger } // NewTranslator creates a new Translator for the given language bundle and configuration. func NewTranslator(b *bundle.Bundle, cfg config.Provider, logger *loggers.Logger) Translator { t := Translator{cfg: cfg, logger: logger, translateFuncs: make(map[string]bundle.TranslateFunc)} t.initFuncs(b) return t } // Func gets the translate func for the given language, or for the default // configured language if not found. func (t Translator) Func(lang string) bundle.TranslateFunc { if f, ok := t.translateFuncs[lang]; ok { return f } t.logger.INFO.Printf("Translation func for language %v not found, use default.", lang) if f, ok := t.translateFuncs[t.cfg.GetString("defaultContentLanguage")]; ok { return f } t.logger.INFO.Println("i18n not initialized; if you need string translations, check that you have a bundle in /i18n that matches the site language or the default language.") return func(translationID string, args ...interface{}) string { return "" } } func (t Translator) initFuncs(bndl *bundle.Bundle) { defaultContentLanguage := t.cfg.GetString("defaultContentLanguage") defaultT, err := bndl.Tfunc(defaultContentLanguage) if err != nil { t.logger.INFO.Printf("No translation bundle found for default language %q", defaultContentLanguage) } translations := bndl.Translations() enableMissingTranslationPlaceholders := t.cfg.GetBool("enableMissingTranslationPlaceholders") for _, lang := range bndl.LanguageTags() { currentLang := lang t.translateFuncs[currentLang] = func(translationID string, args ...interface{}) string { tFunc, err := bndl.Tfunc(currentLang) if err != nil { t.logger.WARN.Printf("could not load translations for language %q (%s), will use default content language.\n", lang, err) } translated := tFunc(translationID, args...) if translated != translationID { return translated } // If there is no translation for translationID, // then Tfunc returns translationID itself. // But if user set same translationID and translation, we should check // if it really untranslated: if isIDTranslated(translations, currentLang, translationID) { return translated } if t.cfg.GetBool("logI18nWarnings") { i18nWarningLogger.Printf("i18n|MISSING_TRANSLATION|%s|%s", currentLang, translationID) } if enableMissingTranslationPlaceholders { return "[i18n] " + translationID } if defaultT != nil { translated := defaultT(translationID, args...) if translated != translationID { return translated } if isIDTranslated(translations, defaultContentLanguage, translationID) { return translated } } return "" } } } // If the translation map contains translationID for specified currentLang, // then the translationID is actually translated. func isIDTranslated(translations map[string]map[string]translation.Translation, lang, id string) bool { _, contains := translations[lang][id] return contains } hugo-0.68.3/langs/i18n/i18n_test.go000066400000000000000000000162441363637351300166230ustar00rootroot00000000000000// Copyright 2017 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package i18n import ( "path/filepath" "testing" "github.com/gohugoio/hugo/modules" "github.com/gohugoio/hugo/tpl/tplimpl" "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/langs" "github.com/gohugoio/hugo/resources/page" "github.com/spf13/afero" "github.com/spf13/viper" "github.com/gohugoio/hugo/deps" qt "github.com/frankban/quicktest" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/hugofs" ) var logger = loggers.NewErrorLogger() type i18nTest struct { name string data map[string][]byte args interface{} lang, id, expected, expectedFlag string } var i18nTests = []i18nTest{ // All translations present { name: "all-present", data: map[string][]byte{ "en.toml": []byte("[hello]\nother = \"Hello, World!\""), "es.toml": []byte("[hello]\nother = \"¡Hola, Mundo!\""), }, args: nil, lang: "es", id: "hello", expected: "¡Hola, Mundo!", expectedFlag: "¡Hola, Mundo!", }, // Translation missing in current language but present in default { name: "present-in-default", data: map[string][]byte{ "en.toml": []byte("[hello]\nother = \"Hello, World!\""), "es.toml": []byte("[goodbye]\nother = \"¡Adiós, Mundo!\""), }, args: nil, lang: "es", id: "hello", expected: "Hello, World!", expectedFlag: "[i18n] hello", }, // Translation missing in default language but present in current { name: "present-in-current", data: map[string][]byte{ "en.toml": []byte("[goodbye]\nother = \"Goodbye, World!\""), "es.toml": []byte("[hello]\nother = \"¡Hola, Mundo!\""), }, args: nil, lang: "es", id: "hello", expected: "¡Hola, Mundo!", expectedFlag: "¡Hola, Mundo!", }, // Translation missing in both default and current language { name: "missing", data: map[string][]byte{ "en.toml": []byte("[goodbye]\nother = \"Goodbye, World!\""), "es.toml": []byte("[goodbye]\nother = \"¡Adiós, Mundo!\""), }, args: nil, lang: "es", id: "hello", expected: "", expectedFlag: "[i18n] hello", }, // Default translation file missing or empty { name: "file-missing", data: map[string][]byte{ "en.toml": []byte(""), }, args: nil, lang: "es", id: "hello", expected: "", expectedFlag: "[i18n] hello", }, // Context provided { name: "context-provided", data: map[string][]byte{ "en.toml": []byte("[wordCount]\nother = \"Hello, {{.WordCount}} people!\""), "es.toml": []byte("[wordCount]\nother = \"¡Hola, {{.WordCount}} gente!\""), }, args: struct { WordCount int }{ 50, }, lang: "es", id: "wordCount", expected: "¡Hola, 50 gente!", expectedFlag: "¡Hola, 50 gente!", }, // Same id and translation in current language // https://github.com/gohugoio/hugo/issues/2607 { name: "same-id-and-translation", data: map[string][]byte{ "es.toml": []byte("[hello]\nother = \"hello\""), "en.toml": []byte("[hello]\nother = \"hi\""), }, args: nil, lang: "es", id: "hello", expected: "hello", expectedFlag: "hello", }, // Translation missing in current language, but same id and translation in default { name: "same-id-and-translation-default", data: map[string][]byte{ "es.toml": []byte("[bye]\nother = \"bye\""), "en.toml": []byte("[hello]\nother = \"hello\""), }, args: nil, lang: "es", id: "hello", expected: "hello", expectedFlag: "[i18n] hello", }, // Unknown language code should get its plural spec from en { name: "unknown-language-code", data: map[string][]byte{ "en.toml": []byte(`[readingTime] one ="one minute read" other = "{{.Count}} minutes read"`), "klingon.toml": []byte(`[readingTime] one = "eitt minutt med lesing" other = "{{ .Count }} minuttar lesing"`), }, args: 3, lang: "klingon", id: "readingTime", expected: "3 minuttar lesing", expectedFlag: "3 minuttar lesing", }, } func doTestI18nTranslate(t testing.TB, test i18nTest, cfg config.Provider) string { tp := prepareTranslationProvider(t, test, cfg) f := tp.t.Func(test.lang) return f(test.id, test.args) } func prepareTranslationProvider(t testing.TB, test i18nTest, cfg config.Provider) *TranslationProvider { c := qt.New(t) fs := hugofs.NewMem(cfg) for file, content := range test.data { err := afero.WriteFile(fs.Source, filepath.Join("i18n", file), []byte(content), 0755) c.Assert(err, qt.IsNil) } tp := NewTranslationProvider() depsCfg := newDepsConfig(tp, cfg, fs) d, err := deps.New(depsCfg) c.Assert(err, qt.IsNil) c.Assert(d.LoadResources(), qt.IsNil) return tp } func newDepsConfig(tp *TranslationProvider, cfg config.Provider, fs *hugofs.Fs) deps.DepsCfg { l := langs.NewLanguage("en", cfg) l.Set("i18nDir", "i18n") return deps.DepsCfg{ Language: l, Site: page.NewDummyHugoSite(cfg), Cfg: cfg, Fs: fs, Logger: logger, TemplateProvider: tplimpl.DefaultTemplateProvider, TranslationProvider: tp, } } func getConfig() *viper.Viper { v := viper.New() v.SetDefault("defaultContentLanguage", "en") v.Set("contentDir", "content") v.Set("dataDir", "data") v.Set("i18nDir", "i18n") v.Set("layoutDir", "layouts") v.Set("archetypeDir", "archetypes") v.Set("assetDir", "assets") v.Set("resourceDir", "resources") v.Set("publishDir", "public") langs.LoadLanguageSettings(v, nil) mod, err := modules.CreateProjectModule(v) if err != nil { panic(err) } v.Set("allModules", modules.Modules{mod}) return v } func TestI18nTranslate(t *testing.T) { c := qt.New(t) var actual, expected string v := getConfig() // Test without and with placeholders for _, enablePlaceholders := range []bool{false, true} { v.Set("enableMissingTranslationPlaceholders", enablePlaceholders) for _, test := range i18nTests { if enablePlaceholders { expected = test.expectedFlag } else { expected = test.expected } actual = doTestI18nTranslate(t, test, v) c.Assert(actual, qt.Equals, expected) } } } func BenchmarkI18nTranslate(b *testing.B) { v := getConfig() for _, test := range i18nTests { b.Run(test.name, func(b *testing.B) { tp := prepareTranslationProvider(b, test, v) b.ResetTimer() for i := 0; i < b.N; i++ { f := tp.t.Func(test.lang) actual := f(test.id, test.args) if actual != test.expected { b.Fatalf("expected %v got %v", test.expected, actual) } } }) } } hugo-0.68.3/langs/i18n/translationProvider.go000066400000000000000000000067101363637351300210530ustar00rootroot00000000000000// Copyright 2017 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package i18n import ( "errors" "github.com/gohugoio/hugo/common/herrors" "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/hugofs" "github.com/gohugoio/hugo/source" "github.com/nicksnyder/go-i18n/i18n/bundle" "github.com/nicksnyder/go-i18n/i18n/language" _errors "github.com/pkg/errors" ) // TranslationProvider provides translation handling, i.e. loading // of bundles etc. type TranslationProvider struct { t Translator } // NewTranslationProvider creates a new translation provider. func NewTranslationProvider() *TranslationProvider { return &TranslationProvider{} } // Update updates the i18n func in the provided Deps. func (tp *TranslationProvider) Update(d *deps.Deps) error { spec := source.NewSourceSpec(d.PathSpec, nil) i18nBundle := bundle.New() en := language.GetPluralSpec("en") if en == nil { return errors.New("the English language has vanished like an old oak table") } var newLangs []string // The source dirs are ordered so the most important comes first. Since this is a // last key win situation, we have to reverse the iteration order. dirs := d.BaseFs.I18n.Dirs for i := len(dirs) - 1; i >= 0; i-- { dir := dirs[i] src := spec.NewFilesystemFromFileMetaInfo(dir) files, err := src.Files() if err != nil { return err } for _, r := range files { currentSpec := language.GetPluralSpec(r.BaseFileName()) if currentSpec == nil { // This may is a language code not supported by go-i18n, it may be // Klingon or ... not even a fake language. Make sure it works. newLangs = append(newLangs, r.BaseFileName()) } } if len(newLangs) > 0 { language.RegisterPluralSpec(newLangs, en) } for _, file := range files { if err := addTranslationFile(i18nBundle, file); err != nil { return err } } } tp.t = NewTranslator(i18nBundle, d.Cfg, d.Log) d.Translate = tp.t.Func(d.Language.Lang) return nil } func addTranslationFile(bundle *bundle.Bundle, r source.File) error { f, err := r.FileInfo().Meta().Open() if err != nil { return _errors.Wrapf(err, "failed to open translations file %q:", r.LogicalName()) } err = bundle.ParseTranslationFileBytes(r.LogicalName(), helpers.ReaderToBytes(f)) f.Close() if err != nil { return errWithFileContext(_errors.Wrapf(err, "failed to load translations"), r) } return nil } // Clone sets the language func for the new language. func (tp *TranslationProvider) Clone(d *deps.Deps) error { d.Translate = tp.t.Func(d.Language.Lang) return nil } func errWithFileContext(inerr error, r source.File) error { fim, ok := r.FileInfo().(hugofs.FileMetaInfo) if !ok { return inerr } meta := fim.Meta() realFilename := meta.Filename() f, err := meta.Open() if err != nil { return inerr } defer f.Close() err, _ = herrors.WithFileContext( inerr, realFilename, f, herrors.SimpleLineMatcher) return err } hugo-0.68.3/langs/language.go000066400000000000000000000165731363637351300160160ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package langs import ( "sort" "strings" "sync" "github.com/gohugoio/hugo/common/maps" "github.com/gohugoio/hugo/config" "github.com/spf13/cast" ) // These are the settings that should only be looked up in the global Viper // config and not per language. // This list may not be complete, but contains only settings that we know // will be looked up in both. // This isn't perfect, but it is ultimately the user who shoots him/herself in // the foot. // See the pathSpec. var globalOnlySettings = map[string]bool{ strings.ToLower("defaultContentLanguageInSubdir"): true, strings.ToLower("defaultContentLanguage"): true, strings.ToLower("multilingual"): true, strings.ToLower("assetDir"): true, strings.ToLower("resourceDir"): true, strings.ToLower("build"): true, } // Language manages specific-language configuration. type Language struct { Lang string LanguageName string LanguageDirection string Title string Weight int Disabled bool // If set per language, this tells Hugo that all content files without any // language indicator (e.g. my-page.en.md) is in this language. // This is usually a path relative to the working dir, but it can be an // absolute directory reference. It is what we get. ContentDir string Cfg config.Provider // These are params declared in the [params] section of the language merged with the // site's params, the most specific (language) wins on duplicate keys. params map[string]interface{} paramsMu sync.Mutex paramsSet bool // These are config values, i.e. the settings declared outside of the [params] section of the language. // This is the map Hugo looks in when looking for configuration values (baseURL etc.). // Values in this map can also be fetched from the params map above. settings map[string]interface{} } func (l *Language) String() string { return l.Lang } // NewLanguage creates a new language. func NewLanguage(lang string, cfg config.Provider) *Language { // Note that language specific params will be overridden later. // We should improve that, but we need to make a copy: params := make(map[string]interface{}) for k, v := range cfg.GetStringMap("params") { params[k] = v } maps.ToLower(params) l := &Language{Lang: lang, ContentDir: cfg.GetString("contentDir"), Cfg: cfg, params: params, settings: make(map[string]interface{})} return l } // NewDefaultLanguage creates the default language for a config.Provider. // If not otherwise specified the default is "en". func NewDefaultLanguage(cfg config.Provider) *Language { defaultLang := cfg.GetString("defaultContentLanguage") if defaultLang == "" { defaultLang = "en" } return NewLanguage(defaultLang, cfg) } // Languages is a sortable list of languages. type Languages []*Language // NewLanguages creates a sorted list of languages. // NOTE: function is currently unused. func NewLanguages(l ...*Language) Languages { languages := make(Languages, len(l)) for i := 0; i < len(l); i++ { languages[i] = l[i] } sort.Sort(languages) return languages } func (l Languages) Len() int { return len(l) } func (l Languages) Less(i, j int) bool { wi, wj := l[i].Weight, l[j].Weight if wi == wj { return l[i].Lang < l[j].Lang } return wj == 0 || wi < wj } func (l Languages) Swap(i, j int) { l[i], l[j] = l[j], l[i] } // Params retunrs language-specific params merged with the global params. func (l *Language) Params() maps.Params { // TODO(bep) this construct should not be needed. Create the // language params in one go. l.paramsMu.Lock() defer l.paramsMu.Unlock() if !l.paramsSet { maps.ToLower(l.params) l.paramsSet = true } return l.params } func (l Languages) AsSet() map[string]bool { m := make(map[string]bool) for _, lang := range l { m[lang.Lang] = true } return m } func (l Languages) AsOrdinalSet() map[string]int { m := make(map[string]int) for i, lang := range l { m[lang.Lang] = i } return m } // IsMultihost returns whether there are more than one language and at least one of // the languages has baseURL specificed on the language level. func (l Languages) IsMultihost() bool { if len(l) <= 1 { return false } for _, lang := range l { if lang.GetLocal("baseURL") != nil { return true } } return false } // SetParam sets a param with the given key and value. // SetParam is case-insensitive. func (l *Language) SetParam(k string, v interface{}) { l.paramsMu.Lock() defer l.paramsMu.Unlock() if l.paramsSet { panic("params cannot be changed once set") } l.params[k] = v } // GetBool returns the value associated with the key as a boolean. func (l *Language) GetBool(key string) bool { return cast.ToBool(l.Get(key)) } // GetString returns the value associated with the key as a string. func (l *Language) GetString(key string) string { return cast.ToString(l.Get(key)) } // GetInt returns the value associated with the key as an int. func (l *Language) GetInt(key string) int { return cast.ToInt(l.Get(key)) } // GetStringMap returns the value associated with the key as a map of interfaces. func (l *Language) GetStringMap(key string) map[string]interface{} { return maps.ToStringMap(l.Get(key)) } // GetStringMapString returns the value associated with the key as a map of strings. func (l *Language) GetStringMapString(key string) map[string]string { return cast.ToStringMapString(l.Get(key)) } // GetStringSlice returns the value associated with the key as a slice of strings. func (l *Language) GetStringSlice(key string) []string { return cast.ToStringSlice(l.Get(key)) } // Get returns a value associated with the key relying on specified language. // Get is case-insensitive for a key. // // Get returns an interface. For a specific value use one of the Get____ methods. func (l *Language) Get(key string) interface{} { local := l.GetLocal(key) if local != nil { return local } return l.Cfg.Get(key) } // GetLocal gets a configuration value set on language level. It will // not fall back to any global value. // It will return nil if a value with the given key cannot be found. func (l *Language) GetLocal(key string) interface{} { if l == nil { panic("language not set") } key = strings.ToLower(key) if !globalOnlySettings[key] { if v, ok := l.settings[key]; ok { return v } } return nil } // Set sets the value for the key in the language's params. func (l *Language) Set(key string, value interface{}) { if l == nil { panic("language not set") } key = strings.ToLower(key) l.settings[key] = value } // IsSet checks whether the key is set in the language or the related config store. func (l *Language) IsSet(key string) bool { key = strings.ToLower(key) key = strings.ToLower(key) if !globalOnlySettings[key] { if _, ok := l.settings[key]; ok { return true } } return l.Cfg.IsSet(key) } hugo-0.68.3/langs/language_test.go000066400000000000000000000026431363637351300170460ustar00rootroot00000000000000// Copyright 2018 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package langs import ( "testing" qt "github.com/frankban/quicktest" "github.com/spf13/viper" ) func TestGetGlobalOnlySetting(t *testing.T) { c := qt.New(t) v := viper.New() v.Set("defaultContentLanguageInSubdir", true) v.Set("contentDir", "content") v.Set("paginatePath", "page") lang := NewDefaultLanguage(v) lang.Set("defaultContentLanguageInSubdir", false) lang.Set("paginatePath", "side") c.Assert(lang.GetBool("defaultContentLanguageInSubdir"), qt.Equals, true) c.Assert(lang.GetString("paginatePath"), qt.Equals, "side") } func TestLanguageParams(t *testing.T) { c := qt.New(t) v := viper.New() v.Set("p1", "p1cfg") v.Set("contentDir", "content") lang := NewDefaultLanguage(v) lang.SetParam("p1", "p1p") c.Assert(lang.Params()["p1"], qt.Equals, "p1p") c.Assert(lang.Get("p1"), qt.Equals, "p1cfg") } hugo-0.68.3/lazy/000077500000000000000000000000001363637351300135435ustar00rootroot00000000000000hugo-0.68.3/lazy/init.go000066400000000000000000000104031363637351300150330ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package lazy import ( "context" "sync" "time" "github.com/pkg/errors" ) // New creates a new empty Init. func New() *Init { return &Init{} } // Init holds a graph of lazily initialized dependencies. type Init struct { mu sync.Mutex prev *Init children []*Init init onceMore out interface{} err error f func() (interface{}, error) } // Add adds a func as a new child dependency. func (ini *Init) Add(initFn func() (interface{}, error)) *Init { if ini == nil { ini = New() } return ini.add(false, initFn) } // AddWithTimeout is same as Add, but with a timeout that aborts initialization. func (ini *Init) AddWithTimeout(timeout time.Duration, f func(ctx context.Context) (interface{}, error)) *Init { return ini.Add(func() (interface{}, error) { return ini.withTimeout(timeout, f) }) } // Branch creates a new dependency branch based on an existing and adds // the given dependency as a child. func (ini *Init) Branch(initFn func() (interface{}, error)) *Init { if ini == nil { ini = New() } return ini.add(true, initFn) } // BranchdWithTimeout is same as Branch, but with a timeout. func (ini *Init) BranchWithTimeout(timeout time.Duration, f func(ctx context.Context) (interface{}, error)) *Init { return ini.Branch(func() (interface{}, error) { return ini.withTimeout(timeout, f) }) } // Do initializes the entire dependency graph. func (ini *Init) Do() (interface{}, error) { if ini == nil { panic("init is nil") } ini.init.Do(func() { prev := ini.prev if prev != nil { // A branch. Initialize the ancestors. if prev.shouldInitialize() { _, err := prev.Do() if err != nil { ini.err = err return } } else if prev.inProgress() { // Concurrent initialization. The following init func // may depend on earlier state, so wait. prev.wait() } } if ini.f != nil { ini.out, ini.err = ini.f() } for _, child := range ini.children { if child.shouldInitialize() { _, err := child.Do() if err != nil { ini.err = err return } } } }) ini.wait() return ini.out, ini.err } // TODO(bep) investigate if we can use sync.Cond for this. func (ini *Init) wait() { var counter time.Duration for !ini.init.Done() { counter += 10 if counter > 600000000 { panic("BUG: timed out in lazy init") } time.Sleep(counter * time.Microsecond) } } func (ini *Init) inProgress() bool { return ini != nil && ini.init.InProgress() } func (ini *Init) shouldInitialize() bool { return !(ini == nil || ini.init.Done() || ini.init.InProgress()) } // Reset resets the current and all its dependencies. func (ini *Init) Reset() { mu := ini.init.ResetWithLock() defer mu.Unlock() for _, d := range ini.children { d.Reset() } } func (ini *Init) add(branch bool, initFn func() (interface{}, error)) *Init { ini.mu.Lock() defer ini.mu.Unlock() if branch { return &Init{ f: initFn, prev: ini, } } ini.checkDone() ini.children = append(ini.children, &Init{ f: initFn, }) return ini } func (ini *Init) checkDone() { if ini.init.Done() { panic("init cannot be added to after it has run") } } func (ini *Init) withTimeout(timeout time.Duration, f func(ctx context.Context) (interface{}, error)) (interface{}, error) { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() c := make(chan verr, 1) go func() { v, err := f(ctx) select { case <-ctx.Done(): return default: c <- verr{v: v, err: err} } }() select { case <-ctx.Done(): return nil, errors.New("timed out initializing value. This is most likely a circular loop in a shortcode") case ve := <-c: return ve.v, ve.err } } type verr struct { v interface{} err error } hugo-0.68.3/lazy/init_test.go000066400000000000000000000102001363637351300160650ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package lazy import ( "context" "errors" "math/rand" "strings" "sync" "testing" "time" qt "github.com/frankban/quicktest" ) var ( rnd = rand.New(rand.NewSource(time.Now().UnixNano())) bigOrSmall = func() int { if rnd.Intn(10) < 5 { return 10000 + rnd.Intn(100000) } return 1 + rnd.Intn(50) } ) func doWork() { doWorkOfSize(bigOrSmall()) } func doWorkOfSize(size int) { _ = strings.Repeat("Hugo Rocks! ", size) } func TestInit(t *testing.T) { c := qt.New(t) var result string f1 := func(name string) func() (interface{}, error) { return func() (interface{}, error) { result += name + "|" doWork() return name, nil } } f2 := func() func() (interface{}, error) { return func() (interface{}, error) { doWork() return nil, nil } } root := New() root.Add(f1("root(1)")) root.Add(f1("root(2)")) branch1 := root.Branch(f1("branch_1")) branch1.Add(f1("branch_1_1")) branch1_2 := branch1.Add(f1("branch_1_2")) branch1_2_1 := branch1_2.Add(f1("branch_1_2_1")) var wg sync.WaitGroup // Add some concurrency and randomness to verify thread safety and // init order. for i := 0; i < 100; i++ { wg.Add(1) go func(i int) { defer wg.Done() var err error if rnd.Intn(10) < 5 { _, err = root.Do() c.Assert(err, qt.IsNil) } // Add a new branch on the fly. if rnd.Intn(10) > 5 { branch := branch1_2.Branch(f2()) _, err = branch.Do() c.Assert(err, qt.IsNil) } else { _, err = branch1_2_1.Do() c.Assert(err, qt.IsNil) } _, err = branch1_2.Do() c.Assert(err, qt.IsNil) }(i) wg.Wait() c.Assert(result, qt.Equals, "root(1)|root(2)|branch_1|branch_1_1|branch_1_2|branch_1_2_1|") } } func TestInitAddWithTimeout(t *testing.T) { c := qt.New(t) init := New().AddWithTimeout(100*time.Millisecond, func(ctx context.Context) (interface{}, error) { return nil, nil }) _, err := init.Do() c.Assert(err, qt.IsNil) } func TestInitAddWithTimeoutTimeout(t *testing.T) { c := qt.New(t) init := New().AddWithTimeout(100*time.Millisecond, func(ctx context.Context) (interface{}, error) { time.Sleep(500 * time.Millisecond) select { case <-ctx.Done(): return nil, nil default: } t.Fatal("slept") return nil, nil }) _, err := init.Do() c.Assert(err, qt.Not(qt.IsNil)) c.Assert(err.Error(), qt.Contains, "timed out") time.Sleep(1 * time.Second) } func TestInitAddWithTimeoutError(t *testing.T) { c := qt.New(t) init := New().AddWithTimeout(100*time.Millisecond, func(ctx context.Context) (interface{}, error) { return nil, errors.New("failed") }) _, err := init.Do() c.Assert(err, qt.Not(qt.IsNil)) } type T struct { sync.Mutex V1 string V2 string } func (t *T) Add1(v string) { t.Lock() t.V1 += v t.Unlock() } func (t *T) Add2(v string) { t.Lock() t.V2 += v t.Unlock() } // https://github.com/gohugoio/hugo/issues/5901 func TestInitBranchOrder(t *testing.T) { c := qt.New(t) base := New() work := func(size int, f func()) func() (interface{}, error) { return func() (interface{}, error) { doWorkOfSize(size) if f != nil { f() } return nil, nil } } state := &T{} base = base.Add(work(10000, func() { state.Add1("A") })) inits := make([]*Init, 2) for i := range inits { inits[i] = base.Branch(work(i+1*100, func() { // V1 is A ab := state.V1 + "B" state.Add2(ab) })) } var wg sync.WaitGroup for _, v := range inits { v := v wg.Add(1) go func() { defer wg.Done() _, err := v.Do() c.Assert(err, qt.IsNil) }() } wg.Wait() c.Assert(state.V2, qt.Equals, "ABAB") } hugo-0.68.3/lazy/once.go000066400000000000000000000030501363637351300150140ustar00rootroot00000000000000// Copyright 2019 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package lazy import ( "sync" "sync/atomic" ) // onceMore is similar to sync.Once. // // Additional features are: // * it can be reset, so the action can be repeated if needed // * it has methods to check if it's done or in progress // type onceMore struct { mu sync.Mutex lock uint32 done uint32 } func (t *onceMore) Do(f func()) { if atomic.LoadUint32(&t.done) == 1 { return } // f may call this Do and we would get a deadlock. locked := atomic.CompareAndSwapUint32(&t.lock, 0, 1) if !locked { return } defer atomic.StoreUint32(&t.lock, 0) t.mu.Lock() defer t.mu.Unlock() // Double check if t.done == 1 { return } defer atomic.StoreUint32(&t.done, 1) f() } func (t *onceMore) InProgress() bool { return atomic.LoadUint32(&t.lock) == 1 } func (t *onceMore) Done() bool { return atomic.LoadUint32(&t.done) == 1 } func (t *onceMore) ResetWithLock() *sync.Mutex { t.mu.Lock() defer atomic.StoreUint32(&t.done, 0) return &t.mu } hugo-0.68.3/livereload/000077500000000000000000000000001363637351300147125ustar00rootroot00000000000000hugo-0.68.3/livereload/connection.go000066400000000000000000000030551363637351300174030ustar00rootroot00000000000000// Copyright 2015 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package livereload import ( "bytes" "sync" "github.com/gorilla/websocket" ) type connection struct { // The websocket connection. ws *websocket.Conn // Buffered channel of outbound messages. send chan []byte // There is a potential data race, especially visible with large files. // This is protected by synchronisation of the send channel's close. closer sync.Once } func (c *connection) close() { c.closer.Do(func() { close(c.send) }) } func (c *connection) reader() { for { _, message, err := c.ws.ReadMessage() if err != nil { break } if bytes.Contains(message, []byte(`"command":"hello"`)) { c.send <- []byte(`{ "command": "hello", "protocols": [ "http://livereload.com/protocols/official-7" ], "serverName": "Hugo" }`) } } c.ws.Close() } func (c *connection) writer() { for message := range c.send { err := c.ws.WriteMessage(websocket.TextMessage, message) if err != nil { break } } c.ws.Close() } hugo-0.68.3/livereload/hub.go000066400000000000000000000026261363637351300160250ustar00rootroot00000000000000// Copyright 2015 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package livereload type hub struct { // Registered connections. connections map[*connection]bool // Inbound messages from the connections. broadcast chan []byte // Register requests from the connections. register chan *connection // Unregister requests from connections. unregister chan *connection } var wsHub = hub{ broadcast: make(chan []byte), register: make(chan *connection), unregister: make(chan *connection), connections: make(map[*connection]bool), } func (h *hub) run() { for { select { case c := <-h.register: h.connections[c] = true case c := <-h.unregister: delete(h.connections, c) c.close() case m := <-h.broadcast: for c := range h.connections { select { case c.send <- m: default: delete(h.connections, c) c.close() } } } } } hugo-0.68.3/livereload/livereload.go000066400000000000000000001077001363637351300173740ustar00rootroot00000000000000// Copyright 2015 The Hugo Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // Contains an embedded version of livereload.js // // Copyright (c) 2010-2015 Andrey Tarantsov // // 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. package livereload import ( "fmt" "net" "net/http" "net/url" "path/filepath" "github.com/gorilla/websocket" ) // Prefix to signal to LiveReload that we need to navigate to another path. const hugoNavigatePrefix = "__hugo_navigate" var upgrader = &websocket.Upgrader{ // Hugo may potentially spin up multiple HTTP servers, so we need to exclude the // port when checking the origin. CheckOrigin: func(r *http.Request) bool { origin := r.Header["Origin"] if len(origin) == 0 { return true } u, err := url.Parse(origin[0]) if err != nil { return false } if u.Host == r.Host { return true } h1, _, err := net.SplitHostPort(u.Host) if err != nil { return false } h2, _, err := net.SplitHostPort(r.Host) if err != nil { return false } return h1 == h2 }, ReadBufferSize: 1024, WriteBufferSize: 1024} // Handler is a HandlerFunc handling the livereload // Websocket interaction. func Handler(w http.ResponseWriter, r *http.Request) { ws, err := upgrader.Upgrade(w, r, nil) if err != nil { return } c := &connection{send: make(chan []byte, 256), ws: ws} wsHub.register <- c defer func() { wsHub.unregister <- c }() go c.writer() c.reader() } // Initialize starts the Websocket Hub handling live reloads. func Initialize() { go wsHub.run() } // ForceRefresh tells livereload to force a hard refresh. func ForceRefresh() { RefreshPath("/x.js") } // NavigateToPath tells livereload to navigate to the given path. // This translates to `window.location.href = path` in the client. func NavigateToPath(path string) { RefreshPath(hugoNavigatePrefix + path) } // NavigateToPathForPort is similar to NavigateToPath but will also // set window.location.port to the given port value. func NavigateToPathForPort(path string, port int) { refreshPathForPort(hugoNavigatePrefix+path, port) } // RefreshPath tells livereload to refresh only the given path. // If that path points to a CSS stylesheet or an image, only the changes // will be updated in the browser, not the entire page. func RefreshPath(s string) { refreshPathForPort(s, -1) } func refreshPathForPort(s string, port int) { // Tell livereload a file has changed - will force a hard refresh if not CSS or an image urlPath := filepath.ToSlash(s) portStr := "" if port > 0 { portStr = fmt.Sprintf(`, "overrideURL": %d`, port) } msg := fmt.Sprintf(`{"command":"reload","path":%q,"originalPath":"","liveCSS":true,"liveImg":true%s}`, urlPath, portStr) wsHub.broadcast <- []byte(msg) } // ServeJS serves the liverreload.js who's reference is injected into the page. func ServeJS(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/javascript") w.Write(liveReloadJS()) } func liveReloadJS() []byte { return []byte(livereloadJS + hugoLiveReloadPlugin) } var ( // This is a patched version, see https://github.com/livereload/livereload-js/pull/84 livereloadJS = `!function(){return function e(t,o,n){function r(s,c){if(!o[s]){if(!t[s]){var a="function"==typeof require&&require;if(!c&&a)return a(s,!0);if(i)return i(s,!0);var l=new Error("Cannot find module '"+s+"'");throw l.code="MODULE_NOT_FOUND",l}var h=o[s]={exports:{}};t[s][0].call(h.exports,function(e){return r(t[s][1][e]||e)},h,h.exports,e,t,o,n)}return o[s].exports}for(var i="function"==typeof require&&require,s=0;sh;)if((c=a[h++])!=c)return!0}else for(;l>h;h++)if((e||h in a)&&a[h]===o)return e||h||0;return!e&&-1}}},{"./_to-absolute-index":38,"./_to-iobject":40,"./_to-length":41}],5:[function(e,t,o){var n={}.toString;t.exports=function(e){return n.call(e).slice(8,-1)}},{}],6:[function(e,t,o){var n=t.exports={version:"2.6.5"};"number"==typeof __e&&(__e=n)},{}],7:[function(e,t,o){var n=e("./_a-function");t.exports=function(e,t,o){if(n(e),void 0===t)return e;switch(o){case 1:return function(o){return e.call(t,o)};case 2:return function(o,n){return e.call(t,o,n)};case 3:return function(o,n,r){return e.call(t,o,n,r)}}return function(){return e.apply(t,arguments)}}},{"./_a-function":1}],8:[function(e,t,o){t.exports=function(e){if(null==e)throw TypeError("Can't call method on "+e);return e}},{}],9:[function(e,t,o){t.exports=!e("./_fails")(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},{"./_fails":13}],10:[function(e,t,o){var n=e("./_is-object"),r=e("./_global").document,i=n(r)&&n(r.createElement);t.exports=function(e){return i?r.createElement(e):{}}},{"./_global":15,"./_is-object":21}],11:[function(e,t,o){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},{}],12:[function(e,t,o){var n=e("./_global"),r=e("./_core"),i=e("./_hide"),s=e("./_redefine"),c=e("./_ctx"),a=function(e,t,o){var l,h,u,d,f=e&a.F,p=e&a.G,_=e&a.S,m=e&a.P,g=e&a.B,y=p?n:_?n[t]||(n[t]={}):(n[t]||{}).prototype,v=p?r:r[t]||(r[t]={}),w=v.prototype||(v.prototype={});for(l in p&&(o=t),o)u=((h=!f&&y&&void 0!==y[l])?y:o)[l],d=g&&h?c(u,n):m&&"function"==typeof u?c(Function.call,u):u,y&&s(y,l,u,e&a.U),v[l]!=u&&i(v,l,d),m&&w[l]!=u&&(w[l]=u)};n.core=r,a.F=1,a.G=2,a.S=4,a.P=8,a.B=16,a.W=32,a.U=64,a.R=128,t.exports=a},{"./_core":6,"./_ctx":7,"./_global":15,"./_hide":17,"./_redefine":34}],13:[function(e,t,o){t.exports=function(e){try{return!!e()}catch(e){return!0}}},{}],14:[function(e,t,o){t.exports=e("./_shared")("native-function-to-string",Function.toString)},{"./_shared":37}],15:[function(e,t,o){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},{}],16:[function(e,t,o){var n={}.hasOwnProperty;t.exports=function(e,t){return n.call(e,t)}},{}],17:[function(e,t,o){var n=e("./_object-dp"),r=e("./_property-desc");t.exports=e("./_descriptors")?function(e,t,o){return n.f(e,t,r(1,o))}:function(e,t,o){return e[t]=o,e}},{"./_descriptors":9,"./_object-dp":28,"./_property-desc":33}],18:[function(e,t,o){var n=e("./_global").document;t.exports=n&&n.documentElement},{"./_global":15}],19:[function(e,t,o){t.exports=!e("./_descriptors")&&!e("./_fails")(function(){return 7!=Object.defineProperty(e("./_dom-create")("div"),"a",{get:function(){return 7}}).a})},{"./_descriptors":9,"./_dom-create":10,"./_fails":13}],20:[function(e,t,o){var n=e("./_cof");t.exports=Object("z").propertyIsEnumerable(0)?Object:function(e){return"String"==n(e)?e.split(""):Object(e)}},{"./_cof":5}],21:[function(e,t,o){t.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},{}],22:[function(e,t,o){"use strict";var n=e("./_object-create"),r=e("./_property-desc"),i=e("./_set-to-string-tag"),s={};e("./_hide")(s,e("./_wks")("iterator"),function(){return this}),t.exports=function(e,t,o){e.prototype=n(s,{next:r(1,o)}),i(e,t+" Iterator")}},{"./_hide":17,"./_object-create":27,"./_property-desc":33,"./_set-to-string-tag":35,"./_wks":45}],23:[function(e,t,o){"use strict";var n=e("./_library"),r=e("./_export"),i=e("./_redefine"),s=e("./_hide"),c=e("./_iterators"),a=e("./_iter-create"),l=e("./_set-to-string-tag"),h=e("./_object-gpo"),u=e("./_wks")("iterator"),d=!([].keys&&"next"in[].keys()),f=function(){return this};t.exports=function(e,t,o,p,_,m,g){a(o,t,p);var y,v,w,b=function(e){if(!d&&e in L)return L[e];switch(e){case"keys":case"values":return function(){return new o(this,e)}}return function(){return new o(this,e)}},S=t+" Iterator",R="values"==_,k=!1,L=e.prototype,x=L[u]||L["@@iterator"]||_&&L[_],j=x||b(_),C=_?R?b("entries"):j:void 0,O="Array"==t&&L.entries||x;if(O&&(w=h(O.call(new e)))!==Object.prototype&&w.next&&(l(w,S,!0),n||"function"==typeof w[u]||s(w,u,f)),R&&x&&"values"!==x.name&&(k=!0,j=function(){return x.call(this)}),n&&!g||!d&&!k&&L[u]||s(L,u,j),c[t]=j,c[S]=f,_)if(y={values:R?j:b("values"),keys:m?j:b("keys"),entries:C},g)for(v in y)v in L||i(L,v,y[v]);else r(r.P+r.F*(d||k),t,y);return y}},{"./_export":12,"./_hide":17,"./_iter-create":22,"./_iterators":25,"./_library":26,"./_object-gpo":30,"./_redefine":34,"./_set-to-string-tag":35,"./_wks":45}],24:[function(e,t,o){t.exports=function(e,t){return{value:t,done:!!e}}},{}],25:[function(e,t,o){t.exports={}},{}],26:[function(e,t,o){t.exports=!1},{}],27:[function(e,t,o){var n=e("./_an-object"),r=e("./_object-dps"),i=e("./_enum-bug-keys"),s=e("./_shared-key")("IE_PROTO"),c=function(){},a=function(){var t,o=e("./_dom-create")("iframe"),n=i.length;for(o.style.display="none",e("./_html").appendChild(o),o.src="javascript:",(t=o.contentWindow.document).open(),t.write("`, []string{ `"\u003cb\u003e \"foo%\" O'Reilly \u0026bar;"`, `"a[href =~ \"//example.com\"]#foo"`, `"Hello, \u003cb\u003eWorld\u003c/b\u003e \u0026amp;tc!"`, `" dir=\"ltr\""`, // Not escaped. `c && alert("Hello, World!");`, // Escape sequence not over-escaped. `"Hello, World & O'Reilly\x21"`, `"greeting=H%69,\u0026addressee=(World)"`, `"greeting=H%69,\u0026addressee=(World) 2x, https://golang.org/favicon.ico 500.5w"`, `",foo/,"`, }, }, { `