diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index aa7547e1..00000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -FROM docker.io/library/ruby:3.0.4 \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 28de3d8b..00000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,24 +0,0 @@ -// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: -// https://github.com/microsoft/vscode-dev-containers/tree/v0.205.2/containers/ruby -{ - "name": "Ruby", - "build": { - "dockerfile": "Dockerfile", - }, - // Set *default* container specific settings.json values on container create. - "settings": {}, - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - "rebornix.Ruby" - ], - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - // Use 'postCreateCommand' to run commands after the container is created. - "postCreateCommand": "gem install bundler:2.3.5 && bundle install", - // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. - // "remoteUser": "vscode" - "workspaceMount": "", - "runArgs": [ - "--volume=${localWorkspaceFolder}:/workspaces/${localWorkspaceFolderBasename}:Z" - ] -} \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 3f35c72c..7038b5a9 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -9,19 +9,12 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - - uses: ruby/setup-ruby@v1 - with: - bundler-cache: true - - run: bundle install - - run: bundle exec middleman build - - - id: variables - run: | - [[ ! -f .ruby-version ]] && exit 1 - RUBY_VERSION="$(< .ruby-version)" - echo "::set-output name=RUBY_VERSION::${RUBY_VERSION}" + - name: Build with Zola + uses: shalzz/zola-deploy-action@v0.19.2 + env: + BUILD_ONLY: true - uses: docker/setup-buildx-action@v2 - uses: docker/login-action@v2 @@ -38,8 +31,6 @@ jobs: tags: | ghcr.io/flatpak/flatpak.github.io:${{ github.sha }} ghcr.io/flatpak/flatpak.github.io:latest - build-args: | - RUBY_VERSION=${{ steps.variables.outputs.RUBY_VERSION }} labels: | org.opencontainers.image.revision=${{ github.sha }} org.opencontainers.image.source=ssh://git@github.com:${{ github.repository }}.git diff --git a/.gitignore b/.gitignore index 7a6470ff..31bc0a2d 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ .jekyll-cache .gem _site +/public diff --git a/.ruby-version b/.ruby-version deleted file mode 100644 index b0f2dcb3..00000000 --- a/.ruby-version +++ /dev/null @@ -1 +0,0 @@ -3.0.4 diff --git a/Dockerfile b/Dockerfile index d2f10734..58f03fff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,9 @@ -ARG RUBY_VERSION -FROM docker.io/library/ruby:$RUBY_VERSION AS build +FROM ghcr.io/getzola/zola:v0.19.2 AS build WORKDIR /builddir COPY . . -RUN bundle install --deployment -RUN bundle exec middleman build +RUN ["zola", "build"] FROM docker.io/nginxinc/nginx-unprivileged:stable -COPY --from=build /builddir/build /srv/http/ +COPY --from=build /builddir/public /srv/http/ ADD nginx.conf /etc/nginx/conf.d/default.conf diff --git a/Gemfile b/Gemfile deleted file mode 100644 index bdb419b3..00000000 --- a/Gemfile +++ /dev/null @@ -1,29 +0,0 @@ -source 'https://rubygems.org' - -gem "middleman", "~> 4"#, github: "middleman/middleman", branch: "v3-stable" -gem "matomo-middleman", git: "https://github.com/flatpak/middleman-matomo" -#gem "middleman-blog" -gem "middleman-livereload" #3.1.0 -gem "nokogiri" #1.6.0 (xml html smarts) -gem "redcarpet" -gem "haml" #4.0.4 -gem "sass" #3.2.12 - -# For feed.xml.builder -# gem "builder"# , "~> 3.0" - -# Syntax highlighting -# gem "middleman-syntax" - -#deployment -gem "middleman-deploy", "~> 2.0.0.pre.alpha" -#gem "middleman-gh-pages" - -#bootstrap -gem "bootstrap-sass" # "3.0.0" -#bug in sprockets 3.1.2 -gem "middleman-sprockets", "~> 4.1.1" - -#Ubuntu specific gems -gem "rb-inotify" -gem "mini_racer", "~> 0.6.2" diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 2f92c3b4..00000000 --- a/Gemfile.lock +++ /dev/null @@ -1,172 +0,0 @@ -GIT - remote: https://github.com/flatpak/middleman-matomo - revision: b375ede03252aa84f396ae06bda5017778e54fdd - specs: - matomo-middleman (0.0.3) - middleman-core (>= 4.2) - -GEM - remote: https://rubygems.org/ - specs: - activesupport (6.1.7.6) - concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 1.6, < 2) - minitest (>= 5.1) - tzinfo (~> 2.0) - zeitwerk (~> 2.3) - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) - autoprefixer-rails (10.4.7.0) - execjs (~> 2) - backports (3.23.0) - bootstrap-sass (3.4.1) - autoprefixer-rails (>= 5.2.1) - sassc (>= 2.0.0) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.12.2) - concurrent-ruby (1.2.2) - contracts (0.13.0) - dotenv (2.7.6) - em-websocket (0.5.3) - eventmachine (>= 0.12.9) - http_parser.rb (~> 0) - erubis (2.7.0) - eventmachine (1.2.7) - execjs (2.8.1) - fast_blank (1.0.1) - fastimage (2.2.6) - ffi (1.15.5) - haml (5.2.2) - temple (>= 0.8.0) - tilt - hamster (3.0.0) - concurrent-ruby (~> 1.0) - hashie (3.6.0) - http_parser.rb (0.8.0) - i18n (1.6.0) - concurrent-ruby (~> 1.0) - kramdown (2.4.0) - rexml - libv8-node (16.10.0.0-aarch64-linux) - libv8-node (16.10.0.0-x86_64-linux) - listen (3.0.8) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - memoist (0.16.2) - middleman (4.4.2) - coffee-script (~> 2.2) - haml (>= 4.0.5) - kramdown (>= 2.3.0) - middleman-cli (= 4.4.2) - middleman-core (= 4.4.2) - middleman-cli (4.4.2) - thor (>= 0.17.0, < 2.0) - middleman-core (4.4.2) - activesupport (>= 6.1, < 7.0) - addressable (~> 2.4) - backports (~> 3.6) - bundler (~> 2.0) - contracts (~> 0.13.0) - dotenv - erubis - execjs (~> 2.0) - fast_blank - fastimage (~> 2.0) - hamster (~> 3.0) - hashie (~> 3.4) - i18n (~> 1.6.0) - listen (~> 3.0.0) - memoist (~> 0.14) - padrino-helpers (~> 0.15.0) - parallel - rack (>= 1.4.5, < 3) - sassc (~> 2.0) - servolux - tilt (~> 2.0.9) - toml - uglifier (~> 3.0) - webrick - middleman-deploy (2.0.0.pre.alpha) - middleman-core (>= 3.2) - net-sftp - ptools - middleman-livereload (3.4.7) - em-websocket (~> 0.5.1) - middleman-core (>= 3.3) - rack-livereload (~> 0.3.15) - middleman-sprockets (4.1.1) - middleman-core (~> 4.0) - sprockets (>= 3.0) - mini_racer (0.6.2) - libv8-node (~> 16.10.0.0) - minitest (5.19.0) - net-sftp (3.0.0) - net-ssh (>= 5.0.0, < 7.0.0) - net-ssh (6.1.0) - nokogiri (1.16.5-aarch64-linux) - racc (~> 1.4) - nokogiri (1.16.5-x86_64-linux) - racc (~> 1.4) - padrino-helpers (0.15.1) - i18n (>= 0.6.7, < 2) - padrino-support (= 0.15.1) - tilt (>= 1.4.1, < 3) - padrino-support (0.15.1) - parallel (1.22.1) - parslet (2.0.0) - ptools (1.4.2) - public_suffix (4.0.7) - racc (1.7.3) - rack (2.2.8.1) - rack-livereload (0.3.17) - rack - rb-fsevent (0.11.1) - rb-inotify (0.10.1) - ffi (~> 1.0) - redcarpet (3.5.1) - rexml (3.3.9) - sass (3.7.4) - sass-listen (~> 4.0.0) - sass-listen (4.0.0) - rb-fsevent (~> 0.9, >= 0.9.4) - rb-inotify (~> 0.9, >= 0.9.7) - sassc (2.4.0) - ffi (~> 1.9) - servolux (0.13.0) - sprockets (4.0.3) - concurrent-ruby (~> 1.0) - rack (> 1, < 3) - temple (0.8.2) - thor (1.2.1) - tilt (2.0.10) - toml (0.3.0) - parslet (>= 1.8.0, < 3.0.0) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - uglifier (3.2.0) - execjs (>= 0.3.0, < 3) - webrick (1.8.2) - zeitwerk (2.6.11) - -PLATFORMS - aarch64-linux - x86_64-linux - -DEPENDENCIES - bootstrap-sass - haml - matomo-middleman! - middleman (~> 4) - middleman-deploy (~> 2.0.0.pre.alpha) - middleman-livereload - middleman-sprockets (~> 4.1.1) - mini_racer (~> 0.6.2) - nokogiri - rb-inotify - redcarpet - sass - -BUNDLED WITH - 2.3.5 diff --git a/README.md b/README.md index 50c2ae35..716ac84b 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,79 @@ -# Flatpak.org website +# flatpak.org website -## Installation and setup +The website for [Flatpak](https://flatpak.org). -To set up middleman locally on Fedora: +## Building -```shell -dnf install ruby rubygems rubygem-bundler rubygem-json +This site is built with [Zola](https://www.getzola.org/), a fast static site generator. + +### Prerequisites + +Install Zola (v0.19+): + +```bash +# Fedora +sudo dnf install zola + +# macOS / Homebrew +brew install zola + +# Or download from https://github.com/getzola/zola/releases ``` -In the git checkout, do a `bundle install`. This installs all -the needed modules in their appropriate versions. +### Development -Add the middleman binary location (probably ~/bin) to $PATH. +```bash +zola serve +``` -## Testing +This starts a local server at `http://127.0.0.1:1111` with live reload. -To run a local web server to test the site: +### Production build -```shell -bundle exec middleman server +```bash +zola build ``` -Edit the haml/scss files and commit your changes, pushing to -origin/source. +Output is written to `public/`. -## Devcontainer +### Docker -You can also use the devcontainer, for e.g. with VSCode. It should setup automatically and just expects you to run the testing command from above or command you would like to run. +```bash +docker build -t flatpak-website . +docker run -p 8080:8080 flatpak-website +``` + +## Structure + +``` +config.toml # Zola configuration +content/ # Markdown content pages + _index.md # Homepage + about.md # About page + faq.md # FAQ + presentations.md # Presentations & articles + setup/ # Distro setup section + _index.md # Setup hub page + ubuntu.md # Per-distro setup pages + ... + press/ # Press releases (blog section with RSS) + _index.md # Press index + 2016-06-21-*.md # Press release pages + ... +templates/ # Zola Tera templates + base.html # Base layout (nav, footer) + index.html # Homepage template + page.html # Generic content page + setup.html # Setup hub + setup-distro.html # Individual distro page + press.html # Press index + press-page.html # Individual press release + 404.html # 404 page +static/ # Static assets (fonts, images, CSS) + style.css # Main stylesheet (modern CSS, no preprocessor) +data/ # Data files (apps.toml) +``` -## Deployment +## Contributing -Pushing new commits automatically causes to trigger new build -and deployment on OpenShift. It usually takes few minutes for -changes to become visible. Files used for build can be found -in `oscp` directory. +Issues and pull requests are welcome on [GitHub](https://github.com/flatpak/flatpak.github.io). diff --git a/config.rb b/config.rb deleted file mode 100644 index 6aa651ee..00000000 --- a/config.rb +++ /dev/null @@ -1,71 +0,0 @@ -### -# Page options, layouts, aliases and proxies -### - -# Per-page layout changes: -# -# With no layout -page '/*.xml', layout: false -page '/*.json', layout: false -page '/*.txt', layout: false - -# With alternative layout -# page "/path/to/file.html", layout: :otherlayout - -# Proxy pages (http://middlemanapp.com/basics/dynamic-pages/) -# proxy "/this-page-has-no-template.html", "/template-file.html", locals: { -# which_fake_page: "Rendering a fake page with a local variable" } - -data.distro.each do |i| - proxy "/setup/#{i.slug ? i.slug : i.name}.html", "/distro-template.html", :locals => { :name => i.name, :logo => i.logo, :introduction => i.introduction, :steps => i.steps, :slug => i.slug }, :ignore => true -end - -# General configuration - -# Reload the browser automatically whenever files change -configure :development do - activate :livereload -end - -### -# Helpers -### - -# Methods defined in the helpers block are available in templates -helpers do - -end - -# Build-specific configuration -configure :build do - # Minify CSS on build - # activate :minify_css - - # Minify Javascript on build - # activate :minify_javascript -end - -#activate :relative_assets -#set :relative_links, true - -activate :deploy do |deploy| - deploy.deploy_method = :git - deploy.branch = 'master' # default: gh-pages -end - -#activate :redcarpet -set :markdown_engine, :redcarpet -set :markdown, :tables => true #, :autolink => true, :gh_blockcode => true, :fenced_code_blocks => true - -activate :matomomiddleman do |p| - p.domain = 'webstats.gnome.org' - p.id = 13 -end - -activate :asset_hash -activate :directory_indexes -# we have reditects on nginx side -#redirect "/hello-world.html", to: "/hello-world/" -# -#redirects happening in nginx -#https://github.com/flatpak/flatpak.github.io/issues/241 diff --git a/config.toml b/config.toml new file mode 100644 index 00000000..44624fe8 --- /dev/null +++ b/config.toml @@ -0,0 +1,18 @@ +base_url = "https://flatpak.org" +title = "Flatpak" +description = "The future of application distribution" +compile_sass = false +generate_feeds = true +feed_filenames = ["atom.xml"] +minify_html = false +build_search_index = false + +taxonomies = [] + +[slugify] +paths = "safe" + +[markdown] + +[extra] +keywords = ["flatpak", "linux", "apps", "sandboxing", "xdg-app"] diff --git a/content/_index.md b/content/_index.md new file mode 100644 index 00000000..a282be50 --- /dev/null +++ b/content/_index.md @@ -0,0 +1,5 @@ ++++ +title = "Flatpak—the future of application distribution" +description = "The days of chasing multiple Linux distributions are over. Standalone apps for Linux are here!" +template = "index.html" ++++ diff --git a/content/about.md b/content/about.md new file mode 100644 index 00000000..95be776a --- /dev/null +++ b/content/about.md @@ -0,0 +1,148 @@ ++++ +title = "About Us" +description = "About Flatpak" +aliases = ["/about.html"] ++++ + +Flatpak is developed by an independent community, made up of contributors, volunteers and supporting organizations. It is a true upstream open source project, dedicated to providing technology and services that can be used by all, with no vendor lock-in. We have strong links to other Free Software projects, including the Freedesktop project. + +All our code is freely available, with no contributor agreement required. Volunteers and contributing organizations are welcome, as equal partners. + +## Contact + +
+
Mailing list
+
flatpak at lists.freedesktop.org
+ +
Security mailing list
+
flatpak-security at lists.freedesktop.org
+ +
Matrix
+
#flatpak on Matrix.org
+ +
GitHub
+
github.com/flatpak
+
+ +Issues with this website can be reported through its [GitHub project](https://github.com/flatpak/flatpak.github.io/issues). + +## Flatpak History + +
+
August 2007
+
Alexander Larsson releases Glick, his first app bundling framework
+ +
November 2011
+
Glick 2 is released, a modernized version of the first Glick framework
+ +
July 2012
+
"GNOME OS" session held at GUADEC, includes initial planning for a new app bundling format
+ +
September 2012
+
Alexander Larsson releases experimental "bundler" framework
+ +
January 2013
+
"Linux Apps" proposal discussed at the GNOME Developer Experience hackfest, Brussels
+ +
December 2014
+
Work begins on xdg-app, which later becomes Flatpak
+ +
March 2015
+
xdg-app 0.1 released, the very first version of Flatpak
+ +
December 2015
+
GNOME's "Software" gains the ability to install xdg-app applications
+ +
May 2016
+
xdg-app renamed to Flatpak, 0.6.0 released; accompanying press release included endorsements by Red Hat, Endless Computers and Collabora
+ +
June 2016
+
Work on desktop portals security framework begins
+ +
June 2016
+
LibreOffice is the first major application to adopt Flatpak for publishing on Linux
+ +
July 2016
+
GTK+ 3.21.4 released with initial support for the portals framework
+ +
August 2016
+
Endless OS 3.0 released, the first publicly available OS to use Flatpak by default. Adoption of Flatpak by Apertis IVI also becomes public knowledge.
+ +
November 2016
+
ClearLinux announces their adoption of Flatpak
+ +
December 2016
+
Flatpak 0.8.0 released, the start of the first stable series with long-term support
+ +
May 2017
+
Initial soft launch of Flathub hosting service
+ +
May 2017
+
KDE Plasma 5.10 released with initial support for portals
+ +
October 2017
+
Flatpak 0.10.0 released, marking the start of the second supported stable release series
+ +
October 2017
+
KDE Plasma 5.11 released, "Discover" gains the ability to install Flatpak apps
+ +
October 2017
+
GIMP adopts Flatpak to publish on Linux
+ +
November 2017
+
Linux Mint 18.3 released, includes out of the box Flatpak integration
+ +
August 2018
+
Flatpak 1.0 released, the first release in a new stable series, with major new features; Flathub beta period ends; Freedesktop runtime 18.08 released with new support period policy
+ +
September 2018
+
KDE introduces the KDE Testing Applications Flatpak repository; commit
+ +
December 2019
+
elementary OS 5.1 Hera released, includes out of the box Flatpak integration
+ +
April 2020
+
Mozilla adopts Flatpak to publish Firefox on Linux
+ +
April 2020
+
System76 releases Pop!_OS 20.04, includes out of the box Flatpak integration
+ +
October 2021
+
1Password adopts Flatpak to publish on Linux
+ +
February 2022
+
Valve releases the Steam Deck; a handheld video game console with out of the box Flatpak and Flathub integration
+ +
February 2022
+
OBS Studio adopts Flatpak to publish on Linux
+ +
May 2022
+
Red Hat Enterprise Linux Workstation 9 released, includes out of the box Flatpak integration
+ +
October 2022
+
Flathub introduces verified status; commit
+ +
April 2023
+
Purism introduces Flatpak and the PureOS Flatpak repository; announcement
+ +
April 2023
+
Valve adopts portals for the popular Steam application
+ +
May 2023
+
Flathub offers more than 2000 apps and celebrates 1B total downloads
+ +
October 2023
+
Discord adopts Flatpak to publish on Linux
+ +
January 2024
+
Flathub surpasses one million active users
+ +
July 2024
+
Flathub reaches 2 billion total downloads
+ +
January 2025
+
Flatpak 1.16.0 released, the first stable release in over two years, packed with new features and improvements
+ +
December 2025
+
Flathub closes the year with 438 million downloads, 21.6% year-over-year growth, and over 3,200 apps available
+
diff --git a/content/blog-posts.md b/content/blog-posts.md new file mode 100644 index 00000000..6c89abab --- /dev/null +++ b/content/blog-posts.md @@ -0,0 +1,203 @@ ++++ +title = "Blog Posts" +description = "Blog posts about Flatpak" +aliases = ["/blog-posts.html"] ++++ + +If you know of a blog post that isn't listed, please [file an issue](https://github.com/flatpak/flatpak.github.io/issues/new) so we can add it! + +## 2026 + +[**Sebastian Wick: Improving the Flatpak Graphics Drivers Situation**](https://blog.sebastianwick.net/posts/flatpak-graphics-drivers/) +January 2026 + + + +## 2025 + +[**Georges Stavracas: Flatpak 1.16 is out!**](https://feaneron.com/2025/01/14/flatpak-1-16-is-out/) +January 2025 + +[**Sebastian Wick: Testing with Portals**](https://blog.sebastianwick.net/posts/testing-with-portals/) +2025 + +## 2024 + +[**Cassidy James Blaede: 2 Billion Downloads & Other Milestones from 2024 So Far**](https://docs.flathub.org/blog/2-billion-downloads-2024/) +August 2024 + +## 2022 + +[**Hubert Figuière: RTKit, portals, and Pipewire**](https://www.figuiere.net/hub/wlog/rtkit-portal-pipewire/) +August 2022 + +[**Will Thompson: How many Flathub apps reuse other package formats?**](https://blogs.gnome.org/wjjt/2022/06/14/how-many-flathub-apps-reuse-other-package-formats/) +June 2022 + +[**Jakub Steiner: Flatpak Brand Refresh**](https://blog.jimmac.eu/2022/flatpak-refresh/) +June 2022 + +[**Martín Abente Lahaye: Flatseal 1.8.0**](https://blogs.gnome.org/tchx84/2022/05/31/flatseal-1-8-0/) +May 2022 + +[**Will Thompson: Evince, Flatpak, and GTK print previews**](https://blogs.gnome.org/wjjt/2022/05/30/evince-flatpak-and-gtk-print-previews/) +May 2022 + +[**TheEvilSkeleton: Response to "Flatpak Is Not the Future"**](https://theevilskeleton.gitlab.io/2022/05/16/response-to-flatpak-is-not-the-future.html) +May 2022 + +[**Jan Grulich: How to use Libportal/libportal-qt**](https://jgrulich.cz/2022/02/10/how-to-use-libportal-libportal-qt/) +February 2022 + +## 2021 + +[**Phaedrus Leeds: A Quick PSA on Writing Portal-friendly Application Code**](https://blogs.gnome.org/mwleeds/2021/12/03/a-quick-psa-on-writing-portal-friendly-application-code/) +December 2021 + +[**Will Thompson: On Flatpak disk usage and deduplication**](https://blogs.gnome.org/wjjt/2021/11/24/on-flatpak-disk-usage-and-deduplication/) +November 2021 + +[**Martín Abente Lahaye: Flatseal 1.7.5**](https://blogs.gnome.org/tchx84/2021/11/20/flatseal-1-7-5/) +November 2021 + +[**Peter Hutterer: Flatpak portals - how do they work?**](https://who-t.blogspot.com/2021/08/flatpak-portals-how-do-they-work.html) +September 2021 + +[**Lionir Deadman: Flathub, runtimes and stats**](https://thelion.website/flathub-runtimes-and-stats/) +June 2021 + +[**Martín Abente Lahaye: Flatseal 1.7.0**](https://blogs.gnome.org/tchx84/2021/04/23/flatseal-1-7-0/) +April 2021 + +[**TheEvilSkeleton: Response to flatkill.org**](https://theevilskeleton.gitlab.io/2021/02/11/response-to-flatkill-org.html) +February 2021 + +[**Phaedrus Leeds: Cleaning Up Unused Flatpak Runtimes**](https://blogs.gnome.org/mwleeds/2021/01/11/cleaning-up-unused-flatpak-runtimes/) +January 2021 + +## 2020 + +[**Alexander Larsson: Scaling Flathub 100x**](https://blogs.gnome.org/alexl/2020/11/20/scaling-flathub/) +November 2020 + +[**Alexander Larsson: Compatibility in a sandboxed world**](https://blogs.gnome.org/alexl/2020/08/11/compatibility-in-a-sandboxed-world/) +August 2020 + +[**Martín Abente Lahaye: Flatseal 1.6.0**](https://blogs.gnome.org/tchx84/2020/06/26/flatseal-1-6-0-and-beyond/) +June 2020 + +[**Hubert Figuière: Getting a stack trace with debug symbols out of a flatpak**](https://www.figuiere.net/technotes/notes/tn001/) +June 2020 + +[**Alexander Larsson: Putting container updates on a diet**](https://blogs.gnome.org/alexl/2020/05/13/putting-container-updates-on-a-diet/) +May 2020 + +## 2019 + +[**Matthias Clasen: More on Flatpak Updates**](https://blogs.gnome.org/mclasen/2019/12/19/9100/) +December 2019 + +[**TingPing: Hardening Flatpak Permissions Over Time**](https://blog.tingping.se/2019/10/06/hardening-flatpak-permissions.html) +October 2019 + +[**Matthias Clasen: Some Flatpak Updates**](https://blogs.gnome.org/mclasen/2019/10/03/some-flatpak-updates/) +October 2019 + +[**Robert McQueen: Flathub, brought to you by...**](https://ramcq.net/2019/08/12/flathub-brought-to-you-by/) +August 2019 + +[**Matthias Clasen: Settings, in a Sandbox World**](https://blogs.gnome.org/mclasen/2019/07/12/settings-in-a-sandbox-world/) +July 2019 + +[**Christian Hergert: Flatpaking Terminals**](https://blogs.gnome.org/chergert/2019/04/25/flatpaking-terminals/) +April 2019 + +[**Alexander Larsson: Introducing flat-manager**](https://blogs.gnome.org/alexl/2019/03/19/introducing-flat-manager/) +March 2019 + +[**Alexander Larsson: Changes in Flathub land**](https://blogs.gnome.org/alexl/2019/02/19/changes-in-flathub-land/) +February 2019 + +[**Matthias Clasen: What's New in Flatpak 1.2**](https://blogs.gnome.org/mclasen/2019/01/28/whats-new-in-flatpak-1-2/) +January 2019 + +## 2018 + +[**Matthias Clasen: Flatpak Commandline Design**](https://blogs.gnome.org/mclasen/2018/12/19/flatpak-commandline-design/) +December 2018 + +[**Matthias Clasen: An Update on Flatpak Updates**](https://blogs.gnome.org/mclasen/2018/11/26/an-update-on-flatpak-updates/) +November 2018 + +[**Robert McQueen: Flatpak, sandboxes and security**](https://ramcq.net/2018/10/15/flatpak-sandbox-security/) +October 2018 + +[**Alexander Larsson: Moving away from the 1.6 freedesktop runtime**](https://blogs.gnome.org/alexl/2018/10/11/moving-away-from-the-1-6-freedesktop-runtime/) +October 2018 + +[**Matthias Clasen: Flatpak, After 1.0**](https://blogs.gnome.org/mclasen/2018/10/08/flatpak-after-1-0/) +October 2018 + +[**Alexander Larsson: Flatpak on windows**](https://blogs.gnome.org/alexl/2018/09/17/flatpak-on-windows/) +September 2018 + +[**Matthias Clasen: On Flatpak Dependencies**](https://blogs.gnome.org/mclasen/2018/09/07/on-flatpak-dependencies/) +September 2018 + +[**Matthias Clasen: About Flatpak Installations**](https://blogs.gnome.org/mclasen/2018/08/26/about-flatpak-installations/) +August 2018 + +[**Alexander Larsson: Kick-starting the revolution 1.0**](https://blogs.gnome.org/alexl/2018/08/21/kick-starting-the-revolution-1-0/) +August 2018 + +[**Alexander Larsson: The birth of a new runtime**](https://blogs.gnome.org/alexl/2018/08/10/the-birth-of-a-new-runtime/) +August 2018 + +[**Matthias Clasen: Flatpak Portal Experiments**](https://blogs.gnome.org/mclasen/2018/08/03/flatpak-portal-experiments/) +August 2018 + +[**Matthias Clasen: Flatpak - A Look Behind the Portal**](https://blogs.gnome.org/mclasen/2018/07/19/flatpak-a-look-behind-the-portal/) +July 2018 + +[**Matthias Clasen: The Flatpak BoF at GUADEC**](https://blogs.gnome.org/mclasen/2018/07/14/the-flatpak-bof-at-guadec/) +July 2018 + +[**Matthias Clasen: Flatpak, Making Contribution Easy**](https://blogs.gnome.org/mclasen/2018/07/07/flatpak-making-contribution-easy/) +July 2018 + +[**Matthias Clasen: Flatpak in Detail, Part 3**](https://blogs.gnome.org/mclasen/2018/07/02/flatpak-in-detail-part-3/) +July 2018 + +[**Alexander Larsson: Flatpak - a history**](https://blogs.gnome.org/alexl/2018/06/20/flatpak-a-history/) +June 2018 + +[**Matthias Clasen: Flatpak in Detail, Part 2**](https://blogs.gnome.org/mclasen/2018/06/19/flatpak-in-detail-part-2/) +June 2018 + +[**Matthias Clasen: Flatpak in Detail**](https://blogs.gnome.org/mclasen/2018/06/13/flatpak-in-detail/) +June 2018 + +[**Alexander Larsson: Flatpak inception**](https://blogs.gnome.org/alexl/2018/04/27/flatpak-inception/) +April 2018 + +[**TingPing: Flatpaking application plugins**](https://blog.tingping.se/2018/03/18/flatpaking-plugins.html) +March 2018 + +[**PointestStick: Flatpak support in Discover**](https://pointieststick.com/2018/01/13/flatpak-support-in-discover/) +January 2018 + +## 2017 + +[**TingPing: Status of emulators Flatpak'd**](https://blog.tingping.se/2017/10/31/flatpaked-emulators.html) +October 2017 + +[**Alexander Larsson: On application sizes and bloat in flatpak**](https://blogs.gnome.org/alexl/2017/10/02/on-application-sizes-and-bloat-in-flatpak/) +October 2017 + +## 2016 + +[**Simon McVittie: Flatpak in Debian**](http://smcv.pseudorandom.co.uk/2016/flatpak/) +June 2016 + +[**Simon McVittie: GNOME Developer Experience hackfest: xdg-app + Debian**](https://smcv.pseudorandom.co.uk/2016/xdg-app/) +January 2016 diff --git a/content/faq.md b/content/faq.md new file mode 100644 index 00000000..8ab41617 --- /dev/null +++ b/content/faq.md @@ -0,0 +1,61 @@ ++++ +title = "Frequently Asked Questions" +description = "FAQ about the Flatpak project." +aliases = ["/faq.html"] ++++ + +### Why the name Flatpak? + +IKEA is a world-wide known brand whose success was partly built upon having developed and refined the idea of flatpacking their furniture, which allowed them huge cost savings and efficiencies compared to their competitors. So when we needed a new name for the packaging technology that had been developed by Alex Larsson, a native Swede, we thought that Flatpak would both be a nice play on his nationality and pay homage to the success of IKEA and at the same time send a strong signal about how revolutionary we thought this new packaging technology could be for the Linux desktop. + +### What is the origin of the Flatpak technology? + +Flatpak is a technology that brings together many of the lessons learned by its creator Alexander Larsson during his long tenure as a Linux desktop developer and having spent time inside Red Hat working on container technologies. Flatpak builds upon existing technologies such as cgroups, namespaces, bind mounts and seccomp in the Linux kernel, OSTree from [Project Atomic](http://www.projectatomic.io/) and the OCI format that is developed by the [Open Container Initiative](https://www.opencontainers.org/). It has also spawned new technologies such as Bubblewrap which is shared between Flatpak and Project Atomic. + +### Is Flatpak tied to GNOME? + +No. While Flatpak has been developed by people with a long involvement in the GNOME community it is not tied to any desktop. In fact, it was designed with the explicit goal of allowing it to build applications using any library stack or programming language an application author might want. + +### Is Flatpak tied to Fedora? + +No. In fact, Flatpak and even [Flathub](https://flathub.org) are enabled by default on Endless OS and Linux Mint. The people developing Flatpak have a long history in contributing to and building Linux distributions like Debian, Fedora, and others, and solving the problems that arise when shipping applications for these platforms. Flatpak was built to be distribution agnostic and allow deployment on any Linux operating system out there. + +### Is Flatpak tied to Linux? + +Yes. We are explicitly using many features of the linux kernel (bind mounts, namespaces, seccomp, etc) to create the sandbox that Flatpak apps are running in. It may be possible to use equivalent technologies on other kernels, but that would be a non-trivial amount of work, and we don't consider this one of our priorities. + +### Is Flatpak tied to systemd? + +No. Versions of Flatpak before 0.6.10 relied on systemd for cgroups setup, but this is no longer required. + +### Is Flatpak the same as xdg-app? + +Yes, while xdg-app was a fine name to use during development we wanted something with wider appeal and more sparkle to it than xdg-app could provide. So as part of formally launching Flatpak as ready for use we decided to pick a more accessible and fun name. + +### Is Flatpak a container technology? + +It can be, but it doesn't have to be. Since a desktop application would require quite extensive changes in order to be usable when run inside a container you will likely see Flatpak mostly deployed as a convenient library bundling technology early on, with the sandboxing or containerization being phased in over time for most applications. In general though we try to avoid using the term container when speaking about Flatpak as it tends to cause comparisons with Docker and rkt, comparisons which quickly stop making technical sense due to the very different problem spaces these technologies try to address. And thus we prefer using the term sandboxing. + +### How does Flatpak relate to freedesktop.org technologies such as desktop files and AppStream metadata? + +These standards are incorporated as mandatory parts in the Flatpak definition. By relying on these standards we are building on years of investment and support under Linux. + +### Can Flatpak be used on servers too? + +Flatpak is designed to run inside a desktop session and relies on certain session services, such as a D-Bus session bus and, optionally, a systemd `--user` instance. This makes Flatpak not a good match for a server. + +However, the build features of Flatpak run fine outside a session, so you can build things on a server. + +### Is Flatpak compatible with other desktop isolation frameworks? + +In general unprivileged container systems can't stack, because anything running inside the sandbox does not have the necessary privileges to set up a sandbox, nor does it have the ability to raise its privileges in any way. For instance, Firejail can never work inside Flatpak, because it is setuid. That being said, using multiple sandboxing frameworks at once does not really make anything more secure, so there is little point in trying to nest things like that. + +It is certainly possible for Flatpak and Flatpak applications to coexist with applications that are packaged in other ways, on the same host system. + +### Are there any IDEs that support Flatpak? + +Yes! Version 3.22.4 and newer of [Builder](https://apps.gnome.org/Builder/) includes support for `flatpak-builder` manifests. This ensures your project is built using your selected Flatpak runtime and any external dependencies. Support for running your application inside Flatpak is also supported. By developing your application within the exact same environment as your users you can squash those "Works for me" bugs before they reach your users! + +### Can I host my Flatpak app on GitHub? + +Flatpak repositories can't (currently) be put on GitHub in a convenient way. As an alternative, you can create a single-file bundle, and put that up on GitHub as a "release." Note that bundles have some drawbacks, compared to a repository. Another option you have is to get your app on [Flathub](https://flathub.org/) which will allow your users to get updates. diff --git a/content/presentations.md b/content/presentations.md new file mode 100644 index 00000000..96c9693f --- /dev/null +++ b/content/presentations.md @@ -0,0 +1,166 @@ ++++ +title = "Presentations & Articles" +description = "Presentations and articles about Flatpak" +aliases = ["/presentations.html"] ++++ + +If you know of a presentation or article that isn't listed, please [file an issue](https://github.com/flatpak/flatpak.github.io/issues/new) so we can add it! + +## 2026 + +[**Sebastian Wick: Flatpak and Portals: A Status Update**](https://www.youtube.com/watch?v=Zt4cUf_AgUg) +Linux App Summit, Berlin, Germany, May 2026 + +[**Adrian Vovk & Sebastian Wick: The next generation of Flatpak and Portals**](https://www.youtube.com/live/1AXBfsiaQNk?t=16197) +Linux App Summit, Berlin, Germany, May 2026 + + +## 2025 + +[**Sebastian Wick: The Future of Flatpak**](https://www.youtube.com/watch?v=3HkYJ7M119I) +Linux App Summit, Tirana, Albania, April 2025 + +[**Jordan Petridis: Flathub: A paradigm shift for distributing applications**](https://www.youtube.com/watch?v=NxOH4wJkfLY) +Linux App Summit, Tirana, Albania, April 2025 + +[**Shipping Flatpak applications with an image based system**](https://cfp.all-systems-go.io/all-systems-go-2025/talk/98W9EX/) +All Systems Go!, October 2025 + +[**Joe Brockmeier: The future of Flatpak**](https://lwn.net/Articles/1020571/) +LWN.net, May 2025 + +## 2023 + +[**Richard Brown: What could go wrong? I was wrong about Flatpak, AppImage, and Snap**](https://www.youtube.com/watch?v=4WuYGcs0t6I) +FOSDEM, Brussels, Belgium, February 2023 + +[**Bartłomiej Piotrowski: Flathub in 2023: Revolutionizing the Linux App Ecosystem**](https://conf.linuxappsummit.org/event/5/contributions/173/) +Linux App Summit, Brno, Czech Republic, April 2023 + +## 2021 + +[**Will Thompson: Automate your Flatpak manifest updates today**](https://www.youtube.com/watch?v=c_dG_ngnJk4) +Linux App Summit, May 2021 + +[**Jan Beran: Making flatpaks from Fedora RPMs**](https://www.youtube.com/watch?v=IuxHidCdbPo) +Linux App Summit, May 2021 + +[**Valentin David: Freedesktop SDK on RISC-V**](https://www.youtube.com/watch?v=INTbqkck258) +Linux App Summit, May 2021 + +## 2020 + +[**Alexander Larsson: Flatpak, an introduction (Lightning Talk)**](https://www.youtube.com/watch?v=0yeXTounX3E) +Linux App Summit, November 2020 + +[**Bartłomiej Piotrowski: Flathub: The State of the Union**](https://www.youtube.com/watch?v=IqHEx-Lug8k) +Linux App Summit, November 2020 + +[**Felipe Borges: Application sandboxing with Flatpak Portals**](https://www.youtube.com/watch?v=3rCIEzfZw1I) +DevConf.CZ, Brno, Czechia, January 2020 + +## 2019 + +[**Robert McQueen: Building an app store with Flathub**](https://www.youtube.com/watch?v=ZGAfYP3OiAI) +Linux App Summit, Barcelona, Spain, November 2019 + +[**Alexander Larsson: Maintaining a Flatpak Repository**](https://www.youtube.com/watch?v=q-_fKWby0ds&list=PLkmRdYgttscEuv9v2-H9P5FBj8-td_Nri&index=24) +GUADEC, Thessaloniki, Greece, August 2019 + +[**Valentin David, Adam Jones: Freedesktop-sdk Status Update and Future Plans**](https://www.youtube.com/watch?v=ky-inEefWpE&list=PLkmRdYgttscEuv9v2-H9P5FBj8-td_Nri&index=20) +GUADEC, Thessaloniki, Greece, August 2019 + +[**Richard Brown: Help, I'm Falling in Love with Flatpak**](https://www.youtube.com/watch?v=7p4y9Meyy0M&list=PLkmRdYgttscEuv9v2-H9P5FBj8-td_Nri&index=12) +GUADEC, Thessaloniki, Greece, August 2019 + +[**Matthias Clasen: Portals - Principles and Practice**](https://www.youtube.com/watch?v=bIzJyp8sb70&list=PLkmRdYgttscEuv9v2-H9P5FBj8-td_Nri&index=9) +GUADEC, Thessaloniki, Greece, August 2019 + +[**Owen Taylor: Flatpaks in Fedora - an update**](https://www.youtube.com/watch?v=mpCXK6PqvDk) +DevConf.CZ, Brno, Czechia, January 2019 + +[**Jiří Janoušek: Fight Linux fragmentation with Flatpak**](https://www.youtube.com/watch?v=_ZmgdnhvjvM) +DevConf.CZ, Brno, Czechia, January 2019 + +[**Felipe Borges: Running virtual machines in the Flatpak sandbox**](https://www.youtube.com/watch?v=EdrSJMKikUM) +DevConf.CZ, Brno, Czechia, January 2019 + +[**Kukuh Syafaat: LibreOffice Flatpak, Snap and AppImage**](https://wiki.documentfoundation.org/File:AsiaCon2019_Kukuh_Syafaat.pdf) +LibreOffice Asia Conference 2019, Tokyo, Japan, May 2019 + +## 2018 + +[**Jiří Janoušek: Why and How I Switched to Flatpak**](https://www.youtube.com/watch?v=OuySHov0gdA) +LinuxDays, Prague, Czechia, October 2018 + +[**Alexander Larsson: Flatpak - a technical walk-through**](https://people.gnome.org/~alexl/presentations/all-systems-go-2018.pdf) +All Systems Go! Berlin, Germany, September 2018 + +[**Robert McQueen & Jorge García: Flathub, app store and build service for flatpak apps**](https://www.youtube.com/watch?v=Hga20qlyknw) +GUADEC, Almeria, Spain, July 2018 + +[**Adam Jones & Valentin David: Freedesktop SDK: the future of Linux runtimes**](https://www.youtube.com/watch?v=rhEzTQg_LEk) +GUADEC, Almeria, Spain, July 2018 + +[**Matthew Leeds: P2P Distribution of Flatpaks and OSTrees**](https://www.youtube.com/watch?v=SIPOfPv1z1s) +GUADEC, Almeria, Spain, July 2018 + +[**Owen Taylor: A distribution approach to building Flatpaks**](https://www.youtube.com/watch?v=EbvxZa2Blgs) +DevConf.CZ, Brno, Czechia, January 2018 + +[**Robert McQueen: Desktop OS of the future: ostree + flatpak**](https://www.youtube.com/watch?v=FcykFHJEDUU) +DevConf.CZ, Brno, Czechia, January 2018 + +[**Alexander Larsson: Flatpaking your app for fame and fortune**](https://www.youtube.com/watch?v=SBWGwwrGR8M) +DevConf.CZ, Brno, Czechia, January 2018 + +[**Kukuh Syafaat: openSUSE Leap & Flatpak**](https://events.opensuse.org/conferences/summitasia18/program/proposals/2005) +openSUSE.Asia Summit 2018, Taipei, Taiwan, August 2018 + +## 2017 + +[**Alexander Larsson: Taking back the apps from the distributions**](https://www.youtube.com/watch?v=IUA38lvb_tM) +LAS GNOME, October 2016, Portland, USA + +[**Jorge Garcia: Building a Flatpak based app store**](https://www.youtube.com/watch?v=MFue217zmyk) +GUADEC, August 2017, Manchester, UK + +[**Jan Grulich & Martin Bříza: Flatpak and KDE & the state of Qt integration in GNOME**](https://www.youtube.com/watch?v=U8zlbXYTN2U) +GUADEC, August 2017, Manchester, UK + +[**Richard Brown: Resurrecting Dinosaurs - what could possibly go wrong?**](https://www.youtube.com/watch?v=RPblTKt4Klo) +GUADEC, August 2017, Manchester, UK + +[**Simon McVittie: Flatpak and Debian**](https://www.collabora.com/news-and-blog/blog/2017/08/17/debconf-17-flatpak-and-debian/) +Debconf, August 2017, Montreal, Canada + +[**Linux Magazine: Flatpak and snap**](http://www.linux-magazine.com/Online/Features/Universal-Package-Formats-and-How-They-Differ) +June 2017 + +[**Mario Sanchez Prada & Richard Hughes: The future of linux application distribution**](https://speakerdeck.com/mariospr/the-future-of-linux-application-distribution-ostree-flatpak-and-gnome-software) +March 2017, Samsung Research, Staines, UK + +[**Alexander Larsson: Flatpak: Apps on the linux desktops**](https://www.youtube.com/watch?v=xIjxNtIwcBA) +foss-north 2017, Gothenburg, Sweden + +[**Matthias Clasen: Flatpak – A new way to distribute applications**](https://mclasen.fedorapeople.org/devconf-flatpak.pdf) +January 2017, devconf.cz, Brno, Czech Republic + +[**Kukuh Syafaat: Flatpak & AppImage Usage on openSUSE. Which One Suitable for openSUSE Users?**](https://events.opensuse.org/conferences/summitasia17/program/proposals/1502) +openSUSE.Asia Summit 2017, October 2017, Chofu, Tokyo, Japan + +## 2016 + +[**Alexander Larsson: Flatpak status update and future plans**](https://www.youtube.com/watch?v=G1OFcNQ5Fw8) +GUADEC, August 2016, Karlsruhe, Germany + +[**Fedora Magazine: Explore Flatpak in Fedora 24**](https://fedoramagazine.org/explore-flatpak-fedora-24/) +June 2016 + +[**Jens Petersen: Generic standalone linux app packages**](https://www.slideshare.net/JensPetersen2/flatpak-introdiction) +FUDCon APAC 2016, Phnom Penh, Cambodia + +## 2015 + +[**Christian Hergert: Flatpak, the easiest, fastest, and safest software distribution platform**](https://www.socallinuxexpo.org/scale/15x/presentations/flatpak-easiest-fastest-and-safest-software-distribution-platform) +SCALE 2015, Pasadena, USA diff --git a/content/press/2016-06-21-flatpak-released.md b/content/press/2016-06-21-flatpak-released.md new file mode 100644 index 00000000..7fa0f19f --- /dev/null +++ b/content/press/2016-06-21-flatpak-released.md @@ -0,0 +1,57 @@ ++++ +title = "Announcing Flatpak – Next Generation Linux Applications" +date = 2016-06-21 +description = "Stockholm, Sweden – 21st June 2016 – The development team behind Flatpak is excited to announce the general availability of their new framework for desktop applications on Linux." +template = "press-page.html" +aliases = ["/press/2016-06-21-flatpak-released.html"] ++++ + +Stockholm, Sweden – 21st June 2016 – The development team behind Flatpak is excited to announce the general availability of their new framework for desktop applications on Linux. Previously named xdg-app, [Flatpak is available on a range of major Linux distributions](http://flatpak.org/getting.html). + +## Build once, run anywhere + +The Linux desktop has long been held back by platform fragmentation. This has been a burden on developers, and creates a high barrier to entry for third party application developers. Flatpak aims to change all that. From the very start its primary goal has been to allow the same application to run across a myriad of Linux distributions and operating systems. In doing so, it greatly increases the number of users that application developers can easily reach. + +Speaking about the goals behind Flatpak, Alexander Larsson, its lead developer, said: "Application developers on Linux have always been prevented from having a direct relationship with their users. With Flatpak we're aiming to change that, so developers know exactly what their users are getting. With this launch we are making that goal a reality." + +Flatpak has been available for a range of Linux distributions for several weeks. It allows application developers to build against a series of stable platforms (known as runtimes), as well as to bundle libraries directly within their applications. Flatpak is also standards compliant, offering support for the [Open Container Initiative](https://www.opencontainers.org/) specification. + +A growing range of applications are already available as Flatpaks, including LibreOffice, the GIMP, InkScape, MyPaint, Darktable, and a large number of stock GNOME applications. Linux desktops are also adopting Flatpak. A fully functional GNOME runtime has been available since March: this allows application developers to build and distribute Flatpaks using the GNOME development stack. Work on a similar runtime for KDE is proceeding. + +Not only does Flatpak provide cross-distribution installation, but it also allows forward compatibility. Michael Meeks, Director of [The Document Foundation](https://www.documentfoundation.org/), said: "Until now, building a LibreOffice that works for every Linux user has involved some horrible compromises caused by the need to build our binaries on an ancient Linux version to get good forward compatibility. Flatpak will enable us (as a Linux ISV) to distribute a better LibreOffice, with up-to-date dependencies and a platform that can run on many systems. I'm excited to see that happen." + +## Security first + +Another area where the Linux desktop has been weak is security: it has never had a viable model for isolating applications, or for gatekeeping access to user data. This is another area where Flatpak aims to upset the status quo. To this end, it has been built from the ground up with security in mind. + +Flatpak apps are sandboxed. From within the sandbox, the only things the app can "see" are itself and a limited set of libraries and operating system interfaces. This effectively isolates apps from each other as well as from the host system and makes it much harder for applications to steal user data or exploit one another. + +Initial Flatpak releases have concentrated on application building, distribution and installation, and while the foundations of sandboxing are in place, there are still missing pieces. "The next major Flatpak release will be all about sandboxing", says Larsson. "Application authors will see a much more complete set of interfaces for interacting with the operating system from within a sandbox." + +Another major part of this work is the widescale move towards the Wayland display server on Linux. X11 is inherently insecure, which makes it impossible to sandbox applications that are using it. In that sense, the growing maturity of Wayland complements Flatpak's emergence, and paves the way for much more complete security model for Linux distributions. + +## Background to Flatpak + +[![Alexander Larsson. Photo by Garrett LeSage](/img/CC-BY-SA-4.0-Garrett-LeSage-sm.jpg "Alexander Larsson. Photo by Garrett LeSage")](/img/CC-BY-SA-4.0-Garrett-LeSage.jpg) + +Flatpak is the brainchild of Alexander Larsson, Principal Software Engineer at Red Hat. Larsson has been working in the Linux desktop space for 18 years. He was the principal author of GVfs (GNOME's Virtual Filesystem) and has done critical work on Docker, the SPICE protocol, the Gecko rendering engine, GLib and GTK+. He has considerable experience in the area of application bundling. + +Flatpak builds on several cutting edge technologies. Under the hood, it makes significant use of [OSTree](https://ostree.readthedocs.org), which can be described as "Git for large binaries". This provides much of the functionality for hosting software repositories. It also makes Flatpak extremely efficient: applications and libraries that are installed with Flatpak are de-duplicated, saving disk space; "static deltas" reduce the size of downloads for software updates. + +For sandboxing, Flatpak makes use of the [Bubblewrap](https://github.com/projectatomic/bubblewrap) utility, as well as several Linux kernel features (such as cgroups and namespaces), which helps to make it portable across distributions. + +## Rapid community growth and adoption + +It is well known that Fedora is making plans around Flatpak. Commenting on Flatpak, Christian F.K. Schaller (Senior Manager at Red Hat and member of the Fedora Workstation Working Group) stated: "The Fedora Workstation team are very excited about Flatpak and the prospects it brings for making the Linux desktop easier to develop for. We plan to continue supporting this effort going forward and help advocate it to a wider audience." + +There is also interest from other parties. One early adopter of Flatpak is [Endless Computers](https://endlessm.com/). Speaking about the launch of Flatpak, Jonathan Blandford (VP of Software Engineering at Endless) said: "The Flatpak launch represents a major milestone in providing a unified context for Linux developers. At Endless, we're proud to be a part of this movement and have fully embraced Flatpak by readily converting all of our applications for our upcoming release and continuing to build new Flatpak apps. We encourage others to do so as well in what we hope to be a revolution among Linux app creation and adoption." + +![Endless Computers and its App ecosystem](/img/endless-apps.png "Endless Computers and its App ecosystem") + +Other distributions are showing interest, as well as other Free Software companies. Simon McVittie is Senior Software Engineer at Collabora and a Debian developer, and is himself looking to Flatpak: "Bringing Flatpak technology into Debian enables us to run applications in a predictable environment with their most suitable library stack, without compromising the base OS's stability and flexibility. Flatpak also retains the ability to deploy security updates, making it a significant enhancement for the many Debian-based desktop and embedded distributions, both in the community and in commercial products." + +One reason for the increasing interest in Flatpak is due to its adaptability and the fact that it is a genuinely upstream project. It can be used and adapted as part of downstream and bespoke solutions, is hosted on Freedesktop.org and Github, and is licensed with the LGPL, with no copyright assignment or contributor license agreement required. + +Larsson is obviously pleased by the momentum behind Flatpak. "It's exciting to see the growing interest in what we are doing, as developers realise the possibilities of the technology," he said. + +More information about Flatpak can be found on [flatpak.org](http://flatpak.org/). diff --git a/content/press/2018-08-20-flatpak-1.0.md b/content/press/2018-08-20-flatpak-1.0.md new file mode 100644 index 00000000..40ce438f --- /dev/null +++ b/content/press/2018-08-20-flatpak-1.0.md @@ -0,0 +1,31 @@ ++++ +title = "Flatpak 1.0 Released, Ready for Prime Time" +date = 2018-08-20 +description = "Flatpak, the Linux desktop app distribution framework, reached an important milestone with the release of its 1.0 version." +template = "press-page.html" +aliases = ["/press/2018-08-20-flatpak-1.0.html"] ++++ + +![](/img/delivery_truck.png) + +**Stockholm, Sweden, 20 August 2018**: Flatpak, the Linux desktop app distribution framework, reached an important milestone today, with the release of its 1.0 version. + +For those who don't know, once an app has been built as a Flatpak, it can be installed on virtually any Linux distribution. This model is designed to make Linux a more attractive option for desktop app developers, and provides developers with a more stable platform on which to build and develop. + +Discussing the release, Flatpak's lead developer, Alexander Larsson, has said: "A lot of work has gone into Flatpak 1.0 and we're confident that it's ready for wider use. Flatpak's goal has always been to revolutionize the Linux ecosystem and this is an important step towards that." A 1.0 release generally marks the point at which software has become "feature complete", so the fact that the developers are calling this a 1.0 is significant. But what does it mean in practice? + +Flatpak 1.0 comes with a collection of new features that application developers can take advantage of. Developers can mark versions of their apps as end of life, to indicate when they are no longer supported. There's a new mechanism for apps to restart themselves. The command line interface has had a raft of improvements, including new commands and options. + +Furthermore, Flatpak has matured since its last major stable release in October 2017. The new version promises to be faster and more reliable. There's also been some internal tidying up and reorganization. (This isn't so interesting to users and app developers, but it makes Flatpak that bit easier to integrate with your favorite Linux distro.) + +However, some of the biggest changes have been in the Flatpak ecosystem. To coincide with the release of Flatpak 1.0, the Flatpak developers are also taking the beta label off their Flathub service. Flathub is the central store for Flatpak apps. It is both a repository that can be used by Linux desktops, and a [website that users can use to browse and install apps](https://flathub.org/). It had a quiet, soft launch back in May 2017 and has seen rapid growth in the number of apps and users since then. + +Flathub has become a major feature for developers, as LibreOffice's Stephan Bergmann made clear: "Flatpak has come a long way since we first started using it; nowadays we can type a trivial command to get the latest LibreOffice 6.1 built and published on Flathub automatically. What keeps impressing me is the breadth and depth of the bug reports we receive for the LibreOffice Flatpak version. It shows that people are using it in all kinds of scenarios." + +Another significant development in the Flatpak ecosystem relates to their "runtimes" — the platforms that applications are built and run against. The main "Freedesktop" runtime that is used by most Flatpak apps is having a major release to coincide with the Flatpak 1.0. This 18.08 release has a new lifecycle policy, which includes a regular release schedule and guarantees for support periods and security updates. This gives Flatpak's app platforms a similar level of support to commercial operating system offerings. + +Flatpak's developers also point to other areas where the framework has matured. Their [developer documentation](https://docs.flatpak.org/en/latest/) has been rewritten and is much more complete. Flatpak's website also includes [tutorials for setting up Flatpak on a lot more Linux distributions](https://flatpak.org/setup/). + +The big question is what this means for the Linux landscape. Last November, Linux Mint, one of the larger Linux distributions, started using Flatpak by default, and Fedora is planning to start building its own Flatpaks very soon. It might just be that a tipping point has been reached. + +*This press release, including all content and media, can be freely used and modified without the need for attribution.* diff --git a/content/press/_index.md b/content/press/_index.md new file mode 100644 index 00000000..c7e7aef8 --- /dev/null +++ b/content/press/_index.md @@ -0,0 +1,8 @@ ++++ +title = "Press" +description = "Press information about Flatpak" +template = "press.html" +sort_by = "date" +generate_feeds = true +aliases = ["/press.html"] ++++ diff --git a/data/apps.toml b/data/apps.toml new file mode 100644 index 00000000..934349bb --- /dev/null +++ b/data/apps.toml @@ -0,0 +1,59 @@ +[[apps]] +name = "Telegram" +id = "org.telegram.desktop" +icon = "img/apps/org.telegram.desktop.png" + +[[apps]] +name = "Slack" +id = "com.slack.Slack" +icon = "img/apps/com.slack.Slack.png" + +[[apps]] +name = "Inkscape" +id = "org.inkscape.Inkscape" +icon = "img/apps/org.inkscape.Inkscape.png" + +[[apps]] +name = "Spotify" +id = "com.spotify.Client" +icon = "img/apps/com.spotify.Client.png" + +[[apps]] +name = "Steam" +id = "com.valvesoftware.Steam" +icon = "img/apps/com.valvesoftware.Steam.png" + +[[apps]] +name = "GIMP" +id = "org.gimp.GIMP" +icon = "img/apps/org.gimp.GIMP.png" + +[[apps]] +name = "Firefox" +id = "org.mozilla.firefox" +icon = "img/apps/org.mozilla.firefox.png" + +[[apps]] +name = "Kdenlive" +id = "org.kde.kdenlive" +icon = "img/apps/org.kde.kdenlive.png" + +[[apps]] +name = "Skype" +id = "com.skype.Client" +icon = "img/apps/com.skype.Client.png" + +[[apps]] +name = "VLC" +id = "org.videolan.VLC" +icon = "img/apps/org.videolan.VLC.png" + +[[apps]] +name = "Blender" +id = "org.blender.Blender" +icon = "img/apps/org.blender.Blender.png" + +[[apps]] +name = "Podman Desktop" +id = "io.podman_desktop.PodmanDesktop" +icon = "img/apps/io.podman_desktop.PodmanDesktop.png" diff --git a/data/apps.yml b/data/apps.yml deleted file mode 100644 index edb9eab5..00000000 --- a/data/apps.yml +++ /dev/null @@ -1,121 +0,0 @@ -- name: "Telegram" - id: "org.telegram.desktop" - ref: "app/org.telegram.desktop/x86_64/stable" - summary: "Desktop messenger" - color: "#6DA9D6" - featured: "yes" - "flatpakref": "https://dl.flathub.org/repo/appstream/org.telegram.desktop.flatpakref" - icons: - "128": "https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.telegram.desktop.png" - "64": "https://dl.flathub.org/repo/appstream/x86_64/icons/64x64/org.telegram.desktop.png" - -- name: "Slack" - id: "com.slack.Slack" - ref: "app/com.slack.Slack/x86_64/stable" - summary: "Chat with your team" - color: "#C5BFB5" - "flatpakref": "https://dl.flathub.org/repo/appstream/com.slack.Slack.flatpakref" - icons: - "128": "https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/com.slack.Slack.png" - "64": "https://dl.flathub.org/repo/appstream/x86_64/icons/64x64/com.slack.Slack.png" - -- name: "Inkscape" - id: "org.inkscape.Inkscape" - ref: "app/org.inkscape.Inkscape/x86_64/stable" - summary: "Vector graphics editor" - color: "#C5BFB5" - "flatpakref": "https://dl.flathub.org/repo/appstream/org.inkscape.Inkscape.flatpakref" - icons: - "128": "https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.inkscape.Inkscape.png" - "64": "https://dl.flathub.org/repo/appstream/x86_64/icons/64x64/org.inkscape.Inkscape.png" - -- name: "Spotify" - id: "com.spotify.Client" - ref: "app/com.spotify.Client/x86_64/stable" - summary: "Online music streaming service" - color: "#1DC558" - "flatpakref": "https://dl.flathub.org/repo/appstream/com.spotify.Client.flatpakref" - icons: - "128": "https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/com.spotify.Client.png" - "64": "https://dl.flathub.org/repo/appstream/x86_64/icons/64x64/com.spotify.Client.png" - -- name: "Steam" - id: "com.valvesoftware.Steam" - ref: "app/com.valvesoftware.Steam/x86_64/stable" - summary: "Manage and play games distributed by Steam" - featured: "yes" - color: "#7C8699" - "flatpakref": "https://dl.flathub.org/repo/appstream/com.valvesoftware.Steam.flatpakref" - icons: - "128": "https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/com.valvesoftware.Steam.png" - "64": "https://dl.flathub.org/repo/appstream/x86_64/icons/64x64/com.valvesoftware.Steam.png" - -- name: "GIMP" - id: "org.gimp.GIMP" - ref: "app/org.gimp.GIMP/x86_64/stable" - summary: "Create images and edit photographs" - color: "#837E77" - "flatpakref": "https://dl.flathub.org/repo/appstream/org.gimp.GIMP.flatpakref" - icons: - "128": "https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.gimp.GIMP.png" - "64": "https://dl.flathub.org/repo/appstream/x86_64/icons/64x64/org.gimp.GIMP.png" - -- name: "Firefox" - id: "org.mozilla.firefox" - ref: "app/org.mozilla.firefox/x86_64/stable" - summary: "Fast, Private & Safe Web Browser" - color: "#FFEF42" - "flatpakref": "https://dl.flathub.org/repo/appstream/org.mozilla.firefox.flatpakref" - icons: - "128": "https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.mozilla.firefox.png" - "64": "https://dl.flathub.org/repo/appstream/x86_64/icons/64x64/org.mozilla.firefox.png" - -- name: "Kdenlive" - id: "org.kde.kdenlive" - ref: "app/org.kde.kdenlive/x86_64/stable" - summary: "Video editor" - color: "#8596C6" - "flatpakref": "https://dl.flathub.org/repo/appstream/org.kde.kdenlive.flatpakref" - icons: - "128": "https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.kde.kdenlive.png" - "64": "https://dl.flathub.org/repo/appstream/x86_64/icons/64x64/org.kde.kdenlive.png" - -- name: "Skype" - id: "com.skype.Client" - ref: "app/com.skype.Client/x86_64/stable" - summary: "Call and message Skype users" - color: "#C5BFB5" - "flatpakref": "https://dl.flathub.org/repo/appstream/com.skype.Client.flatpakref" - icons: - "128": "https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/com.skype.Client.png" - "64": "https://dl.flathub.org/repo/appstream/x86_64/icons/64x64/com.skype.Client.png" - -- name: "VLC" - id: "org.videolan.VLC" - ref: "app/org.videolan.VLC/x86_64/stable" - summary: "Open-source multimedia player" - color: "#DB946C" - "flatpakref": "https://dl.flathub.org/repo/appstream/org.videolan.VLC.flatpakref" - icons: - "128": "https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.videolan.VLC.png" - "64": "https://dl.flathub.org/repo/appstream/x86_64/icons/64x64/org.videolan.VLC.png" - -- name: "Blender" - id: "org.blender.Blender" - ref: "app/org.blender.Blender/x86_64/stable" - summary: "3D modelling and animation" - color: "#D89C7F" - "flatpakref": "https://dl.flathub.org/repo/appstream/com.slack.Slack.flatpakref" - icons: - "128": "https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/org.blender.Blender.png" - "64": "https://dl.flathub.org/repo/appstream/x86_64/icons/64x64/org.blender.Blender.png" - -- name: "Podman Desktop" - id: "io.podman_desktop.PodmanDesktop" - ref: "app/io.podman_desktop.PodmanDesktop/x86_64/stable" - summary: "Manage Podman and other container engines from a single UI and tray" - color: "#A337D4" - "flatpakref": "https://dl.flathub.org/repo/appstream/io.podman_desktop.PodmanDesktop.flatpakref" - icons: - "128": "https://dl.flathub.org/repo/appstream/x86_64/icons/128x128/io.podman_desktop.PodmanDesktop.png" - "64": "https://dl.flathub.org/repo/appstream/x86_64/icons/64x64/io.podman_desktop.PodmanDesktop.png" diff --git a/data/distro.yml b/data/distro.yml deleted file mode 100644 index 4ad209e1..00000000 --- a/data/distro.yml +++ /dev/null @@ -1,521 +0,0 @@ -- name: Ubuntu - logo: "ubuntu.svg" - steps: - - name: Install Flatpak - text: " -

To install Flatpak on Ubuntu 18.10 (Cosmic Cuttlefish) or later, open the Terminal app and run:

- sudo apt install flatpak" - - name: Install GNOME Software Flatpak plugin - text: ' -

The GNOME Software plugin makes it possible to install apps without needing the command line. To install, run:

- sudo apt install gnome-software-plugin-flatpak -

Note: Ubuntu distributes GNOME Software as a Snap in versions 20.04 to 23.04, and replaced it with App Center in 23.10 and newer—neither of which support installing Flatpak apps. Installing the Flatpak plugin will also install a deb version of GNOME Software, resulting in two "Software" apps being installed at the same time on Ubuntu 20.04 to 23.04, and a single new "Software" app on Ubuntu 23.10 and newer.

' - - name: Add the Flathub repository - text: ' -

Flathub is the best place to get Flatpak apps. To enable it, download and install the Flathub repository file or run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo' - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: Fedora - logo: "fedora.svg" - introduction: > -

Flatpak is installed by default on Fedora Workstation, Fedora Silverblue, and Fedora Kinoite. To get started, all you need to do is enable Flathub, which is the best way to get Flatpak apps. Flathub is pre-configured as a part of the Third-Party Repositories. Alternatively, you can download and install the Flathub repository file.

-

Now all you have to do is install apps!

-

The above links should work on the default GNOME and KDE Fedora installations, but if they fail for some reason you can manually add the Flathub remote by running:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo - -- name: Manjaro - logo: "manjaro.svg" - steps: - - name: Enable Flatpak through the Software Manager - text: ' -

Flatpak is installed by default on Manjaro 20 or higher.

-

To enable its support, navigate to the Software Manager (Add/Remove Programs)

-

Click on the triple line menu [or dots depending on the Desktop Environment] on the right, in the drop down menu select "Preferences"

-

Navigate to the "Flatpak" tab and slide the toggle to Enable Flatpak support (it is also possible to enable checking for updates, which is recommended).

' - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: Endless OS - logo: "endless.svg" - introduction: > -

Flatpak support is built into Endless OS 3.0.0 and newer—no setup required!

- -- name: ALT Linux - logo: "altlinux.svg" - logo_dark: "altlinux-dark.svg" - steps: - - name: Install Flatpak - text: " -

To install Flatpak on operating systems of the Alt family, open the Terminal app and run:

- - su -\n - apt-get update\n - apt-get install flatpak\n - " - - name: Add the Flathub repository - text: " -

Flathub is the best place to get Flatpak apps. To enable it on your Alt system, run:

- - su -\n - apt-get update\n - apt-get install flatpak-repo-flathub\n - " - - name: Restart - text: ' -

Restart your device to complete the Flatpak installation. Now you can install apps!

' - -- name: Chrome OS - logo: "chrome-os.svg" - introduction: > -

Flatpak applications can be installed on ChromeOS with the Crostini Linux compatibility layer. This is not available for all ChromeOS devices, so you should ensure your device is compatible before proceeding. A list of compatible devices is maintained here.

- steps: - - name: Enable Linux support - text: ' -

Navigate to chrome://os-settings, and scroll down to Developers and turn on Linux development environment. ChromeOS will take some time downloading and installing Linux.

' - - name: Start a Linux terminal - text: ' -

Press the Search/Launcher key, type "Terminal", and launch the Terminal app.

' - - name: Install Flatpak - text: ' -

To install Flatpak, run the following in the terminal:

- sudo apt install flatpak' - - name: Add the Flathub repository - text: " -

Flathub is the best place to get Flatpak apps. To enable it, run:

- flatpak --user remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo" - - name: Restart - text: ' -

To complete setup, restart Linux. You can do this by right-clicking terminal, and then clicking "Shut down Linux". Now all you have to do is install apps!

' - -- name: Red Hat Enterprise Linux - logo: "redhat.svg" - introduction: > -

Flatpak is installed by default on Red Hat Enterprise Linux Workstation 9 and newer. To get started, all you need to do is enable Flathub, which is the best way to get Flatpak apps. Just download and install the Flathub repository file.

-

To install Flatpak on Red Hat Enterprise Linux Workstation 8 or older, run the following in a terminal:

- - sudo yum install flatpak -

Now all you have to do is install apps!

-

The above links should work on the default Red Hat Enterprise Linux Workstation 9 installation, but if they fail for some reason you can manually add the Flathub remote by running:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo - -- name: Linux Mint - logo: "mint.svg" - introduction: > -

Flatpak support is built into Linux Mint 18.3 and newer—no setup required!

- -- name: openSUSE - logo: "opensuse.svg" - steps: - - name: Install Flatpak - text: ' -

Flatpak is available in the default repositories of all currently maintained openSUSE Leap and openSUSE Tumbleweed versions.

-

If you prefer a graphical installation, you can install Flatpak using a "1-click installer" from software.opensuse.org. If your distribution version is not shown by default, click Show under Unsupported distributions category and then select from the list.

-

Alternatively, install Flatpak from the command line using Zypper:

- sudo zypper install flatpak' - - name: Add the Flathub repository - text: ' -

Flathub is the best place to get Flatpak apps. To enable it, download and install the Flathub repository file or run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo' - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: Arch - logo: "arch.svg" - steps: - - name: Install Flatpak - text: " -

To install Flatpak on Arch, open the Terminal app and run:

- sudo pacman -S flatpak" - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: Debian - logo: "debian.svg" - steps: - - name: Install Flatpak - text: " -

A flatpak package is available in Debian 10 (Buster) and newer. To install it, run the following as root:

- sudo apt install flatpak" - - name: Install the Software Flatpak plugin - text: " -

If you are running GNOME, it is also a good idea to install the Flatpak plugin for GNOME Software. To do this, run:

- sudo apt install gnome-software-plugin-flatpak -

If you are running KDE, you should instead install the Plasma Discover Flatpak backend:

- sudo apt install plasma-discover-backend-flatpak" - - name: Add the Flathub repository - text: ' -

Flathub is the best place to get Flatpak apps. To enable it, download and install the Flathub repository file or run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo' - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: Rocky Linux - logo: "rockylinux.svg" - steps: - - name: Install Flatpak - text: " -

Flatpak is installed by default on Rocky Linux 8 and newer, when installed with a software selection that includes GNOME (Server with GUI, Workstation). If you are using such a system, you may skip this step. To install Flatpak on Rocky Linux, run the following in a terminal:

- sudo dnf install flatpak" - - name: Add the Flathub repository - text: ' -

Flathub is the best place to get Flatpak apps. To enable it, download and install the Flathub repository file or run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo' - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: CentOS Stream - logo: "centos.svg" - introduction: > -

Flatpak is installed by default on CentOS Stream 8 and newer, when using GNOME. To get started, all you need to do is enable Flathub, which is the best way to get Flatpak apps. Just download and install the Flathub repository file.

-

Now all you have to do is install apps!

- -- name: AlmaLinux - logo: "almalinux.svg" - introduction: > -

Flatpak is installed by default on AlmaLinux 8 and newer, when using GNOME. To get started, all you need to do is enable Flathub, which is the best way to get Flatpak apps. Just download and install the Flathub repository file.

-

Now all you have to do is install apps!

- -- name: Gentoo - logo: "gentoo.svg" - steps: - - name: Install Flatpak - text: " -

To install Flatpak on Gentoo, open the Terminal app and run:

- emerge --ask --verbose sys-apps/flatpak" - - name: Add the Flathub repository - text: " -

Flathub is the best place to get Flatpak apps. To enable it, run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo" - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

-

Note: graphical installation of Flatpak apps may not be possible with Gentoo.

' - -- name: Kubuntu - logo: "kubuntu.svg" - steps: - - name: Install Flatpak - text: " -

To install Flatpak on Kubuntu, open Discover, go to Settings, install the Flatpak backend and restart Discover.

" - - name: Install the Flatpak system settings add-on - text: " -

To integrate Flatpak support into the Plasma System Settings, open the Terminal app and run:

- sudo apt install kde-config-flatpak" - - name: Add the Flathub repository - text: " -

Flathub is the best place to get Flatpak apps. To enable it, open Discover, go to Settings and add the Flathub repository.

" - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: Solus - logo: "solus.svg" - steps: - - name: Install Flatpak - text: " -

To install Flatpak on Solus, open the Terminal app and run:

- sudo eopkg install flatpak" - - name: Add the Flathub repository - text: ' -

Flathub is the best place to get Flatpak apps. To enable it, download and install the Flathub repository file or run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo' - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

-

Note: graphical installation of Flatpak apps is not yet possible with Solus, but will be available in the near future.

' - -- name: Alpine - logo: "alpine.svg" - steps: - - name: Install Flatpak - text: " -

Flatpak can be installed from the community repository. Run the following in a terminal:

- doas apk add flatpak" - - name: Install the Software Flatpak plugin - text: " -

You can install the Flatpak plugin for either the GNOME Software (since v3.13) or KDE Discover (since v3.11), making it possible to install apps without needing the command line. To install, for GNOME Software run:

- doas apk add gnome-software-plugin-flatpak -

For KDE Discover run:

- doas apk add discover-backend-flatpak" - - name: Add the Flathub repository - text: ' -

Flathub is the best place to get Flatpak apps. To enable it, download and install the Flathub repository file or run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo' - - name: Restart - text: ' -

To complete the setup, restart your system. Now all you have to do is install apps!

' - -- name: Mageia - logo: "mageia.svg" - steps: - - name: Install Flatpak - text: " -

A flatpak package is available for Mageia 6 and newer. To install with DNF, run the following as root:

- dnf install flatpak -

Or, to install with urpmi, run:

- urpmi flatpak" - - name: Add the Flathub repository - text: ' -

Flathub is the best place to get Flatpak apps. To enable it, download and install the Flathub repository file or run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo' - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: OpenMandriva Lx - logo: "openmandriva.svg" - introduction: > -

Flatpak support is built into OpenMandriva for all actively supported versions, starting from the stable/fixed release 'Rock 5.0', through the development release 'Cooker', and ending with the rolling release 'ROME'.

-

Flatpak comes with the pre-configured Flathub repository.

- -- name: "Pop!_OS" - logo: "pop-os.svg" - introduction: > -

Flatpak support is built into Pop!_OS 20.04 and newer—no setup required!

- -- name: elementary OS - logo: "elementary-os.svg" - logo_dark: "elementary-os-dark.svg" - steps: - - name: Install Apps - text: - '

elementary OS 5.1 and newer comes with Flatpak support out of the box. For non-curated apps, head to Flathub to install any app using the big "Install" button, and open the downloaded `.flatpakref` file with Sideload.

-

Note: After installing one app from a remote like Flathub, all other apps from that remote will also automatically show up in AppCenter.

' - -- name: Raspberry Pi OS - logo: "raspberry-pi-os.svg" - steps: - - name: Install Flatpak - text: " -

A flatpak package is available in Raspberry Pi OS (previously called Raspbian) Stretch and newer. To install it, run the following as root:

- sudo apt install flatpak" - - name: Add the Flathub repository - text: " -

Flathub is the best place to get Flatpak apps. To enable it, run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo -

Important note: It is recommended to use Raspberry Pi OS 64-bit as newer applications are more likely to be available for that platform only.

" - - name: Restart - text: - '

To complete setup, restart your system. Now all you have to do is install apps!

-

Note: graphical installation of Flatpak apps may not be possible with Raspberry Pi OS.

' - -- name: Void Linux - logo: "void.svg" - logo_dark: "void-dark.svg" - steps: - - name: Install Flatpak - text: " -

To install Flatpak on Void Linux, run the following in a terminal:

- sudo xbps-install -S flatpak" - - name: Add the Flathub repository - text: " -

Flathub is the best place to get Flatpak apps. To enable it, run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo" - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: NixOS - logo: "nixos.svg" - steps: - - name: Install Flatpak - text: " -

To install Flatpak, set NixOS option services.flatpak.enable to true by putting the following into your /etc/nixos/configuration.nix:

- services.flatpak.enable = true; -

Then, rebuild and switch to the new configuration with:

- sudo nixos-rebuild switch -

For more details see the NixOS documentation.

" - - name: Add the Flathub repository - text: " -

Flathub is the best place to get Flatpak apps. To enable it, run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo" - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: PureOS - logo: "pureos.svg" - logo_dark: "pureos-dark.svg" - introduction: > -

Flatpak is installed by default on PureOS. To get started, all you need to do is enable Flathub, which is the best way to get Flatpak apps. Just download and install the Flathub repository file.

-

Now all you have to do is install apps!

- -- name: Zorin OS - logo: "zorin-os.svg" - introduction: > -

Flatpak support is built into Zorin OS

-

You can use the Software Store app to download Flatpak apps.

- -- name: Deepin - logo: "deepin.svg" - steps: - - name: Install Flatpak - text: " -

To install Flatpak on Deepin, run the following in a terminal:

- sudo apt install flatpak" - - name: Add the Flathub repository - text: " -

Flathub is the best place to get Flatpak apps. To enable it, run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo" - - name: Install the Deepin themes - text: ' -

To install light and dark themes, run:

- - flatpak install flathub org.gtk.Gtk3theme.deepin\n - flatpak install flathub org.gtk.Gtk3theme.deepin-dark\n - ' - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: Pardus - logo: "pardus.svg" - steps: - - name: Install Flatpak - text: ' -

A flatpak package is available in Pardus 2019 and newer. To install it, run the following as root:

- sudo apt install flatpak' - - name: Install the Software Flatpak plugin - text: " -

If you are running GNOME, it is also a good idea to install the Flatpak plugin for GNOME Software. To do this, run:

- sudo apt install gnome-software-plugin-flatpak" - - name: Add the Flathub repository - text: ' -

Flathub is the best place to get Flatpak apps. To enable it, download and install the Flathub repository file or run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo' - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: MX Linux - logo: "mxlinux.svg" - steps: - - name: Enable Flatpak through the Software Manager - text: ' -

Flatpak support is built in from MX 18 and later. It is only required to activate the Flathub repository following these instructions:

-

Open MX Package Installer (open the menu and look in MX Tools), select the "Flatpaks" tab, to activate the repository you will need to enter the root password.

' - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: "Pisi GNU/Linux" - slug: "Pisi GNU Linux" - logo: "pisi.svg" - logo_dark: "pisi-dark.svg" - steps: - - name: Install Flatpak - text: " -

A flatpak package is available in Pisi 2.1 and newer. To install it, run the following as root:

- sudo pisi it flatpak" - - name: Add the Flathub repository - text: " -

Flathub is the best place to get Flatpak apps. To enable it, run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo" - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

-

Note: graphical installation of Flatpak apps may not be possible with Pisi GNU/Linux.

' - -- name: EndeavourOS - logo: "endeavouros.svg" - logo_dark: "endeavouros-dark.svg" - steps: - - name: Install Flatpak - text: " -

To install Flatpak on EndeavorOS, you must first make sure your installation is up to date, run the following in a terminal:

- sudo pacman -Syu -

Then install Flatpak:

- sudo pacman -S flatpak" - - name: Add the Flathub repository - text: - "

Flathub is the best place to get Flatpak apps. To enable it, run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo" - - name: Restart - text: - '

To complete setup, restart your system. Now all you have to do is install apps!

-

Note: graphical installation of Flatpak apps may not be possible with EndeavourOS.

' - -- name: KDE neon - logo: "kdeneon.svg" - introduction: > -

Flatpak support is built into KDE neon 19 and newer—no setup required!

- -- name: GNU Guix - logo: "guix.svg" - logo_dark: "guix-dark.svg" - steps: - - name: Install Flatpak - text: " -

To install Flatpak on GNU Guix, run the following in a terminal:

- guix install flatpak" - - name: Add the Flathub repository - text: " -

Flathub is the best place to get Flatpak apps. To enable it, run:

- flatpak --user remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo" - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

-

Note: graphical installation of Flatpak apps may not be possible with GNU Guix.

' - -- name: Crystal Linux - logo: "crystallinux.svg" - introduction: > -

Flatpak is installed by default on Crystal Linux.

-

If you didn't use jade_gui to install crystal or selected not to install it, you can set Flatpak up by using the following steps.

- steps: - - name: Install Flatpak - text: " -

To install Flatpak in Crystal Linux, you must first make sure your packages are up to date. Run the following in a terminal:

- ame upg -

Then install Flatpak:

- ame ins flatpak" - - name: Add the Flathub repository - text: " -

Flathub is the best place to get Flatpak apps. To enable it, run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo" - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

' - -- name: Vanilla OS - logo: "vanillaos.svg" - introduction: > -

Flatpak is installed by default on Vanilla OS.

-

You can use the Software app or browse Flathub to install apps.

-

If for some reason Flathub is not available, you can configure it manually using the following command:

- host-shell flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo - -- name: Salix - logo: "salix.svg" - introduction: > -

Flatpak is installed by default on Salix since version 15.0—no setup required!

-

Flatpak comes preconfigured with the Flathub repository and desktop integration tools are included to allow 1-click install from Flathub.

-

All you have to do is install apps!

- -- name: Slackware - logo: "slackware.svg" - steps: - - name: Install Flatpak - text: " -

A Flatpak package is available on SlackBuilds. To install it (assuming you use Sbopkg/sqg), first create the queuefile and run the following as root:

- sqg -p flatpak -

Then compile it. Load the queuefile, press 'Q', and wait:

- sbopkg -i flatpak" - - - name: Add the Flathub repository - text: " -

Flathub is the best place to get Flatpak apps. To enable it, run:

- flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo" - - - name: Restart - text: ' -

To complete setup, restart your system. Now all you have to do is install apps!

-

Note: graphical installation of Flatpak apps may not be possible with Slackware.

' diff --git a/data/menu.toml b/data/menu.toml new file mode 100644 index 00000000..1616ef7b --- /dev/null +++ b/data/menu.toml @@ -0,0 +1,37 @@ +[[items]] +title = "Get Setup ↗" +url = "https://flathub.org/setup" +external = true +topnav = true + +[[items]] +title = "Browse Apps ↗" +url = "https://flathub.org/" +external = true + +[[items]] +title = "Developer Guide ↗" +url = "https://docs.flatpak.org/" +external = true + +[[items]] +title = "FAQ" +url = "faq" + +[[items]] +title = "Blog Posts" +url = "blog-posts" + +[[items]] +title = "Presentations & Articles" +url = "presentations" + +[[items]] +title = "About" +url = "about" +topnav = true + +[[items]] +title = "Press" +url = "press" +topnav = true diff --git a/data/menu.yml b/data/menu.yml deleted file mode 100644 index ab0958b3..00000000 --- a/data/menu.yml +++ /dev/null @@ -1,23 +0,0 @@ -- title: Get Setup - link: "/setup/" - onlyfooter: true -- title: Browse Apps ↗ - link: "https://flathub.org/" - onlyfooter: true -- title: Developer guide ↗ - link: "https://docs.flatpak.org/" - onlyfooter: true -- title: FAQ - link: "/faq.html" - onlyfooter: true -- title: Presentations & Articles - link: "/presentations.html" - onlyfooter: true -- title: Blog Posts - link: "/blog-posts.html" - onlyfooter: true -- title: About Us & Contact - link: "/about.html" -- title: Press - link: "/press.html" - onlyfooter: true diff --git a/data/site.yml b/data/site.yml deleted file mode 100644 index 1812dc01..00000000 --- a/data/site.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Flatpak -domain: https://flatpak.org -punchline: The Future of Application Distribution - -## If unspecified, timezone defaults to UTC -## For more TZs, see the top of: -## https://github.com/rails/rails/blob/master/activesupport/lib/active_support/values/time_zone.rb -#timezone: Berlin -#timezone: America/New_York -#timezone: Eastern Time (US & Canada) - - -# Global meta tags on each page <> -# To have page-specific tags added, please add a YAML list to "tags:" -# in that page's frontmatter block (the part at the top between ---) -keywords: - - xdgapp - - xdg - - zapp - - flatpack - - flatpak - diff --git a/nginx.conf b/nginx.conf index 5234d22d..236a1d73 100644 --- a/nginx.conf +++ b/nginx.conf @@ -44,12 +44,11 @@ server { server_name _; root /srv/http/; - try_files $uri $uri/ $uri.html =404; + try_files $uri $uri/index.html $uri.html =404; error_page 404 /404.html; absolute_redirect off; - rewrite ^/setup/(.*)/ https://flatpak.org/setup/$1; - + # External redirects (cannot be handled by Zola aliases) location /apps.html { return 301 https://flathub.org/; } @@ -58,10 +57,6 @@ server { return 301 http://docs.flatpak.org/en/latest/; } - location /getting.html { - return 301 /setup/; - } - location /hello-world.html { return 301 http://docs.flatpak.org/en/latest/getting-started.html; } @@ -70,6 +65,14 @@ server { return 301 http://docs.flatpak.org/en/latest/available-runtimes.html; } + # Blog posts page removed — redirect to homepage + location /blog-posts.html { + return 301 /; + } + location /blog-posts/ { + return 301 /; + } + # Some flatpak images are compressed SVG files. Skip compressing # them again but tell clients that they're already compressed since # many browsers don't know that svgz is compressed. diff --git a/source/404.html.haml b/source/404.html.haml deleted file mode 100644 index 967260ac..00000000 --- a/source/404.html.haml +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: Flatpak—page not found -description: 404 Page not Found ---- - -%section#notfound - .container - .row - .col-lg-5.col-lg-offset-4 - %p - = partial "404.svg" - %p.centered - Sorry, that page can't be found. diff --git a/source/_footer.haml b/source/_footer.haml deleted file mode 100644 index fb0f091a..00000000 --- a/source/_footer.haml +++ /dev/null @@ -1,38 +0,0 @@ -%section#footer.bg-black - .container - .row - .col-lg-3.col-lg-offset-1.col-sm-3.hidden-xs - %a.navbar-brand.page-scroll{:href => "#page-top"} - =partial "logo.svg" - %ul.col-lg-7.col-lg-offset-0.col-sm-8.col-sm-offset-0.col-xs-7.col-xs-offset-2 - %li.toplevel - = link_to "Home", "/index.html" - - data.menu.each do |i| - %li.toplevel - /id links on index page - - if (current_page.path == 'index.html') - = link_to i.title, i.link, :class => "page-scroll" - - else - - if (i.link.match('^#')) - = "#{i.title}" - - else - = link_to i.title, i.link, :class => "page-scroll" - - if !i.submenu.nil? - %ul - - i.submenu.each do |j| - %li - = link_to j.title, j.link, :class => "page-scroll" - .col-lg-1.col-sm-1.col-xs-1 - - =partial "twitter.svg" - - :css - #twitterbird path { transition: fill 400ms ease-in-out; } - #twitterbird path:hover { fill: #fff !important; } - .col-lg-1.col-sm-1.col-xs-1 - - =partial "mastodon.svg" - - :css - #mastodonlogo path { transition: fill 400ms ease-in-out; } - #mastodonlogo path:hover { fill: #fff !important; } diff --git a/source/_graph.svg b/source/_graph.svg deleted file mode 100644 index 65bd37e8..00000000 --- a/source/_graph.svg +++ /dev/null @@ -1,709 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - - - - - - - - - LIBRARY - - LIBRARY - - LIBRARY - - - - - - - - SANDBOX - - - - PORTAL - OPERATING SYSTEM - - - DATA - - CODE - - APPLICATION - - - - LIBRARY - - LIBRARY - - LIBRARY - - LIBRARY - - LIBRARY - - LIBRARY - - - - RUNTIME - (SHARED) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PORTAL - PORTAL - - - - - - - - diff --git a/source/_logo.svg b/source/_logo.svg deleted file mode 100644 index 8c113579..00000000 --- a/source/_logo.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/source/_mastodon.svg b/source/_mastodon.svg deleted file mode 100644 index dec86e3e..00000000 --- a/source/_mastodon.svg +++ /dev/null @@ -1,40 +0,0 @@ - - diff --git a/source/_navigation.haml b/source/_navigation.haml deleted file mode 100644 index 7df06139..00000000 --- a/source/_navigation.haml +++ /dev/null @@ -1,17 +0,0 @@ -#bs-example-navbar-collapse-1.collapse.navbar-collapse - %ul.nav.navbar-nav.navbar-right - -if (current_page.path == 'index.html') - - data.menu.each do |i| - -if (!i.onlyfooter) - %li - = link_to i.title, i.link, :class => "page-scroll" - -else - - data.menu.each do |i| - -if (!i.onlyfooter) - - if i.link.match('^#').nil? - %li - = link_to i.title, i.link, :class => "page-scroll" - - else - %li - = "#{i.title}" - / /.navbar-collapse diff --git a/source/_twitter.svg b/source/_twitter.svg deleted file mode 100644 index 10c6f887..00000000 --- a/source/_twitter.svg +++ /dev/null @@ -1,25 +0,0 @@ - -image/svg+xml diff --git a/source/about.html.haml b/source/about.html.haml deleted file mode 100644 index a8cac871..00000000 --- a/source/about.html.haml +++ /dev/null @@ -1,160 +0,0 @@ ---- -title: Flatpak—the future of application distribution -description: About Flatpak ---- - -%section#about - .container - .row - .col-lg-8.col-lg-offset-2 - %h1.section-heading.text-center About Us - %hr.primary - %p - Flatpak is developed by an independent community, made up of contributors, volunteers and supporting organizations. It is a true upstream open source project, dedicated to providing technology and services that can be used by all, with no vendor lock-in. We have strong links to other Free Software projects, including the Freedesktop project. - %p - All our code is freely available, with no contributor agreement required. Volunteers and contributing organizations are welcome, as equal partners. - .row - .col-lg-8.col-lg-offset-2 - %h1.section-heading.text-center Contact - %hr.primary - .row - .col-lg-2.col-xs-4.col-lg-offset-4 - .right.toneddown Mailing list - .col-lg-4.col-xs-8 - =link_to "flatpak at lists.freedesktop.org", "https://lists.freedesktop.org/mailman/listinfo/flatpak" - .row - .col-lg-4.col-xs-2.col-lg-offset-2 - .right.toneddown Private mailing list for security issues - .col-lg-4.col-xs-8 - =link_to "flatpak-security at lists.freedesktop.org", "https://lists.freedesktop.org/mailman/listinfo/flatpak-security" - .row - .col-lg-2.col-xs-4.col-lg-offset-4 - .right.toneddown Matrix - .col-lg-4.col-xs-8 - =link_to "#flatpak on Matrix.org", "https://matrix.to/#/#flatpak:matrix.org" - .row - .col-lg-2.col-xs-4.col-lg-offset-4 - .right.toneddown GitHub - .col-lg-4.col-xs-8 - =link_to "github.com/flatpak", "https://github.com/flatpak" - .row.largegap - .col-lg-8.col-lg-offset-2 - %p - Issues with this website can be reported through its - = succeed "." do - =link_to "GitHub project", "https://github.com/flatpak/flatpak.github.io/issues"# - .row.largegap - .col-lg-8.col-lg-offset-2 - %h1.section-heading.text-center Flatpak History - %hr.primary - .timeline.mediumgap - .date August 2007 - .description - Alexander Larsson releases Glick, his first app bundling framework - .date November 2011 - .description - Glick 2 is released, a modernized version of the first Glick framework - .date July 2012 - .decription - “GNOME OS” session held at GUADEC, includes initial planning for a new app bundling format - .date September 2012 - .description - Alexander Larsson releases experimental “bundler” framework - .date January 2013 - .description - “Linux Apps” proposal discussed at the GNOME Developer Experience hackfest, Brussels - .date December 2014 - .description - Work begins on xdg-app, which later becomes Flatpak - .date March 2015 - .descripton - xdg-app 0.1 released, the very first version of Flatpak - .date December 2015 - .description - GNOME's “Software” gains the ability to install xdg-app applications - .date May 2016 - .description - xdg-app renamed to Flatpak, 0.6.0 released; - = succeed " included endorsements by Red Hat, Endless Computers and Collabora" do - =link_to "accompanying press release", "https://flatpak.org/press/2016-06-21-flatpak-released.html" - .date June 2016 - .description - Work on desktop portals security framework begins - .date June 2016 - .description - LibreOffice is the first major application to adopt Flatpak for publishing on Linux - .date July 2016 - .description - GTK+ 3.21.4 released with initial support for the portals framework - .date August 2016 - .description - Endless OS 3.0 released, the first publicly available OS to use Flatpak by default. Adoption of Flatpak by Apertis IVI also becomes public knowledge. - .date November 2016 - .description - ClearLinux announces their adoption of Flatpak - .date December 2016 - .description - Flatpak 0.8.0 released, the start of the first stable series with long-term support - .date May 2017 - .description - Initial soft launch of Flathub hosting service - .date May 2017 - .description - KDE Plasma 5.10 released with initial support for portals - .date October 2017 - .description - Flatpak 0.10.0 released, marking the start of the second supported stable release series - .date October 2017 - .description - KDE Plasma 5.11 released, “Discover” gains the ability to install Flatpak apps - .date October 2017 - .description - GIMP adopts Flatpak to publish on Linux - .date November 2017 - .description - Linux Mint 18.3 released, includes out of the box Flatpak integration - .date August 2018 - .description - Flatpak 1.0 released, the first release in a new stable series, with major new features; Flathub beta period ends; Freedesktop runtime 18.08 released with new support period policy - .date September 2018 - .description - KDE introduces the KDE Testing Applications Flatpak repository; - =link_to "commit", "https://invent.kde.org/packaging/flatpak-kde-applications/-/commit/2d759a0d601942c3cf3a1d6a562942da543f7f83" - .date December 2019 - .description - elementary OS 5.1 Hera released, includes out of the box Flatpak integration - .date April 2020 - .description - Mozilla adopts Flatpak to publish Firefox on Linux - .date April 2020 - .description - System76 releases Pop!_OS 20.04, includes out of the box Flatpak integration - .date October 2021 - .description - 1Password adopts Flatpak to publish on Linux - .date Febuary 2022 - .description - Valve releases the Steam Deck; a handheld video game console with out of the box Flatpak and Flathub integration - .date Febuary 2022 - .description - OBS Studio adopts Flatpak to publish on Linux - .date May 2022 - .description - Red Hat Enterprise Linux Workstation 9 released, includes out of the box Flatpak integration - .date October 2022 - .description - Flathub introduces verified status; - =link_to "commit", "https://github.com/flathub/website/commit/5aae6b759b15ae26c155a0c8c18f13ca0da29ee3" - .date April 2023 - .description - Purism introduces Flatpak and the PureOS Flatpak repository; - =link_to "announcement", "https://puri.sm/posts/introducing-flatpaks-on-pureos/" - .date April 2023 - .description - Valve adopts portals for the popular Steam application - .date May 2023 - .description - Flathub offers more than 2000 apps and celebrates 1B total downloads - .date October 2023 - .description - Discord adopts Flatpak to publish on Linux diff --git a/source/blog-posts.html.haml.markdown b/source/blog-posts.html.haml.markdown deleted file mode 100644 index 3d8b5fcd..00000000 --- a/source/blog-posts.html.haml.markdown +++ /dev/null @@ -1,216 +0,0 @@ ---- -title: Blog Posts -description: Blog posts about Flatpak ---- -
-:markdown - - # Blog Posts - -
    - - If you know of a blog post that isn't listed, please [file an issue](https://github.com/flatpak/flatpak.github.io/issues/new) so we can add it! - - ## 2024 - - [**Cassidy James Blaede: 2 Billion Downloads & Other Milestones from 2024 So Far**](https://docs.flathub.org/blog/2-billion-downloads-2024/) - August 2024 - - ## 2022 - - [**Hubert Figuière: RTKit, portals, and Pipewire**](https://www.figuiere.net/hub/wlog/rtkit-portal-pipewire/) - August 2022 - - [**Will Thompson: How many Flathub apps reuse other package formats?**](https://blogs.gnome.org/wjjt/2022/06/14/how-many-flathub-apps-reuse-other-package-formats/) - June 2022 - - [**Jakub Steiner: Flatpak Brand Refresh**](https://blog.jimmac.eu/2022/flatpak-refresh/) - June 2022 - - [**Martín Abente Lahaye: Flatseal 1.8.0**](https://blogs.gnome.org/tchx84/2022/05/31/flatseal-1-8-0/) - May 2022 - - [**Will Thompson: Evince, Flatpak, and GTK print previews**](https://blogs.gnome.org/wjjt/2022/05/30/evince-flatpak-and-gtk-print-previews/) - May 2022 - - [**TheEvilSkeleton: Response to "Flatpak Is Not the Future"**](https://theevilskeleton.gitlab.io/2022/05/16/response-to-flatpak-is-not-the-future.html) - May 2022 - - [**Jan Grulich: How to use Libportal/libportal-qt**](https://jgrulich.cz/2022/02/10/how-to-use-libportal-libportal-qt/) - February 2022 - - ## 2021 - - [**Phaedrus Leeds: A Quick PSA on Writing Portal-friendly Application Code**](https://blogs.gnome.org/mwleeds/2021/12/03/a-quick-psa-on-writing-portal-friendly-application-code/) - December 2021 - - [**Will Thompson: On Flatpak disk usage and deduplication**](https://blogs.gnome.org/wjjt/2021/11/24/on-flatpak-disk-usage-and-deduplication/) - November 2021 - - [**Martín Abente Lahaye: Flatseal 1.7.5**](https://blogs.gnome.org/tchx84/2021/11/20/flatseal-1-7-5/) - November 2021 - - [**Peter Hutterer: Flatpak portals - how do they work?**](https://who-t.blogspot.com/2021/08/flatpak-portals-how-do-they-work.html) - September 2021 - - [**Lionir Deadman: Flathub, runtimes and stats**](https://thelion.website/flathub-runtimes-and-stats/) - June 2021 - - [**Martín Abente Lahaye: Flatseal 1.7.0**](https://blogs.gnome.org/tchx84/2021/04/23/flatseal-1-7-0/) - April 2021 - - [**TheEvilSkeleton: Response to flatkill.org**](https://theevilskeleton.gitlab.io/2021/02/11/response-to-flatkill-org.html) - February 2021 - - [**Phaedrus Leeds: Cleaning Up Unused Flatpak Runtimes**](https://blogs.gnome.org/mwleeds/2021/01/11/cleaning-up-unused-flatpak-runtimes/) - January 2021 - - ## 2020 - - [**Alexander Larsson: Scaling Flathub 100x**](https://blogs.gnome.org/alexl/2020/11/20/scaling-flathub/) - November 2020 - - [**Alexander Larsson: Compatibility in a sandboxed world**](https://blogs.gnome.org/alexl/2020/08/11/compatibility-in-a-sandboxed-world/) - August 2020 - - [**Martín Abente Lahaye: Flatseal 1.6.0**](https://blogs.gnome.org/tchx84/2020/06/26/flatseal-1-6-0-and-beyond/) - June 2020 - - [**Hubert Figuière: Getting a stack trace with debug symbols out of a flatpak**](https://www.figuiere.net/technotes/notes/tn001/) - June 2020 - - [**Alexander Larsson: Putting container updates on a diet**](https://blogs.gnome.org/alexl/2020/05/13/putting-container-updates-on-a-diet/) - May 2020 - - ## 2019 - - [**Matthias Clasen: More on Flatpak Updates**](https://blogs.gnome.org/mclasen/2019/12/19/9100/) - December 2019 - - [**TingPing: Hardening Flatpak Permissions Over Time**](https://blog.tingping.se/2019/10/06/hardening-flatpak-permissions.html) - October 2019 - - [**Matthias Clasen: Some Flatpak Updates**](https://blogs.gnome.org/mclasen/2019/10/03/some-flatpak-updates/) - October 2019 - - [**Robert McQueen: Flathub, brought to you by...**](https://ramcq.net/2019/08/12/flathub-brought-to-you-by/) - August 2019 - - [**Matthias Clasen: Settings, in a Sandbox World**](https://blogs.gnome.org/mclasen/2019/07/12/settings-in-a-sandbox-world/) - July 2019 - - [**Christian Hergert: Flatpaking Terminals**](https://blogs.gnome.org/chergert/2019/04/25/flatpaking-terminals/) - April 2019 - - [**Alexander Larsson: Introducing flat-manager**](https://blogs.gnome.org/alexl/2019/03/19/introducing-flat-manager/) - March 2019 - - [**Alexander Larsson: Changes in Flathub land**](https://blogs.gnome.org/alexl/2019/02/19/changes-in-flathub-land/) - February 2019 - - [**Matthias Clasen: What's New in Flatpak 1.2**](https://blogs.gnome.org/mclasen/2019/01/28/whats-new-in-flatpak-1-2/) - January 2019 - - ## 2018 - - [**Matthias Clasen: Flatpak Commandline Design**](https://blogs.gnome.org/mclasen/2018/12/19/flatpak-commandline-design/) - December 2018 - - [**Matthias Clasen: An Update on Flatpak Updates**](https://blogs.gnome.org/mclasen/2018/11/26/an-update-on-flatpak-updates/) - November 2018 - - [**Robert McQueen: Flatpak, sandboxes and security**](https://ramcq.net/2018/10/15/flatpak-sandbox-security/) - October 2018 - - [**Alexander Larsson: Moving away from the 1.6 freedesktop runtime**](https://blogs.gnome.org/alexl/2018/10/11/moving-away-from-the-1-6-freedesktop-runtime/) - October 2018 - - [**Matthias Clasen: Flatpak, After 1.0**](https://blogs.gnome.org/mclasen/2018/10/08/flatpak-after-1-0/) - October 2018 - - [**Alexander Larsson: Flatpak on windows**](https://blogs.gnome.org/alexl/2018/09/17/flatpak-on-windows/) - September 2018 - - [**Matthias Clasen: On Flatpak Dependencies**](https://blogs.gnome.org/mclasen/2018/09/07/on-flatpak-dependencies/) - September 2018 - - [**Matthias Clasen: About Flatpak Installations**](https://blogs.gnome.org/mclasen/2018/08/26/about-flatpak-installations/) - August 2018 - - [**TingPing: Using host Nvidia driver with Flatpak**](https://blog.tingping.se/2018/08/26/flatpak-host-extensions.html) - August 2018 - - [**Alexander Larsson: Kick-starting the revolution 1.0**](https://blogs.gnome.org/alexl/2018/08/21/kick-starting-the-revolution-1-0/) - August 2018 - - [**TingPing: Easier Flatpak manifest editing with VSCode**](https://blog.tingping.se/2018/08/19/flatpak-schema.html) - August 2018 - - [**Alexander Larsson: The birth of a new runtime**](https://blogs.gnome.org/alexl/2018/08/10/the-birth-of-a-new-runtime/) - August 2018 - - [**Matthias Clasen: Flatpak Portal Experiments**](https://blogs.gnome.org/mclasen/2018/08/03/flatpak-portal-experiments/) - August 2018 - - [**Matthias Clasen: Flatpak - A Look Behind the Portal**](https://blogs.gnome.org/mclasen/2018/07/19/flatpak-a-look-behind-the-portal/) - July 2018 - - [**Matthias Clasen: The Flatpak BoF at GUADEC**](https://blogs.gnome.org/mclasen/2018/07/14/the-flatpak-bof-at-guadec/) - July 2018 - - [**Matthias Clasen: Flatpak, Making Contribution Easy**](https://blogs.gnome.org/mclasen/2018/07/07/flatpak-making-contribution-easy/) - July 2018 - - [**Matthias Clasen: Flatpak in Detail, Part 3**](https://blogs.gnome.org/mclasen/2018/07/02/flatpak-in-detail-part-3/) - July 2018 - - [**Alexander Larsson: Flatpak - a history**](https://blogs.gnome.org/alexl/2018/06/20/flatpak-a-history/) - June 2018 - - [**Matthias Clasen: Flatpak in Detail, Part 2**](https://blogs.gnome.org/mclasen/2018/06/19/flatpak-in-detail-part-2/) - June 2018 - - [**Matthias Clasen: Flatpak in Detail**](https://blogs.gnome.org/mclasen/2018/06/13/flatpak-in-detail/) - June 2018 - - [**Alexander Larsson: Flatpak inception**](https://blogs.gnome.org/alexl/2018/04/27/flatpak-inception/) - April 2018 - - [**TingPing: Flatpaking application plugins**](https://blog.tingping.se/2018/03/18/flatpaking-plugins.html) - March 2018 - - [**PointestStick: Flatpak support in Discover**](https://pointieststick.com/2018/01/13/flatpak-support-in-discover/) - January 2018 - - ## 2017 - - [**TingPing: Status of emulators Flatpak'd**](https://blog.tingping.se/2017/10/31/flatpaked-emulators.html) - October 2017 - - [**Alexander Larsson: On application sizes and bloat in flatpak**](https://blogs.gnome.org/alexl/2017/10/02/on-application-sizes-and-bloat-in-flatpak/) - October 2017 - - [**Simon McVittie: DebConf 17: Flatpak and Debian**](http://smcv.pseudorandom.co.uk/2017/flatpak_and_debian/) - August 2017 - - [**Robert McQueen: Welcome, Flathub!**](https://ramcq.net/2017/07/29/welcome-flathub/) - July 2017 - - [**TingPing: Flatpak now supports themes**](https://blog.tingping.se/2017/05/11/flatpak-theming.html) - May 2017 - - [**Simon McVittie: GTK hackfest 2017: D-Bus communication with containers**](http://smcv.pseudorandom.co.uk/2017/dbus_and_containers/) - March 2017 - - [**Matthias Clasen: Debugging a Flatpak Application**](https://blogs.gnome.org/mclasen/2017/01/20/debugging-a-flatpak-application/) - January 2017 - - ## 2016 - - [**Simon McVittie: Flatpak in Debian**](http://smcv.pseudorandom.co.uk/2016/flatpak/) - June 2016 - - [**Simon McVittie: GNOME Developer Experience hackfest: xdg-app + Debian**](https://smcv.pseudorandom.co.uk/2016/xdg-app/) - January 2016 - -
    diff --git a/source/distro-template.html.haml b/source/distro-template.html.haml deleted file mode 100644 index a8425d2a..00000000 --- a/source/distro-template.html.haml +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: Flatpak—the future of application distribution -description: #{locals[:name]} Quick Setup ---- - -%section#setup - .container - .row - .col-lg-10.col-lg-offset-1 - %h1.centered - = locals[:name] - Quick Setup - %p.centered - Follow these simple steps to start using Flatpak - - .row.largegap - .col-lg-12 - %ol.distrotut - - if locals[:introduction] - = locals[:introduction] - - Array(locals[:steps]).each_with_index do |step, i| - %li - %h2= step[:name] - %p= step[:text] \ No newline at end of file diff --git a/source/faq.html.haml.markdown b/source/faq.html.haml.markdown deleted file mode 100644 index ab7da3f3..00000000 --- a/source/faq.html.haml.markdown +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: Flatpak Frequently Asked Questions -description: FAQ about the Flatpak project. ---- -
    -:markdown - - # Frequently Asked Questions - -
      - - ### Why the name Flatpak? - - IKEA is a world-wide known brand whose success was partly built upon having developed and refined the idea of flatpacking - their furniture, which allowed them huge cost savings and efficiencies compared to their competitors. So when we needed - a new name for the packaging technology that had been developed by Alex Larsson, a native Swede, we thought that Flatpak would - both be a nice play on his nationality and pay homage to the success of IKEA and at the same time send a strong signal - about how revolutionary we thought this new packaging technology could be for the Linux desktop. - - ### What is the origin of the Flatpak technology? - - Flatpak is a technology that brings together many of the lessons learned by its creator Alexander Larsson during his long tenure - as a Linux desktop developer and having spent time inside Red Hat working on container technologies. Flatpak builds upon existing - technologies such as cgroups, namespaces, bind mounts and seccomp in the Linux kernel, OSTree from [Project Atomic](http://www.projectatomic.io/) - and the OCI format that is developed by the [Open Container Initiative](https://www.opencontainers.org/). - It has also spawned new technologies such as Bubblewrap which is shared between Flatpak and Project Atomic. - - ### Is Flatpak tied to GNOME? - - No. While Flatpak has been developed by people with a long involvement in the GNOME community it is not tied - to any desktop. In fact, it was designed with the explicit goal of allowing it to build applications using any library stack or - programming language an application author might want. - - ### Is Flatpak tied to Fedora? - - No. In fact, Flatpak and even [Flathub](https://flathub.org) are enabled by default on Endless OS and Linux Mint. - The people developing Flatpak have a long history in contributing to and building Linux distributions like Debian, - Fedora, and others, and solving the problems that arise when shipping applications for these platforms. Flatpak - was built to be distribution agnostic and allow deployment on any Linux operating system out there. - - ### Is Flatpak tied to Linux? - - Yes. We are explicitly using many features of the linux kernel (bind mounts, namespaces, seccomp, etc) to create the sandbox that - Flatpak apps are running in. It may be possible to use equivalent technologies on other kernels, but that would be a non-trivial - amount of work, and we don’t consider this one of our priorities. - - ### Is Flatpak tied to systemd? - - No. Versions of Flatpak before 0.6.10 relied on systemd for cgroups setup, but this is no longer required. - - ### Is Flatpak the same as xdg-app? - - Yes, while xdg-app was a fine name to use during development we wanted something with wider appeal and more sparkle - to it than xdg-app could provide. So as part of formally launching Flatpak as ready for use we decided to pick a more accessible - and fun name. - - ### Is Flatpak a container technology? - - It can be, but it doesn’t have to be. Since a desktop application would require quite extensive changes in order to - be usable when run inside a container you will likely see Flatpak mostly deployed as a convenient library bundling technology - early on, with the sandboxing or containerization being phased in over time for most applications. In general though we - try to avoid using the term container when speaking about Flatpak as it tends to cause comparisons with Docker and rkt, - comparisons which quickly stop making technical sense due to the very different problem spaces these technologies - try to address. And thus we prefer using the term sandboxing. - - ### How does Flatpak relate to freedesktop.org technologies such as desktop files and AppStream metadata? - - These standards are incorporated as mandatory parts in the Flatpak definition. By relying on these standards - we are building on years of investment and support under Linux. - - ### Can Flatpak be used on servers too? - - Flatpak is designed to run inside a desktop session and relies on certain session services, such as a D-Bus session bus - and, optionally, a systemd `--user` instance. This makes Flatpak not a good match for a server. - - However, the build features of Flatpak run fine outside a session, so you can build things on a server. - - ### Is Flatpak compatible with other desktop isolation frameworks? - - In general unprivileged container systems can’t stack, because anything running inside the sandbox does not have the necessary privileges to set up a sandbox, nor does it have the ability to raise its privileges in any way. For instance, Firejail can never work inside Flatpak, because it is setuid. That being said, using multiple sandboxing frameworks at once does not really make anything more secure, so there is little point in trying to nest things like that. - - It is certainly possible for Flatpak and Flatpak applications to coexist with applications that are packaged in other ways, on the same host system. - - ### Are there any IDEs that support Flatpak? - - Yes! - - Version 3.22.4 and newer of [Builder](https://apps.gnome.org/Builder/) includes support for `flatpak-builder` manifests. This ensures your project is built using your selected Flatpak runtime and any external dependencies. Support for running your application inside Flatpak is also supported. By developing your application within the exact same environment as your users you can squash those “Works for me” bugs before they reach your users! - - ### Can I host my Flatpak app on GitHub? - - Flatpak repositories can’t (currently) be put on GitHub in a convenient way. - As an alternative, you can create a single-file bundle, and put that up on GitHub - as a “release.” Note that bundles have some drawbacks, compared to a repository. - Another option you have is to get your app on [Flathub](https://flathub.org/) - which will allow your users to get updates. - -
      diff --git a/source/fonts/Inter.var.woff2 b/source/fonts/Inter.var.woff2 deleted file mode 100644 index 365eedc5..00000000 Binary files a/source/fonts/Inter.var.woff2 and /dev/null differ diff --git a/source/img/apple-touch-icon.svg b/source/img/apple-touch-icon.svg deleted file mode 100644 index b3415397..00000000 --- a/source/img/apple-touch-icon.svg +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/container.webp b/source/img/container.webp deleted file mode 100644 index 7bce53ed..00000000 Binary files a/source/img/container.webp and /dev/null differ diff --git a/source/img/delivery_truck.original.png b/source/img/delivery_truck.original.png deleted file mode 100644 index bf792872..00000000 Binary files a/source/img/delivery_truck.original.png and /dev/null differ diff --git a/source/img/delivery_truck2.original.png b/source/img/delivery_truck2.original.png deleted file mode 100644 index ff4a3701..00000000 Binary files a/source/img/delivery_truck2.original.png and /dev/null differ diff --git a/source/img/delivery_truck2.png b/source/img/delivery_truck2.png deleted file mode 100644 index 86770c34..00000000 Binary files a/source/img/delivery_truck2.png and /dev/null differ diff --git a/source/img/distro/almalinux.svg b/source/img/distro/almalinux.svg deleted file mode 100644 index b2e050ae..00000000 --- a/source/img/distro/almalinux.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - diff --git a/source/img/distro/alpine.svg b/source/img/distro/alpine.svg deleted file mode 100644 index 6b43c64e..00000000 --- a/source/img/distro/alpine.svg +++ /dev/null @@ -1,276 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/source/img/distro/altlinux-dark.svg b/source/img/distro/altlinux-dark.svg deleted file mode 100644 index affd52c5..00000000 --- a/source/img/distro/altlinux-dark.svg +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/altlinux.svg b/source/img/distro/altlinux.svg deleted file mode 100644 index de3d97ab..00000000 --- a/source/img/distro/altlinux.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/source/img/distro/arch.svg b/source/img/distro/arch.svg deleted file mode 100644 index c4d13f3e..00000000 --- a/source/img/distro/arch.svg +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff --git a/source/img/distro/centos.svg b/source/img/distro/centos.svg deleted file mode 100644 index 1a3f9f10..00000000 --- a/source/img/distro/centos.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/img/distro/chrome-os.svg b/source/img/distro/chrome-os.svg deleted file mode 100644 index 9aad7bba..00000000 --- a/source/img/distro/chrome-os.svg +++ /dev/null @@ -1,838 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/crystallinux.svg b/source/img/distro/crystallinux.svg deleted file mode 100644 index 6f4c9263..00000000 --- a/source/img/distro/crystallinux.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/source/img/distro/debian.svg b/source/img/distro/debian.svg deleted file mode 100644 index 30329f47..00000000 --- a/source/img/distro/debian.svg +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/deepin.svg b/source/img/distro/deepin.svg deleted file mode 100644 index 9738f0e1..00000000 --- a/source/img/distro/deepin.svg +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - image/svg+xml - - ISO安装器-256px - - - - - - ISO安装器-256px - Created with Sketch. - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/elementary-os-dark.svg b/source/img/distro/elementary-os-dark.svg deleted file mode 100644 index f845c32d..00000000 --- a/source/img/distro/elementary-os-dark.svg +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/source/img/distro/elementary-os.svg b/source/img/distro/elementary-os.svg deleted file mode 100644 index f86f1141..00000000 --- a/source/img/distro/elementary-os.svg +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/source/img/distro/endeavouros-dark.svg b/source/img/distro/endeavouros-dark.svg deleted file mode 100644 index 5e6482be..00000000 --- a/source/img/distro/endeavouros-dark.svg +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/endeavouros.svg b/source/img/distro/endeavouros.svg deleted file mode 100644 index 24c7ea25..00000000 --- a/source/img/distro/endeavouros.svg +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/endless.svg b/source/img/distro/endless.svg deleted file mode 100644 index 7ef91b0a..00000000 --- a/source/img/distro/endless.svg +++ /dev/null @@ -1,82 +0,0 @@ - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - diff --git a/source/img/distro/fedora.svg b/source/img/distro/fedora.svg deleted file mode 100644 index d789e9eb..00000000 --- a/source/img/distro/fedora.svg +++ /dev/null @@ -1,53 +0,0 @@ - - - - - Fedora logo (2021) - - - - - Fedora logo (2021) - - - - diff --git a/source/img/distro/gentoo.svg b/source/img/distro/gentoo.svg deleted file mode 100644 index 7c382cf1..00000000 --- a/source/img/distro/gentoo.svg +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/source/img/distro/guix-dark.svg b/source/img/distro/guix-dark.svg deleted file mode 100644 index bf36ebcc..00000000 --- a/source/img/distro/guix-dark.svg +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/guix.svg b/source/img/distro/guix.svg deleted file mode 100644 index 9b9e8f6f..00000000 --- a/source/img/distro/guix.svg +++ /dev/null @@ -1,177 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/kdeneon.svg b/source/img/distro/kdeneon.svg deleted file mode 100644 index 5068c338..00000000 --- a/source/img/distro/kdeneon.svg +++ /dev/null @@ -1,176 +0,0 @@ - -image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/kubuntu.svg b/source/img/distro/kubuntu.svg deleted file mode 100644 index 6aa4feaf..00000000 --- a/source/img/distro/kubuntu.svg +++ /dev/null @@ -1,101 +0,0 @@ - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - diff --git a/source/img/distro/mageia.svg b/source/img/distro/mageia.svg deleted file mode 100644 index 060b1c4d..00000000 --- a/source/img/distro/mageia.svg +++ /dev/null @@ -1,316 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/manjaro.svg b/source/img/distro/manjaro.svg deleted file mode 100644 index e7774b7e..00000000 --- a/source/img/distro/manjaro.svg +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - diff --git a/source/img/distro/mint.svg b/source/img/distro/mint.svg deleted file mode 100644 index ed8950e5..00000000 --- a/source/img/distro/mint.svg +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - - - - - - diff --git a/source/img/distro/mxlinux.svg b/source/img/distro/mxlinux.svg deleted file mode 100644 index e15d9046..00000000 --- a/source/img/distro/mxlinux.svg +++ /dev/null @@ -1,81 +0,0 @@ - -image/svg+xml - - - - - - - - - - - diff --git a/source/img/distro/nixos.svg b/source/img/distro/nixos.svg deleted file mode 100644 index 19e3a619..00000000 --- a/source/img/distro/nixos.svg +++ /dev/null @@ -1,518 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/openmandriva.svg b/source/img/distro/openmandriva.svg deleted file mode 100644 index 5992d10c..00000000 --- a/source/img/distro/openmandriva.svg +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - image/svg+xml - - - - - ruru - - - - - - - - - diff --git a/source/img/distro/opensuse.svg b/source/img/distro/opensuse.svg deleted file mode 100644 index d93730a0..00000000 --- a/source/img/distro/opensuse.svg +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/pardus.svg b/source/img/distro/pardus.svg deleted file mode 100644 index 5fece936..00000000 --- a/source/img/distro/pardus.svg +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/pisi-dark.svg b/source/img/distro/pisi-dark.svg deleted file mode 100644 index 7555bc0d..00000000 --- a/source/img/distro/pisi-dark.svg +++ /dev/null @@ -1,306 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/pisi.svg b/source/img/distro/pisi.svg deleted file mode 100644 index 05dc0259..00000000 --- a/source/img/distro/pisi.svg +++ /dev/null @@ -1,306 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/pop-os.svg b/source/img/distro/pop-os.svg deleted file mode 100644 index 0d06a7dd..00000000 --- a/source/img/distro/pop-os.svg +++ /dev/null @@ -1,98 +0,0 @@ - - - - - - image/svg+xml - - Pop_icon - - - - - - Pop_icon - - - - - - - - - - - - diff --git a/source/img/distro/pureos-dark.svg b/source/img/distro/pureos-dark.svg deleted file mode 100644 index 9c3a67cf..00000000 --- a/source/img/distro/pureos-dark.svg +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - - PureOS - - - - diff --git a/source/img/distro/pureos.svg b/source/img/distro/pureos.svg deleted file mode 100644 index 70cd1caf..00000000 --- a/source/img/distro/pureos.svg +++ /dev/null @@ -1,52 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - - PureOS - - - - diff --git a/source/img/distro/raspberry-pi-os.svg b/source/img/distro/raspberry-pi-os.svg deleted file mode 100644 index ac958e5c..00000000 --- a/source/img/distro/raspberry-pi-os.svg +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/source/img/distro/redhat.svg b/source/img/distro/redhat.svg deleted file mode 100644 index 7e6715e6..00000000 --- a/source/img/distro/redhat.svg +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - diff --git a/source/img/distro/rockylinux.svg b/source/img/distro/rockylinux.svg deleted file mode 100644 index 58f22104..00000000 --- a/source/img/distro/rockylinux.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/source/img/distro/salix.svg b/source/img/distro/salix.svg deleted file mode 100644 index 9de77679..00000000 --- a/source/img/distro/salix.svg +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - diff --git a/source/img/distro/slackware.svg b/source/img/distro/slackware.svg deleted file mode 100644 index ccea5803..00000000 --- a/source/img/distro/slackware.svg +++ /dev/null @@ -1,157 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - S - S - S - S - - - - - - - - - \ No newline at end of file diff --git a/source/img/distro/solus.svg b/source/img/distro/solus.svg deleted file mode 100644 index 059974fe..00000000 --- a/source/img/distro/solus.svg +++ /dev/null @@ -1,331 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/sulinos.svg b/source/img/distro/sulinos.svg deleted file mode 100644 index bcf430bd..00000000 --- a/source/img/distro/sulinos.svg +++ /dev/null @@ -1,251 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/ubuntu.svg b/source/img/distro/ubuntu.svg deleted file mode 100644 index f5e18550..00000000 --- a/source/img/distro/ubuntu.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/source/img/distro/vanillaos.svg b/source/img/distro/vanillaos.svg deleted file mode 100644 index b56a6dca..00000000 --- a/source/img/distro/vanillaos.svg +++ /dev/null @@ -1,321 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/void-dark.svg b/source/img/distro/void-dark.svg deleted file mode 100644 index e59fbc84..00000000 --- a/source/img/distro/void-dark.svg +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/void.svg b/source/img/distro/void.svg deleted file mode 100644 index 734cdfec..00000000 --- a/source/img/distro/void.svg +++ /dev/null @@ -1,87 +0,0 @@ - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - diff --git a/source/img/distro/zorin-os.svg b/source/img/distro/zorin-os.svg deleted file mode 100644 index 4445744f..00000000 --- a/source/img/distro/zorin-os.svg +++ /dev/null @@ -1,71 +0,0 @@ - - - - - - - image/svg+xml - - - - - - - - - - - - - diff --git a/source/img/download.original.svg b/source/img/download.original.svg deleted file mode 100644 index 6f9de522..00000000 --- a/source/img/download.original.svg +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - image/svg+xml - - Gnome Symbolic Icon Theme - - - - Gnome Symbolic Icon Theme - - - - - - - - - - - diff --git a/source/img/download.svg b/source/img/download.svg deleted file mode 100644 index 7b03bc26..00000000 --- a/source/img/download.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/source/img/endless-apps.original.png b/source/img/endless-apps.original.png deleted file mode 100644 index 6b87d055..00000000 Binary files a/source/img/endless-apps.original.png and /dev/null differ diff --git a/source/img/logo.svgz b/source/img/logo.svgz deleted file mode 100644 index 55a22751..00000000 Binary files a/source/img/logo.svgz and /dev/null differ diff --git a/source/index.html.haml b/source/index.html.haml deleted file mode 100644 index e80210b9..00000000 --- a/source/index.html.haml +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: Flatpak—the future of application distribution -description: The days of chasing multiple Linux distributions are over. Standalone apps for Linux are here! ---- - -%section.imagebanner - .container - .row.largegap - .col-lg-10.col-lg-offset-1 - %h1.section-heading - The future of apps on Linux - -%section#appsplash.bg-secondary - .container - .row - .col-sm-6.col-sm-offset-1 - %h3 - Start using Flatpak and install from a growing collection of apps - .appgrid - - 0.upto(6) do |i| - - if data.apps[i].icons["128"] - .icon.featured{:style => "background-image: url(#{data.apps[i].icons['128']})"} - - elsif data.apps[i].icons["64"] - .icon{:style => "background-image: url(#{data.apps[i].icons['64']})"} - .col-sm-4.col-sm-offset-1.centered - %a#quicksetupbtn.btn-default.btn.btn-xl.page-scroll{:href => "/setup"} Get set up - - %p.small.mediumgap - Already set up? Head over to - = link_to "Flathub", "https://flathub.org" - to install apps. - - - -%section.bg-primary-neutral - .container - .row.centered - .col-sm-10.col-sm-offset-1 - %iframe.full{'width'=>'100%', 'src'=>'https://www.youtube.com/embed/jDVCITRWGgs', 'frameborder'=>'0', 'allowfullscreen'=>'true'} - =link_to 'Flatpak 1.0', 'https://youtu.be/jDVCITRWGgs' - .row.centered - .col-sm-6.col-sm-offset-3 - %h2 A new world for application developers - %p Flatpak changes app distribution for the better. Advantages include: - .row.largegap - .col-sm-5.col-sm-offset-1 - %h4 Build for every distro - %p Create one app and distribute it to the entire Linux desktop market. - .col-sm-5 - %h4 Stable platforms - %p Runtimes provide platforms of common libraries that you can depend on. - .row - .col-sm-5.col-sm-offset-1 - %h4 Consistent environments - %p Develop and test your application in an environment that’s identical to the one users have. - .col-sm-5 - %h4 Full control over dependencies - %p Flatpak makes it easy to bundle your own libraries as part of your app. - .row - .col-sm-5.col-sm-offset-1 - %h4 Easy build tools - %p - Flatpak’s build tools are simple and easy to use, and come with a - =link_to 'full set of documentation.', 'https://docs.flatpak.org/' - .col-sm-5 - %h4 Future-proof builds - %p Flatpak apps continue to be compatible with new versions of Linux distributions. - .row - .col-sm-5.col-sm-offset-1 - %h4 Distribution made easy - %p - Make your app available to a rapidly growing audience of Flatpak users, with - =link_to 'Flathub.', 'https://flathub.org/' - .col-sm-5 - %h4 An independent project - %p Flatpak is developed by an independent community, with no lock-in to a single vendor. - .row.largegap - .col-sm-6.col-sm-offset-4 - %a.btn.btn-default.btn-xl.page-scroll{:href => "https://docs.flatpak.org/en/latest/getting-started.html"} 5 minute tutorial - %a.btn.btn-primary.btn-xl.page-scroll{:href => "https://docs.flatpak.org/en/latest/"} Developer guide - -%section#devsplash.bg-secondary - .container - .row.largegap - .col-sm-5.col-sm-offset-1 - %h3 - Flatpak can be used with a total of - = data.distro.count - distros - %p - See the - = link_to "complete list.", "/setup" - .col-sm-6 - .distrogrid - - 0.upto(4) do |i| - .icon{:style => "background-image: url(/img/distro/#{data.distro[i].logo})"} - -%section.bg-primary - .container - .row.centered - .col-sm-6.col-sm-offset-3 - %h2 What people are saying about Flatpak - .row.largegap - .col-sm-5.col-sm-offset-1 - %blockquote - %p - Bringing Flatpak technology into Debian enables us to run applications in a predictable environment with their most suitable library stack, without compromising the base OS's stability and flexibility. - .author - %em Simon McVittie - .title Senior Software Engineer, Collabora - .col-sm-5 - %blockquote - %p - At Endless, we’re proud to be a part of this movement and have fully embraced Flatpak by readily converting all of our applications for our upcoming release and continuing to build new Flatpak apps. - .author - %em Jonathan Blandford - .title VP of Software Engineering, Endless - .row - .col-sm-5.col-sm-offset-1 - %blockquote - %p - The Fedora Workstation team are very excited about Flatpak and the prospects it brings for making the Linux desktop easier to develop for. We plan to continue supporting this effort going forward. - .author - %em Christian F.K. Schaller - .title Senior Manager, Red Hat - .col-sm-5 - %blockquote - %p - Flatpak will enable us (as a Linux ISV) to distribute a better LibreOffice, with up-to-date dependencies and a platform that can run on many systems. I’m excited to see that happen. - .author - %em Michael Meeks - .title Director, The Document Foundation diff --git a/source/javascripts/all.js b/source/javascripts/all.js deleted file mode 100644 index 01fc3fe3..00000000 --- a/source/javascripts/all.js +++ /dev/null @@ -1,41 +0,0 @@ -/*! - * Start Bootstrap - Creative Bootstrap Theme (http://startbootstrap.com) - * Code licensed under the Apache License v2.0. - * For details, see http://www.apache.org/licenses/LICENSE-2.0. - */ - -(function($) { - "use strict"; // Start of use strict - - // jQuery for page scrolling feature - requires jQuery Easing plugin - $('body').on('click', 'a.page-scroll', function(event) { - var $anchor = $(this); - $('html, body').stop().animate({ - scrollTop: ($($anchor.attr('href')).offset().top - 80) - }, 1250, 'easeInOutExpo'); - //event.preventDefault(); - }); - - // Highlight the top nav as scrolling occurs - $('body').scrollspy({ - target: '.navbar-fixed-top', - offset: 51 - }) - - // Closes the Responsive Menu on Menu Item Click - $('.navbar-collapse ul li a').click(function() { - $('.navbar-toggle:visible').click(); - }); - - // Offset for Main Navigation - $('#mainNav').affix({ - offset: { - top: 100 - } - }) - - $('#toc').on('click', 'a', function(event) { - $(this).addClass('page-scroll'); - }); - -})(jQuery); // End of use strict diff --git a/source/javascripts/bootstrap.js b/source/javascripts/bootstrap.js deleted file mode 100644 index 01fbbcba..00000000 --- a/source/javascripts/bootstrap.js +++ /dev/null @@ -1,2363 +0,0 @@ -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under the MIT license - */ - -if (typeof jQuery === 'undefined') { - throw new Error('Bootstrap\'s JavaScript requires jQuery') -} - -+function ($) { - 'use strict'; - var version = $.fn.jquery.split(' ')[0].split('.') - if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 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); diff --git a/source/javascripts/command.js b/source/javascripts/command.js deleted file mode 100644 index 45ebfce6..00000000 --- a/source/javascripts/command.js +++ /dev/null @@ -1,39 +0,0 @@ -// A web component to display a terminal command with a copy button. - -// Icons are from https://github.com/lucide-icons/lucide -const copyIcon = ``; -const checkIcon = ``; - -// Define custom element, so we can do apt install flatpak -class TerminalCommand extends HTMLElement { - constructor() { - super(); - } - connectedCallback() { - const commands = this.textContent - .trim() - .split(/\n|\\n/) - .map((command) => command.trim()) - .filter(Boolean); - - this.innerHTML = ""; - - const code = document.createElement("code"); - code.innerHTML = commands - .map((command) => `$ ${command}`) - .join("\n"); - this.appendChild(code); - - const button = document.createElement("button"); - button.title = "Copy the command to clipboard"; - button.innerHTML = copyIcon; - button.addEventListener("click", () => { - navigator.clipboard.writeText(commands.join("\n")); - button.innerHTML = checkIcon; - setTimeout(() => (button.innerHTML = copyIcon), 1000); - }); - this.appendChild(button); - } -} - -customElements.define("terminal-command", TerminalCommand); diff --git a/source/javascripts/jquery-2.2.4.min.js b/source/javascripts/jquery-2.2.4.min.js deleted file mode 100644 index 4024b662..00000000 --- a/source/javascripts/jquery-2.2.4.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v2.2.4 | (c) jQuery Foundation | 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=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.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()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){var b;if("object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype||{},"isPrototypeOf"))return!1;for(b in a);return void 0===b||k.call(a,b)},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),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="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),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")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=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)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){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 fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(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 la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(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 oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.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]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);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"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(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(".#.+[+~]")}),ia(function(a){var b=n.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=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.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===n||a.ownerDocument===v&&t(v,a)?-1:b===n||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,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!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 fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.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},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.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=fa.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=fa.selectors={cacheLength:50,createPseudo:ha,match:W,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(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===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]||fa.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]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.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(ba,ca).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=fa.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(P," ")+" ").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,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(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:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(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:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).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 Y.test(a.nodeName)},input:function(a){return X.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:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(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,k=[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(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(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 ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(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 va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(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=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(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=[ra(sa(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 va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.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(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.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(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(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}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c; -}catch(e){}O.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return O.hasData(a)||N.hasData(a)},data:function(a,b,c){return O.access(a,b,c)},removeData:function(a,b){O.remove(a,b)},_data:function(a,b,c){return N.access(a,b,c)},_removeData:function(a,b){N.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=O.get(f),1===f.nodeType&&!N.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),R(f,d,e[d])));N.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){O.set(this,a)}):K(this,function(b){var c,d;if(f&&void 0===b){if(c=O.get(f,a)||O.get(f,a.replace(Q,"-$&").toLowerCase()),void 0!==c)return c;if(d=n.camelCase(a),c=O.get(f,d),void 0!==c)return c;if(c=R(f,d,void 0),void 0!==c)return c}else d=n.camelCase(a),this.each(function(){var c=O.get(this,d);O.set(this,d,b),a.indexOf("-")>-1&&void 0!==c&&O.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){O.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=N.get(a,b),c&&(!d||n.isArray(c)?d=N.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return N.get(a,c)||N.access(a,c,{empty:n.Callbacks("once memory").add(function(){N.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length",""],thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};$.optgroup=$.option,$.tbody=$.tfoot=$.colgroup=$.caption=$.thead,$.th=$.td;function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",!b||N.get(b[c],"globalEval"))}var ba=/<|&#?\w+;/;function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],o=0,p=a.length;p>o;o++)if(f=a[o],f||0===f)if("object"===n.type(f))n.merge(m,f.nodeType?[f]:f);else if(ba.test(f)){g=g||l.appendChild(b.createElement("div")),h=(Y.exec(f)||["",""])[1].toLowerCase(),i=$[h]||$._default,g.innerHTML=i[1]+n.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;n.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",o=0;while(f=m[o++])if(d&&n.inArray(f,d)>-1)e&&e.push(f);else if(j=n.contains(f.ownerDocument,f),g=_(l.appendChild(f),"script"),j&&aa(g),c){k=0;while(f=g[k++])Z.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var da=/^key/,ea=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,fa=/^([^.]*)(?:\.(.+)|)/;function ga(){return!0}function ha(){return!1}function ia(){try{return d.activeElement}catch(a){}}function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ja(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ha;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return"undefined"!=typeof n&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(G)||[""],j=b.length;while(j--)h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.hasData(a)&&N.get(a);if(r&&(i=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&N.remove(a,"handle events")}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(N.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!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&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,la=/\s*$/g;function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&&(f=N.access(a),g=N.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}O.hasData(a)&&(h=O.access(a),i=n.extend({},h),O.set(b,i))}}function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.type)?b.checked=a.checked:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&ma.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),ua(f,b,c,d)});if(o&&(e=ca(b,a[0].ownerDocument,!1,a,d),g=e.firstChild,1===e.childNodes.length&&(e=g),g||d)){for(h=n.map(_(e,"script"),qa),i=h.length;o>m;m++)j=e,m!==p&&(j=n.clone(j,!0,!0),i&&n.merge(h,_(j,"script"))),c.call(a[m],j,m);if(i)for(k=h[h.length-1].ownerDocument,n.map(h,ra),m=0;i>m;m++)j=h[m],Z.test(j.type||"")&&!N.access(j,"globalEval")&&n.contains(k,j)&&(j.src?n._evalUrl&&n._evalUrl(j.src):n.globalEval(j.textContent.replace(oa,"")))}return a}function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(_(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&aa(_(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(ka,"<$1>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=_(h),f=_(a),d=0,e=f.length;e>d;d++)ta(f[d],g[d]);if(b)if(c)for(f=f||_(a),g=g||_(h),d=0,e=f.length;e>d;d++)sa(f[d],g[d]);else sa(a,h);return g=_(h,"script"),g.length>0&&aa(g,!i&&_(a,"script")),h},cleanData:function(a){for(var b,c,d,e=n.event.special,f=0;void 0!==(c=a[f]);f++)if(L(c)){if(b=c[N.expando]){if(b.events)for(d in b.events)e[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);c[N.expando]=void 0}c[O.expando]&&(c[O.expando]=void 0)}}}),n.fn.extend({domManip:ua,detach:function(a){return va(this,a,!0)},remove:function(a){return va(this,a)},text:function(a){return K(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.appendChild(a)}})},prepend:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(_(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return K(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!la.test(a)&&!$[(Y.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(_(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return ua(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(_(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),f=e.length-1,h=0;f>=h;h++)c=h===f?this:this.clone(!0),n(e[h])[b](c),g.apply(d,c.get());return this.pushStack(d)}});var wa,xa={HTML:"block",BODY:"block"};function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(wa||n("