commit 845632d0acaf2d95814702c5841360c9965414e2 Author: George Hunt Date: Sat May 27 11:09:50 2017 -0700 initial checkin -- May 27, 2017 diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..69fe02e9e --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +xs-config.spec +build +deprecated +.patches diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..d159169d1 --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..a85c1571d --- /dev/null +++ b/LICENSE @@ -0,0 +1,16 @@ +COPYRIGHT and LICENSE + +Many files in this repository have an explicit copyright notice and terms of license in the file. + +Authors contributing to this repository are encouraged to provide a copyright notice and to license their work +under the terms of the GNU Library General Public License as published by the Free Software Foundation; +either version 2 of the License, or (at your option) any later version. + +This license is contained in the file named COPYING. The simplest way to do this is to include +the following two lines at the top of the file: + +# Copyright (C) 20xx +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. + +All files not containing an explicit copyright notice or terms of license in the file are Copyright © 2015, Unleash Kids, +and are licensed under the terms of the GPLv2 license in the file named COPYING in the root of the repository. diff --git a/README.rst b/README.rst new file mode 100644 index 000000000..f1da871b1 --- /dev/null +++ b/README.rst @@ -0,0 +1,41 @@ +====================================== +School Server Community Edition (XSCE) +====================================== + +Welcome to the Git repository of the XSCE project. XSCE is a community-based +project developed and supported by volunteers from around the world. It +provides communication, networking, content, and maintenance to schools and +classrooms. In everyday usage the school server provides services which extend +capabilities of the connected laptops while being transparent to the +user. These services include: + +* Classroom connectivity – Similar to what you would find in an advanced home router. +* Internet gateway – If available, an internet connection is made available to laptops. +* Content – Tools to make instructional media available to their schools and classrooms. +* Maintenance – Tools to keep laptop updated and running smoothly. + +All of our server code resides in this repository. We are using ansible_ as the +underlying technology to install, deploy, configure and manage the various +server components. + +Documentation has recently moved to the wiki of this repo + +Please see the `XSCE wiki`_ + +Installation procedures are in the process of being reworked to include: + +* Offline install on bare metal from a usb stick +* Offline install with an iso file +* Manual install of all or part of the server in combination with either of the above + +Full installation instructions are in the wiki of this repo: + +Please read the `installation`_ documentation. + +See the `XSCE project`_ for more information about the project. + +.. _XSCE wiki: https://github.com/XSCE/xsce/wiki +.. _installation: https://github.com/XSCE/xsce/wiki/XSCE-Installation +.. _ansible: http://www.ansibleworks.com/ +.. _ansible documentation: http://www.ansibleworks.com/docs/ +.. _XSCE project: http://schoolserver.org/ diff --git a/ReleaseNotes6.0.md b/ReleaseNotes6.0.md new file mode 100644 index 000000000..7087f103e --- /dev/null +++ b/ReleaseNotes6.0.md @@ -0,0 +1,53 @@ +# Release Notes for XSCE 6.0 + +## What is it? + +XSCE is the digital backbone for your education revolution. Put simply, School Server is an open-education project inspired by +One Laptop Per Child to provide breakthrough digital learning tools to the world’s poorest children. + +### A Rose by any other Name + +Internally and in the source code we refer to this software as XSCE, the Community Edition of the XS server originally from +OLPC. Students and teachers often know it as Internet in a Box, a collection of educational materials and applications found on the internet, +but available on the server even without an internet connection. We also refer to it as a School Server since it is aimed at +schools and other places where people learn and performs the function of a server. + +## What's new in XSCE Release 6.0? + +This release extends the tools available to educators in three ways: + +* It makes available free and open source content that is available in many languages +* It provides new avenues for students to create, and share their work +* It contains number of advances to permit easy configuration, tailoring of content, and monitoring of student work. + +### Newly Available Open Source Educational Content + + +* KA Lite brings the online features of **Khan Academy** to the **offline** schoolserver based classroom. There are videos, exercises, tests, and student tracking in a number of languages, all selectable via a Graphical User Interface. https://learningequality.org/ka-lite/ +* Searchable **offline** access to **Wikipedia** and other content such as Wiktionaries and TED Talks in a variety of subjects and many languages, provided by the **Kiwix server** technology. http://www.kiwix.org/wiki/Main_Page +* RACHEL (a currated selection of offline materials) http://worldpossible.org/rachel/ +* Bring your **own content** by inserting a **USB thumbdrive** with content into the server having it immediately viewable by students. + +### Encourage Students to Write, Foster the Creative Process + +* Elgg provides the tools for generating social networks http://learn.elgg.org/en/2.0/intro/features.html +* ownCloud provides client based tools for storing and retrieving materials stored on the XSCE local cloud. +* DokuWiki (EXPERIMENTAL) provides a means for students to publish their work. https://www.dokuwiki.org/features +* Wordpress (EXPERIMENTAL -- enable in "local_vars") gives students experience editing/sharing using a tool that is becoming an industry standard. + +### New Tools for Administering the XSCE schoolserver + +* A new Graphical User Interface (Admin Console) to enable services, select and download content, get information +* AWstats is a flexible tool for summarizing the web traffic on and through the server in graphical and detailed ways. http://www.awstats.org/ + +## How do I get it? + +There are three main methods of installing this software: + +* Use ansible and the git repository - this is the fall back when you need to customize or you have a platform for which we have not created an image. +* Use an image you download - for some commonly used platforms we create image files that you can download, put on a usb stick or sd card and boot in your new hardware. +* Create and use your own image - this will appeal to you if you want an image to use in multiple machines and are able to use the tools we provide to create it. + +In each case you need hardware that has been assembled, but with nothing installed on it. + +Detailed instructions on each of these methods is at https://github.com/XSCE/xsce/wiki/XSCE-Installation. diff --git a/ReleaseNotes6.1.md b/ReleaseNotes6.1.md new file mode 100644 index 000000000..40abc6b10 --- /dev/null +++ b/ReleaseNotes6.1.md @@ -0,0 +1,36 @@ +# Release Notes for Release 6.1 +**What's New?** + +* Calibre -- A tool for managing a library of eBooks, modifyiing their file formats, adding search terms, and making them availabe online. +* Wordpress -- A content management system which gives students experience with editing wiki pages, blogs, menuing systems, and which is widely used. +* Dokuwiki -- An alternate wiki system, similar to wordpress, but less popular, which makes transferring wiki materials easy from one school server to another. +* Sugarizer -- Makes some of the sugar activities available to browser clients on laptops, and smart phones/tablets. +* CUPS -- Common Unix Printing System provides the ability to connect to and share network or USB connected printers. + +**What's Upgraded?** + +* Moodle is now upgraded to version 3.1, the most recent (long term support) version that will be supported until May 2019. +* Elgg -- A social networking application is upgraded to 2.1. +* Owncloud -- Permits sharing of all kinds of content between clients of a local server that is not internet connected (version 9). + +**Do all these new Services Slow my Server down?** + +A service that is installed on your hard disk, but not enabled in the administrative console, will have no impact on computer speed (will not use cpu cycles, or occupy scarce memory resources). The XSCE default is to install everything, and only enable the few things which are essential for a server to operate. + +If you want to enable a service, you must browse to http://schoolserver.lan/admin, and click on configure, services enabled, and the appropriate checkbox. In addition, many services require additional content to be downloaded, which can also be accomplished by selecting the "Install Content" header button. + +**How Do I Install 6.1?** + +The install instructions have not changed much since release-6.0. Please refer to https://github.com/XSCE/xsce/wiki/XSCE-Installation for the overall process -- Noting the following: + +* On FC22, add "yum" to the installs prior to running the ansible playbook i.e. +``` + yum install -y git yum ansible1.9 + cd /opt + mkdir /opt/schoolserver + cd schoolserver + git clone https://github.com/XSCE/xsce --branch release-6.1 --depth 1 + cd xsce + ./install-console +``` + diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 000000000..531760843 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,193 @@ +# config file for ansible -- http://ansible.com/ +# ============================================== + +# nearly all parameters can be overridden in ansible-playbook +# or with command line flags. ansible will read ANSIBLE_CONFIG, +# ansible.cfg in the current working directory, .ansible.cfg in +# the home directory or /etc/ansible/ansible.cfg, whichever it +# finds first + +[defaults] + +# some basic default values... + +hostfile = /etc/ansible/hosts +library = /usr/share/ansible +remote_tmp = $HOME/.ansible/tmp +pattern = * +forks = 5 +poll_interval = 15 +sudo_user = root +#ask_sudo_pass = True +#ask_pass = True +transport = smart +remote_port = 22 +module_lang = C + +# plays will gather facts by default, which contain information about +# the remote system. +# +# smart - gather by default, but don't regather if already gathered +# implicit - gather by default, turn off with gather_facts: False +# explicit - do not gather by default, must say gather_facts: True +gathering = implicit + +# additional paths to search for roles in, colon separated +#roles_path = /etc/ansible/roles + +# uncomment this to disable SSH key host checking +#host_key_checking = False + +# change this for alternative sudo implementations +sudo_exe = sudo + +# what flags to pass to sudo +#sudo_flags = -H + +# SSH timeout +timeout = 10 + +# default user to use for playbooks if user is not specified +# (/usr/bin/ansible will use current user as default) +#remote_user = root + +# logging is off by default unless this path is defined +# if so defined, consider logrotate +#log_path = /var/log/ansible.log + +# default module name for /usr/bin/ansible +#module_name = command + +# use this shell for commands executed under sudo +# you may need to change this to bin/bash in rare instances +# if sudo is constrained +#executable = /bin/sh + +# if inventory variables overlap, does the higher precedence one win +# or are hash values merged together? The default is 'replace' but +# this can also be set to 'merge'. +#hash_behaviour = replace + +# list any Jinja2 extensions to enable here: +#jinja2_extensions = jinja2.ext.do,jinja2.ext.i18n + +# if set, always use this private key file for authentication, same as +# if passing --private-key to ansible or ansible-playbook +#private_key_file = /path/to/file + +# format of string {{ ansible_managed }} available within Jinja2 +# templates indicates to users editing templates files will be replaced. +# replacing {file}, {host} and {uid} and strftime codes with proper values. +ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host} + +# by default, ansible-playbook will display "Skipping [host]" if it determines a task +# should not be run on a host. Set this to "False" if you don't want to see these "Skipping" +# messages. NOTE: the task header will still be shown regardless of whether or not the +# task is skipped. +#display_skipped_hosts = True + +# by default (as of 1.3), Ansible will raise errors when attempting to dereference +# Jinja2 variables that are not set in templates or action lines. Uncomment this line +# to revert the behavior to pre-1.3. +#error_on_undefined_vars = False + +# by default (as of 1.6), Ansible may display warnings based on the configuration of the +# system running ansible itself. This may include warnings about 3rd party packages or +# other conditions that should be resolved if possible. +# to disable these warnings, set the following value to False: +system_warnings = False + +# by default (as of 1.4), Ansible may display deprecation warnings for language +# features that should no longer be used and will be removed in future versions. +# to disable these warnings, set the following value to False: +deprecation_warnings = False + +# set plugin path directories here, separate with colons +action_plugins = /usr/share/ansible_plugins/action_plugins +callback_plugins = /usr/share/ansible_plugins/callback_plugins +connection_plugins = /usr/share/ansible_plugins/connection_plugins +lookup_plugins = /usr/share/ansible_plugins/lookup_plugins +vars_plugins = /usr/share/ansible_plugins/vars_plugins +filter_plugins = /usr/share/ansible_plugins/filter_plugins + +# don't like cows? that's unfortunate. +# set to 1 if you don't want cowsay support or export ANSIBLE_NOCOWS=1 +#nocows = 1 + +# don't like colors either? +# set to 1 if you don't want colors, or export ANSIBLE_NOCOLOR=1 +#nocolor = 1 + +# the CA certificate path used for validating SSL certs. This path +# should exist on the controlling node, not the target nodes +# common locations: +# RHEL/CentOS: /etc/pki/tls/certs/ca-bundle.crt +# Fedora : /etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem +# Ubuntu : /usr/share/ca-certificates/cacert.org/cacert.org.crt +#ca_file_path = + +# the http user-agent string to use when fetching urls. Some web server +# operators block the default urllib user agent as it is frequently used +# by malicious attacks/scripts, so we set it to something unique to +# avoid issues. +#http_user_agent = ansible-agent + +[paramiko_connection] + +# uncomment this line to cause the paramiko connection plugin to not record new host +# keys encountered. Increases performance on new host additions. Setting works independently of the +# host key checking setting above. +#record_host_keys=False + +# by default, Ansible requests a pseudo-terminal for commands executed under sudo. Uncomment this +# line to disable this behaviour. +#pty=False + +[ssh_connection] + +# ssh arguments to use +# Leaving off ControlPersist will result in poor performance, so use +# paramiko on older platforms rather than removing it +#ssh_args = -o ControlMaster=auto -o ControlPersist=60s + +# The path to use for the ControlPath sockets. This defaults to +# "%(directory)s/ansible-ssh-%%h-%%p-%%r", however on some systems with +# very long hostnames or very long path names (caused by long user names or +# deeply nested home directories) this can exceed the character limit on +# file socket names (108 characters for most platforms). In that case, you +# may wish to shorten the string below. +# +# Example: +# control_path = %(directory)s/%%h-%%r +#control_path = %(directory)s/ansible-ssh-%%h-%%p-%%r + +# Enabling pipelining reduces the number of SSH operations required to +# execute a module on the remote server. This can result in a significant +# performance improvement when enabled, however when using "sudo:" you must +# first disable 'requiretty' in /etc/sudoers +# +# By default, this option is disabled to preserve compatibility with +# sudoers configurations that have requiretty (the default on many distros). +# +#pipelining = False + +# if True, make ansible use scp if the connection type is ssh +# (default is sftp) +#scp_if_ssh = True + +[accelerate] +accelerate_port = 5099 +accelerate_timeout = 30 +accelerate_connect_timeout = 5.0 + +# The daemon timeout is measured in minutes. This time is measured +# from the last activity to the accelerate daemon. +accelerate_daemon_timeout = 30 + +# If set to yes, accelerate_multi_key will allow multiple +# private keys to be uploaded to it, though each user must +# have access to the system via SSH to add a new key. The default +# is "no". +#accelerate_multi_key = yes + +command_warnings = False diff --git a/ansible_hosts b/ansible_hosts new file mode 100644 index 000000000..7a69cae3f --- /dev/null +++ b/ansible_hosts @@ -0,0 +1,3 @@ +[localhost] +127.0.0.1 + diff --git a/install-console b/install-console new file mode 100755 index 000000000..685ffc4d2 --- /dev/null +++ b/install-console @@ -0,0 +1,51 @@ +#!/bin/bash + +# copy var files to /etc/xsce for subsequent use + +#./install-init + +# if not the first run, repo location is here + +if [ -f /etc/xsce/xsce.env ] +then + . /etc/xsce/xsce.env + cd $XSCE_DIR +else + XSCE_DIR=/opt/schoolserver/xsce + mkdir -p /etc/xsce + touch /etc/xsce/config_vars.yml +fi + +# don't track vars/local_vars.yml +git update-index --assume-unchanged vars/local_vars.yml + +PLAYBOOK="xsce-base.yml" +INVENTORY="ansible_hosts" +SELINUX_BEFORE="" +SELINUX_AFTER="" + +if [ ! -f $PLAYBOOK ] +then + echo "XSCE Playbook not found." + echo "Please run this command from the top level of the git repo." + echo "Exiting." + exit 1 +fi + +if [ -f /etc/selinux/config ] +then + SELINUX_BEFORE=`cat /etc/selinux/config | gawk -F= '/^SELINUX=/{ print $2 }'` +fi + +export ANSIBLE_LOG_PATH="$XSCE_DIR/xsce-install.log" +ansible-playbook -i $INVENTORY $PLAYBOOK --connection=local + +if [ -f /etc/selinux/config ] +then + SELINUX_AFTER=`cat /etc/selinux/config | gawk -F= '/^SELINUX=/{ print $2 }'` +fi + +if [ "$SELINUX_BEFORE" != "$SELINUX_AFTER" ]; then + echo "Rebooting ..." + reboot +fi diff --git a/roles/1-prep/README.rst b/roles/1-prep/README.rst new file mode 100644 index 000000000..660c800d3 --- /dev/null +++ b/roles/1-prep/README.rst @@ -0,0 +1,6 @@ +=========== +Prep README +=========== + +This role is a sort on init or startup. It includes preliminaries like hostname and is where things +that are specific to a particular platform, such as the XO, are done before the bulk of the install. diff --git a/roles/1-prep/defaults/main.yml b/roles/1-prep/defaults/main.yml new file mode 100644 index 000000000..f6f477e2c --- /dev/null +++ b/roles/1-prep/defaults/main.yml @@ -0,0 +1,57 @@ +# use these as a tag a release at a point in time +xsce_base_ver: 0 +gui_version: 2 +NUC6_firmware_needed: False + +# These entries should never be changed in this file. +# These are defaults for boolean routines, +installing: False +exFAT_enabled: False +no_NM_reload: False +has_WAN: False +wireless_lan_present: False +udev_needs_patch: False +strict_networking: False +xsce_demo_mode: False +gw_active: False +gui_static_wan: False +has_internet_connection: False +is_F18: False +is_F20: False +is_F21: False +is_F22: False +is_F23: False +is_F24: False + +# Set default for discovered hardware +driver_name: nl80211 +rpi_model: none +is_rpi: False +xo_model: none +rtc_id: none + +# Set defaults for discovery process as strings +wifi1: "not found-1" +wifi2: "not found-2" +discovered_wan_iface: "none" +discovered_lan_iface: "none" +discovered_wireless_iface: "none" +xsce_wireless_lan_iface: "none" +xsce_lan_iface: "none" +xsce_wan_iface: "none" +device_gw: "none" +has_ifcfg_gw: "none" +has_wifi_gw: "none" +ap_device: "none" +device_gw2: "" + +# WiFi +ssid: XSCE +hostapd_wait: 10 +gui_port: 80 + +# must keep roles/xsce-admin/defaults/main.yml sync'd +admin_console_path: "{{ xsce_base }}/admin_console" +cmdsrv_path: "{{ xsce_base }}/xsce_cmdsrv" +xsce_cmdsrv_dbname : "xsce_cmdsrv.0.2.db" +wifi_id: none diff --git a/roles/1-prep/tasks/computed_vars.yml b/roles/1-prep/tasks/computed_vars.yml new file mode 100644 index 000000000..4ca0460b6 --- /dev/null +++ b/roles/1-prep/tasks/computed_vars.yml @@ -0,0 +1,162 @@ +# get local vars from scripts in /etc/ansible/facts.d +# on first run, this will generate UUID + +- name: re-read facts + setup: filter=ansible_local + +# set top level variables from local facts for convenience +- set_fact: + xo_model: '{{ ansible_local["local_facts"]["xo_model"] }}' + phplib_dir: '{{ ansible_local["local_facts"]["phplib_dir"] }}' + xsce_base_ver: '{{ ansible_local["local_facts"]["xsce_base_ver"] }}' + xsce_preload: '{{ ansible_local["local_facts"]["xsce_preload"] }}' + +- name: Defaulting xsce_base_ver + set_fact: + xsce_base_ver: 0 + when: xsce_base_ver == "" + +- name: Defaulting xsce_prepped + set_fact: + xsce_prepped: False + tags: + - download + - download2 + +- name: Set exFAT enabled for XOs + set_fact: + exFAT_enabled: True + when: xo_model != "none" + +- name: add version section + ini_file: dest='{{ xsce_config_file }}' + section=runtime + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: 'runtime_branch' + value: '{{ ansible_local["local_facts"]["xsce_branch"] }}' + - option: 'runtime_commit' + value: '{{ ansible_local["local_facts"]["xsce_commit"] }}' + - option: 'runtime_date' + value: '{{ ansible_date_time["iso8601"] }}' + - option: 'runtime_php' + value: '{{ phplib_dir }}' + - option: 'runtime_preload' + value: '{{ xsce_preload }}' + - option: 'runtime_base_ver' + value: '{{ xsce_base_ver }}' + - option: 'kernel' + value: '{{ ansible_kernel }}' + - option: 'memory_mb' + value: '{{ ansible_memtotal_mb }}' + - option: 'swap_mb' + value: '{{ ansible_swaptotal_mb }}' + - option: 'product_id' + value: '{{ ansible_product_uuid }}' + +# Put all computed vars here so derive properly from any prior var file +- name: Set port 80 for Admin Console + set_fact: + gui_port: 80 + when: not adm_cons_force_ssl + +- name: Set port 443 for Admin Console + set_fact: + gui_port: 443 + when: adm_cons_force_ssl + +- name: Turn on mysql if elgg or rachel enabled + set_fact: + mysql_install: True + mysql_enabled: True + +# we decided to enable mysql unconditionally +# when: elgg_enabled or rachel_enabled or owncloud_enabled or phpmyadmin_enabled or wordpress_enabled or iiab_menu_install + +- name: Turn on mongodb if sugarizer enabled + set_fact: + mongodb_install: True + mongodb_enabled: True + when: sugarizer_enabled + +# There might be other db's +- name: Turn on postgresql if moodle or pathagar enabled + set_fact: + postgresql_install: True + postgresql_enabled: True + when: moodle_enabled or pathagar_enabled + +- name: Turn on docker if schooltool is to be installed + set_fact: + docker_install: True + docker_enabled: True + when: schooltool_enabled or schooltool_install + +# for various reasons the mysql service can not be enabled on fedora 20, +# but 'mariadb', which is its real name can +# on fedora 18 we need to use 'mysqld' + +- name: Set mysqld service name to mariadb by default + set_fact: + mysql_service: mariadb + +- name: Set mysqld service name to mysqld for fedora 18 + set_fact: + mysql_service: mysqld + no_NM_reload: True + is_F18: True + when: ansible_distribution_release == "based on Fedora 18" or ansible_distribution_version == "18" + +- name: Set mysql service name to mysql for debian + set_fact: + mysql_service: mysql + when: ansible_distribution == "Debian" + +- name: Fedora 20 + set_fact: + is_F20: True + when: ansible_distribution == "Fedora" and ansible_distribution_version == "20" + +- name: Fedora 21 + set_fact: + is_F21: True + when: ansible_distribution == "Fedora" and ansible_distribution_version == "21" + +- name: Fedora 22 + set_fact: + is_F22: True + when: ansible_distribution == "Fedora" and ansible_distribution_version == "22" + +- name: Fedora 23 + set_fact: + is_F23: True + when: ansible_distribution == "Fedora" and ansible_distribution_version == "23" + +- name: Fedora 24 + set_fact: + is_F24: True + when: ansible_distribution == "Fedora" and ansible_distribution_version == "24" + +- name: CentOS + set_fact: + is_CentOS: True + when: ansible_distribution == "CentOS" + +- name: Set kiwix source file name i686 + set_fact: + kiwix_src_file: "kiwix-linux-i686.tar.bz2" + kiwix_src_bin_only: False + when: ansible_machine == "i686" + +- name: Set kiwix source file name x86_64 + set_fact: + kiwix_src_file: "kiwix-0.9-linux-x86_64.tar.bz2" + kiwix_src_bin_only: False + when: ansible_machine == "x86_64" + +- name: Set kiwix source file name armv7l + set_fact: + kiwix_src_file: "kiwix-server-0.9-linux-armv5tejl.tar.bz2" + kiwix_src_bin_only: True + when: ansible_machine == "armv7l" diff --git a/roles/1-prep/tasks/detected_network.yml b/roles/1-prep/tasks/detected_network.yml new file mode 100644 index 000000000..8a05f8fb1 --- /dev/null +++ b/roles/1-prep/tasks/detected_network.yml @@ -0,0 +1,305 @@ +- name: Checking xs_domain_name + shell: "cat /etc/sysconfig/xs_domain_name" + register: prior_domain + ignore_errors: True + +# above always registers +- name: Checking for prior domain name + set_fact: + xsce_domain: "{{ prior_domain.stdout }}" + when: prior_domain.stdout != "lan" and prior_domain.stdout != "" + +- name: xs_wan_device + shell: "cat /etc/sysconfig/xs_wan_device" + register: prior_gw + ignore_errors: True + +- name: Checking for old device gateway interface for device test + set_fact: + device_gw: "{{ prior_gw.stdout }}" + device_gw2: "{{ prior_gw.stdout }}" + when: prior_gw is defined and prior_gw.stdout != "" + +- name: Checking for ifcfg-WAN file + stat: path=/etc/sysconfig/network-scripts/ifcfg-WAN + register: has_ifcfg_WAN + +- name: Setting ifcfg-WAN True + set_fact: + has_WAN: True + when: has_ifcfg_WAN.stat.exists + +# DETECT -- gateway and wireless +- name: Get a list of slaves from previous config + shell: "egrep -rn BRIDGE=br0 /etc/sysconfig/network-scripts/ifcfg-* | gawk -F'[-:]' '{print $3}'" + register: ifcfg_slaves + ignore_errors: True + changed_when: False + +# Discover do we have a gateway? -- if ansible detects gateway, becomes WAN candidate +- name: Finding gateway + set_fact: + discovered_wan_iface: "{{ ansible_default_ipv4.alias }}" + when: 'ansible_default_ipv4.gateway is defined' + +- name: Verify gateway present + shell: ping -c2 "{{ ansible_default_ipv4.gateway }}" &> /dev/null ; echo $? + register: gw_active_test + when: discovered_wan_iface != "none" + +- name: Recording gateway response + set_fact: + gw_active: True + when: discovered_wan_iface != "none" and gw_active_test.stdout == "0" + +- name: Test for internet access + get_url: url="{{ xsce_download_url }}/heart-beat.txt" dest=/tmp/heart-beat.txt + ignore_errors: True +# async: 10 +# poll: 2 + register: internet_access_test + +- name: Set has_internet_connection true if wget succeeded + set_fact: + has_internet_connection: True + when: not internet_access_test|failed + +- name: Cleanup internet test file + file: path=/tmp/heart-beat.txt + state=absent + +- name: Turn off downloads if no internet connection + set_fact: + no_network: True + when: not has_internet_connection + +- name: Testing for xsce_preload + set_fact: + use_cache: True + no_network: True + when: xsce_preload == "True" + +- name: Setting wan if detected + set_fact: + xsce_wan_iface: "{{ discovered_wan_iface }}" + device_gw: "{{ discovered_wan_iface }}" + when: discovered_wan_iface != "none" + +# returns list of paths +- name: Find gateway config based on device + shell: "egrep -rn {{ device_gw }} /etc/sysconfig/network-scripts/ifcfg* | gawk -F ':' '{print $1}'" + register: ifcfg_gw_device + ignore_errors: True + changed_when: False + when: device_gw != "none" + +# last match wins +- name: Setting has ifcfg gw based on device if found + set_fact: + has_ifcfg_gw: "{{ item|trim }}" + ignore_errors: True + when: ifcfg_gw_device.stdout_lines is defined and item|trim != "" and item|trim != "/etc/sysconfig/network-scripts/ifcfg-LAN" + with_items: + - "{{ ifcfg_gw_device.stdout_lines }}" + +# returns path +- name: Find active gateway config based on macaddress + shell: "egrep -irn {{ ansible_default_ipv4.macaddress }} /etc/sysconfig/network-scripts/ifcfg* | gawk -F ':' '{print $1}' | head -n 1" + register: ifcfg_gw_mac + ignore_errors: True + changed_when: False + when: 'ansible_default_ipv4.gateway is defined' + +- name: Set has ifcfg gw based on on macaddress if found + set_fact: + has_ifcfg_gw: "{{ ifcfg_gw_mac.stdout|trim }}" + when: ifcfg_gw_mac is defined and ifcfg_gw_mac.stdout != "" + +# could use something else +- name: Find wifi gateway config if present + shell: egrep -rn ESSID /etc/sysconfig/network-scripts/ifcfg* | gawk -F ':' '{print $1}' | gawk -F '/' '{print $5}' + register: ifcfg_WAN_wifi + ignore_errors: True + +#returns file name +- name: Setting has_wifi_gw based on ESSID if found + set_fact: + has_wifi_gw: "{{ item|trim }}" + when: ifcfg_WAN_wifi.changed and item|trim != "" + with_items: + - "{{ ifcfg_WAN_wifi.stdout_lines }}" + +- name: Finding device for wifi AP gateway + shell: egrep -rn DEVICE /etc/sysconfig/network-scripts/{{ has_wifi_gw }} | gawk -F '=' '{print $2}' + register: AP_device + when: has_wifi_gw != "none" and has_ifcfg_gw != "none" + +- name: Setting wifi device + set_fact: + ap_device: "{{ AP_device.stdout }}" + when: AP_device.stdout is defined and AP_device.stdout != "" + +# WIRELESS -- if any wireless is detected as gateway, it becomes WAN +- name: Look for any wireless interfaces + shell: "cat /proc/net/wireless | grep -v -e Inter -e face | gawk -F: '{print $1}' " + register: wireless_list1 + ignore_errors: True + changed_when: False + +- name: Set the discovered wireless, if found + set_fact: + wifi1: "{{ item|trim }}" + discovered_wireless_iface: "{{ item|trim }}" + when: item|trim != "" and item|trim != discovered_wan_iface + with_items: + - "{{ wireless_list1.stdout_lines }}" + +# WIRELESS -- Sigh... Not all drivers update /proc/net/wireless correctly +- name: Look for any wireless interfaces take 2 + shell: "ls -la /sys/class/net/*/phy80211 | awk -F / '{print $5}'" + register: wireless_list2 + ignore_errors: True + changed_when: False + +# Last device is used +- name: Set the discovered wireless, if found take 2 + set_fact: + wifi2: "{{ item|trim }}" + discovered_wireless_iface: "{{ item|trim }}" + when: wireless_list2.stdout != "" and item|trim != discovered_wan_iface + with_items: + - "{{ wireless_list2.stdout_lines }}" + +- name: Count Wifi ifaces + shell: "ls -la /sys/class/net/*/phy80211 | awk -F / '{print $5}' | wc -l" + register: count_wifi_interfaces + +- name: Remember number of Wifi devices + set_fact: + num_wifi_interfaces: "{{ count_wifi_interfaces.stdout|int }}" + +# XO hack here ap_device would not be active therefore not set with +# wired as gw use ap_device to exclude eth0 from network calulations + +- name: XO override 2 wifi on LAN + set_fact: + ap_device: "eth0" + when: xsce_wan_iface != "eth0" and discovered_wireless_iface != "none" and xo_model == "XO-1.5" + +# takes adapter name +- name: Blacklisted wifi adapter + set_fact: + ap_device: "{{ blacklist_wifi }}" + when: blacklist_wifi is defined and discovered_wireless_iface != xsce_wan_iface and num_wifi_interfaces >= "2" + +# LAN - pick non WAN's +- name: Create list of LAN (non wan) ifaces + shell: ls /sys/class/net | grep -v -e wwlan -e ppp -e lo -e br0 -e tun -e {{ device_gw }} -e {{ ap_device }} + register: lan_list_result + ignore_errors: True + changed_when: false + +# Select an adapter that is not WAN and not wireless +# if there is more than one the last one wins +- name: Set xsce discovered lan fact + set_fact: + discovered_lan_iface: "{{ item|trim }}" + when: item|trim != discovered_wireless_iface and item|trim != discovered_wan_iface + with_items: + - "{{ lan_list_result.stdout_lines }}" + +- name: Count LAN ifaces + shell: ls /sys/class/net | grep -v -e wwlan -e ppp -e lo -e br0 -e tun -e {{ device_gw }} -e {{ ap_device }} | wc -l + register: num_lan_interfaces_result + ignore_errors: True + changed_when: false + +# facts are apparently all stored as text, so do text comparisons from here on +- name: Calulate number of LAN interfaces including WiFi + set_fact: + num_lan_interfaces: "{{ num_lan_interfaces_result.stdout|int }}" + +# If 2 interfaces found in gateway mode, with one wifi, declare other to be wan +#- name: In gateway mode with one wifi adapter, the other is WAN +# set_fact: +# xsce_wan_iface: "{{ discovered_lan_iface }}" +# xsce_lan_iface: "{{ discovered_wireless_iface }}" +# num_lan_interfaces: "1" +# when: xsce_lan_enabled and xsce_wan_enabled and num_lan_interfaces == "2" and discovered_wireless_iface != "none" and xsce_wan_iface == "none" + +- name: Set the variable for wireless_iface if present + set_fact: + xsce_wireless_lan_iface: "{{ discovered_wireless_iface }}" + when: discovered_wireless_iface != "none" and discovered_wireless_iface != xsce_wan_iface + +#unused +- name: Get a list of ifcfg files to delete + shell: "ls -1 /etc/sysconfig/network-scripts/ifcfg-* | grep -v -e ifcfg-lo -e ifcfg-WAN -e {{ has_wifi_gw }}" + register: ifcfg_files + changed_when: False + ignore_errors: True + when: num_lan_interfaces >= "1" or xsce_wireless_lan_iface != "none" +# + +# use value only if present +- name: Setting detected lan + set_fact: + xsce_lan_iface: "{{ discovered_lan_iface }}" + when: 'discovered_lan_iface != "none" and num_lan_interfaces == "1"' + +- name: for debian, always use bridging + set_fact: + xsce_lan_iface: br0 + when: 'discovered_lan_iface != "none" and num_lan_interfaces >= "1" and is_debian' + +- name: 2 or more devices on the LAN - use bridging + set_fact: + xsce_lan_iface: br0 + when: 'discovered_lan_iface != "none" and num_lan_interfaces >= "2" and not is_debian' + +- name: WiFi is on the LAN - use bridging + set_fact: + xsce_lan_iface: br0 + when: xsce_wireless_lan_iface != "none" + +# OK try old gw this is a best guess based on what's in +# /etc/sysconfig/xs_wan_device's last state intended to +# provide a seed value to display in the GUI when no +# gateway is present but we had one. +- name: Has old gateway and no discovered gateway setting WAN + set_fact: + gui_wan_iface: "{{ device_gw }}" + when: user_wan_iface == "auto" and device_gw != "none" and discovered_wan_iface == "none" + +- name: Add location section to config file + ini_file: dest='{{ xsce_config_file }}' + section=network + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: 'gateway_active' + value: '{{ gw_active }}' + - option: 'internet_accessible' + value: '{{ has_internet_connection }}' + - option: 'gateway_ifcfg' + value: '{{ has_ifcfg_gw }}' + - option: 'detected_gateway' + value: '{{ discovered_wan_iface }}' + - option: 'prior_gateway' + value: '{{ device_gw2 }}' + - option: 'wireless_list_1' + value: '{{ wifi1 }}' + - option: 'wireless_list_2' + value: '{{ wifi2 }}' + - option: 'num_wifi_interfaces' + value: '{{ num_wifi_interfaces }}' + - option: 'discovered_wireless_iface' + value: '{{ discovered_wireless_iface }}' + - option: 'xsce_wireless_lan_iface' + value: '{{ xsce_wireless_lan_iface }}' + - option: 'num_lan_interfaces' + value: '{{ num_lan_interfaces }}' + - option: 'detected_lan' + value: '{{ discovered_lan_iface }}' + - option: 'static_wan' + value: '{{ gui_static_wan }}' diff --git a/roles/1-prep/tasks/main.yml b/roles/1-prep/tasks/main.yml new file mode 100644 index 000000000..ae9ad3af3 --- /dev/null +++ b/roles/1-prep/tasks/main.yml @@ -0,0 +1,102 @@ +- name: Set flag for fedora 18 + set_fact: + is_F18: True + when: ansible_distribution_release == "based on Fedora 18" or ansible_distribution_version == "18" + +- name: get the uuidgen program + package: name=uuid-runtime + state=present + when: is_debian + +# for rpi, without rtc, we need time as soon as possible +- name: Install chrony package + package: name={{ item }} + state=present + with_items: + - chrony + tags: + - download + +#TODO: Use regexp filter instead of hard-code ip +- name: Update chrony config file + template: backup=no + dest=/etc/chrony.conf + src=chrony.conf.j2 + +- name: Disable selinux on next boot + selinux: state=disabled + register: selinux_disabled + when: ansible_selinux is defined and ansible_version >= '2' and ansible_selinux or ansible_selinux['status'] is defined and ansible_version < '2' and ansible_selinux['status'] != 'disabled' + +- name: Disable selinux for this session (if needed) + command: setenforce Permissive + when: selinux_disabled is defined and selinux_disabled.changed + +## DISCOVER PLATFORMS ###### +- name: Discover if this is a rpi -- if so it has a bcm2709 processor + set_fact: + rpi_model: "rpi" + is_rpi: "True" + when: ansible_cmdline["bcm2709.serial"] is defined + ignore_errors: true + +- include: prep.yml + +# we need to inialize the ini file +- include: xsce_ini.yml + +- include: computed_vars.yml + +- include: detected_network.yml + when: not installing + +# Patch Fedora 21+ so usbmount works +# Set flag to True that was initialized to False in role defaults +# We can't undo this +- name: Does udev need patching + set_fact: + udev_needs_patch: True + when: ansible_distribution == "Fedora" and ansible_distribution_version >= "21" + +# Same patch for CentOS 7.2 +- name: Does udev need patching for Centos + set_fact: + udev_needs_patch: True + when: ansible_distribution == "CentOS" and ansible_distribution_version >= "7.2.1511" + +- name: Copy udevd service to /etc/systemd/system to modify + copy: src=/usr/lib/systemd/system/systemd-udevd.service + dest=/etc/systemd/system/systemd-udevd.service + owner=root + group=root + mode=0644 + when: udev_needs_patch + +- name: Change MountFlags from slave to shared + lineinfile: backup=no + dest=/etc/systemd/system/systemd-udevd.service + regexp='^MountFlags' + line='MountFlags=shared' + state=present + when: udev_needs_patch + +- name: Restart systemd-udevd.service + service: name=systemd-udevd + state=restarted + when: udev_needs_patch and not installing + + +# Put conditional actions for hardware platforms here +- include: raspberry_pi_2.yml + when: rpi_model != "none" + +- name: Check if the identifier for intel's NUC6 builtin wifi is present + shell: "lsusb | grep 8087:0a2b | wc |gawk '{print $1}'" + register: usb_NUC6 + ignore_errors: true + +- name: download the firmware for built in wifi on NUC6 + get_url: dest=/lib/firmware + url={{ xsce_download_url }}/iwlwifi-8000C-13.ucode + when: usb_NUC6.stdout|int > 0 + diff --git a/roles/1-prep/tasks/prep.yml b/roles/1-prep/tasks/prep.yml new file mode 100644 index 000000000..9bc38e46d --- /dev/null +++ b/roles/1-prep/tasks/prep.yml @@ -0,0 +1,74 @@ +- name: Since f22, dnf has replaced yum, but ansible works with yum + command: dnf install -y yum + when: ansible_distribution == "Fedora" and ansible_distribution_version|int >= 22 + +- name: Install xsce-extra repos + template: backup=yes + dest=/etc/yum.repos.d/xsce-extra.repo + src=xsce-extra.repo + owner=root + mode=0666 + when: ansible_distribution != "Debian" + +- name: Install xsce-testing repos + template: backup=yes + dest=/etc/yum.repos.d/xsce-testing.repo + src=xsce-testing.repo + owner=root + mode=0666 + when: ansible_distribution != "Debian" + +- name: Install rpmfusion-free-updates repo -- for exfat + template: dest=/etc/yum.repos.d/rpmfusion-free-updates.repo + src=rpmfusion-free-updates.repo + owner=root + mode=0666 + when: ansible_distribution == "Fedora" + +- name: Create /etc/xsce + file: path=/etc/xsce + owner=root + group=root + mode=0755 + state=directory + +# this script can be sourced to get xsce location +- name: Create xsce.env file + template: src=xsce.env.j2 + dest=/etc/xsce/xsce.env + owner=root + group=root + mode=0644 + +- name: create ansible.d facts directory + file: path=/etc/ansible/facts.d + owner=root + group=root + mode=0750 + state=directory + +- name: local facts script + template: src=local_facts.fact.j2 + dest=/etc/ansible/facts.d/local_facts.fact + owner=root + group=root + mode=0700 + +- name: re-read facts + setup: filter=ansible_local + +- name: Set XO model and preload + set_fact: + phplib_dir: '{{ ansible_local["local_facts"]["phplib_dir"] }}' + xo_model: '{{ ansible_local["local_facts"]["xo_model"] }}' + xsce_preload: '{{ ansible_local["local_facts"]["xsce_preload"] }}' + +- name: Install script to fully initialize network config, and/or collect data +# calling xs-network-reset w/ snapshot name, stores info, but aborts reset +# intended as a convenience function for us + template: src=xs-network-reset + dest=/usr/bin + owner=root + group=root + mode=0755 + diff --git a/roles/1-prep/tasks/raspberry_pi_2.yml b/roles/1-prep/tasks/raspberry_pi_2.yml new file mode 100644 index 000000000..f79b09f47 --- /dev/null +++ b/roles/1-prep/tasks/raspberry_pi_2.yml @@ -0,0 +1,62 @@ +# Setup specific to the Raspberry Pi +# +- name: Add a udev rule to transfer hwclock to system clock at dev creation + template: src=92-rtc-i2c.rules + dest=/etc/udev/rules.d/92-rtc-i2c.rules + owner=root + group=root + mode=0644 + when: rtc_id is defined and rtc_id != "none" + +# +# RTC requires a change to the device tree (and reboot) +- name: Check for needing to enable i2c rtc device in config.txt + lineinfile: dest=/boot/config.txt + line="dtoverlay=i2c-rtc,{{ rtc_id }}=on" + state=present + register: rpiconfig + when: rtc_id != "none" + + +- name: Add a udev rule to transfer hwclock to system clock at dev creation + template: src=92-rtc-i2c.rules + dest=/etc/udev/rules.d/92-rtc-i2c.rules + owner=root + group=root + mode=0644 + when: rtc_id != "none" + +- name: pre-Install packages + package: name={{ item }} + state=latest + with_items: + - ntp + +- name: increase the swap file size (kalite pip download fails) + lineinfile: regexp="^CONF_SWAPSIZE" + line=CONF_SWAPSIZE=500 + dest=/etc/dphys-swapfile + when: is_debian + +- name: restart the swqp service + command: /etc/init.d/dphys-swapfile restart + when: is_debian + +- name: Add rpi rootfs resizing service + template: src={{ item.src }} + dest={{ item.dest }} + owner=root + group=root + mode={{ item.mode }} + with_items: + - { src: 'xsce-rpi-max-rootfs.sh', dest: '/usr/sbin/xsce-rpi-max-rootfs.sh', mode: '0755'} + - { src: 'xsce-rpi-root-resize.service', dest: '/etc/systemd/system/xsce-rpi-root-resize.service', mode: '0644'} + +- name: Enable rootfs resizing service + service: name=xsce-rpi-root-resize + enabled=yes +- name: Reboot if the config.txt was changed + command: /sbin/reboot + when: rpiconfig.changed + async: 300 + poll: 120 diff --git a/roles/1-prep/tasks/xsce_ini.yml b/roles/1-prep/tasks/xsce_ini.yml new file mode 100755 index 000000000..2229b4802 --- /dev/null +++ b/roles/1-prep/tasks/xsce_ini.yml @@ -0,0 +1,34 @@ +# workaround for fact that auto create does not work on ini_file +- name: Create xsce config file + file: dest='{{ xsce_config_file }}' + state=touch + +- name: Add location section to config file + ini_file: dest='{{ xsce_config_file }}' + section=location + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: 'xsce_base' + value: '{{ xsce_base }}' + - option: 'xsce_dir' + value: '{{ xsce_dir }}' + +- name: add version section + ini_file: dest='{{ xsce_config_file }}' + section=version + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: 'distribution' + value: '{{ ansible_distribution }}' + - option: 'arch' + value: '{{ ansible_architecture }}' + - option: 'xsce_branch' + value: '{{ ansible_local["local_facts"]["xsce_branch"] }}' + - option: 'xsce_commit' + value: '{{ ansible_local["local_facts"]["xsce_commit"] }}' + - option: 'install_date' + value: '{{ ansible_date_time["iso8601"] }}' + - option: 'install_xo' + value: '{{ xo_model }}' diff --git a/roles/1-prep/templates/92-rtc-i2c.rules b/roles/1-prep/templates/92-rtc-i2c.rules new file mode 100644 index 000000000..34b1d093f --- /dev/null +++ b/roles/1-prep/templates/92-rtc-i2c.rules @@ -0,0 +1,3 @@ +# /etc/udev/rules.d/92-rtc-i2c.rules +# +ACTION=="add", SUBSYSTEM=="rtc", ATTRS{hctosys}=="0", RUN+="/usr/sbin/hwclock -s --utc" diff --git a/roles/1-prep/templates/chrony.conf.j2 b/roles/1-prep/templates/chrony.conf.j2 new file mode 100644 index 000000000..d2286d87c --- /dev/null +++ b/roles/1-prep/templates/chrony.conf.j2 @@ -0,0 +1,46 @@ +# Use public servers from the pool.ntp.org project. +# Please consider joining the pool (http://www.pool.ntp.org/join.html). +server 0.fedora.pool.ntp.org iburst +server 1.fedora.pool.ntp.org iburst +server 2.fedora.pool.ntp.org iburst +server 3.fedora.pool.ntp.org iburst + +# Ignore stratum in source selection. +stratumweight 0 + +# Record the rate at which the system clock gains/losses time. +driftfile /var/lib/chrony/drift + +# Enable kernel RTC synchronization. +rtcsync + +# In first three updates step the system clock instead of slew +# if the adjustment is larger than 10 seconds. +makestep 10 3 + +# Allow NTP client access from local network. +allow 172.18 + +# Listen for commands only on localhost. +bindcmdaddress 127.0.0.1 +bindcmdaddress ::1 + +# Serve time even if not synchronized to any NTP server. +local stratum 10 + +keyfile /etc/chrony.keys + +# Specify the key used as password for chronyc. +commandkey 1 + +# Generate command key if missing. +generatecommandkey + +# Disable logging of client accesses. +noclientlog + +# Send a message to syslog if a clock adjustment is larger than 0.5 seconds. +logchange 0.5 + +#log measurements statistics tracking +logdir /var/log/chrony diff --git a/roles/1-prep/templates/local_facts.fact.j2 b/roles/1-prep/templates/local_facts.fact.j2 new file mode 100644 index 000000000..9f188cf60 --- /dev/null +++ b/roles/1-prep/templates/local_facts.fact.j2 @@ -0,0 +1,65 @@ +#!/bin/bash +OS=`grep ^ID= /etc/*release|cut -d= -f2` +OS=${OS//\"/} + +# enable this install config to be tracked +if [ ! -f /etc/xsce/uuid ]; then + uuidgen > /etc/xsce/uuid +fi +UUID=`cat /etc/xsce/uuid` + +source /etc/xsce/xsce.env +cd $XSCE_DIR + +# get current version +BRANCH=`git rev-parse --abbrev-ref HEAD` +COMMIT=`git rev-parse --verify HEAD` + +if [ -d /usr/lib64/php ] +then + PHPLIB_DIR=/usr/lib64/php +else + if [ -d /usr/lib/php5 ]; then + PHPLIB_DIR=/usr/lib/php5 + else + PHPLIB_DIR=/usr/lib/php + fi +fi + +if [ -f /proc/device-tree/mfg-data/MN ] +then + XO_VERSION=`cat /proc/device-tree/mfg-data/MN` +else + XO_VERSION="none" +fi + +if [ -f /etc/xsce/xsce.env ] +then + . /etc/xsce/xsce.env + if [ -z $BASE_VERSION ] + then + BASE_VERSION="0" + fi + BASE="$BASE_VERSION" +else + BASE="0" +fi + +if [ -f /.preload ] +then + PRELOAD="True" +else + PRELOAD="False" +fi +ANSIBLE_VERSION=$(ansible --version|head -n 1|cut -f 2 -d " ") +cat < /tmp/script2overview +#!/bin/bash +# generate the body overview part diagnostic package about network +echo "==========================================================" +for f in \$(ls /etc/sysconfig/network-scripts/ifcfg-*|gawk '{printf(" %s",\$1)}'); do + echo + echo \$f + cat \$f +done +echo +echo "==========================================================" +echo ifconfig +ifconfig +echo +echo "==========================================================" +echo ip addr +ip addr +echo +echo "==========================================================" +echo "brctl show" +brctl show +echo +echo "==========================================================" +echo "/etc/resolv.conf" +cat /etc/resolv.conf +echo +echo "==========================================================" +echo "cat /etc/xsce/xsce.ini" +cat /etc/xsce/xsce.ini +echo +echo "==========================================================" +echo "routing table" +netstat -rn +echo +echo "==========================================================" +echo "install log -- last 50 lines" +tail -50 /opt/schoolserver/xsce/xsce-install.log +echo +echo "==========================================================" +echo "xsce-network log -- last 50 lines" +if [ -f /opt/schoolserver/xsce/xsce-network.log ]; then +tail -50 /opt/schoolserver/xsce/xsce-network.log +else + echo no xsce-network.log +fi +echo +echo "==========================================================" +cat /etc/fedora-release | grep 18 +if [ \$? -eq 0 ]; then + echo "nmcli conn list" + nmcli conn list 3>&2 +else + echo "nmcli conn show" + nmcli conn show 3>&2 +fi +echo +echo "==========================================================" +echo nmcli dev wifi list +nmcli dev wifi list +EOF +chmod 755 /tmp/script2overview +/tmp/script2overview > /tmp/$basket/overview + +if [ -f /opt/schoolserver/xsce/xsce-network.log ]; then + cp /opt/schoolserver/xsce/xsce-network.log /tmp/$basket +else + touch /tmp/$basket/no_xsce-network.log +fi + +if [ -f /etc/sysconfig/xs_domain_name ];then + cp -p /etc/sysconfig/xs_domain_name /tmp/$basket +else + touch /tmp/$basket/xs_domain_name_not_set +fi + +if [ -f /etc/sysconfig/xs_lan_device ];then + cp -p /etc/sysconfig/xs_lan_device /tmp/$basket +else + touch /tmp/$basket/xs_lan_device_not_set +fi +if [ -f /etc/sysconfig/xs_wan_device ];then + cp -p /etc/sysconfig/xs_wan_device /tmp/$basket +else + touch /tmp/$basket/xs_wan_device_not_set +fi +ls /etc/NetworkManager/system-connections > /dev/null +if [ $? -eq 0 ]; then + cp -rp /etc/NetworkManager/system-connections /tmp/$basket +fi +cp /etc/sysconfig/network-scripts/ifcfg-* /tmp/$basket +if [ -f /opt/schoolserver/xsce/xsce-network.log ]; then + cp -p /opt/schoolserver/xsce/xsce-network.log /tmp/$basket +fi + +mkdir -p /etc/xsce/diagnose/ +if [ ! -z $diagnose_name ];then + pushd /tmp > /dev/null + tar czf /etc/xsce/diagnose/$basket.tgz $basket/* + popd > /dev/null + rm -rf /tmp/$basket + exit 0 +else + pushd /tmp > /dev/null + tar czf /etc/xsce/diagnose/$basket.tgz $basket/* + popd > /dev/null + rm -rf /tmp/$basket +fi + +# clear out all the memory variables and let auto-configure start from scratch +rm -rf /etc/sysconfig/xs_domain_name +rm -rf /etc/sysconfig/xs_lan_device +rm -rf /etc/sysconfig/xs_wan_device +rm -rf /etc/NetworkManager/system-connestions/* +if [ -f /etc/sysconfig/network-scripts/ifcfg-WAN ];then + mv /etc/sysconfig/network-scripts/ifcfg-WAN /root + echo -e "\n\nWAN setup file moved to /root for safekeeping.\n\n" +fi + +ls -1 /etc/sysconfig/network-scripts/ifcfg-*|grep -v -e ifcfg-lo +if [ $? -eq 0 ]; then + ls -1 /etc/sysconfig/network-scripts/ifcfg-*|grep -v -e ifcfg-lo|xargs rm +fi + +echo -e "\n\nAll Network variables erased. Now run 'xsce-network' to set up the new network configuration.\n\nPlease see /opt/schoolserver/xsce/docs/GETTING_HELP.rst for ways to get help or \nprovide the feedback which will improve XSCE\n\n" diff --git a/roles/1-prep/templates/xsce-extra.repo b/roles/1-prep/templates/xsce-extra.repo new file mode 100644 index 000000000..b326c3f20 --- /dev/null +++ b/roles/1-prep/templates/xsce-extra.repo @@ -0,0 +1,16 @@ +[xsce-extra] +name=xsce-extra +failovermethod=priority +baseurl=http://download.unleashkids.org/xsce/repos/xs-extra/ +enabled=1 +metadata_expire=1d +gpgcheck=0 + +[dummy-config] +name=dummy-config +failovermethod=priority +baseurl=http://download.unleashkids.org/xsce/repos/xsce-extra/ +enabled=1 +metadata_expire=1d +gpgcheck=0 + diff --git a/roles/1-prep/templates/xsce-rpi-max-rootfs.sh b/roles/1-prep/templates/xsce-rpi-max-rootfs.sh new file mode 100644 index 000000000..02c8cbe15 --- /dev/null +++ b/roles/1-prep/templates/xsce-rpi-max-rootfs.sh @@ -0,0 +1,20 @@ +#!/bin/bash -x +# Resize rootfs and its partition on the rpi SD card to maximum size +# To be used by systemd service on boot +# Only resizes if /.resize-rootfs exists +# Assumes root is last partition +# Only works on F22 + where resizepart command exists +# Assumes sd card style partition name like p + +if [ -f /.resize-rootfs ];then + echo "$0: maximizing rootfs partion" + # Calculate root partition + root_part=`lsblk -aP -o NAME,MOUNTPOINT|grep 'MOUNTPOINT="/"' |awk -F\" '{ print $2 }'` + root_dev=${root_part:0:-2} + root_part_no=${root_part: (-1)} + + # Resize partition + parted -s /dev/$root_dev resizepart $root_part_no 100% + resize2fs /dev/$root_part + rm /.resize-rootfs +fi diff --git a/roles/1-prep/templates/xsce-rpi-root-resize.service b/roles/1-prep/templates/xsce-rpi-root-resize.service new file mode 100644 index 000000000..86864308c --- /dev/null +++ b/roles/1-prep/templates/xsce-rpi-root-resize.service @@ -0,0 +1,12 @@ +[Unit] +Description=Root Filesystem Auto-Resizer + +[Service] +Environment=TERM=linux +Type=oneshot +ExecStart=/usr/sbin/xsce-rpi-max-rootfs.sh +StandardError=syslog +RemainAfterExit=no + +[Install] +WantedBy=multi-user.target diff --git a/roles/1-prep/templates/xsce-testing.repo b/roles/1-prep/templates/xsce-testing.repo new file mode 100644 index 000000000..0be71788d --- /dev/null +++ b/roles/1-prep/templates/xsce-testing.repo @@ -0,0 +1,7 @@ +[xsce-testing] +name=xsce-testing +failovermethod=priority +baseurl=http://download.unleashkids.org/xsce/repos/xsce/testing +enabled=1 +metadata_expire=1d +gpgcheck=0 diff --git a/roles/1-prep/templates/xsce.env.j2 b/roles/1-prep/templates/xsce.env.j2 new file mode 100644 index 000000000..53868a196 --- /dev/null +++ b/roles/1-prep/templates/xsce.env.j2 @@ -0,0 +1,6 @@ +# This is a configuration file for XSCE +# It can sourced in a shell script or read into an application +XSCE_BASE_PATH={{ xsce_base }} +XSCE_DIR={{ xsce_dir }} +OS={{ ansible_distribution }} +WWWROOT={{ doc_root }} diff --git a/roles/2-common/README.rst b/roles/2-common/README.rst new file mode 100644 index 000000000..7ca305eac --- /dev/null +++ b/roles/2-common/README.rst @@ -0,0 +1,6 @@ +============= +Common README +============= + +This role aggregates roles containing packages and a few other tasks that are common to all platforms +and are required before creating a functioning server. diff --git a/roles/2-common/tasks/centos.yml b/roles/2-common/tasks/centos.yml new file mode 100644 index 000000000..5b02a9532 --- /dev/null +++ b/roles/2-common/tasks/centos.yml @@ -0,0 +1,38 @@ +- name: Centos Server specific tasks + command: echo Starting centos.yml + +- name: Keep yum cache + ini_file: dest=/etc/yum.conf + section=main + option=keepcache + value=1 + +- name: Install epel-release for CentOS + package: name={{ item }} + state=present + with_items: + - epel-release + +- name: Install XECE repo for CentOS + template: src={{ item }} dest=/etc/yum.repos.d/ owner=root group=root mode=0644 + with_items: + - xsce-centos.repo + - li.nux.ro.repo + +- name: Disable updating ejabberd on CentOS + shell: sed -i -e '/^enabled=/a exclude=ejabberd' {{ item }} + with_items: + - /etc/yum.repos.d/CentOS-Base.repo + - /etc/yum.repos.d/CentOS-CR.repo + - /etc/yum.repos.d/CentOS-fasttrack.repo + - /etc/yum.repos.d/CentOS-Vault.repo + +- name: Disable updating ansible on CentOS + shell: sed -i -e '/^enabled=/a exclude=ansible' {{ item }} + with_items: + - /etc/yum.repos.d/CentOS-Base.repo + - /etc/yum.repos.d/CentOS-CR.repo + - /etc/yum.repos.d/CentOS-fasttrack.repo + - /etc/yum.repos.d/CentOS-Vault.repo + when: ansible_distribution == "CentOS" + diff --git a/roles/2-common/tasks/fedora.yml b/roles/2-common/tasks/fedora.yml new file mode 100644 index 000000000..789c85898 --- /dev/null +++ b/roles/2-common/tasks/fedora.yml @@ -0,0 +1,30 @@ +- name: Keep yum cache + ini_file: dest=/etc/yum.conf + section=main + option=keepcache + value=1 + +- name: Install Fedora specifc packages + package: name={{ item }} + state=present + with_items: + - mtd-utils + +- name: Install optional exFAT packages for Fedora + shell: yum --enablerepo=rpmfusion-free-updates install exfat-utils fuse-exfat + when: exFAT_enabled == "True" + +- name: Disable updating ejabberd on Fedora + shell: sed -i -e '/^enabled=/a exclude=ejabberd' {{ item }} + with_items: + - /etc/yum.repos.d/fedora.repo + - /etc/yum.repos.d/fedora-updates.repo + - /etc/yum.repos.d/fedora-updates-testing.repo + +- name: Disable updating ansible on Fedora + shell: sed -i -e '/^enabled=/a exclude=ansible' {{ item }} + with_items: + - /etc/yum.repos.d/fedora.repo + - /etc/yum.repos.d/fedora-updates.repo + - /etc/yum.repos.d/fedora-updates-testing.repo + when: ansible_distribution == "Fedora" diff --git a/roles/2-common/tasks/fl.yml b/roles/2-common/tasks/fl.yml new file mode 100644 index 000000000..00d6d7fe2 --- /dev/null +++ b/roles/2-common/tasks/fl.yml @@ -0,0 +1,68 @@ +- name: Create /opt/schoolserver/xsce + file: path={{ xsce_dir }} + owner=root + group=root + mode=0755 + state=directory + +- name: Create /opt/schoolserver/yum-packages + file: path={{ yum_packages_dir }} + owner=root + group=root + mode=0755 + state=directory + +- name: Create /opt/schoolserver/pip-packages + file: path={{ pip_packages_dir }} + owner=root + group=root + mode=0755 + state=directory + +- name: Create /opt/schoolserver/downloads + file: path={{ downloads_dir }} + owner=root + group=root + mode=0755 + state=directory + +- name: Create various library directories + file: path={{ item }} + owner=root + group=root + mode=0755 + state=directory + with_items: + - /library/downloads/zims + - /library/downloads/rachel + - /library/working/zims + - /library/working/rachel + - "{{ xsce_zim_path }}/content" + - "{{ xsce_zim_path }}/index" + - "{{ rachel_doc_root }}" + +- name: Create directory for common packages + file: path={{ item }} + mode=0755 + owner=root + group=root + state=directory + with_items: + - "{{ doc_root }}/common/css" + - "{{ doc_root }}/common/js" + - "{{ doc_root }}/common/fonts" + - "{{ doc_root }}/common/html" + - "{{ doc_root }}/common/images" + - "{{ doc_root }}/common/assets" + - "{{ doc_root }}/common/menu-defs" + +- name: Create olpc-scripts directory + file: path={{ item }} + owner=root + group=root + mode=0755 + state=directory + with_items: + - /etc/sysconfig/olpc-scripts/ + - /etc/sysconfig/olpc-scripts/setup.d/installed/ + diff --git a/roles/2-common/tasks/main.yml b/roles/2-common/tasks/main.yml new file mode 100644 index 000000000..57aa258c4 --- /dev/null +++ b/roles/2-common/tasks/main.yml @@ -0,0 +1,44 @@ + +- include: xsce_ini.yml + +# create the directory structure for XSCE +- include: fl.yml + +- include: xo.yml + when: xo_model != "none" or osbuilder is defined + +- include: centos.yml + when: ansible_distribution == "CentOS" + +- include: fedora.yml + when: ansible_distribution == "Fedora" + +# the following installs common packages for both debian and fedora +- include: packages.yml + +- sysctl: name=net.ipv4.ip_forward value=1 state=present +- sysctl: name=net.ipv4.conf.default.rp_filter value=1 state=present +- sysctl: name=net.ipv4.conf.default.accept_source_route value=0 state=present +- sysctl: name=kernel.sysrq value=1 state=present +- sysctl: name=kernel.core_uses_pid value=1 state=present +- sysctl: name=net.ipv4.tcp_syncookies value=1 state=present +- sysctl: name=kernel.shmmax value=268435456 state=present +# IPv6 disabled +- sysctl: name=net.ipv6.conf.all.disable_ipv6 value=1 state=present +- sysctl: name=net.ipv6.conf.default.disable_ipv6 value=1 state=present +- sysctl: name=net.ipv6.conf.lo.disable_ipv6 value=1 state=present + +- name: Set default Timezone + shell: ln -sf /usr/share/zoneinfo/{{ xsce_TZ }} /etc/localtime + when: xsce_TZ is defined and xsce_TZ != "" + +- name: Install custom profile file + template: dest=/etc/profile.d/zzz_xsce.sh + src=zzz_xsce.sh + owner=root + mode=0644 + backup=no + +- include: net_mods.yml + when: not is_debian and not is_F18 + diff --git a/roles/2-common/tasks/net_mods.yml b/roles/2-common/tasks/net_mods.yml new file mode 100644 index 000000000..c4e886bf0 --- /dev/null +++ b/roles/2-common/tasks/net_mods.yml @@ -0,0 +1,31 @@ +- name: Disable systemd-networkd.service + service: name=systemd-networkd.service + enabled=no + when: not is_centos + +- name: Mask systemd-networkd.service + shell: 'systemctl mask systemd-networkd' + when: not is_centos + +- name: Disable systemd-hostnamed.service + service: name=systemd-hostnamed.service + enabled=no + +- name: Disable dbus-org.freedesktop.hostname1.service + service: name=dbus-org.freedesktop.hostname1 + enabled=no + +- name: Mask dbus-org.freedesktop.hostname1.service + shell: 'systemctl mask dbus-org.freedesktop.hostname1' + +- name: Disable network.service + service: name=network + enabled=no + +- name: Mask network.service + shell: 'systemctl mask network.service' + +# Network Manager starts this if needed +- name: Disable wpa_supplicant + service: name=wpa_supplicant + enabled=no diff --git a/roles/2-common/tasks/packages.yml b/roles/2-common/tasks/packages.yml new file mode 100644 index 000000000..d6be0ee1e --- /dev/null +++ b/roles/2-common/tasks/packages.yml @@ -0,0 +1,118 @@ +- name: install yum deps for arm!!! + shell: dnf install -y python-urlgrabber pyxattr yum-metadata-parser + when: ansible_distribution == "Fedora" and ansible_machine == "armv7l" and ansible_distribution_version|int >= 22 + +- name: install yum from Fedora 23 for arm!!! + shell: dnf install -y https://kojipkgs.fedoraproject.org//packages/yum/3.4.3/506.fc23/noarch/yum-3.4.3-506.fc23.noarch.rpm python-dnf + when: ansible_distribution == "Fedora" and ansible_machine == "armv7l" and ansible_distribution_version|int >= 22 + +- name: install yum if it has been dropped from our distribution -- Fedora 22 uses dnf!!! + shell: dnf install -y yum + when: ansible_distribution == "Fedora" and ansible_distribution_version|int >= 22 and ansible_machine != "armv7l" + +- name: get the createrepo program + package: name=createrepo + state=present + when: ansible_distribution != "Debian" + +- name: Create local repo + shell: createrepo {{ yum_packages_dir }} + when: ansible_distribution != "Debian" + +- name: Install local repo file. + template: dest=/etc/yum.repos.d/xsce-local.repo + src=local.repo + owner=root + mode=0644 + when: ansible_distribution != "Debian" + +- name: Install yum packages + package: name={{ item }} + state=present + with_items: + - yum-utils + - createrepo + - wpa_supplicant + - linux-firmware + - syslog + - xml-common + when: ansible_distribution != "Debian" + tags: + - download + +- name: Install yum packages for Debian + package: name={{ item }} + state=present + with_items: + - inetutils-syslogd + - wpasupplicant + when: ansible_distribution == "Debian" + tags: + - download + +- name: Install common packages + package: name={{ item }} + state=present + with_items: + - acpid + - mlocate + - rsync + - htop + - etckeeper + - python-passlib + - usbmount + - net-tools + - openssh-server + - sudo + - logrotate + - make + - tar + - unzip + - bzip2 + - i2c-tools + - bridge-utils + - usbutils + - hostapd + - wget + - openssl #FC 18 does not supply, but pear requires + - gawk + tags: + - download + +- name: Update common packages (not debian + package: name={{ item }} + state=latest + with_items: + - NetworkManager + - glibc # CVE-2015-7547 + - bash + - iptables + when: ansible_distribution != "Debian" + tags: + - download + +- name: Update common packages (debian) + package: name={{ item }} + state=latest + with_items: + - libc6 + - bash + - iptables + when: ansible_distribution == "Debian" + tags: + - download + + +# instuctions state to start with a fully updated system before starting, stop using +# ansible as a crutch for developers not following the directions and taking short-cuts + +#- name: If version of Network manager has changed, subsequent nmcli commands will fail,restart now +# service: name=NetworkManager +# state=restarted +# when: not installing +# the above should use a handler - all reboots should wait until all +# mods are preformed + +- name: Install optional exFAT packages for CentOS + shell: yum --enablerepo=li-nux-ro install exfat-utils fuse-exfat + when: exFAT_enabled == "True" and ansible_distribution == "CentOS" diff --git a/roles/2-common/tasks/xo.yml b/roles/2-common/tasks/xo.yml new file mode 100644 index 000000000..0dde79008 --- /dev/null +++ b/roles/2-common/tasks/xo.yml @@ -0,0 +1,135 @@ +- name: XO Server specific tasks + command: echo Starting XO.yml + +- name: Disable sleep + command: touch /etc/powerd/flags/inhibit-suspend + creates=/etc/powerd/flags/inhibit-suspend + +- name: Disable sleep on lid closing + lineinfile: dest=/etc/powerd/powerd.conf + regexp='^config_SLEEP_WHEN_LID_CLOSED' + line='config_SLEEP_WHEN_LID_CLOSED="no"' + state=present + backup=yes + +- name: Keep yum cache + ini_file: dest=/etc/yum.conf + section=main + option=keepcache + value=1 + when: not installing + +- name: Keep docs when installing packages + lineinfile: backup=yes + dest=/etc/rpm/macros.imgcreate + regexp='^%_excludedocs' + state=absent + +- name: pre-Install packages + package: name={{ item }} + state=latest + with_items: + - usbmount + - man + - man-db + - man-pages + +- name: re-Install packages + shell: yum -y reinstall sed libidn grep which util-linux wget gnupg2 groff gnash yum + when: not osbuilder is defined + +- name: Configure networkmanager plugin + ini_file: dest=/etc/NetworkManager/NetworkManager.conf + section=main + option=plugins + value=ifcfg-rh,keyfile + +- name: check for modem config file + stat: path=/etc/NetworkManager/system-connections/"Sugar Modem Connection" + register: config + +- name: Change failure and interval settings for modem connection + ini_file: dest=/etc/NetworkManager/system-connections/"Sugar Modem Connection" + section=ppp + option={{ item.option }} + value={{ item.value }} + backup=yes + mode=0600 + with_items: + - { option: 'lcp-echo-failure', value: '5' } + - { option: 'lcp-echo-interval', value: '30' } + when: config.stat.exists + +- name: Create bigger rwtab + lineinfile: backup=yes + dest=/etc/sysconfig/readonly-root + regexp='^RW_OPTIONS' + line='RW_OPTIONS="-o size=4M -o nr_inodes=2048"' + state=present + +- name: Remove dhcpd entry from /etc/rwtab + lineinfile: backup=yes + dest=/etc/rwtab + regexp='^empty.*/var/lib/dhcpd' + state=absent + +- name: Remove php entry from /etc/rwtab + lineinfile: backup=yes + dest=/etc/rwtab + regexp='^empty.*/var/lib/php' + state=absent + +- name: Persist /etc/hosts between reboots + lineinfile: backup=yes + dest=/etc/statetab.d/olpc + regexp='^/etc/hosts' + state=absent + + +- name: Disable /var/log tmpfs + lineinfile: backup=yes + dest=/etc/fstab + regexp='^varlog.*' + state=absent + +- name: Enlarge the /tmp directory so that url_get does not error out + lineinfile: backup=yes + dest=/etc/fstab + regexp='^/tmp*' + line='/tmp /tmp tmpfs rw,size=600m 0 0' + +- name: Disable graphical login + file: path=/etc/systemd/system/default.target + src=/lib/systemd/system/multi-user.target + state=link + register: disabled_login + +- name: Remove custom profile settings + file: path=/etc/profile.d/zzz_olpc.sh + state=absent + +- name: Download substitute software for i386 on FC18 XO1.5 + get_url: url="{{ xsce_download_url }}/{{ item }}" dest={{ downloads_dir}}/{{ item }} + with_items: + - hostapd_8188_i386 + when: wifi_id == "tplink_WM725M" and xo_model == "XO-1.5" and not {{ use_cache }} and not {{ no_network }} + tags: + - xo + +- name: Put the substitute in place + copy: src={{ downloads_dir }}/hostapd_8188_i386 + dest=/usr/sbin/hostapd + backup=yes + mode=0775 + owner=root + group=root + when: wifi_id == "tplink_WM725M" and xo_model == "XO-1.5" + +- name: Reboot system + command: /sbin/reboot + when: disabled_login.changed and not installing + ignore_errors: yes + async: 300 + poll: 120 + + diff --git a/roles/2-common/tasks/xsce_ini.yml b/roles/2-common/tasks/xsce_ini.yml new file mode 100644 index 000000000..2229b4802 --- /dev/null +++ b/roles/2-common/tasks/xsce_ini.yml @@ -0,0 +1,34 @@ +# workaround for fact that auto create does not work on ini_file +- name: Create xsce config file + file: dest='{{ xsce_config_file }}' + state=touch + +- name: Add location section to config file + ini_file: dest='{{ xsce_config_file }}' + section=location + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: 'xsce_base' + value: '{{ xsce_base }}' + - option: 'xsce_dir' + value: '{{ xsce_dir }}' + +- name: add version section + ini_file: dest='{{ xsce_config_file }}' + section=version + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: 'distribution' + value: '{{ ansible_distribution }}' + - option: 'arch' + value: '{{ ansible_architecture }}' + - option: 'xsce_branch' + value: '{{ ansible_local["local_facts"]["xsce_branch"] }}' + - option: 'xsce_commit' + value: '{{ ansible_local["local_facts"]["xsce_commit"] }}' + - option: 'install_date' + value: '{{ ansible_date_time["iso8601"] }}' + - option: 'install_xo' + value: '{{ xo_model }}' diff --git a/roles/2-common/tasks/yum.yml b/roles/2-common/tasks/yum.yml new file mode 100644 index 000000000..4e8d6a2cc --- /dev/null +++ b/roles/2-common/tasks/yum.yml @@ -0,0 +1,119 @@ +- name: install yum deps for arm!!! + shell: dnf install -y python-urlgrabber pyxattr yum-metadata-parser + when: ansible_distribution == "Fedora" and ansible_machine == "armv7l" and ansible_distribution_version|int >= 22 + +- name: install yum from Fedora 23 for arm!!! + shell: dnf install -y https://kojipkgs.fedoraproject.org//packages/yum/3.4.3/506.fc23/noarch/yum-3.4.3-506.fc23.noarch.rpm python-dnf + when: ansible_distribution == "Fedora" and ansible_machine == "armv7l" and ansible_distribution_version|int >= 22 + +- name: install yum if it has been dropped from our distribution -- Fedora 22 uses dnf!!! + shell: dnf install -y yum + when: ansible_distribution == "Fedora" and ansible_distribution_version|int >= 22 and ansible_machine != "armv7l" + +- name: get the createrepo program + package: name=createrepo + state=present + when: ansible_distribution != "Debian" + +- name: Create local repo + shell: createrepo {{ yum_packages_dir }} + when: ansible_distribution != "Debian" + +- name: Install local repo file. + template: dest=/etc/yum.repos.d/xsce-local.repo + src=local.repo + owner=root + mode=0644 + when: ansible_distribution != "Debian" + +- name: Install yum packages + package: name={{ item }} + state=present + with_items: + - yum-utils + - createrepo + - wpa_supplicant + - linux-firmware + - syslog + - xml-common + when: ansible_distribution != "Debian" + tags: + - download + +- name: Install yum packages for Debian + package: name={{ item }} + state=present + with_items: + - inetutils-syslogd + - wpasupplicant + when: ansible_distribution == "Debian" + tags: + - download + +- name: Install common packages + package: name={{ item }} + state=present + with_items: + - acpid + - mlocate + - rsync + - htop + - etckeeper + - python-passlib + - usbmount + - net-tools + - openssh-server + - sudo + - logrotate + - make + - tar + - unzip + - bzip2 + - i2c-tools + - bridge-utils + - usbutils + - hostapd + - wget + - openssl #FC 18 does not supply, but pear requires + - gawk + - sqlite3 + tags: + - download + +- name: Update common packages (not debian + package: name={{ item }} + state=latest + with_items: + - NetworkManager + - glibc # CVE-2015-7547 + - bash + - iptables + when: ansible_distribution != "Debian" + tags: + - download + +- name: Update common packages (debian) + package: name={{ item }} + state=latest + with_items: + - libc6 + - bash + - iptables + when: ansible_distribution == "Debian" + tags: + - download + + +# instuctions state to start with a fully updated system before starting, stop using +# ansible as a crutch for developers not following the directions and taking short-cuts + +#- name: If version of Network manager has changed, subsequent nmcli commands will fail,restart now +# service: name=NetworkManager +# state=restarted +# when: not installing +# the above should use a handler - all reboots should wait until all +# mods are preformed + +- name: Install optional exFAT packages for CentOS + shell: yum --enablerepo=li-nux-ro install exfat-utils fuse-exfat + when: exFAT_enabled == "True" and ansible_distribution == "CentOS" diff --git a/roles/2-common/templates/li.nux.ro.repo b/roles/2-common/templates/li.nux.ro.repo new file mode 100644 index 000000000..299d01fe5 --- /dev/null +++ b/roles/2-common/templates/li.nux.ro.repo @@ -0,0 +1,8 @@ +[li-nux-ro] +name=RPMs missing in EPEL +baseurl=http://li.nux.ro/download/nux/dextop/el7/x86_64/ +enabled=0 +gpgcheck=1 +gpgkey=http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro + + diff --git a/roles/2-common/templates/local.repo b/roles/2-common/templates/local.repo new file mode 100644 index 000000000..d026b8881 --- /dev/null +++ b/roles/2-common/templates/local.repo @@ -0,0 +1,5 @@ +[xsce-local] +name=xsce-local +baseurl=file://{{ yum_packages_dir }} +enabled=1 +gpgcheck=0 diff --git a/roles/2-common/templates/xsce-centos.repo b/roles/2-common/templates/xsce-centos.repo new file mode 100644 index 000000000..cbb4b0fc0 --- /dev/null +++ b/roles/2-common/templates/xsce-centos.repo @@ -0,0 +1,7 @@ +[xsce-centos] +name=xsce-centos +failovermethod=priority +baseurl=http://download.unleashkids.org/xsce/repos/centos +enabled=1 +metadata_expire=1d +gpgcheck=0 diff --git a/roles/2-common/templates/zzz_xsce.sh b/roles/2-common/templates/zzz_xsce.sh new file mode 100644 index 000000000..8e23db882 --- /dev/null +++ b/roles/2-common/templates/zzz_xsce.sh @@ -0,0 +1,5 @@ +# Add back sbin dirs to unprivileged users PATH +case $PATH in + */sbin/*) ;; + *) PATH=/usr/local/sbin:/usr/sbin:/sbin:$PATH ;; +esac diff --git a/roles/3-base-server/README.rst b/roles/3-base-server/README.rst new file mode 100644 index 000000000..366e5a9e8 --- /dev/null +++ b/roles/3-base-server/README.rst @@ -0,0 +1,12 @@ +================== +Base Server README +================== + +This role is a place to aggregate roles that are required to create a basic web server. +The functionality here is not packages that are not directly consumed by users, which are in common, +nor specific applications, such as those found in the apps and tools roles. + +The difference between this aggregate and server-options is that the roles here are required. + +Eventually a graphical configuration console will be added here. + diff --git a/roles/3-base-server/meta/main.yml b/roles/3-base-server/meta/main.yml new file mode 100644 index 000000000..ce6c17983 --- /dev/null +++ b/roles/3-base-server/meta/main.yml @@ -0,0 +1,4 @@ +dependencies: + - { role: httpd, tags: ['services','httpd','base'] } + - { role: xsce-admin, tags: ['services','xsce-admin','base'] } + - { role: network, tags: ['services','base','network'], when: not gui_desired_network_role is defined } diff --git a/roles/3-base-server/tasks/main.yml b/roles/3-base-server/tasks/main.yml new file mode 100644 index 000000000..d7966493f --- /dev/null +++ b/roles/3-base-server/tasks/main.yml @@ -0,0 +1,41 @@ +- name: Make sure there is a content directory + file: dest={{ doc_root }}/local_content + state=directory + +- name: Set up to issue warning if xsce-admin password is still default + template: src=profile_ssh_warn.sh + dest=/etc/profile.d/ + +- name: Is this LXDE? + stat: path=/home/pi/.config/lxsession + register: lx + +- name: Do the same if running on raspbian + template: src=lxde_ssh_warn.sh + dest=/home/pi/.config/lxsession/LXDE-pi/ + when: lx.stat.isdir is defined and lx.stat.isdir and is_rpi and is_debian + +- name: put a autostart line to check for default password in LXDE + lineinfile: line=@/home/pi/.config/lxsession/LXDE-pi/lxde_ssh_warn.sh + dest=/home/pi/.config/lxsession/LXDE-pi/autostart + when: lx.stat.isdir is defined and lx.stat.isdir and is_rpi and is_debian + +- name: Base Server Installed + command: echo Base Server Installed + +- name: Restart xsce-cmdsrv service + service: name=xsce-cmdsrv + state=restarted + when: not installing + +- name: Restart httpd + service: name={{ apache_service }} + state=restarted + when: not installing + +# If we got here we're done +- name: Record base gui version + lineinfile: dest=/etc/xsce/xsce.env + regexp='^BASE_VERSION=*' + line='BASE_VERSION="{{ gui_version }}"' + state=present diff --git a/roles/3-base-server/templates/lxde_ssh_warn.sh b/roles/3-base-server/templates/lxde_ssh_warn.sh new file mode 100755 index 000000000..ff53a1a3b --- /dev/null +++ b/roles/3-base-server/templates/lxde_ssh_warn.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# credit to the folks at raspberry pi foundatioon +check_hash () +{ + if ! id -u xsce-admin > /dev/null 2>&1 ; then return 0 ; fi + if grep -q "^PasswordAuthentication\s*no" /etc/ssh/sshd_config ; then return 0 ; fi + test -x /usr/bin/mkpasswd || return 0 + SHADOW="$(sudo -n grep -E '^xsce-admin:' /etc/shadow 2>/dev/null)" + test -n "${SHADOW}" || return 0 + if echo $SHADOW | grep -q "xsce-admin:!" ; then return 0 ; fi + SHADOW_PW=$(echo $SHADOW | cut -d: -f2) + if [ "$SHADOW_PW" != "\$6\$xsce51\$D.IrrEeLBYIuJkGDmi27pZUGOwPFp98qpl3hxMwWV4hXigFGmdSvy3s/j7tn6OnyTTLmlV7SsN0lCUAFzxSop." ]; then return 0 ; fi + + if echo "${SHADOW}" | grep -q "${HASH}"; then + zenity --warning --text="SSH is enabled and the default password for the 'xsce-admin' user has not been changed.\nThis is a security risk - please go to the xsce-console and use utilities-> change password to set a new password." + fi +} + +if service ssh status | grep -q running; then + check_hash +fi +unset check_hash diff --git a/roles/3-base-server/templates/profile_ssh_warn.sh b/roles/3-base-server/templates/profile_ssh_warn.sh new file mode 100755 index 000000000..74fa75641 --- /dev/null +++ b/roles/3-base-server/templates/profile_ssh_warn.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# credit to the folks at raspberry pi foundatioon +check_hash () +{ + if ! id -u xsce-admin > /dev/null 2>&1 ; then return 0 ; fi + if grep -q "^PasswordAuthentication\s*no" /etc/ssh/sshd_config ; then return 0 ; fi + test -x /usr/bin/mkpasswd || return 0 + SHADOW="$(sudo -n grep -E '^xsce-admin:' /etc/shadow 2>/dev/null)" + test -n "${SHADOW}" || return 0 + if echo $SHADOW | grep -q "xsce-admin:!" ; then return 0 ; fi + SHADOW_PW=$(echo $SHADOW | cut -d: -f2) + if [ "$SHADOW_PW" != "\$6\$xsce51\$D.IrrEeLBYIuJkGDmi27pZUGOwPFp98qpl3hxMwWV4hXigFGmdSvy3s/j7tn6OnyTTLmlV7SsN0lCUAFzxSop." ]; then return 0 ; fi + + echo + echo "SSH is enabled and the default password for the 'xsce-admin' user is unchanged." + echo "This is a security risk - please login as the 'xsce-admin' user and type 'passwd' to change password." + echo +} + +if /usr/sbin/service ssh status | grep -q running; then + check_hash +fi +unset check_hash diff --git a/roles/4-server-options/README.rst b/roles/4-server-options/README.rst new file mode 100644 index 000000000..4ad68b2c9 --- /dev/null +++ b/roles/4-server-options/README.rst @@ -0,0 +1,8 @@ +===================== +Server Options README +===================== + +This role is a place to aggregate roles that may be optionally added to the basic server, +whereas the roles in base-server are required. As in the case of the base-server the +functionality here is not packages that are not directly consumed by users, which are in common, +nor specific applications, such as those found in the apps and tools roles. \ No newline at end of file diff --git a/roles/4-server-options/meta/main.yml b/roles/4-server-options/meta/main.yml new file mode 100644 index 000000000..f23e63f80 --- /dev/null +++ b/roles/4-server-options/meta/main.yml @@ -0,0 +1,10 @@ +dependencies: + - { role: sshd, tags: ['services','sshd','base'] } + - { role: network, tags: ['services','base','network'], when: gui_desired_network_role is defined } + - { role: postgresql, tags: ['services','postgresql','base'], when: postgresql_install } + - { role: authserver, tags: ['services','authserver','base'], when: authserver_install } + - { role: openvpn, tags: ['options','openvpn'], when: openvpn_install } + - { role: samba, tags: ['services','samba','options'], when: samba_install } + - { role: usb-lib, tags: ['services','usb-lib','options'], when: usb_lib_install } + - { role: cups, tags: ['services','cups','options'], when: cups_install } + - { role: menu, tags: ['services','menu','options'], when: iiab_menu_install } diff --git a/roles/4-server-options/tasks/main.yml b/roles/4-server-options/tasks/main.yml new file mode 100644 index 000000000..f9cc47a73 --- /dev/null +++ b/roles/4-server-options/tasks/main.yml @@ -0,0 +1,26 @@ +- name: Server Options Installed + command: echo Server Options Installed + +- name: Stop postgresql service + command: "/etc/init.d/postgresql stop" + ignore_errors: True + when: postgresql_install and is_debian + +- name: Start postgresql service + service: name=postgresql-xs + state=restarted + enabled=yes + when: postgresql_enabled + +- name: Stop authserver service + service: name=xs-authserver + state=stopped + enabled=no + when: not authserver_enabled and authserver_install + +- name: Start xs-authserver service + service: name=xs-authserver + state=restarted + when: authserver_enabled + + diff --git a/roles/5-xo-services/README.rst b/roles/5-xo-services/README.rst new file mode 100644 index 000000000..b215621b0 --- /dev/null +++ b/roles/5-xo-services/README.rst @@ -0,0 +1,6 @@ +================== +XO Services README +================== + +This role is a place to aggregate roles that provide XO specific services. + diff --git a/roles/5-xo-services/meta/main.yml b/roles/5-xo-services/meta/main.yml new file mode 100644 index 000000000..ad1bb8a34 --- /dev/null +++ b/roles/5-xo-services/meta/main.yml @@ -0,0 +1,4 @@ +dependencies: + - { role: ejabberd, tags: ['olpc','ejabberd','xo-services'], when: ejabberd_install } + - { role: idmgr, tags: ['olpc','idmgr','xo-services'], when: idmgr_install } + - { role: activity-server, tags: ['olpc','activity-server','xo-services'], when: activity_server_install } diff --git a/roles/5-xo-services/tasks/main.yml b/roles/5-xo-services/tasks/main.yml new file mode 100644 index 000000000..700fc1270 --- /dev/null +++ b/roles/5-xo-services/tasks/main.yml @@ -0,0 +1,3 @@ +- name: XO Services Installed + command: echo XO Services Installed + diff --git a/roles/6-generic-apps/README.rst b/roles/6-generic-apps/README.rst new file mode 100644 index 000000000..03df57f50 --- /dev/null +++ b/roles/6-generic-apps/README.rst @@ -0,0 +1,7 @@ +=================== +Generic Apps README +=================== + +This role is a place to aggregate roles that install apps of a more generic nature, as opposed to educational or managment. +Content Management Systems or Chat or Wiki applications would go here. + diff --git a/roles/6-generic-apps/meta/main.yml b/roles/6-generic-apps/meta/main.yml new file mode 100644 index 000000000..4c9369321 --- /dev/null +++ b/roles/6-generic-apps/meta/main.yml @@ -0,0 +1,7 @@ +dependencies: + - { role: mysql, tags: ['generic','mysql'], when: mysql_install } + - { role: elgg, tags: ['generic','elgg'], when: elgg_install } + - { role: owncloud, tags: ['generic','owncloud'], when: owncloud_install } + - { role: dokuwiki, tags: ['generic','dokuwiki'], when: dokuwiki_install } + - { role: wordpress, tags: ['generic','wordpress'], when: wordpress_install } + - { role: calibre, tags: ['generic','calibre'], when: calibre_install } diff --git a/roles/6-generic-apps/tasks/main.yml b/roles/6-generic-apps/tasks/main.yml new file mode 100644 index 000000000..f0c33e80f --- /dev/null +++ b/roles/6-generic-apps/tasks/main.yml @@ -0,0 +1,3 @@ +- name: Generic Apps Installed + command: echo Generic Apps Installed + diff --git a/roles/7-edu-apps/README.rst b/roles/7-edu-apps/README.rst new file mode 100644 index 000000000..05ede48d8 --- /dev/null +++ b/roles/7-edu-apps/README.rst @@ -0,0 +1,6 @@ +=================================== +Educational Apps and Content README +=================================== + +This role is a place to aggregate roles that provide Educational Content or +are specifically targetted at pedagogical activities. diff --git a/roles/7-edu-apps/meta/main.yml b/roles/7-edu-apps/meta/main.yml new file mode 100644 index 000000000..25ff2fb28 --- /dev/null +++ b/roles/7-edu-apps/meta/main.yml @@ -0,0 +1,9 @@ +dependencies: + - { role: moodle, tags: ['olpc','moodle','edu-apps'], when: moodle_install } + - { role: iiab, tags: ['iiab','edu-apps'], when: iiab_install } + - { role: pathagar, tags: ['pathagar','edu-apps'], when: pathagar_install } + - { role: rachel, tags: ['rachel','edu-apps'], when: rachel_install } + - { role: kalite, tags: ['kalite','edu-apps'], when: kalite_install } + - { role: kiwix, tags: ['kiwix','edu-apps'], when: kiwix_install } + - { role: sugarizer, tags: ['sugarizer','edu-apps'], when: sugarizer_install } + - { role: debian_schooltool, tags: ['schooltool','debian_schooltool','edu-apps'], when: debian_schooltool_install and is_debian } diff --git a/roles/7-edu-apps/tasks/main.yml b/roles/7-edu-apps/tasks/main.yml new file mode 100644 index 000000000..6b0d15d1a --- /dev/null +++ b/roles/7-edu-apps/tasks/main.yml @@ -0,0 +1,3 @@ +- name: Educational Apps and Content Installed + command: echo Educational Apps and Content Installed + diff --git a/roles/8-mgmt-tools/README.rst b/roles/8-mgmt-tools/README.rst new file mode 100644 index 000000000..2207054a5 --- /dev/null +++ b/roles/8-mgmt-tools/README.rst @@ -0,0 +1,6 @@ +====================================== +Assessment and Monitoring Tools README +====================================== + +This role is a place to aggregate roles that provide tools for Administering and +Monitoring the Server and for Assessing its use and effectiveness. diff --git a/roles/8-mgmt-tools/meta/main.yml b/roles/8-mgmt-tools/meta/main.yml new file mode 100644 index 000000000..05c4bc315 --- /dev/null +++ b/roles/8-mgmt-tools/meta/main.yml @@ -0,0 +1,10 @@ +dependencies: + - { role: sugar-stats, tags: ['olpc','sugar-stats','tools'], when: sugar_stats_install and ansible_distribution != "CentOS" } +# - { role: ajenti, tags: ['services','ajenti','tools'], when: ajenti_install } + - { role: munin, tags: ['services','munin','tools'], when: munin_install } + - { role: monit, tags: ['services','monit','tools'], when: monit_install } + - { role: vnstat, tags: ['services','vnstat','tools'], when: vnstat_install } + - { role: xovis, tags: ['services','xovis','tools'], when: xovis_install and ansible_distribution != "CentOS" } + - { role: phpmyadmin, tags: ['services','phpmyadmin','tools'], when: phpmyadmin_install } + - { role: awstats, tags: ['services','awstats','tools'], when: awstats_install } + - { role: teamviewer, tags: ['services','teamviewer','tools'], when: teamviewer_install } diff --git a/roles/8-mgmt-tools/tasks/main.yml b/roles/8-mgmt-tools/tasks/main.yml new file mode 100644 index 000000000..004bf470f --- /dev/null +++ b/roles/8-mgmt-tools/tasks/main.yml @@ -0,0 +1,3 @@ +- name: Assessment and Monitoring Tools Installed + command: echo Assessment and Monitoring Tools Installed + diff --git a/roles/9-local-addons/README.rst b/roles/9-local-addons/README.rst new file mode 100644 index 000000000..89be22318 --- /dev/null +++ b/roles/9-local-addons/README.rst @@ -0,0 +1,21 @@ +=================== +Local Addons README +=================== + +This role is a place to aggregate roles developed by various contributors or locally developed. + +Development +----------- + +Create the role you wish to add to the XSCE School Server by following the pattern of another role or any other means. + +Packaging +--------- + +Add your role into the main.yml file in the meta directory of the 7-local-addons role. It will now get installed as part of +the next ansible run. + +More Info +--------- + +Have a look at the docs section of this git repo for more detailed information. \ No newline at end of file diff --git a/roles/9-local-addons/meta/main.yml b/roles/9-local-addons/meta/main.yml new file mode 100644 index 000000000..c88edbe27 --- /dev/null +++ b/roles/9-local-addons/meta/main.yml @@ -0,0 +1,3 @@ +# Add your role to this list and then uncomment dependencies. Adding a tag is handy for testing. +#dependencies: + \ No newline at end of file diff --git a/roles/9-local-addons/tasks/main.yml b/roles/9-local-addons/tasks/main.yml new file mode 100644 index 000000000..ce546dfe9 --- /dev/null +++ b/roles/9-local-addons/tasks/main.yml @@ -0,0 +1,3 @@ +- name: Addon services installed + command: echo Addon services installed + diff --git a/roles/activity-server/README.rst b/roles/activity-server/README.rst new file mode 100644 index 000000000..504112fb9 --- /dev/null +++ b/roles/activity-server/README.rst @@ -0,0 +1,139 @@ +Serve XO activities from the XS school server +============================================= + +XO laptops can update their activities via HTTP, using specially +microformatted html pages to determine what to download. + +This package imports XO activities from a USB stick and generates the +correct html to serve them, in as many languages as it knows how, +using the localisation information from the activity bundles. Content +negotiation between Apache and the laptops decides what html is seen. + +The URL for this index is http://schoolserver/activities/. + +A facility exists to add extra descriptive html to the generated +indexes. + +USB import +---------- + +When a USB drive is inserted, the server looks for a directory in the +root directory called xs-activity-server. In there it expects to find +any number of activity bundles, a file called manifest.sha1, and +optionally a file or files with the suffix ".info". Depending on the +configuration of the school server, a file called "manifest.sha1.sig" +might also be required. + +Activity bundles are zip files with the suffix .xo and an internal +layout described at http://wiki.laptop.org/go/Activity_bundles. + +The manifest file should contain sha1sums for each activity bundle and +the metadata files, as if you had run + + sha1sum *.xo *.info > manifest.sha1 + +in the directory. + +If full XS security is enabled (by the presence of /etc/xs-security-on +-- see the xs-tools documentation), then manifest.sha1.sig should +contain a detached GPG signature for manifest.sha1, signed by a key +that the XS knows. If the school server lacks the /etc/xs-security-on +flag, the manifest.sha1.sig file is ignored. + +Multiple languages +------------------ + +Activities can contain localisation information, which usually +consists of a translated activity name. The localised information is +found in the bundle in a directory like: + +SomeWonderful.activity/locale/pt-BR/activity.linfo + +where pt-BR is an RFC1788 language code. If any activity contains an +activity.linfo file for a language, then an index is generated. The +server has templates for indexes in some languages (currently Spanish +and English); for other languages the indexes will be in English +except for the localised names. + +These index files are saved with names like +activities/index.html.zh-es. You can choose to look at them directly +that way, or let your browser decide which one is best for you by +visiting activities/index.html. + +If some activities lack localised information for a multi-part +language code, the index will include information that exists for the +corresponding single part code, before defaulting to English. For +example, a zh-CN page will include zh localisation if need be. (This +may not always be the best result: bn and bn-IN appear to use +different scripts). + + +Including extra descriptions +---------------------------- + +The optional .info files in the xs-activation-server directory should +consist of sections in this format: + + [com.microsoft.Word] + description = Write replacement, without distraction of collaboration. + + [some.other.Something] + description = another description, all on one line. + +If a section heading (in square brackets) matches the bundle_id or +service_name of an activity, the description will be displayed on the +generated html page. This information is not used by automatic +updates, but it might assist children in browsing and manually +installing activities. Note: there is no clever localisation here. + +Multiple versions +----------------- + +Over the course of a server deployment, an activity might be updated +several times. To preserve disk space, only the 4 most recent +versions of an activity are kept. Links to the second, third and +fourth newest versions are presented in the activities html file, but +these do not use the activity microformat and will not be visible to +automated updaters. + +To determine which activities are the most recent, the file's modification +times (mtime) are examined. The version number is not considered here. + +Note: If you plug in a USB stick with very out-of-date activities they +will be deleted as soon as they get on the server. + +HTML microformat +---------------- + +The microformat is described at +http://wiki.laptop.org/go/Activity_microformat. + +Utility script +-------------- + +/usr/bin/xs-check-activities will print statistics about a directory +of activities to stderr. Its output is not particularly well +formatted or explained, but it is there if you want it. + +Files and directories +--------------------- + +Activities are stored in /library/xs-activity-server/activities, with +the html index being index.html in that directory. Apache is coaxed +into serving this by /etc/httpd/conf.d/xs-activity-server.conf. + +Bugs +---- + +Old versions are only saved if the different versions have different +file names. Most activity bundles have names like 'Maze-4.xo', +'Maze-5.xo' and so on, but some lack the version number in the file +name, so the most recently imported version ends up overwriting the +older ones. + +Source +------ + +This role is based on the xs-activity-server rpm. + +http://dev.laptop.org/git/users/martin/xs-activity-server/ v0.4 release \ No newline at end of file diff --git a/roles/activity-server/defaults/main.yml b/roles/activity-server/defaults/main.yml new file mode 100644 index 000000000..6086cd987 --- /dev/null +++ b/roles/activity-server/defaults/main.yml @@ -0,0 +1,3 @@ +activity_server_enabled: False +activity_server_install: True + diff --git a/roles/activity-server/files/bin/xs-check-activities b/roles/activity-server/files/bin/xs-check-activities new file mode 100644 index 000000000..6255b9e7a --- /dev/null +++ b/roles/activity-server/files/bin/xs-check-activities @@ -0,0 +1,30 @@ +#!/usr/bin/python +# Copyright (C) 2008 One Laptop Per Child Association, Inc. +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. +# +# written by Douglas Bagnall + +"""This script reads activity.info from bundle files and reports on +their quality. +""" + +import xs_activities +import sys, os + +xs_activities.USE_STDERR = True + +show_all = '--show-all' in sys.argv +if show_all: + sys.argv.remove('--show-all') + + +try: + directory = sys.argv[1] + os.stat(directory) +except (IndexError, OSError): + print __doc__ + print "USAGE: %s DIRECTORY" % sys.argv[0] + sys.exit(1) + +xs_activities.check_all_bundles(directory, show_all) + diff --git a/roles/activity-server/files/bin/xs-regenerate-activities b/roles/activity-server/files/bin/xs-regenerate-activities new file mode 100644 index 000000000..9ad549c79 --- /dev/null +++ b/roles/activity-server/files/bin/xs-regenerate-activities @@ -0,0 +1,93 @@ +#!/usr/bin/python +# Copyright (C) 2008 One Laptop Per Child Association, Inc. +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. +# +# written by Douglas Bagnall + +"""Read activity.info files from a directory full of activity bundles +and write an appropriate html manifest of the most recent versions. +The manifest uses the OLPC activity microformat: + + http://wiki.laptop.org/go/Activity_microformat + +This is put in a place where apache can find it, and apache will serve +it and the activities to the laptops. Messages go to /var/log/user.log. +""" + +import os +import sys +import shutil +from time import time + +import xs_activities + +INPUT_DIR = "/library/xs-activity-server/activities" +OUTPUT_LINK = "/library/xs-activity-server/www" + +try: + CURRENT_DIR = os.readlink(OUTPUT_LINK) +except OSError: + CURRENT_DIR = None + + +def create_dir_manifest(dir_path): + manifest = [] + os.chdir(dir_path) + for root, dirs, files in os.walk("."): + for filename in files: + if not filename.endswith(".xo") and not filename.endswith(".xol"): + continue + + path = os.path.join(root, filename) + s = os.stat(path) + manifest.append((path, s.st_ino)) + + manifest.sort() + return manifest + + +def input_changed(): + if CURRENT_DIR is None: + return True + + input_manifest = create_dir_manifest(INPUT_DIR) + current_manifest = create_dir_manifest(CURRENT_DIR) + return input_manifest != current_manifest + + +if not input_changed(): + # no changes or nothing to do + sys.exit(0) + +# create new output dir +OUTPUT_DIR = OUTPUT_LINK + "." + str(time()) +os.mkdir(OUTPUT_DIR) + +# link in all activities +os.chdir(INPUT_DIR) +for root, dirs, files in os.walk("."): + output_dir = os.path.join(OUTPUT_DIR, root) + if not os.path.isdir(output_dir): + os.makedirs(output_dir) + + for filename in files: + if not filename.endswith(".xo") and not filename.endswith(".xol"): + continue + + path = os.path.join(root, filename) + output_path = os.path.join(output_dir, filename) + os.link(path, output_path) + + # create html index + output_html = os.path.join(output_dir, 'index.html') + xs_activities.htmlise_bundles(output_dir, output_html) + + +# update symlink atomically +link = OUTPUT_DIR + ".lnk" +os.symlink(OUTPUT_DIR, link) +os.rename(link, OUTPUT_LINK) + +# remove old index +if CURRENT_DIR is not None: + shutil.rmtree(CURRENT_DIR, ignore_errors=True) diff --git a/roles/activity-server/files/lang_templates/en/activity b/roles/activity-server/files/lang_templates/en/activity new file mode 100644 index 000000000..b600053e5 --- /dev/null +++ b/roles/activity-server/files/lang_templates/en/activity @@ -0,0 +1,10 @@ +
+

%(name)s

+%(description)s +
    +
  • Identifier: %(bundle_id)s
  • +
  • Version: %(activity_version)s
  • +
  • URL: %(bundle_url)s
  • +
  • Older versions: %(older_versions)s
  • +
+
diff --git a/roles/activity-server/files/lang_templates/en/page b/roles/activity-server/files/lang_templates/en/page new file mode 100644 index 000000000..fac41f0d6 --- /dev/null +++ b/roles/activity-server/files/lang_templates/en/page @@ -0,0 +1,7 @@ + + +

Locally available activities

+

These activities are stored on the school server.

+%(activities)s + + diff --git a/roles/activity-server/files/lang_templates/es/activity b/roles/activity-server/files/lang_templates/es/activity new file mode 100644 index 000000000..37c99a58d --- /dev/null +++ b/roles/activity-server/files/lang_templates/es/activity @@ -0,0 +1,10 @@ +
+

%(name)s

+%(description)s +
    +
  • Identificador: %(bundle_id)s
  • +
  • Versión: %(activity_version)s
  • +
  • URL: %(bundle_url)s
  • +
  • Versiones anteriores: %(older_versions)s
  • +
+
diff --git a/roles/activity-server/files/lang_templates/es/page b/roles/activity-server/files/lang_templates/es/page new file mode 100644 index 000000000..9b65895a5 --- /dev/null +++ b/roles/activity-server/files/lang_templates/es/page @@ -0,0 +1,8 @@ + + + +

Actividades disponibles localmente

+

Estas actividades están almacenads en el servidor de la escuela.

+%(activities)s + + diff --git a/roles/activity-server/files/lang_templates/fr/activity b/roles/activity-server/files/lang_templates/fr/activity new file mode 100644 index 000000000..6725ddecb --- /dev/null +++ b/roles/activity-server/files/lang_templates/fr/activity @@ -0,0 +1,10 @@ +
+

%(name)s

+%(description)s +
    +
  • Identifiant: %(bundle_id)s
  • +
  • Version: %(activity_version)s
  • +
  • URL: %(bundle_url)s
  • +
  • Anciennes versions: %(older_versions)s
  • +
+
diff --git a/roles/activity-server/files/lang_templates/fr/page b/roles/activity-server/files/lang_templates/fr/page new file mode 100644 index 000000000..a1676aa0c --- /dev/null +++ b/roles/activity-server/files/lang_templates/fr/page @@ -0,0 +1,8 @@ + + + +

Activités disponibles localement

+

Ces activités sont stockées sur le serveur de l’école.

+%(activities)s + + diff --git a/roles/activity-server/files/lang_templates/ht/activity b/roles/activity-server/files/lang_templates/ht/activity new file mode 100644 index 000000000..81c7efe8b --- /dev/null +++ b/roles/activity-server/files/lang_templates/ht/activity @@ -0,0 +1,10 @@ +
+

%(name)s

+%(description)s +
    +
  • Pou idantifye: %(bundle_id)s
  • +
  • Vesyon: %(activity_version)s
  • +
  • URL: %(bundle_url)s
  • +
  • Vesyon ansyen: %(older_versions)s
  • +
+
diff --git a/roles/activity-server/files/lang_templates/ht/page b/roles/activity-server/files/lang_templates/ht/page new file mode 100644 index 000000000..409ba93c5 --- /dev/null +++ b/roles/activity-server/files/lang_templates/ht/page @@ -0,0 +1,8 @@ + + + +

Aktivite ki disponib nan Bwat la

+

Aktivite sa yo disponib sou sit lekòl la.

+%(activities)s + + diff --git a/roles/activity-server/files/www.0/index.html.en b/roles/activity-server/files/www.0/index.html.en new file mode 100644 index 000000000..7a7aea2f0 --- /dev/null +++ b/roles/activity-server/files/www.0/index.html.en @@ -0,0 +1,10 @@ + + +

Locally available activities

+

These activities are stored on the school server.

+
+There are currently no activities. Insert a USB drive with activities on it to add some. +
+ + + diff --git a/roles/activity-server/files/www.0/index.html.fr b/roles/activity-server/files/www.0/index.html.fr new file mode 100644 index 000000000..744d902f0 --- /dev/null +++ b/roles/activity-server/files/www.0/index.html.fr @@ -0,0 +1,11 @@ + + + +

Activités disponibles localement

+

Ces activités sont stockées sur le serveur de l’école.

+
+Il n'y a pas d'activités. Insérez une clé USB avec des activités sur pour ajouter. +
+ + + diff --git a/roles/activity-server/files/www.0/index.html.ht b/roles/activity-server/files/www.0/index.html.ht new file mode 100644 index 000000000..9767b6ff6 --- /dev/null +++ b/roles/activity-server/files/www.0/index.html.ht @@ -0,0 +1,11 @@ + + + +

Aktivite ki disponib nan Bwat la

+

Aktivite sa yo disponib sou sit lekòl la.

+
+Gen kounye a pa gen okenn aktivite. Antre yon USB ak aktivite sou li ajoute kèk. +
+ + + diff --git a/roles/activity-server/files/xs_activities/__init__.py b/roles/activity-server/files/xs_activities/__init__.py new file mode 100644 index 000000000..5defd41bf --- /dev/null +++ b/roles/activity-server/files/xs_activities/__init__.py @@ -0,0 +1,535 @@ +# Copyright (C) 2008 One Laptop Per Child Association, Inc. +# Licensed under the terms of the GNU GPL v2 or later; see COPYING for details. +# +# written by Douglas Bagnall + +"""Functions for processing XO activities, either for indexing and +presentaton to the laptops, or for diagnostics. +""" + +import os, sys, shutil +import zipfile +import re +from cStringIO import StringIO +#import traceback +import syslog +from ConfigParser import SafeConfigParser + +# we no longer really have a default in that it is set in the conf file +# we assume that we have a lang_template for the default language +TEMPLATE_DIR = '/library/xs-activity-server/lang_templates' +DEFAULT_LANG = 'en' + +# how many versions before the latest are worth having around. +KEEP_OLD_VERSIONS = 3 + +#print to stderr, rathe than syslog? +USE_STDERR=False + +REQUIRED_TAGS = ('bundle_id', 'activity_version', 'host_version', 'name', 'license') +OPTIONAL_TAGS = ('show_launcher', 'exec', 'mime_types', 'icon') +#XXX need either icon or show_launcher=no + +def log(msg, level=syslog.LOG_NOTICE): + if USE_STDERR: + print >> sys.stderr, msg + else: + syslog.openlog( 'xs-activity-server', 0, syslog.LOG_USER ) + syslog.syslog(level, msg) + syslog.closelog() + +class BundleError(Exception): + pass + +class Bundle(object): + def __init__(self, bundle): + self.linfo = {} + self.zf = zipfile.ZipFile(bundle) + # The activity path will be 'Something.activity/activity/activity.info' + for p in self.zf.namelist(): + if p.endswith(self.INFO_PATH): + self.raw_data = read_info_file(self.zf, p, self.INFO_SECTION) + + # the file name itself is needed for the URL + self.url = os.path.basename(bundle) + self.mtime = os.stat(bundle).st_mtime + + self.name = self.raw_data.get('name') + self.license = self.raw_data.get('license', None) + + # child ctor should now call + # _set_bundle_id + # _set_version + # _set_description + def _set_bundle_id(self, id): + if id is None: + raise BundleError("bad bundle: No bundle ID") + self.bundle_id = id + if self.name is None: + self.name = id + + def _set_version(self, version): + self.version = version + + def _set_description(self, description): + self.description = description + + def __cmp__(self, other): + """Alphabetical sort (locale dependant of course)""" + if self.bundle_id == other.bundle_id: + return cmp(self.version, other.version) + return cmp(self.name, other.name) + + def set_older_versions(self, versions): + """Versions should be a list of (version number, version tuples)""" + self.older_versions = ', '.join('%s' % (v.url, v.version) for v in versions) + + def to_html(self, locale, template=None): + """Fill in the template with data approriate for the locale.""" + if template is None: + template = read_template('activity', locale) + + d = {'older_versions': self.older_versions, + 'bundle_id': self.bundle_id, + 'activity_version': self.version, + 'bundle_url': self.url, + 'name': self.name, + 'description': self.description, + } + + d.update(self.linfo.get(locale, {})) + + if d['older_versions']: + d['show_older_versions'] = 'inline' + else: + d['show_older_versions'] = 'none' + + return template % d + + def get_name(self, locale=None): + return self.name + +class Content(Bundle): + INFO_PATH = "library/library.info" + INFO_SECTION = "Library" + + def __init__(self, bundle): + super(Content, self).__init__(bundle) + + d = self.raw_data + # bundle_id is often missing; service name is used instead. + self._set_bundle_id(d.get('global_name', None)) + self._set_version(d.get('library_version', 1)) + self._set_description(d.get('long_name', '')) + + def debug(self, force_recheck=False): + # FIXME: implement debug checking for content bundles + return {} + +class Activity(Bundle): + INFO_PATH = "activity/activity.info" + INFO_SECTION = "Activity" + + #Activities appear to be looser than RFC3066, using e.g. _ in place of -. + linfo_re = re.compile(r'/locale/([A-Za-z]+[\w-]*)/activity.linfo$') + + def __init__(self, bundle): + """Takes a zipped .xo bundle name, returns a dictionary of its + activity info. Can raise a variety of exceptions, all of + which should indicate the bundle is invalid.""" + super(Activity, self).__init__(bundle) + + # The locale info will be Something.activity/locale/xx_XX/activity.linfo + for p in self.zf.namelist(): + linfo = self.linfo_re.search(p) + if linfo: + lang = canonicalise(linfo.group(1)) + self.linfo[lang] = read_info_file(self.zf, p, self.INFO_SECTION) + + # Unfortunately the dictionary lacks some information, and + # stores other bits in inconsistent ways. + + d = self.raw_data + # bundle_id is often missing; service name is used instead. + self._set_bundle_id(d.get('bundle_id', d.get('service_name'))) + self._set_version(d.get('activity_version', 1)) + self._set_description(d.get('description', '')) + + def debug(self, force_recheck=False): + """Make a copy of the raw data with added bits so we can work + out what is going on. This is useful for diagnosing problems + with odd activities and composing tut-tut-ing emails to their + authors. + + Not used in production.""" + if hasattr(self, '_debug_data') and not force_recheck: + return self._debug_data + + d = self.raw_data.copy() + + correct_forms = { + 'name': str.upper, + 'activity_version': str.isdigit, + 'host_version': str.isdigit, + 'bundle_id': re.compile(r'^[\w.]+$').match, + 'service_name': re.compile(r'^[\w.]+$').match, + 'icon': re.compile(r'^[\S]+$').match, + 'exec': str.upper, + 'mime_types': re.compile(r'^([\w.+-]+/[\w.+-]+;?)*$').match, + 'update_url': re.compile(r'^http://([\w-]+\.?)+(:\d+)?(/[\w~%.-]+)*$').match, + #'update_url': re.compile(r'^$').match, + 'show_launcher': re.compile(r'^(yes)|(no)$').match, + 'class': re.compile(r'^(\w+.?)+$').match, + 'license': str.upper, + #'license': re.compile(r'^GPLv[23]\+?$').match, + } + + for k, v in d.items(): + if k in correct_forms: + f = correct_forms.get(k, len) + if not f(v): + d['BAD ' + k] = v + + rcount = 0 + for k in REQUIRED_TAGS: + if k not in d: + d['LACKS %s' % k] = True + rcount += 1 + d['MISSING KEYS'] = rcount + + for t in OPTIONAL_TAGS: + if t not in d: + d['NO ' + t] = True + + if not 'icon' in d and d.get('show_launcher') != 'no': + d['NO icon AND show_launcher'] = True + + self._debug_data = d + return d + + def get_name(self, locale): + """Return the best guess at a name for the locale.""" + for loc in locale_search_path(locale): + if loc in self.linfo and 'name' in self.linfo[loc]: + return self.linfo[loc]['name'] + return super(Activity, self).get_name() + + + +def check_all_bundles(directory, show_all_bundles=False): + """A verbose debug function.""" + all_bundles = [] + unique_bundles = {} + counts = {} + # watch for these tags and print out the lists + bad_contents = {} + all_linfo = {} + unique_linfo = {} + linfo_keys = {} + log('Checking all activities in %s\n' % directory) + for f in os.listdir(directory): + if not f.endswith('.xo') and not f.endswith('.xol'): + continue + #log(f) + try: + if f.endswith('.xo'): + bundle = Activity(os.path.join(directory, f)) + else: + bundle = Content(os.path.join(directory, f)) + except Exception, e: + log("IRREDEEMABLE bundle %-25s (Error: %s)" % (f, e), syslog.LOG_WARNING) + + #Clump together bundles of the same ID + x = unique_bundles.setdefault(bundle.bundle_id, []) + x.append(bundle) + all_bundles.append(bundle) + + if not show_all_bundles: + #only show the newest one of each set. + bundles = [] + for versions in unique_bundles.values(): + versions.sort() + bundles.append(versions[-1]) + + else: + bundles = all_bundles + + licenses = {} + for bundle in bundles: + bid = bundle.bundle_id + for k, v in bundle.debug().iteritems(): + counts[k] = counts.get(k, 0) + 1 + if k.startswith('BAD '): + bc = bad_contents.setdefault(k, {}) + bc[bid] = v + for k, v in bundle.linfo.iteritems(): + linfo_l = all_linfo.setdefault(k, []) + linfo_l.append(bundle) + for x in v: + linfo_keys[x] = linfo_keys.get(x, 0) + 1 + if v['name'] != bundle.name: + linfo_l = unique_linfo.setdefault(k, []) + linfo_l.append(bundle) + + if bundle.license: + lic = licenses.setdefault(bundle.license, []) + lic.append(bundle.bundle_id) + + citems = counts.items() + rare_keys = [k for k, v in citems if v < 10] + lack_counts = dict((k, v) for k, v in citems if k.startswith('LACKS ')) + bad_counts = dict((k, v) for k, v in citems if k.startswith('BAD ')) + no_counts = dict((k, v) for k, v in citems if k.startswith('NO ')) + tag_counts = dict((k, v) for k, v in citems if k not in lack_counts and + k not in bad_counts and k not in no_counts and k != 'MISSING KEYS') + + # flag whether the tag is needed, ok, or not + tag_quality = dict((k, '*') for k in REQUIRED_TAGS) + tag_quality.update((k, '+') for k in OPTIONAL_TAGS) + linfo_counts = dict((k, len(v)) for k, v in all_linfo.iteritems()) + linfo_uniq_counts = dict((k, len(v)) for k, v in unique_linfo.iteritems()) + + log('\nFound: %s bundles\n %s unique bundles' % (len(all_bundles), len(unique_bundles))) + for d, name, d2 in [(tag_counts, '\nattribute counts:', tag_quality), + (lack_counts, '\nmissing required keys:', {}), + (no_counts, '\nunused optional keys:', {}), + (bad_counts, '\nill-formed values:', {}), + (linfo_counts, '\nlinfo counts: total localised', linfo_uniq_counts), + (linfo_keys, '\nlinfo keys:', {})]: + log(name) + counts_reversed = [(v, k) for (k, v) in d.iteritems()] + counts_reversed.sort() + counts_reversed.reverse() + for (k, v) in counts_reversed: + log("%-25s %4s %4s" % (v, k, d2.get(v, ''))) + + log("\nRare keys:") + for k in rare_keys: + if k.startswith('BAD '): + continue + log(k) + for b in bundles: + v = b.debug().get(k) + if v: + log(' %-25s %s' % (b.bundle_id, v)) + + + log("\nInteresting contents:") + for k, v in bad_contents.iteritems(): + log(k) + for x in v.iteritems(): + log(' %s: %s' % x) + + log("\nInteresting linfo:") + for k in ('pseudo',): + log(k) + for a in all_linfo[k]: + if a in unique_linfo.get(k, []): + log(' * %s (%s vs. %s)' % (a.bundle_id, a.name, a.linfo[k]['name'])) + else: + log(' %s (%s)' % (a.bundle_id, a.name)) + + log("\nLicenses:") + for lic, v in licenses.iteritems(): + log("%-20s %s" %(repr(lic), len(v))) + + log("\nRare licenses:") + for lic, v in licenses.iteritems(): + if len(v) < 3: + log(' %s' % lic) + for x in v: + log(" %s" %(x)) + + + + log("\nAlmost valid activities:") + for b in bundles: + d = b.debug() + if d['MISSING KEYS'] == 1: + missing = ', '.join(x for x in d if x.startswith('LACKS')) + bad_values = ', '. join(x for x in d if x.startswith('BAD')) + log("%-20s %s %s" %(b.name, missing, bad_values)) + + log("\nValid activities (maybe):") + for b in bundles: + d = b.debug() + bid = b.bundle_id + if (d['MISSING KEYS'] == 0 and + bid not in bad_contents['BAD mime_types']): + log("%-20s - %s" %(b.name, bid)) + #log(a.raw_data) + + + + +def read_info_file(zipfile, path, section): + """Return a dictionary matching the contents of the config file at + path in zipfile""" + cp = SafeConfigParser() + info = StringIO(zipfile.read(path)) + cp.readfp(info) + return dict(cp.items(section)) + +def canonicalise(lang): + """Make all equivalent language strings the same. + >>> canonicalise('Zh-cN') + zh-CN + >>> canonicalise('zh_CN') + zh-CN + """ + lang = lang.replace('_', '-').upper() + bits = lang.split('-', 1) + bits[0] = bits[0].lower() + return '-'.join(bits) + +def locale_search_path(locale): + """Find a series of sensible locales to try, including + DEFAULT_LANG. For example 'zh-CN' would become ('zh-CN', 'zh', + 'DEFAULT_LANG').""" + #XXX might be better to be storing locale as tuple + if '-' in locale: + return (locale, locale.split('-')[0], DEFAULT_LANG) + return (locale, DEFAULT_LANG) + + + +def read_metadata(bundle_dir): + """Attempt to read data in a metadata file. Raises expected + exceptions if the metadata file isn't readable. The file should + look something like this: + + [org.laptop.Pippy] + description = Succinct description of this activity. + + [org.laptop.Develop] + description = Succinct description of this activity. + web_icon = develop.png + """ + md_files = [os.path.join(bundle_dir, x) + for x in os.listdir(bundle_dir) if x.endswith('.info')] + cp = SafeConfigParser() + cp.read(md_files) + metadata = {} + for section in cp.sections(): + metadata[section] = dict(x for x in cp.items(section)) + return metadata + + +def htmlise_bundles(bundle_dir, dest_html): + """Makes a nice html manifest for the bundles in a directory. The + manifest only shows the newest version of each bundle. + """ + #so, we collect up a dictionary of lists, then sort each list on + #the version number to find the newest. + + bundles = [os.path.join(bundle_dir, x) + for x in os.listdir(bundle_dir) if x.endswith('.xo') or x.endswith('.xol')] + + try: + metadata = read_metadata(bundle_dir) + except Exception, e: + log("had trouble reading metadata: %s" % e) + metadata = {} + + all_bundles = {} + for filename in bundles: + try: + if filename.endswith('.xo'): + bundle = Activity(filename) + else: + bundle = Content(filename) + x = all_bundles.setdefault(bundle.bundle_id, []) + x.append((bundle.mtime, bundle)) + except Exception, e: + log("Couldn't find good activity/library info in %s (Error: %s)" % (filename, e)) + + newest = [] + # create an index for each language that has a template + # but track any locales in bundles in case we do not have templates for them + locales = [os.path.join(o) for o in os.listdir(TEMPLATE_DIR) if os.path.isdir(os.path.join(TEMPLATE_DIR,o))] + locales_found = set () + for versions in all_bundles.values(): + versions = [x[1] for x in sorted(versions)] + # end of list is the newest; beginning of list might need deleting + latest = versions.pop() + locales_found.update(latest.linfo) + newest.append(latest) + goners = versions[:-KEEP_OLD_VERSIONS] + keepers = versions[-KEEP_OLD_VERSIONS:] + for v in goners: + fn = os.path.join(bundle_dir, v.url) + os.remove(fn) + latest.set_older_versions(keepers) + + if latest.bundle_id in metadata: + # we have extra metadata with which to fill out details + # presumably this is mainly human-oriented description. + d = metadata[latest.bundle_id] + for k in ('description', 'name'): + if k in d: + setattr(latest, k, d[k]) + + log('found locales: %s' % locales) + + # assume locales is not empty as we have at least the default language + for locale in locales: + try: + make_html(newest, locale, '%s.%s' % (dest_html, locale)) + except Exception, e: + log("Couldn't make page for %s (Error: %s)" % (locale, e), syslog.LOG_WARNING) + + # make_varfile(locales, dest_html)- have switched to multiviews, so var not needed + + +def make_varfile(locales, dest_html): + f = open(dest_html + '.var', 'w') + index = os.path.basename(dest_html) + f.write('URI: %s\n\n' % index) + for locale in locales: + f.write('URI: %s.%s\n' % (index, locale)) + f.write('Content-type: text/html; charset=utf-8\n') + f.write('Content-language: %s\n\n' % locale) + # now the default, slightly higher qs + f.write('URI: %s.DEFAULT\n' % index) + f.write('Content-type: text/html; charset=utf-8\n') + f.write('Content-language: en\n\n') + + f.close() + +def read_template(name, locale): + """Try to read the locale's template, falling back to the + default.""" + #also try containing locales, eg 'zh' for 'zh-CN' + for x in locale_search_path(locale): + try: + f = open(os.path.join(TEMPLATE_DIR, x, name)) + break + except (OSError, IOError), e: + #log(str(e)) + continue + s = f.read() + f.close() + return s + + +def make_html(bundles, locale, filename): + """Write a microformated index for the activities in the appropriate language, + and save it to filename.""" + page_tmpl = read_template('page', locale) + act_tmpl = read_template('activity', locale) + + #bundles.sort() won't cut it. + schwartzian = [ (x.get_name(locale), x.to_html(locale, act_tmpl)) for x in bundles ] + schwartzian.sort() + s = page_tmpl % {'activities': '\n'.join(x[1] for x in schwartzian)} + + if os.path.exists(filename): + shutil.move(filename, filename + '~') + f = open(filename, 'w') + f.write(s) + f.close() + + + + + diff --git a/roles/activity-server/tasks/main.yml b/roles/activity-server/tasks/main.yml new file mode 100644 index 000000000..39d0c06bb --- /dev/null +++ b/roles/activity-server/tasks/main.yml @@ -0,0 +1,133 @@ +# assume apache in admin group + +- name: Create xs-activity-server directory tree + file: path={{ item }} + mode=0755 + owner=root + group=admin + state=directory + with_items: + - /library/xs-activity-server + - /library/xs-activity-server/activities + - /library/xs-activity-server/lang_templates + - /library/xs-activity-server/www.0 + - /library/xs-activity-server/tmp + +# Wish synchronize worked, but it doesn't + +- name: Copy language templates + command: rsync -a {{xsce_dir}}/roles/activity-server/files/lang_templates /library/xs-activity-server/ + +- name: Copy default index files + copy: src={{ item }} + dest=/library/xs-activity-server/www.0 + mode=0755 + owner=root + group=root + with_fileglob: + - www.0/index.html.* + +- name: Point www to www.0 as default + file: src=/library/xs-activity-server/www.0 + dest=/library/xs-activity-server/www + owner=root + group=admin + state=link + +- name: Chown language templates + file: path=/library/xs-activity-server/lang_templates + mode=0644 + owner=root + group=admin + state=directory + recurse=yes + +# We should have a var for python site-packages directory + +- name: Create xs-activity-server python site-packages directory + file: path=/usr/lib/python2.7/site-packages/xs_activities + mode=0755 + owner=root + group=root + state=directory + +- name: Install Python module + copy: src=xs_activities/__init__.py + dest=/usr/lib/python2.7/site-packages/xs_activities + mode=0644 + owner=root + group=root + +- name: Copy scripts to /usr/bin + copy: src={{ item }} + dest=/usr/bin + mode=0755 + owner=root + group=root + with_items: + - bin/xs-regenerate-activities + - bin/xs-check-activities + +# Do in ansible what was done in /etc/sysconfig/olpc-scripts/setup.d/xs-activity-server script + +- name: Copy xs-activity-server config file + template: src=xs-activity-server.conf + dest=/etc/{{ apache_config_dir }} + owner=root + group=root + mode=0644 + +- name: enable mod_expires for debian + command: a2enmod expires + when: is_debian + +- name: create the link which enables the site + file: src=/etc/apache2/sites-available/xs-activity-server.conf + dest=/etc/apache2/sites-enabled/xs-activity-server.conf + state=link + when: activity_server_enabled and is_debian + +- name: delete the link which enables the site + file: src=/etc/apache2/sites-available/xs-activity-server.conf + dest=/etc/apache2/sites-enabled/xs-activity-server.conf + state=absent + when: not activity_server_enabled and is_debian + + +- name: Copy xs-activity-server usbmount file + template: src=usbmount-60-xs-activity-server-installcontent + dest=/etc/usbmount/mount.d + owner=root + group=root + mode=0755 + +# TODO: Fix multiview so it supports portal language menu +# For it only supports client's language code + +# TODO: Upload Activity via web interface +# and figure out what to do with olpc_activities.service + +# short term addition of link for upload-activity server +# ln -sf /usr/share/xs-config/cfg/html/top/en/cntr_upl_activity.php {{ doc_root }}/upload_activity.php + + +- name: Restart httpd + service: name={{ apache_service }} + enabled=yes + state=restarted + +- name: add xs-activity-server to service list + ini_file: dest='{{ service_filelist }}' + section=activity-server + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: name + value: "Activity Server" + - option: description + value: "Download an Activity." + - option: path + value: /activities + - option: enabled + value: "{{ xo_services_enabled }}" + diff --git a/roles/activity-server/templates/usbmount-60-xs-activity-server-installcontent b/roles/activity-server/templates/usbmount-60-xs-activity-server-installcontent new file mode 100644 index 000000000..d2fc834e6 --- /dev/null +++ b/roles/activity-server/templates/usbmount-60-xs-activity-server-installcontent @@ -0,0 +1,115 @@ +#!/bin/bash +# Part of the xs-activity-server package +# +# based on a similarly named script in the xs-rsync package +# by Martin Langhoff +# +# Adapted for xs-activity-server by Douglas Bagnall +# +# +# Copyright: One Laptop per Child + +set -e + +VERBOSE=yes +MAGIC_DIR=$UM_MOUNTPOINT/xs-activity-server + +FINAL_DIR=/library/xs-activity-server/activities + +FILES_TO_RM="" + +# combined with set -e, error() is called if something fails. +error(){ + logger -puser.err -t "xs-activity-server[$$]" "Error at line $(caller)" + [ "$FILES_TO_RM" ] && rm -rf $FILES_TO_RM +} +trap error ERR + + +# Log a string via the syslog facility. +log() +{ + if test $1 != debug || expr "$VERBOSE" : "[yY]" > /dev/null; then + logger -p user.$1 -t "xs-activity-server[$$]" -- "$2" + fi +} + + +STEPS=7 + +[ -d $MAGIC_DIR ] || exit 0 + +log notice 'Found activity install directory'; +log notice "[1/$STEPS] Checking whether it has a manifest"; + +if [ -r $MAGIC_DIR/manifest.sha1 ];then + log notice "[2/$STEPS] Seems to have a manifest"; +else + log err "[2/$STEPS] Missing manifest" + exit 1; +fi + +## Do we have enough space? +# note: we could use awk {'print $4'} instead of the +# perl regex, but it breaks with long /dev nodes +# such as those from LVMs -which wrap. The regex captures the +# number just left of the number with the percentage sign. +NEED=`du -s -B1M $MAGIC_DIR | awk {'print $1'}` +HAVE=`df -B1M $FINAL_DIR | tail -n1 | \ + perl -pe 'm/(\d+)\s+\d+\%/; $_=($1-1);'` +if [ $NEED -gt $HAVE ];then + log err 'Not enough free space in /library for these activities - cancelling'; + exit 1; +fi + +### Copy it first - as the media is bound to be slow +# - make this atomic by cp'ing to a tmpdir, and mv'ing into place +# to be fail-safe +# - mv aside manifest.sha1 and its sig +# - TODO? we could avoid cp'ing files we already have using +# rsync --copy-dest instead of cp +# +log notice "[3/$STEPS] Copying activities to disk"; +TMPDEST=`mktemp -d -p /library/xs-activity-server/tmp` + +#make sure the tmp directory goes +FILES_TO_RM="$FILES_TO_RM '$TMPDEST'" + +cp --preserve=timestamps $MAGIC_DIR/* $TMPDEST + +# In a tmpdir we own, safe from race conditions +# run the checksums... +log notice "[4/$STEPS] Checking the manifest"; +# mv the manifest to a different dir +TMPMANIF=`mktemp -d -p /library/xs-activity-server/tmp` + +FILES_TO_RM="$FILES_TO_RM '$TMPMANIF'" + + +mv $TMPDEST/manifest.sha1 $TMPMANIF/ +if [ -e $TMPDEST/manifest.sha1.sig ]; then + mv $TMPDEST/manifest.sha1.sig $TMPMANIF/ +fi +xs-sum -c $TMPMANIF/manifest.sha1 -d $TMPDEST + +#Let syslog know what we're doing +cd $TMPDEST +log notice "found $(ls *.xo |wc -l) activities" +log debug "found these activities: $(ls *.xo)" +cd - + +log notice "[5/$STEPS] Copy the directories into place"; +#XXX not checking whether this clobbers existing files. +mv $TMPDEST/* $FINAL_DIR + +#So, now all the activities are in place, but maybe they're not +#newer than what we have. So xs-regenerate-activities has to work that out. + +log notice "[6/$STEPS] Regenerating the list of available activities"; + +/usr/bin/xs-regenerate-activities $FINAL_DIR 2>&1 | logger -p user.debug -t "xs-activity-server[$$]" + +log notice "[$STEPS/$STEPS] Finished - XOs can now update activities."; + + +rm -fr $FILES_TO_RM diff --git a/roles/activity-server/templates/xs-activity-server.conf b/roles/activity-server/templates/xs-activity-server.conf new file mode 100644 index 000000000..17946eab6 --- /dev/null +++ b/roles/activity-server/templates/xs-activity-server.conf @@ -0,0 +1,30 @@ +# xs-activity-server +# +# Copyright: On Laptop per Child +# GPL v2 +# written by Douglas Bagnall +# +# This belongs in the apache conf.d directory. +# (probably /etc/httpd/conf.d/) + +Alias /activities /library/xs-activity-server/www + + # Languages are set in 010-xsce.conf + + ExpiresActive On + ExpiresDefault now + Options +MultiViews + Require all granted + #NOTE: an index.html.var file is generated, which ought to make + # MultiViews redundant (by my reading) but it doesn't seem to + # work. Someone could look at that sometime. + + +# +# ExpiresActive On +# ExpiresDefault now +# +# +# ExpiresActive On +# ExpiresDefault now +# \ No newline at end of file diff --git a/roles/ajenti/handlers/main.yml b/roles/ajenti/handlers/main.yml new file mode 100644 index 000000000..2fb883440 --- /dev/null +++ b/roles/ajenti/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: restart ajenti service + service: name=ajenti + enabled=yes + state=restarted diff --git a/roles/ajenti/tasks/ajenti-wondershaper.yml b/roles/ajenti/tasks/ajenti-wondershaper.yml new file mode 100644 index 000000000..a57f09049 --- /dev/null +++ b/roles/ajenti/tasks/ajenti-wondershaper.yml @@ -0,0 +1,14 @@ +- name: download wondershaper ajenti plugin + pip: name="{{ xsce_download_url }}"/ajenti-plugin-wondershaper-0.3.tar.gz + extra_args="--download {{ pip_packages_dir }}" + when: not {{ use_cache }} and not {{ no_network }} + tags: + - download2 + + +- name: install wondershaper from local download directory + pip: name=ajenti-plugin-wondershaper + extra_args="--no-index --find-links=file://{{ pip_packages_dir }}" + +# notify: +# - restart ajenti service diff --git a/roles/ajenti/tasks/main.yml b/roles/ajenti/tasks/main.yml new file mode 100644 index 000000000..b38c04efc --- /dev/null +++ b/roles/ajenti/tasks/main.yml @@ -0,0 +1,79 @@ +- name: Install python-pip package + package: name=python-pip + state=present + tags: + - download + +- name: Install required libraries + package: name={{ item.pkg }} + state=present + with_items: + - pkg: python-imaging + - pkg: python-devel + - pkg: libxslt-devel + - pkg: pyOpenSSL + - pkg: python-daemon + - pkg: gcc + tags: + - download + +- name: download ajenti from our repo + pip: name="{{ xsce_download_url }}"/ajenti-0.99.34-patched5.tar.gz + extra_args="--download {{ pip_packages_dir }}" + when: not {{ use_cache }} and not {{ no_network }} + tags: + - download2 + +- name: install ajenti from local download directory + pip: name=ajenti + extra_args="--no-index --find-links=file://{{ pip_packages_dir }}" + +# notify: +# - restart ajenti service + +- name: download python-catcher + pip: name=python-catcher version=0.1.3 + extra_args="--download {{ pip_packages_dir }}" + when: not {{ use_cache }} and not {{ no_network }} + tags: + - download2 + +- name: install python-catcher from local download directory + pip: name=python-catcher + extra_args="--no-index --find-links=file://{{ pip_packages_dir }}/python-catcher" + +- name: change default port + lineinfile: backup=yes + dest=/etc/ajenti/config.json + state=present + backrefs=yes + regexp='"port":\s*[0-9]{1,5}' + line='"port":9990' + +- name: exe permission to ajenti + file: path=/etc/rc.d/init.d/ajenti + mode=0744 + state=file + +- include: ajenti-wondershaper.yml + when: 'xsce_lan_iface != ""' + +# handler doesn't fire +- name: restart ajenti service + service: name=ajenti + enabled=yes + state=restarted + when: ajenti_enabled + +- name: Add ajenti to service list + ini_file: dest='{{ service_filelist }}' + section=ajenti + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: name + value: ajenti + - option: description + value: "Ajenti is a client server systems administration tool controlled by a web browser" + - option: enabled + value: "{{ ajenti_enabled }}" diff --git a/roles/authserver/tasks/main.yml b/roles/authserver/tasks/main.yml new file mode 100644 index 000000000..769c86454 --- /dev/null +++ b/roles/authserver/tasks/main.yml @@ -0,0 +1,72 @@ +- name: check pip is installed + package: name=python-pip + state=present + tags: + - download + +- name: download xs-authserver from pypi + pip: name=xs-authserver + extra_args="--download {{ pip_packages_dir }}" + when: not {{ use_cache }} and not {{ no_network }} + tags: + - download2 + +- name: install xs-authserver from pypi + pip: name=xs-authserver + extra_args="--no-index --find-links=file://{{ pip_packages_dir }}" + +- name: install gunicorn + package: name=python-gunicorn + state=present + tags: + - download + +- name: Configure xs-authserver + template: backup=yes + src={{ item.src }} + dest={{ item.dest }} + owner=root + group=root + mode={{ item.mode }} + with_items: + - src: xs-authserver.env.j2 + dest: /etc/sysconfig/xs-authserver + mode: 0644 + - src: xs-authserver.service.j2 + dest: /etc/systemd/system/xs-authserver.service + mode: 0644 + +- name: create database folder + file: state=directory + path=/var/lib/xs-authserver/ + owner=root + group=root + mode=0644 + +- name: init database + command: xs-authserverctl initdb + ignore_errors: yes + environment: + XS_AUTHSERVER_DATABASE: /var/lib/xs-authserver/data.db + +- name: Enable xs-authserver service + service: name=xs-authserver + enabled=yes + when: authserver_enabled + +- name: add xs-authserver to service list + ini_file: dest='{{ service_filelist }}' + section=xs-authserver + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: name + value: XS-authserver + - option: description + value: '"xs-authserver implements a seamless web authentication service + using XO laptop registration capabilities. It is heavily inspired + by the Moodle OLPC-XS authentication plugin"' + - option: port + value: 5000 + - option: path + value: / diff --git a/roles/authserver/templates/xs-authserver.env.j2 b/roles/authserver/templates/xs-authserver.env.j2 new file mode 100644 index 000000000..40902055c --- /dev/null +++ b/roles/authserver/templates/xs-authserver.env.j2 @@ -0,0 +1,2 @@ +XS_AUTHSERVER_OLPC_XS_DB='/home/idmgr/identity.db' +XS_AUTHSERVER_DATABASE='/var/lib/xs-authserver/data.db' diff --git a/roles/authserver/templates/xs-authserver.service.j2 b/roles/authserver/templates/xs-authserver.service.j2 new file mode 100755 index 000000000..64cc1167b --- /dev/null +++ b/roles/authserver/templates/xs-authserver.service.j2 @@ -0,0 +1,10 @@ +[Unit] +Description=XS authentication server +After={{ apache_service }}.service local-fs.target + +[Service] +EnvironmentFile=-/etc/sysconfig/xs-authserver +ExecStart=/usr/bin/gunicorn -n xs-authserver xs_authserver:app -b 0.0.0.0:5000 + +[Install] +WantedBy=multi-user.target diff --git a/roles/awstats/defaults/main.yml b/roles/awstats/defaults/main.yml new file mode 100644 index 000000000..0fb92113a --- /dev/null +++ b/roles/awstats/defaults/main.yml @@ -0,0 +1,3 @@ +awstats_install: True +awstats_enabled: False +awstats_data_dir: /library/awstats/ diff --git a/roles/awstats/tasks/install.yml b/roles/awstats/tasks/install.yml new file mode 100644 index 000000000..71a353880 --- /dev/null +++ b/roles/awstats/tasks/install.yml @@ -0,0 +1,99 @@ +- name: Install awstats package + package: name={{ item }} + state=present + with_items: + - awstats + - pwauth + - openssl + tags: + - download + +- name: Install awstats package + package: name={{ item }} + state=present + with_items: + - libapache2-mod-authnz-external + - apache2-utils + when: is_debian + tags: + - download + +- name: enable cgi execution + command: a2enmod cgi + when: is_debian + +- name: Create directory for awstat to use as intermediate summary storage + file: path={{ item }} + mode=0750 + owner={{ apache_data }} + group={{ apache_data }} + state=directory + force=true + with_items: + - "{{ awstats_data_dir }}" + - "{{ apache_log_dir }}" + +- name: Install the Apache config for Advanced Web Statistics + template: src=apache.conf + dest=/etc/{{ apache_config_dir }}/awstats.conf + owner=root + group=root + mode=0644 + when: awstats_enabled and is_debian + +- name: Install the Apache config for Advanced Web Statistics + template: src=apache-awstats.conf + dest=/etc/{{ apache_config_dir }}/awstats.conf + owner=root + group=root + mode=0644 + when: awstats_enabled and not is_debian + +- name: make sure logrotate does not make logs unreadable + template: src=logrotate.d.apache2 + dest=/etc/logrotate.d/apache2 + when: is_debian + +- name: See if awstats package installed a config file + stat: path=/etc/awstats/awstats.conf + register: awstats + +- debug: var=awstats + +- name: If there was a config file installed by package, move it aside + command: mv /etc/awstats/awstats.conf /etc/awstats/awstats.conf.dist + when: awstats.stat.islnk is defined and not awstats.stat.islnk + +- name: Enable Awstats + file: src=/etc/apache2/sites-available/awstats.conf + path=/etc/apache2/sites-enabled/awstats.conf + state=link + when: awstats_enabled and is_debian + +- name: Disable Awstats + file: path=/etc/apache2/sites-enabled/awstats.conf + state=absent + when: not awstats_enabled and is_debian + +- name: Install the awstats config for Advanced Web Statistics + template: src=awstats.schoolserver.conf.j2 + dest=/etc/awstats/awstats.schoolserver.conf + owner=root + group=root + mode=0644 + when: awstats_enabled + +- name: Create a symbolic link to use when access is by ip address + file: src=/etc/awstats/awstats.schoolserver.conf + dest=/etc/awstats/awstats.conf + state=link + when: awstats_enabled + +- name: On first enabling of awstats, summarize httpd logs up to now + shell: /bin/perl /usr/share/awstats/wwwroot/cgi-bin/awstats.pl -config=schoolserver -update + when: awstats_enabled and not is_debian + +- name: On first enabling of awstats, summarize httpd logs up to now + shell: /usr/bin/perl /usr/lib/cgi-bin/awstats.pl -config=schoolserver -update + when: awstats_enabled and is_debian + diff --git a/roles/awstats/tasks/main.yml b/roles/awstats/tasks/main.yml new file mode 100644 index 000000000..b60e7367e --- /dev/null +++ b/roles/awstats/tasks/main.yml @@ -0,0 +1,17 @@ +- include: install.yml + when: awstats_install + +- name: Add awstats to service list + ini_file: dest='{{ service_filelist }}' + section=awstats + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: name + value: awstats + - option: description + value: '"Awstats is Advanced Web Statistics package written in perl which generates static or dynamic html summaries based upon web server logs"' + - option: installed + value: "{{ awstats_install }}" + - option: enabled + value: "{{ awstats_enabled }}" diff --git a/roles/awstats/templates/apache-awstats.conf b/roles/awstats/templates/apache-awstats.conf new file mode 100644 index 000000000..8d696f5e4 --- /dev/null +++ b/roles/awstats/templates/apache-awstats.conf @@ -0,0 +1,39 @@ +# +# Content of this file, with correct values, can be automatically added to +# your Apache server by using the AWStats configure.pl tool. +# + + +# If using Windows and Perl ActiveStat, this is to enable Perl script as CGI. +#ScriptInterpreterSource registry + + +# +# Directives to add to your Apache conf file to allow use of AWStats as a CGI. +# Note that path "/usr/share/awstats/" must reflect your AWStats install path. +# +Alias /awstatsclasses "/usr/share/awstats/wwwroot/classes/" +Alias /awstatscss "/usr/share/awstats/wwwroot/css/" +Alias /awstatsicons "/usr/share/awstats/wwwroot/icon/" +ScriptAlias /awstats/ "/usr/share/awstats/wwwroot/cgi-bin/" +ScriptAlias /awstats "/usr/share/awstats/wwwroot/" + + +# +# This is to permit URL access to scripts/files in AWStats directory. +# + + Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch + AllowOverride None + DirectoryIndex awstats.pl + AuthType Basic + AuthName "Admin Console" + AuthBasicProvider external + AuthExternal pwauth + require valid-user + +# Additional Perl modules + + SetEnv PERL5LIB /usr/share/awstats/lib:/usr/share/awstats/plugins + + diff --git a/roles/awstats/templates/apache.conf b/roles/awstats/templates/apache.conf new file mode 100644 index 000000000..113f04655 --- /dev/null +++ b/roles/awstats/templates/apache.conf @@ -0,0 +1,47 @@ +# This provides worldwide access to everything below the directory +# Security concerns: +# * Raw log processing data is accessible too for everyone +# * The directory is by default writable by the httpd daemon, so if +# any PHP, CGI or other script can be tricked into copying or +# symlinking stuff here, you have a looking glass into your server, +# and if stuff can be uploaded to here, you have a public warez site! +ScriptAlias /awstats /usr/lib/cgi-bin + + Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch + AllowOverride None + DirectoryIndex /cgi-bin/awstats.pl + require all granted + + +# This provides worldwide access to everything below the directory +# Security concerns: none known + + Options None + AllowOverride None + require all granted + + +# This provides worldwide access to everything below the directory +# Security concerns: none known + + Options FollowSymLinks + AllowOverride None + require all granted + + +# This provides worldwide access to everything in the directory +# Security concerns: none known +Alias /awstats-icon/ /usr/share/awstats/icon/ + +# This provides worldwide access to everything in the directory +# Security concerns: none known +Alias /awstatsclasses/ /usr/share/java/awstats/ + +# This (hopefully) enables _all_ CGI scripts in the default directory +# Security concerns: Are you sure _all_ CGI scripts are safe? +ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/ + + Options +ExecCGI + SetHandler cgi-script + require all granted + diff --git a/roles/awstats/templates/awstats.schoolserver.conf.j2 b/roles/awstats/templates/awstats.schoolserver.conf.j2 new file mode 100644 index 000000000..0f792f452 --- /dev/null +++ b/roles/awstats/templates/awstats.schoolserver.conf.j2 @@ -0,0 +1,1561 @@ +# AWSTATS CONFIGURE FILE 7.3 +#----------------------------------------------------------------------------- +# Copy this file into awstats.www.mydomain.conf and edit this new config file +# to setup AWStats (See documentation in docs/ directory). +# The config file must be in /etc/awstats, /usr/local/etc/awstats or /etc (for +# Unix/Linux) or same directory than awstats.pl (Windows, Mac, Unix/Linux...) +# To include an environment variable in any parameter (AWStats will replace +# it with its value when reading it), follow the example: +# Parameter="__ENVNAME__" +# Note that environment variable AWSTATS_CURRENT_CONFIG is always defined with +# the config value in an AWStats running session and can be used like others. +#----------------------------------------------------------------------------- + + + +#----------------------------------------------------------------------------- +# MAIN SETUP SECTION (Required to make AWStats work) +#----------------------------------------------------------------------------- + +# "LogFile" contains the web, ftp or mail server log file to analyze. +# Possible values: A full path, or a relative path from awstats.pl directory. +# Example: "/var/log/apache/access.log" +# Example: "../logs/mycombinedlog.log" +# You can also use tags in this filename if you need a dynamic file name +# depending on date or time (Replacement is made by AWStats at the beginning +# of its execution). This is available tags : +# %YYYY-n is replaced with 4 digits year we were n hours ago +# %YY-n is replaced with 2 digits year we were n hours ago +# %MM-n is replaced with 2 digits month we were n hours ago +# %MO-n is replaced with 3 letters month we were n hours ago +# %DD-n is replaced with day we were n hours ago +# %HH-n is replaced with hour we were n hours ago +# %NS-n is replaced with number of seconds at 00:00 since 1970 +# %WM-n is replaced with the week number in month (1-5) +# %Wm-n is replaced with the week number in month (0-4) +# %WY-n is replaced with the week number in year (01-52) +# %Wy-n is replaced with the week number in year (00-51) +# %DW-n is replaced with the day number in week (1-7, 1=sunday) +# use n=24 if you need (1-7, 1=monday) +# %Dw-n is replaced with the day number in week (0-6, 0=sunday) +# use n=24 if you need (0-6, 0=monday) +# Use 0 for n if you need current year, month, day, hour... +# Example: "/var/log/access_log.%YYYY-0%MM-0%DD-0.log" +# Example: "C:/WINNT/system32/LogFiles/W3SVC1/ex%YY-24%MM-24%DD-24.log" +# You can also use a pipe if log file come from a pipe : +# Example: "gzip -d outputpath/output.html"), enter +# path of icon directory relative to the output directory 'outputpath'. +# Example: "/awstatsicons" +# Example: "../icon" +# Default: "/icon" (means you must copy icon directories in "/mywwwroot/icon") +# +DirIcons="/awstatsicons" + + +# When this parameter is set to 1, AWStats adds a button on report page to +# allow to "update" statistics from a web browser. Warning, when "update" is +# made from a browser, AWStats is run as a CGI by the web server user defined +# in your web server (user "nobody" by default with Apache, "IUSR_XXX" with +# IIS), so the "DirData" directory and all already existing history files +# awstatsMMYYYY[.xxx].txt must be writable by this user. Change permissions if +# necessary to "Read/Write" (and "Modify" for Windows NTFS file systems). +# Warning: Update process can be long so you might experience "time out" +# browser errors if you don't launch AWStats frequently enough. +# When set to 0, update is only made when AWStats is run from the command +# line interface (or a task scheduler). +# Possible values: 0 or 1 +# Default: 0 +# +AllowToUpdateStatsFromBrowser=1 + + +# AWStats saves and sorts its database on a month basis (except if using +# databasebreak option from command line). +# However, if you choose the -month=all from command line or +# value '-Year-' from CGI combo form to have a report for all year, AWStats +# needs to reload all data for full year (each month), and sort them, +# requiring a large amount of time, memory and CPU. This might be a problem +# for web hosting providers that offer AWStats for large sites, on shared +# servers, to non CPU cautious customers. +# For this reason, the 'full year' is only enabled on Command Line by default. +# You can change this by setting this parameter to 0, 1, 2 or 3. +# Possible values: +# 0 - Never allowed +# 1 - Allowed on CLI only, -Year- value in combo is not visible +# 2 - Allowed on CLI only, -Year- value in combo is visible but not allowed +# 3 - Possible on CLI and CGI +# Default: 2 +# +AllowFullYearView=2 + + + +#----------------------------------------------------------------------------- +# OPTIONAL SETUP SECTION (Not required but increase AWStats features) +#----------------------------------------------------------------------------- + +# When the update process runs, AWStats can set a lock file in TEMP or TMP +# directory. This lock is to avoid to have 2 update processes running at the +# same time to prevent unknown conflicts problems and avoid DoS attacks when +# AllowToUpdateStatsFromBrowser is set to 1. +# Because, when you use lock file, you can experience sometimes problems in +# lock file not correctly removed (killed process for example requires that +# you remove the file manualy), this option is not enabled by default (Do +# not enable this option with no console server access). +# Change : Effective immediatly +# Possible values: 0 or 1 +# Default: 0 +# +EnableLockForUpdate=1 + + +# AWStats can do reverse DNS lookups through a static DNS cache file that was +# previously created manually. If no path is given in static DNS cache file +# name, AWStats will search DirData directory. This file is never changed. +# This option is not used if DNSLookup=0. +# Note: DNS cache file format is 'minsince1970 ipaddress resolved_hostname' +# or just 'ipaddress resolved_hostname' +# Change : Effective for new updates only +# Example: "/mydnscachedir/dnscache" +# Default: "dnscache.txt" +# +DNSStaticCacheFile="dnscache.txt" + + +# AWStats can do reverse DNS lookups through a DNS cache file that was created +# by a previous run of AWStats. This file is erased and recreated after each +# statistics update process. You don't need to create and/or edit it. +# AWStats will read and save this file in DirData directory. +# This option is used only if DNSLookup=1. +# Note: If a DNSStaticCacheFile is available, AWStats will check for DNS +# lookup in DNSLastUpdateCacheFile after checking into DNSStaticCacheFile. +# Change : Effective for new updates only +# Example: "/mydnscachedir/dnscachelastupdate" +# Default: "dnscachelastupdate.txt" +# +DNSLastUpdateCacheFile="dnscachelastupdate.txt" + + +# You can specify specific IP addresses that should NOT be looked up in DNS. +# This option is used only if DNSLookup=1. +# Note: Use space between each value. +# Note: You can use regular expression values writing value with REGEX[value]. +# Change : Effective for new updates only +# Example: "123.123.123.123 REGEX[^192\.168\.]" +# Default: "" +# +SkipDNSLookupFor="" + + +# The following two parameters allow you to protect a config file from being +# read by AWStats when called from a browser if web user has not been +# authenticated. Your AWStats program must be in a web protected "realm" (With +# Apache, you can use .htaccess files to do so. With other web servers, see +# your server setup manual). +# Change : Effective immediatly +# Possible values: 0 or 1 +# Default: 0 +# +AllowAccessFromWebToAuthenticatedUsersOnly=0 + + +# This parameter gives the list of all authorized authenticated users to view +# statistics for this domain/config file. This parameter is used only if +# AllowAccessFromWebToAuthenticatedUsersOnly is set to 1. +# Change : Effective immediatly +# Example: "user1 user2" +# Example: "__REMOTE_USER__" +# Default: "" +# +AllowAccessFromWebToFollowingAuthenticatedUsers="" + + +# When this parameter is defined to something, the IP address of the user that +# reads its statistics from a browser (when AWStats is used as a CGI) is +# checked and must match one of the IP address values or ranges. +# Change : Effective immediatly +# Example: "127.0.0.1 123.123.123.1-123.123.123.255" +# Default: "" +# +AllowAccessFromWebToFollowingIPAddresses="" + + +# If the "DirData" directory (see above) does not exist, AWStats return an +# error. However, you can ask AWStats to create it. +# This option can be used by some Web Hosting Providers that has defined a +# dynamic value for DirData (for example DirData="/home/__REMOTE_USER__") and +# don't want to have to create a new directory each time they add a new user. +# Change : Effective immediatly +# Possible values: 0 or 1 +# Default: 0 +# +CreateDirDataIfNotExists=0 + + +# You can choose in which format the Awstats history database is saved. +# Note: Using "xml" format make AWStats building database files three times +# larger than using "text" format. +# Change : Database format is switched after next update +# Possible values: text or xml +# Default: text +# +BuildHistoryFormat=text + + +# If you prefer having the report output pages be built as XML compliant pages +# instead of simple HTML pages, you can set this to 'xhtml' (May not work +# properly with old browsers). +# Change : Effective immediatly +# Possible values: html or xhtml +# Default: html +# +BuildReportFormat=html + + +# AWStats databases can be updated from command line of from a browser (when +# used as a cgi program). So AWStats database files need write permission +# for both command line user and default web server user (nobody for Unix, +# IUSR_xxx for IIS/Windows,...). +# To avoid permission problems between update process (run by an admin user) +# and CGI process (ran by a low level user), AWStats can save its database +# files with read and write permissions for everyone. +# By default, AWStats keeps default user permissions on updated files. If you +# set AllowToUpdateStatsFromBrowser to 1, you can change this parameter to 1. +# Change : Effective for new updates only +# Possible values: 0 or 1 +# Default: 0 +# +SaveDatabaseFilesWithPermissionsForEveryone=0 + + +# AWStats can purge log file, after analyzing it. Note that AWStats is able +# to detect new lines in a log file, to process only them, so you can launch +# AWStats as often as you want, even with this parameter to 0. +# With 0, no purge is made, so you must use a scheduled task or a web server +# that make this purge frequently. +# With 1, the purge of the log file is made each time AWStats update is run. +# This parameter doesn't work with IIS (This web server doesn't let its log +# file to be purged). +# Change : Effective for new updates only +# Possible values: 0 or 1 +# Default: 0 +# +PurgeLogFile=0 + + +# When PurgeLogFile is setup to 1, AWStats will clean your log file after +# processing it. You can however keep an archive file of all processed log +# records by setting this parameter (For example if you want to use another +# log analyzer). The archived log file is saved in "DirData" with name +# awstats_archive.configname[.suffix].log +# This parameter is not used if PurgeLogFile=0 +# Change : Effective for new updates only +# Possible values: 0, 1, or tags (See LogFile parameter) for suffix +# Example: 1 +# Example: %YYYY%MM%DD +# Default: 0 +# +ArchiveLogRecords=0 + + +# Each time you run the update process, AWStats overwrites the 'historic file' +# for the month (awstatsMMYYYY[.*].txt) with the updated one. +# When write errors occurs (IO, disk full,...), this historic file can be +# corrupted and must be deleted. Because this file contains information of all +# past processed log files, you will loose old stats if removed. So you can +# ask AWStats to save last non corrupted file in a .bak file. This file is +# stored in "DirData" directory with other 'historic files'. +# Change : Effective for new updates only +# Possible values: 0 or 1 +# Default: 0 +# +KeepBackupOfHistoricFiles=0 + + +# Default index page name for your web server. +# Change : Effective for new updates only +# Example: "index.php index.html default.html" +# Default: "index.php index.html" +# +DefaultFile="index.php index.html" + + +# Do not include access from clients that match following criteria. +# If your log file contains IP addresses in host field, you must enter here +# matching IP addresses criteria. +# If DNS lookup is already done in your log file, you must enter here hostname +# criteria, else enter ip address criteria. +# The opposite parameter of "SkipHosts" is "OnlyHosts". +# Note: Use space between each value. This parameter is not case sensitive. +# Note: You can use regular expression values writing value with REGEX[value]. +# Change : Effective for new updates only +# Example: "127.0.0.1 REGEX[^192\.168\.] REGEX[^10\.]" +# Example: "localhost REGEX[^.*\.localdomain$]" +# Default: "" +# +SkipHosts="127.0.0.1" + + +# Do not include access from clients with a user agent that match following +# criteria. If you want to exclude a robot, you should update the robots.pm +# file instead of this parameter. +# The opposite parameter of "SkipUserAgents" is "OnlyUserAgents". +# Note: Use space between each value. This parameter is not case sensitive. +# Note: You can use regular expression values writing value with REGEX[value]. +# Change : Effective for new updates only +# Example: "konqueror REGEX[ua_test_v\d\.\d]" +# Default: "" +# +SkipUserAgents="" + + +# Use SkipFiles to ignore access to URLs that match one of following entries. +# You can enter a list of not important URLs (like framed menus, hidden pages, +# etc...) to exclude them from statistics. You must enter here exact relative +# URL as found in log file, or a matching REGEX value. Check apply on URL with +# all its query paramaters. +# For example, to ignore /badpage.php, just add "/badpage.php". To ignore all +# pages in a particular directory, add "REGEX[^\/directorytoexclude]". +# The opposite parameter of "SkipFiles" is "OnlyFiles". +# Note: Use space between each value. This parameter is or not case sensitive +# depending on URLNotCaseSensitive parameter. +# Note: You can use regular expression values writing value with REGEX[value]. +# Change : Effective for new updates only +# Example: "/badpage.php /page.php?param=x REGEX[^\/excludedirectory]" +# Default: "" +# +SkipFiles="" + + +# Use SkipReferrersBlackList if you want to exclude records coming from a SPAM +# referrer. Parameter must receive a local file name containing rules applied +# on referrer field. If parameter is empty, no filter is applied. +# An example of such a file is available in lib/blacklist.txt +# Change : Effective for new updates only +# Example: "/mylibpath/blacklist.txt" +# Default: "" +# +# WARNING!! Using this feature make AWStats running very slower (5 times slower +# with black list file provided with AWStats ! +# +SkipReferrersBlackList="" + + +# Include in stats, only accesses from hosts that match one of following +# entries. For example, if you want AWStats to filter access to keep only +# stats for visits from particular hosts, you can add those host names in +# this parameter. +# If DNS lookup is already done in your log file, you must enter here hostname +# criteria, else enter ip address criteria. +# The opposite parameter of "OnlyHosts" is "SkipHosts". +# Note: Use space between each value. This parameter is not case sensitive. +# Note: You can use regular expression values writing value with REGEX[value]. +# Change : Effective for new updates only +# Example: "127.0.0.1 REGEX[^192\.168\.] REGEX[^10\.]" +# Default: "" +# +OnlyHosts="" + + +# Include in stats, only accesses from user agent that match one of following +# entries. For example, if you want AWStats to filter access to keep only +# stats for visits from particular browsers, you can add their user agents +# string in this parameter. +# The opposite parameter of "OnlyUserAgents" is "SkipUserAgents". +# Note: Use space between each value. This parameter is not case sensitive. +# Note: You can use regular expression values writing value with REGEX[value]. +# Change : Effective for new updates only +# Example: "msie" +# Default: "" +# +OnlyUserAgents="" + + +# Include in stats, only accesses from authenticated users that match one of +# following entries. For example, if you want AWStats to filter access to keep +# only stats for authenticated users, you can add those users names in +# this parameter. Useful for statistics for per user ftp logs. +# Note: Use space between each value. This parameter is not case sensitive. +# Note: You can use regular expression values writing value with REGEX[value]. +# Change : Effective for new updates only +# Example: "john bob REGEX[^testusers]" +# Default: "" +# +OnlyUsers="" + + +# Include in stats, only accesses to URLs that match one of following entries. +# For example, if you want AWStats to filter access to keep only stats that +# match a particular string, like a particular directory, you can add this +# directory name in this parameter. +# The opposite parameter of "OnlyFiles" is "SkipFiles". +# Note: Use space between each value. This parameter is or not case sensitive +# depending on URLNotCaseSensitive parameter. +# Note: You can use regular expression values writing value with REGEX[value]. +# Change : Effective for new updates only +# Example: "REGEX[marketing_directory] REGEX[office\/.*\.(csv|sxw)$]" +# Default: "" +# +OnlyFiles="" + + +# Add here a list of kind of url (file extension) that must be counted as +# "Hit only" and not as a "Hit" and "Page/Download". You can set here all +# image extensions as they are hit downloaded that must be counted but they +# are not viewed pages. URLs with such extensions are not included in the TOP +# Pages/URL report. +# Note: If you want to exclude particular URLs from stats (No Pages and no +# Hits reported), you must use SkipFiles parameter. +# Change : Effective for new updates only +# Example: "css js class gif jpg jpeg png bmp ico rss xml swf zip arj rar gz z bz2 wav mp3 wma mpg avi" +# Example: "" +# Default: "css js class gif jpg jpeg png bmp ico rss xml swf" +# +NotPageList="css js class gif jpg jpeg png bmp ico rss xml swf" + + +# By default, AWStats considers that records found in web log file are +# successful hits if HTTP code returned by server is a valid HTTP code (200 +# and 304). Any other code are reported in HTTP status chart. +# Note that HTTP 'control codes', like redirection (302, 305) are not added by +# default in this list as they are not pages seen by a visitor but are +# protocol exchange codes to tell the browser to ask another page. Because +# this other page will be counted and seen with a 200 or 304 code, if you +# add such codes, you will have 2 pages viewed reported for only one in facts. +# Change : Effective for new updates only +# Example: "200 304 302 305" +# Default: "200 304" +# +ValidHTTPCodes="200 304" + + +# By default, AWStats considers that records found in mail log file are +# successful mail transfers if field that represent return code in analyzed +# log file match values defined by this parameter. +# Change : Effective for new updates only +# Example: "1 250 200" +# Default: "1 250" +# +ValidSMTPCodes="1 250" + + +# Some web servers on some Operating systems (IIS-Windows) consider that a +# login with same value but different case are the same login. To tell AWStats +# to also consider them as one, set this parameter to 1. +# Change : Effective for new updates only +# Possible values: 0 or 1 +# Default: 0 +# +AuthenticatedUsersNotCaseSensitive=0 + + +# Some web servers on some Operating systems (IIS-Windows) considers that two +# URLs with same value but different case are the same URL. To tell AWStats to +# also considers them as one, set this parameter to 1. +# Change : Effective for new updates only +# Possible values: 0 or 1 +# Default: 0 +# +URLNotCaseSensitive=0 + + +# Keep or remove the anchor string you can find in some URLs. +# Change : Effective for new updates only +# Possible values: 0 or 1 +# Default: 0 +# +URLWithAnchor=0 + + +# In URL links, "?" char is used to add parameter's list in URLs. Syntax is: +# /mypage.html?param1=value1¶m2=value2 +# However, some servers/sites use also other chars to isolate dynamic part of +# their URLs. You can complete this list with all such characters. +# Change : Effective for new updates only +# Example: "?;," +# Default: "?;" +# +URLQuerySeparators="?;" + + +# Keep or remove the query string to the URL in the statistics for individual +# pages. This is primarily used to differentiate between the URLs of dynamic +# pages. If set to 1, mypage.html?id=x and mypage.html?id=y are counted as two +# different pages. +# Warning, when set to 1, memory required to run AWStats is dramatically +# increased if you have a lot of changing URLs (for example URLs with a random +# id inside). Such web sites should not set this option to 1 or use seriously +# the next parameter URLWithQueryWithOnlyFollowingParameters (or eventually +# URLWithQueryWithoutFollowingParameters). +# Change : Effective for new updates only +# Possible values: +# 0 - URLs are cleaned from the query string (ie: "/mypage.html") +# 1 - Full URL with query string is used (ie: "/mypage.html?p=x&q=y") +# Default: 0 +# +URLWithQuery=0 + + +# When URLWithQuery is on, you will get the full URL with all parameters in +# URL reports. But among thoose parameters, sometimes you don't need a +# particular parameter because it does not identify the page or because it's +# a random ID changing for each access even if URL points to same page. In +# such cases, it is higly recommanded to ask AWStats to keep only parameters +# you need (if you know them) before counting, manipulating and storing URL. +# Enter here list of wanted parameters. For example, with "param", one hit on +# /mypage.cgi?param=abc&id=Yo4UomP9d and /mypage.cgi?param=abc&id=Mu8fdxl3r +# will be reported as 2 hits on /mypage.cgi?param=abc +# This parameter is not used when URLWithQuery is 0 and can't be used with +# URLWithQueryWithoutFollowingParameters. +# Change : Effective for new updates only +# Example: "param" +# Default: "" +# +URLWithQueryWithOnlyFollowingParameters="" + + +# When URLWithQuery is on, you will get the full URL with all parameters in +# URL reports. But among thoose parameters, sometimes you don't need a +# particular parameter because it does not identify the page or because it's +# a random ID changing for each access even if URL points to same page. In +# such cases, it is higly recommanded to ask AWStats to remove such parameters +# from the URL before counting, manipulating and storing URL. Enter here list +# of all non wanted parameters. For example if you enter "id", one hit on +# /mypage.cgi?param=abc&id=Yo4UomP9d and /mypage.cgi?param=abc&id=Mu8fdxl3r +# will be reported as 2 hits on /mypage.cgi?param=abc +# This parameter is not used when URLWithQuery is 0 and can't be used with +# URLWithQueryWithOnlyFollowingParameters. +# Change : Effective for new updates only +# Example: "PHPSESSID jsessionid" +# Default: "" +# +URLWithQueryWithoutFollowingParameters="" + + +# Keep or remove the query string to the referrer URL in the statistics for +# external referrer pages. This is used to differentiate between the URLs of +# dynamic referrer pages. If set to 1, mypage.html?id=x and mypage.html?id=y +# are counted as two different referrer pages. +# Change : Effective for new updates only +# Possible values: +# 0 - Referrer URLs are cleaned from the query string (ie: "/mypage.html") +# 1 - Full URL with query string is used (ie: "/mypage.html?p=x&q=y") +# Default: 0 +# +URLReferrerWithQuery=0 + + +# AWStats can detect setup problems or show you important informations to have +# a better use. Keep this to 1, except if AWStats says you can change it. +# Change : Effective immediatly +# Possible values: 0 or 1 +# Default: 1 +# +WarningMessages=1 + + +# When an error occurs, AWStats outputs a message related to errors. If you +# want (in most cases for security reasons) to have no error messages, you +# can set this parameter to your personalized generic message. +# Change : Effective immediatly +# Example: "An error occurred. Contact your Administrator" +# Default: "" +# +ErrorMessages="" + + +# AWStat can be run with debug=x parameter to output various informations +# to help in debugging or solving troubles. If you want to allow this (not +# enabled by default for security reasons), set this parameter to 0. +# Change : Effective immediatly +# Possible values: 0 or 1 +# Default: 0 +# +DebugMessages=0 + + +# To help you to detect if your log format is good, AWStats reports an error +# if all the first NbOfLinesForCorruptedLog lines have a format that does not +# match the LogFormat parameter. +# However, some worm virus attack on your web server can result in a very high +# number of corrupted lines in your log. So if you experience awstats stop +# because of bad virus records at the beginning of your log file, you can +# increase this parameter (very rare). +# Change : Effective for new updates only +# Default: 50 +# +NbOfLinesForCorruptedLog=50 + + +# For some particular integration needs, you may want to have CGI links to +# point to another script than awstats.pl. +# Use the name of this script in WrapperScript parameter. +# Change : Effective immediatly +# Example: "awstatslauncher.pl" +# Example: "awstatswrapper.cgi?key=123" +# Default: "" +# +WrapperScript="" + + +# DecodeUA must be set to 1 if you use Roxen web server. This server converts +# all spaces in user agent field into %20. This make the AWStats robots, OS +# and browsers detection fail in some cases. Just change it to 1 if and only +# if your web server is Roxen. +# Change : Effective for new updates only +# Possible values: 0 or 1 +# Default: 0 +# +DecodeUA=0 + + +# MiscTrackerUrl can be used to make AWStats able to detect some miscellaneous +# things, that can not be tracked on other way, like: +# - Javascript disabled +# - Java enabled +# - Screen size +# - Color depth +# - Macromedia Director plugin +# - Macromedia Shockwave plugin +# - Realplayer G2 plugin +# - QuickTime plugin +# - Mediaplayer plugin +# - Acrobat PDF plugin +# To enable all these features, you must copy the awstats_misc_tracker.js file +# into a /js/ directory stored in your web document root and add the following +# HTML code at the end of your index page (but before ) : +# +# +# +# +# If code is not added in index page, all those detection capabilities will be +# disabled. You must also check that ShowScreenSizeStats and ShowMiscStats +# parameters are set to 1 to make results appear in AWStats report page. +# If you want to use another directory than /js/, you must also change the +# awstatsmisctrackerurl variable into the awstats_misc_tracker.js file. +# Change : Effective for new updates only. +# Possible value: URL of javascript tracker file added in your HTML code. +# Default: "/js/awstats_misc_tracker.js" +# +MiscTrackerUrl="/js/awstats_misc_tracker.js" + + +# AddLinkToExternalCGIWrapper can be used to add a link to a wrapper script +# into each title of Dolibarr reports. This can be used to add a wrapper +# to download data into a CSV file for example. +# +# AddLinkToExternalCGIWrapper="/awstats/awdownloadcsv.pl" + + + +#----------------------------------------------------------------------------- +# OPTIONAL ACCURACY SETUP SECTION (Not required but increase AWStats features) +#----------------------------------------------------------------------------- + +# The following values allow you to define accuracy of AWStats entities +# (robots, browsers, os, referers, file types) detection. +# It might be a good idea for large web sites or ISP that provides AWStats to +# high number of customers, to set this parameter to 1 (or 0), instead of 2. +# Possible values: +# 0 = No detection, +# 1 = Medium/Standard detection +# 2 = Full detection +# Change : Effective for new updates only +# Note : LevelForBrowsersDetection can also accept value "allphones". This +# enable detailed detection of phone/pda browsers. +# Default: 2 (0 for LevelForWormsDetection) +# +LevelForBrowsersDetection=2 # 0 disables Browsers detection. + # 2 reduces AWStats speed by 2% + # allphones reduces AWStats speed by 5% +LevelForOSDetection=2 # 0 disables OS detection. + # 2 reduces AWStats speed by 3% +LevelForRefererAnalyze=2 # 0 disables Origin detection. + # 2 reduces AWStats speed by 14% +LevelForRobotsDetection=2 # 0 disables Robots detection. + # 2 reduces AWStats speed by 2.5% +LevelForSearchEnginesDetection=2 # 0 disables Search engines detection. + # 2 reduces AWStats speed by 9% +LevelForKeywordsDetection=2 # 0 disables Keyphrases/Keywords detection. + # 2 reduces AWStats speed by 1% +LevelForFileTypesDetection=2 # 0 disables File types detection. + # 2 reduces AWStats speed by 1% +LevelForWormsDetection=0 # 0 disables Worms detection. + # 2 reduces AWStats speed by 15% + + + +#----------------------------------------------------------------------------- +# OPTIONAL APPEARANCE SETUP SECTION (Not required but increase AWStats features) +#----------------------------------------------------------------------------- + +# When you use AWStats as a CGI, you can have the reports shown in HTML frames. +# Frames are only available for report viewed dynamically. When you build +# pages from command line, this option is not used and no frames are built. +# Possible values: 0 or 1 +# Default: 1 +# +UseFramesWhenCGI=1 + + +# This parameter asks your browser to open detailed reports into a different +# window than the main page. +# Possible values: +# 0 - Open all in same browser window +# 1 - Open detailed reports in another window except if using frames +# 2 - Open always in a different window even if reports are framed +# Default: 1 +# +DetailedReportsOnNewWindows=1 + + +# You can add, in the HTML report page, a cache lifetime (in seconds) that +# will be returned to the browser in HTTP header answer by server. +# This parameter is not used when reports are built with -staticlinks option. +# Example: 3600 +# Default: 0 +# +Expires=3600 + + +# To avoid too large web pages, you can ask AWStats to limit number of rows of +# all reported charts to this number when no other limits apply. +# Default: 1000 +# +MaxRowsInHTMLOutput=1000 + + +# Set your primary language (ISO-639-1 language codes). +# Possible values: +# Albanian=al, Bosnian=ba, Bulgarian=bg, Catalan=ca, +# Chinese (Taiwan)=tw, Chinese (Simpliefied)=cn, Croatian=hr, Czech=cz, +# Danish=dk, Dutch=nl, English=en, Estonian=et, Euskara=eu, Finnish=fi, +# French=fr, Galician=gl, German=de, Greek=gr, Hebrew=he, Hungarian=hu, +# Icelandic=is, Indonesian=id, Italian=it, Japanese=jp, Korean=ko, +# Latvian=lv, Norwegian (Nynorsk)=nn, Norwegian (Bokmal)=nb, Polish=pl, +# Portuguese=pt, Portuguese (Brazilian)=br, Romanian=ro, Russian=ru, +# Serbian=sr, Slovak=sk, Slovenian=si, Spanish=es, Swedish=se, Turkish=tr, +# Ukrainian=ua, Welsh=cy. +# First available language accepted by browser=auto +# Default: "auto" +# +Lang="auto" + + +# Set the location of language files. +# Example: "/usr/share/awstats/lang" +# Default: "./lang" (means lang directory is in same location than awstats.pl) +# +DirLang="./lang" + + +# Show menu header with reports' links +# Possible values: 0 or 1 +# Default: 1 +# +ShowMenu=1 + + +# You choose here which reports you want to see in the main page and what you +# want to see in those reports. +# Possible values: +# 0 - Report is not shown at all +# 1 - Report is shown in main page with an entry in menu and default columns +# XYZ - Report shows column informations defined by code X,Y,Z... +# X,Y,Z... are code letters among the following: +# U = Unique visitors +# V = Visits +# P = Number of pages +# H = Number of hits (or mails) +# B = Bandwith (or total mail size for mail logs) +# L = Last access date +# E = Entry pages +# X = Exit pages +# C = Web compression (mod_gzip,mod_deflate) +# M = Average mail size (mail logs) +# + +# Show monthly summary +# Context: Web, Streaming, Mail, Ftp +# Default: UVPHB, Possible column codes: UVPHB +ShowSummary=UVPHB + +# Show monthly chart +# Context: Web, Streaming, Mail, Ftp +# Default: UVPHB, Possible column codes: UVPHB +ShowMonthStats=UVPHB + +# Show days of month chart +# Context: Web, Streaming, Mail, Ftp +# Default: VPHB, Possible column codes: VPHB +ShowDaysOfMonthStats=VPHB + +# Show days of week chart +# Context: Web, Streaming, Mail, Ftp +# Default: PHB, Possible column codes: PHB +ShowDaysOfWeekStats=PHB + +# Show hourly chart +# Context: Web, Streaming, Mail, Ftp +# Default: PHB, Possible column codes: PHB +ShowHoursStats=PHB + +# Show domains/country chart +# Context: Web, Streaming, Mail, Ftp +# Default: PHB, Possible column codes: UVPHB +ShowDomainsStats=PHB + +# Show hosts chart +# Context: Web, Streaming, Mail, Ftp +# Default: PHBL, Possible column codes: PHBL +ShowHostsStats=PHBL + +# Show authenticated users chart +# Context: Web, Streaming, Ftp +# Default: 0, Possible column codes: PHBL +ShowAuthenticatedUsers=0 + +# Show robots chart +# Context: Web, Streaming +# Default: HBL, Possible column codes: HBL +ShowRobotsStats=HBL + +# Show worms chart +# Context: Web, Streaming +# Default: 0 (If set to other than 0, see also LevelForWormsDetection), Possible column codes: HBL +ShowWormsStats=0 + +# Show email senders chart (For use when analyzing mail log files) +# Context: Mail +# Default: 0, Possible column codes: HBML +ShowEMailSenders=0 + +# Show email receivers chart (For use when analyzing mail log files) +# Context: Mail +# Default: 0, Possible column codes: HBML +ShowEMailReceivers=0 + +# Show session chart +# Context: Web, Streaming, Ftp +# Default: 1, Possible column codes: None +ShowSessionsStats=1 + +# Show pages-url chart. +# Context: Web, Streaming, Ftp +# Default: PBEX, Possible column codes: PBEX +ShowPagesStats=PBEX + +# Show file types chart. +# Context: Web, Streaming, Ftp +# Default: HB, Possible column codes: HBC +ShowFileTypesStats=HB + +# Show file size chart (Not yet available) +# Context: Web, Streaming, Mail, Ftp +# Default: 1, Possible column codes: None +ShowFileSizesStats=0 + +# Show downloads chart. +# Context: Web, Streaming, Ftp +# Default: HB, Possible column codes: HB +ShowDownloadsStats=HB + +# Show operating systems chart +# Context: Web, Streaming, Ftp +# Default: 1, Possible column codes: None +ShowOSStats=1 + +# Show browsers chart +# Context: Web, Streaming +# Default: 1, Possible column codes: None +ShowBrowsersStats=1 + +# Show screen size chart +# Context: Web, Streaming +# Default: 0 (If set to 1, see also MiscTrackerUrl), Possible column codes: None +ShowScreenSizeStats=0 + +# Show origin chart +# Context: Web, Streaming +# Default: PH, Possible column codes: PH +ShowOriginStats=PH + +# Show keyphrases chart +# Context: Web, Streaming +# Default: 1, Possible column codes: None +ShowKeyphrasesStats=1 + +# Show keywords chart +# Context: Web, Streaming +# Default: 1, Possible column codes: None +ShowKeywordsStats=1 + +# Show misc chart +# Context: Web, Streaming +# Default: a (See also MiscTrackerUrl parameter), Possible column codes: anjdfrqwp +ShowMiscStats=a + +# Show http errors chart +# Context: Web, Streaming +# Default: 1, Possible column codes: None +ShowHTTPErrorsStats=1 + +# Show smtp errors chart (For use when analyzing mail log files) +# Context: Mail +# Default: 0, Possible column codes: None +ShowSMTPErrorsStats=0 + +# Show the cluster report (Your LogFormat must contains the %cluster tag) +# Context: Web, Streaming, Ftp +# Default: 0, Possible column codes: PHB +ShowClusterStats=0 + + +# Some graphical reports are followed by the data array of values. +# If you don't want this array (to reduce the report size for example), you +# can set thoose options to 0. +# Possible values: 0 or 1 +# Default: 1 +# +# Data array values for the ShowMonthStats report +AddDataArrayMonthStats=1 +# Data array values for the ShowDaysOfMonthStats report +AddDataArrayShowDaysOfMonthStats=1 +# Data array values for the ShowDaysOfWeekStats report +AddDataArrayShowDaysOfWeekStats=1 +# Data array values for the ShowHoursStats report +AddDataArrayShowHoursStats=1 + + +# In the Origin chart, you have stats on where your hits came from. You can +# include hits on pages that come from pages of same sites in this chart. +# Possible values: 0 or 1 +# Default: 0 +# +IncludeInternalLinksInOriginSection=0 + + +# The following parameters can be used to choose the maximum number of lines +# shown for the particular following reports. +# +# Stats by countries/domains +MaxNbOfDomain = 10 +MinHitDomain = 1 +# Stats by hosts +MaxNbOfHostsShown = 10 +MinHitHost = 1 +# Stats by authenticated users +MaxNbOfLoginShown = 10 +MinHitLogin = 1 +# Stats by robots +MaxNbOfRobotShown = 10 +MinHitRobot = 1 +# Stats for Downloads +MaxNbOfDownloadsShown = 10 +MinHitDownloads = 1 +# Stats by pages +MaxNbOfPageShown = 10 +MinHitFile = 1 +# Stats by OS +MaxNbOfOsShown = 10 +MinHitOs = 1 +# Stats by browsers +MaxNbOfBrowsersShown = 10 +MinHitBrowser = 1 +# Stats by screen size +MaxNbOfScreenSizesShown = 5 +MinHitScreenSize = 1 +# Stats by window size (following 2 parameters are not yet used) +MaxNbOfWindowSizesShown = 5 +MinHitWindowSize = 1 +# Stats by referers +MaxNbOfRefererShown = 10 +MinHitRefer = 1 +# Stats for keyphrases +MaxNbOfKeyphrasesShown = 10 +MinHitKeyphrase = 1 +# Stats for keywords +MaxNbOfKeywordsShown = 10 +MinHitKeyword = 1 +# Stats for sender or receiver emails +MaxNbOfEMailsShown = 20 +MinHitEMail = 1 + + +# Choose if you want the week report to start on sunday or monday +# Possible values: +# 0 - Week starts on sunday +# 1 - Week starts on monday +# Default: 1 +# +FirstDayOfWeek=1 + + +# List of visible flags that link to other language translations. +# See Lang parameter for list of allowed flag/language codes. +# If you don't want any flag link, set ShowFlagLinks to "". +# This parameter is used only if ShowMenu parameter is set to 1. +# Possible values: "" or "language_codes_separated_by_space" +# Example: "en es fr nl de" +# Default: "" +# +ShowFlagLinks="" + + +# Each URL, shown in stats report views, are links you can click. +# Possible values: 0 or 1 +# Default: 1 +# +ShowLinksOnUrl=1 + + +# When AWStats builds HTML links in its report pages, it starts those links +# with "http://". However some links might be HTTPS links, so you can enter +# here the root of all your HTTPS links. If all your site is a SSL web site, +# just enter "/". +# This parameter is not used if ShowLinksOnUrl is 0. +# Example: "/shopping" +# Example: "/" +# Default: "" +# +UseHTTPSLinkForUrl="" + + +# Maximum length of URL part shown on stats page (number of characters). +# This affects only URL visible text, links still work. +# Default: 64 +# +MaxLengthOfShownURL=64 + + +# You can enter HTML code that will be added at the top of AWStats reports. +# Default: "" +# +HTMLHeadSection="" + + +# You can enter HTML code that will be added at the end of AWStats reports. +# Great to add advert ban. +# Default: "" +# +HTMLEndSection="" + + +# By default AWStats page contains meta tag robots=noindex,nofollow +# If you want to have your statistics to be indexed, set this option to 1. +# Default: 0 +# +MetaRobot=0 + + +# You can set Logo and LogoLink to use your own logo. +# Logo must be the name of image file (must be in $DirIcons/other directory). +# LogoLink is the expected URL when clicking on Logo. +# Default: "awstats_logo6.png" +# +Logo="awstats_logo6.png" +LogoLink="http://www.awstats.org" + + +# Value of maximum bar width/height for horizontal/vertical HTML graphics bars. +# Default: 260/90 +# +BarWidth = 260 +BarHeight = 90 + + +# You can ask AWStats to use a particular CSS (Cascading Style Sheet) to +# change its look. To create a style sheet, you can use samples provided with +# AWStats in wwwroot/css directory. +# Example: "/awstatscss/awstats_bw.css" +# Example: "/css/awstats_bw.css" +# Default: "" +# +StyleSheet="" + + +# Those color parameters can be used (if StyleSheet parameter is not used) +# to change AWStats look. +# Example: color_name="RRGGBB" # RRGGBB is Red Green Blue components in Hex +# +color_Background="FFFFFF" # Background color for main page (Default = "FFFFFF") +color_TableBGTitle="CCCCDD" # Background color for table title (Default = "CCCCDD") +color_TableTitle="000000" # Table title font color (Default = "000000") +color_TableBG="CCCCDD" # Background color for table (Default = "CCCCDD") +color_TableRowTitle="FFFFFF" # Table row title font color (Default = "FFFFFF") +color_TableBGRowTitle="ECECEC" # Background color for row title (Default = "ECECEC") +color_TableBorder="ECECEC" # Table border color (Default = "ECECEC") +color_text="000000" # Color of text (Default = "000000") +color_textpercent="606060" # Color of text for percent values (Default = "606060") +color_titletext="000000" # Color of text title within colored Title Rows (Default = "000000") +color_weekend="EAEAEA" # Color for week-end days (Default = "EAEAEA") +color_link="0011BB" # Color of HTML links (Default = "0011BB") +color_hover="605040" # Color of HTML on-mouseover links (Default = "605040") +color_u="FFAA66" # Background color for number of unique visitors (Default = "FFAA66") +color_v="F4F090" # Background color for number of visites (Default = "F4F090") +color_p="4477DD" # Background color for number of pages (Default = "4477DD") +color_h="66DDEE" # Background color for number of hits (Default = "66DDEE") +color_k="2EA495" # Background color for number of bytes (Default = "2EA495") +color_s="8888DD" # Background color for number of search (Default = "8888DD") +color_e="CEC2E8" # Background color for number of entry pages (Default = "CEC2E8") +color_x="C1B2E2" # Background color for number of exit pages (Default = "C1B2E2") + + + +#----------------------------------------------------------------------------- +# PLUGINS +#----------------------------------------------------------------------------- + +# Add here all plugin files you want to load. +# Plugin files must be .pm files stored in 'plugins' directory. +# Uncomment LoadPlugin lines to enable a plugin after checking that perl +# modules required by the plugin are installed. + +# PLUGIN: Tooltips +# REQUIRED MODULES: None +# PARAMETERS: None +# DESCRIPTION: Add tooltips pop-up help boxes to HTML report pages. +# NOTE: This will increased HTML report pages size, thus server load and bandwidth. +# +#LoadPlugin="tooltips" + +# PLUGIN: DecodeUTFKeys +# REQUIRED MODULES: Encode and URI::Escape +# PARAMETERS: None +# DESCRIPTION: Allow AWStats to show correctly (in language charset) +# keywords/keyphrases strings even if they were UTF8 coded by the +# referer search engine. +# +#LoadPlugin="decodeutfkeys" + +# PLUGIN: IPv6 +# PARAMETERS: None +# REQUIRED MODULES: Net::IP and Net::DNS +# DESCRIPTION: This plugin gives AWStats capability to make reverse DNS +# lookup on IPv6 addresses. +# +#LoadPlugin="ipv6" + +# PLUGIN: HashFiles +# REQUIRED MODULES: Storable +# PARAMETERS: None +# DESCRIPTION: AWStats DNS cache files are read/saved as native hash files. +# This increases DNS cache files loading speed, above all for very large web sites. +# +#LoadPlugin="hashfiles" + + +# PLUGIN: UserInfo +# REQUIRED MODULES: None +# PARAMETERS: None +# DESCRIPTION: Add a text (Firtname, Lastname, Office Department, ...) in +# authenticated user reports for each login value. +# A text file called userinfo.myconfig.txt, with two fields (first is login, +# second is text to show, separated by a tab char) must be created in DirData +# directory. +# +#LoadPlugin="userinfo" + +# PLUGIN: HostInfo +# REQUIRED MODULES: Net::XWhois +# PARAMETERS: None +# DESCRIPTION: Add a column into host chart with a link to open a popup window that shows +# info on host (like whois records). +# +#LoadPlugin="hostinfo" + +# PLUGIN: ClusterInfo +# REQUIRED MODULES: None +# PARAMETERS: None +# DESCRIPTION: Add a text (for example a full hostname) in cluster reports for each cluster +# number. A text file called clusterinfo.myconfig.txt, with two fields (first is +# cluster number, second is text to show) separated by a tab char. must be +# created into DirData directory. +# Note this plugin is useless if ShowClusterStats is set to 0 or if you don't +# use a personalized log format that contains %cluster tag. +# +#LoadPlugin="clusterinfo" + +# PLUGIN: UrlAliases +# REQUIRED MODULES: None +# PARAMETERS: None +# DESCRIPTION: Add a text (Page title, description...) in URL reports before URL value. +# A text file called urlalias.myconfig.txt, with two fields (first is URL, +# second is text to show, separated by a tab char) must be created into +# DirData directory. +# +#LoadPlugin="urlalias" + +# PLUGIN: TimeHiRes +# REQUIRED MODULES: Time::HiRes (if Perl < 5.8) +# PARAMETERS: None +# DESCRIPTION: Time reported by -showsteps option is in millisecond. For debug purpose. +# +#LoadPlugin="timehires" + +# PLUGIN: TimeZone +# REQUIRED MODULES: Time::Local +# PARAMETERS: [timezone offset] +# DESCRIPTION: Allow AWStats to adjust time stamps for a different timezone +# This plugin reduces AWStats speed of 10% !!!!!!! +# LoadPlugin="timezone" +# LoadPlugin="timezone +2" +# LoadPlugin="timezone CET" +# +#LoadPlugin="timezone +2" + +# PLUGIN: Rawlog +# REQUIRED MODULES: None +# PARAMETERS: None +# DESCRIPTION: This plugin adds a form in AWStats main page to allow users to see raw +# content of current log files. A filter is also available. +# +#LoadPlugin="rawlog" + +# PLUGIN: GraphApplet +# REQUIRED MODULES: None +# PARAMETERS: [CSS classes to override] +# DESCRIPTION: Supported charts are built by a 3D graphic applet. +# +#LoadPlugin="graphapplet /awstatsclasses" # EXPERIMENTAL FEATURE + +# PLUGIN: GraphGoogleChartAPI +# REQUIRED MODULES: None +# PARAMETERS: None +# DESCRIPTION: Replaces the standard charts with free Google API generated images +# in HTML reports. If country data is available and more than one country has hits, +# a map will be generated using Google Visualizations. +# Note: The machine where reports are displayed must have Internet access for the +# charts to be generated. The only data sent to Google includes the statistic numbers, +# legend names and country names. +# Warning: This plugin is not compatible with option BuildReportFormat=xhtml. +# +#LoadPlugin="graphgooglechartapi" + +# PLUGIN: GeoIPfree +# REQUIRED MODULES: Geo::IPfree version 0.2+ (from Graciliano M.P.) +# PARAMETERS: None +# DESCRIPTION: Country chart is built from an Internet IP-Country database. +# This plugin is useless for intranet only log files. +# Note: You must choose between using this plugin (need Perl Geo::IPfree +# module, database is free but not up to date) or the GeoIP plugin (need +# Perl Geo::IP module from Maxmind, database is also free and up to date). +# Note: Activestate provide a corrupted version of Geo::IPfree 0.2 Perl +# module, so install it from elsewhere (from www.cpan.org for example). +# This plugin reduces AWStats speed by up to 10% ! +# +#LoadPlugin="geoipfree" + +# MAXMIND GEO IP MODULES: Please see documentation for notes on all Maxmind modules + +# PLUGIN: GeoIP +# REQUIRED MODULES: Geo::IP or Geo::IP::PurePerl (from Maxmind) +# PARAMETERS: [GEOIP_STANDARD | GEOIP_MEMORY_CACHE] [/pathto/geoip.dat[+/pathto/override.txt]] +# DESCRIPTION: Builds a country chart and adds an entry to the hosts +# table with country name +# Replace spaces in the path of geoip data file with string "%20". +# +#LoadPlugin="geoip GEOIP_STANDARD /pathto/GeoIP.dat" + +# PLUGIN: GeoIP_City_Maxmind +# REQUIRED MODULES: Geo::IP or Geo::IP::PurePerl (from Maxmind) +# PARAMETERS: [GEOIP_STANDARD | GEOIP_MEMORY_CACHE] [/pathto/GeoIPCity.dat[+/pathto/override.txt]] +# DESCRIPTION: This plugin adds a column under the hosts field and tracks the pageviews +# and hits by city including regions. +# Replace spaces in the path of geoip data file with string "%20". +# +#LoadPlugin="geoip_city_maxmind GEOIP_STANDARD /pathto/GeoIPCity.dat" + +# PLUGIN: GeoIP_ASN_Maxmind +# REQUIRED MODULES: Geo::IP or Geo::IP::PurePerl (from Maxmind) +# PARAMETERS: [GEOIP_STANDARD | GEOIP_MEMORY_CACHE] [/pathto/GeoIPASN.dat[+/pathto/override.txt][+http://linktoASlookup]] +# DESCRIPTION: This plugin adds a chart of AS numbers where the host IP address is registered. +# This plugin can display some ISP information if included in the database. You can also provide +# a link that will be used to lookup additional registration data. Put the link at the end of +# the parameter string and the report page will include the link with the full AS number at the end. +# Replace spaces in the path of geoip data file with string "%20". +# +#LoadPlugin="geoip_asn_maxmind GEOIP_STANDARD /usr/local/geoip.dat+http://enc.com.au/itools/aut-num.php?autnum=" + +# PLUGIN: GeoIP_Region_Maxmind +# REQUIRED MODULES: Geo::IP or Geo::IP::PurePerl (from Maxmind) +# PARAMETERS: [GEOIP_STANDARD | GEOIP_MEMORY_CACHE] [/pathto/GeoIPRegion.dat[+/pathto/override.txt]] +# DESCRIPTION:This plugin adds a chart of hits by regions. Only regions for US and +# Canada can be detected. +# Replace spaces in the path of geoip data file with string "%20". +# +#LoadPlugin="geoip_region_maxmind GEOIP_STANDARD /pathto/GeoIPRegion.dat" + +# PLUGIN: GeoIP_ISP_Maxmind +# REQUIRED MODULES: Geo::IP or Geo::IP::PurePerl (from Maxmind) +# PARAMETERS: [GEOIP_STANDARD | GEOIP_MEMORY_CACHE] [/pathto/GeoIPISP.dat[+/pathto/override.txt]] +# DESCRIPTION: This plugin adds a chart of hits by ISP. +# Replace spaces in the path of geoip data file with string "%20". +# +#LoadPlugin="geoip_isp_maxmind GEOIP_STANDARD /pathto/GeoIPISP.dat" + +# PLUGIN: GeoIP_Org_Maxmind +# REQUIRED MODULES: Geo::IP or Geo::IP::PurePerl (from Maxmind) +# PARAMETERS: [GEOIP_STANDARD | GEOIP_MEMORY_CACHE] [/pathto/GeoIPOrg.dat[+/pathto/override.txt]] +# DESCRIPTION: This plugin add a chart of hits by Organization name +# Replace spaces in the path of geoip data file with string "%20". +# +#LoadPlugin="geoip_org_maxmind GEOIP_STANDARD /pathto/GeoIPOrg.dat" + + +#----------------------------------------------------------------------------- +# EXTRA SECTIONS +#----------------------------------------------------------------------------- + +# You can define your own charts, you choose here what are rows and columns +# keys. This feature is particularly useful for marketing purpose, tracking +# products orders for example. +# For this, edit all parameters of Extra section. Each set of parameter is a +# different chart. For several charts, duplicate section changing the number. +# Note: Each Extra section reduces AWStats speed by 8%. +# +# WARNING: A wrong setup of Extra section might result in too large arrays +# that will consume all your memory, making AWStats unusable after several +# updates, so be sure to setup it correctly. +# In most cases, you don't need this feature. +# +# ExtraSectionNameX is title of your personalized chart. +# ExtraSectionCodeFilterX is list of codes the record code field must match. +# Put an empty string for no test on code. +# ExtraSectionConditionX are conditions you can use to count or not the hit, +# Use one of the field condition +# (URL,URLWITHQUERY,QUERY_STRING,REFERER,UA,HOSTINLOG,HOST,VHOST,extraX) +# and a regex to match, after a coma. Use "||" for "OR". +# ExtraSectionFirstColumnTitleX is the first column title of the chart. +# ExtraSectionFirstColumnValuesX is a string to tell AWStats which field to +# extract value from +# (URL,URLWITHQUERY,QUERY_STRING,REFERER,UA,HOSTINLOG,HOST,VHOST,extraX) +# and how to extract the value (using regex syntax). Each different value +# found will appear in first column of report on a different row. Be sure +# that list of different possible values will not grow indefinitely. +# ExtraSectionFirstColumnFormatX is the string used to write value. +# ExtraSectionStatTypesX are things you want to count. You can use standard +# code letters (P for pages,H for hits,B for bandwidth,L for last access). +# ExtraSectionAddAverageRowX add a row at bottom of chart with average values. +# ExtraSectionAddSumRowX add a row at bottom of chart with sum values. +# MaxNbOfExtraX is maximum number of rows shown in chart. +# MinHitExtraX is minimum number of hits required to be shown in chart. +# + +# Example to report the 20 products the most ordered by "order.cgi" script +#ExtraSectionName1="Product orders" +#ExtraSectionCodeFilter1="200 304" +#ExtraSectionCondition1="URL,\/cgi\-bin\/order\.cgi||URL,\/cgi\-bin\/order2\.cgi" +#ExtraSectionFirstColumnTitle1="Product ID" +#ExtraSectionFirstColumnValues1="QUERY_STRING,productid=([^&]+)" +#ExtraSectionFirstColumnFormat1="%s" +#ExtraSectionStatTypes1=PL +#ExtraSectionAddAverageRow1=0 +#ExtraSectionAddSumRow1=1 +#MaxNbOfExtra1=20 +#MinHitExtra1=1 + + +# There is also a global parameter ExtraTrackedRowsLimit that limits the +# number of possible rows an ExtraSection can report. This parameter is +# here to protect too much memory use when you make a bad setup in your +# ExtraSection. It applies to all ExtraSection independently meaning that +# none ExtraSection can report more rows than value defined by ExtraTrackedRowsLimit. +# If you know an ExtraSection will report more rows than its value, you should +# increase this parameter or AWStats will stop with an error. +# Example: 2000 +# Default: 500 +# +ExtraTrackedRowsLimit=500 + + +#----------------------------------------------------------------------------- +# INCLUDES +#----------------------------------------------------------------------------- + +# You can include other config files using the directive with the name of the +# config file. +# This is particularly useful for users who have a lot of virtual servers, so +# a lot of config files and want to maintain common values in only one file. +# Note that when a variable is defined both in a config file and in an +# included file, AWStats will use the last value read for parameters that +# contains one value and AWStats will concat all values from both files for +# parameters that are lists of values. +# + +#Include "" + diff --git a/roles/awstats/templates/cron.d.awstats b/roles/awstats/templates/cron.d.awstats new file mode 100644 index 000000000..dc8a66595 --- /dev/null +++ b/roles/awstats/templates/cron.d.awstats @@ -0,0 +1,6 @@ +MAILTO=root + +*/10 * * * * www-data [ -x /usr/share/awstats/tools/update.sh ] && /usr/share/awstats/tools/update.sh + +# Generate static reports: +10 03 * * * www-data [ -x /usr/share/awstats/tools/buildstatic.sh ] && /usr/share/awstats/tools/buildstatic.sh diff --git a/roles/awstats/templates/logrotate.d.apache2 b/roles/awstats/templates/logrotate.d.apache2 new file mode 100644 index 000000000..644aa5a1f --- /dev/null +++ b/roles/awstats/templates/logrotate.d.apache2 @@ -0,0 +1,20 @@ +/var/log/apache2/*.log { + daily + missingok + rotate 14 + compress + delaycompress + notifempty + create 640 root www-data + sharedscripts + postrotate + if /etc/init.d/apache2 status > /dev/null ; then \ + /etc/init.d/apache2 reload > /dev/null; \ + fi; + endscript + prerotate + if [ -d /etc/logrotate.d/httpd-prerotate ]; then \ + run-parts /etc/logrotate.d/httpd-prerotate; \ + fi; \ + endscript +} diff --git a/roles/calibre/defaults/main.yml b/roles/calibre/defaults/main.yml new file mode 100644 index 000000000..da9a7155e --- /dev/null +++ b/roles/calibre/defaults/main.yml @@ -0,0 +1,3 @@ +calibre_port: 8010 +calibre_dbpath: "/library/calibre" +calibre_src_url: "https://raw.githubusercontent.com/kovidgoyal/calibre/master/setup/linux-installer.py" diff --git a/roles/calibre/tasks/main.yml b/roles/calibre/tasks/main.yml new file mode 100644 index 000000000..343dd0314 --- /dev/null +++ b/roles/calibre/tasks/main.yml @@ -0,0 +1,75 @@ +- name: Get calibre setup file +# the installer works for intel fedora, and Centos, and deals with dependencies + get_url: + url="{{ calibre_src_url }}" + dest="{{ downloads_dir }}/calibre-installer.py" + mode=0755 + tags: + download2 + when: ansible_distribution == "CentOS" + +- name: Install calibre + shell: "{{ downloads_dir }}/calibre-installer.py >> /dev/null" + args: + creates: /usr/bin/calibre-uninstall + tags: + download2 + when: calibre_install and ansible_distribution == 'CentOS' + +- name: Install Caibre rpms +# the fedora rpm arm version, though older, takes care of dependencies, and exists + package: name={{ item }} + state=present + with_items: + - calibre + when: calibre_install and ansible_distribution != 'CentOS' + tags: download + +- name: Create calibre service(s) and support scripts + template: backup=no + src={{ item.src }} + dest={{ item.dest }} + owner=root + group=root + mode={{ item.mode }} + with_items: + - { src: 'calibre-serve.service.j2', dest: '/etc/systemd/system/calibre-serve.service', mode: '0644'} + - { src: 'calibre.conf', dest: '/etc/{{ apache_config_dir }}', mode: '0644'} + when: calibre_install + +- name: Create the link for sites-enabled + file: src=/etc/apache2/sites-available/calibre.conf + dest=/etc/apache2/sites-enabled/calibre.conf + state=link + when: is_debian and calibre_enabled + +- name: Enable Calibre server + service: name=calibre-serve + enabled=yes + state=started + #async: 900 + #poll: 5 + when: calibre_enabled + +- name: Disable Calibre server + service: name=calibre-serve + enabled=no + state=stopped + when: not calibre_enabled + +- name: Add calibre to service list + ini_file: dest='{{ service_filelist }}' + section=calibre + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: description + value: '"Calibre epub book server"' + - option: url + value: "{{ calibre_src_url }}" + - option: database + value: "{{ calibre_dbpath }}" + - option: port + value: "{{ calibre_port }}" + - option: enabled + value: "{{ calibre_enabled }}" diff --git a/roles/calibre/templates/calibre-serve.service.j2 b/roles/calibre/templates/calibre-serve.service.j2 new file mode 100644 index 000000000..12d2d45d5 --- /dev/null +++ b/roles/calibre/templates/calibre-serve.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description=Provides the Calibre Book Server +After=syslog.target network.target local-fs.target + +[Service] +Type=forking +PIDFile=/var/run/calibre.pid +{% if is_debian %} +ExecStart=/usr/bin/calibre-server --daemonize --pidfile=/var/run/calibre.pid --port={{ calibre_port }} --with-library={{ calibre_dbpath }} +{% else %} +ExecStart=/bin/calibre-server --daemonize --pidfile=/var/run/calibre.pid --port={{ calibre_port }} --with-library={{ calibre_dbpath }} +{% endif %} +[Install] +TimeoutStartSec=900 +WantedBy=multi-user.target diff --git a/roles/calibre/templates/calibre.conf b/roles/calibre/templates/calibre.conf new file mode 100644 index 000000000..ede22f890 --- /dev/null +++ b/roles/calibre/templates/calibre.conf @@ -0,0 +1,2 @@ +ProxyPass /calibre http://localhost:8010 +ProxyPassReverse /calibre http://localhost:8010 diff --git a/roles/cups/defaults/main.yml b/roles/cups/defaults/main.yml new file mode 100644 index 000000000..4d9d5227e --- /dev/null +++ b/roles/cups/defaults/main.yml @@ -0,0 +1,2 @@ +cups_install: True +cups_enabled: False diff --git a/roles/cups/tasks/main.yml b/roles/cups/tasks/main.yml new file mode 100644 index 000000000..948a45f06 --- /dev/null +++ b/roles/cups/tasks/main.yml @@ -0,0 +1,73 @@ +# administer this service by browsing to localhost:631 +- debug: var=cups_install +- name: get the CUPS package installed + package: name={{ item }} + state=present + with_items: + - cups + when: cups_install + tags: + - download + +- name: Put our own config file in place, to permit local lan admin + template: dest=/etc/cups/cupsd.conf + src=cupsd.conf + +- name: Put an apache2 config file in place + template: dest=/etc/{{ apache_config_dir }}/ + src=cups.conf + +- name: Create the link for sites-enabled + file: src=/etc/apache2/sites-available/cups.conf + dest=/etc/apache2/sites-enabled/cups.conf + state=link + when: cups_enabled and is_debian + +- name: Enable services for cups + service: name={{ item }} + state=started + enabled=yes + with_items: + - cups + - cups-browsed + when: cups_enabled and not is_F18 + +- name: Enable services for cups for xo's + service: name=cups + state=started + enabled=yes + when: cups_enabled and is_F18 + +- name: Permit headless admin of CUPS -- only works when cups daemon is running + shell: "cupsctl --remote-admin" + when: cups_enabled + +- name: Disable services for cups + service: name={{ item }} + state=stopped + enabled=no + with_items: + - cups + - cups-browsed + when: not cups_enabled and not is_F18 + +- name: Disable services for cups for xo's + service: name=cups + state=stopped + enabled=no + when: not cups_enabled and is_F18 + +- name: add cups to service list + ini_file: dest={{ service_filelist }} + section=cups + option={{ item.option }} + value={{ item.value }} + with_items: + - option: name + value: '"Common UNIX Printing System (CUPS)"' + - option: description + value: '"CUPS is a modular printing system which allows a computer to act as a print server. A computer running CUPS is a host that can accept print jobs from client computers, process them, and send them to the appropriate printer."' + - option: installed + value: "{{ cups_install }}" + - option: enabled + value: "{{ cups_enabled }}" diff --git a/roles/cups/templates/cups.conf b/roles/cups/templates/cups.conf new file mode 100644 index 000000000..8cf2b199f --- /dev/null +++ b/roles/cups/templates/cups.conf @@ -0,0 +1,2 @@ +ProxyPass /cups http://localhost:631 +ProxyPassReverse /cups http://localhost:631 diff --git a/roles/cups/templates/cupsd.conf b/roles/cups/templates/cupsd.conf new file mode 100644 index 000000000..92a395cb8 --- /dev/null +++ b/roles/cups/templates/cupsd.conf @@ -0,0 +1,84 @@ +ServerAlias * +LogLevel warn +MaxLogSize 1m +Listen {{ lan_ip }}:631 +Listen localhost:631 +Listen /var/run/cups/cups.sock +Browsing On +BrowseLocalProtocols dnssd +DefaultAuthType Basic +WebInterface Yes + + Order allow,deny + + + Order allow,deny + + + AuthType Default + Require user @SYSTEM + Order allow,deny + + + JobPrivateAccess default + JobPrivateValues default + SubscriptionPrivateAccess default + SubscriptionPrivateValues default + + Order deny,allow + + + Require user @OWNER @SYSTEM + Order deny,allow + + + AuthType Default + Require user @SYSTEM + Order deny,allow + + + AuthType Default + Require user @SYSTEM + Order deny,allow + + + Require user @OWNER @SYSTEM + Order deny,allow + + + Order deny,allow + + + + JobPrivateAccess default + JobPrivateValues default + SubscriptionPrivateAccess default + SubscriptionPrivateValues default + + AuthType Default + Order deny,allow + + + AuthType Default + Require user @OWNER @SYSTEM + Order deny,allow + + + AuthType Default + Require user @SYSTEM + Order deny,allow + + + AuthType Default + Require user @SYSTEM + Order deny,allow + + + AuthType Default + Require user @OWNER @SYSTEM + Order deny,allow + + + Order deny,allow + + diff --git a/roles/debian_schooltool/defaults/main.yml b/roles/debian_schooltool/defaults/main.yml new file mode 100644 index 000000000..989e9f1d8 --- /dev/null +++ b/roles/debian_schooltool/defaults/main.yml @@ -0,0 +1,5 @@ +schooltool_version: schooltool-2.8.5 +schooltool_src: '{{ schooltool_version }}.tar.gz' +debian_schooltool_install: True +debian_schooltool_enabled: False + diff --git a/roles/debian_schooltool/tasks/main.yml b/roles/debian_schooltool/tasks/main.yml new file mode 100644 index 000000000..a2ed6b74a --- /dev/null +++ b/roles/debian_schooltool/tasks/main.yml @@ -0,0 +1,51 @@ +- name: get the required build packages + package: name={{ item }} + state=present + with_items: + - build-essential + - gettext + - python-dev + - libicu-dev + - libxslt1-dev + - libfreetype6-dev + - libjpeg-dev + - enscript + - python-virtualenv + - ttf-liberation + - redis-server + - libjpeg-dev + - xvfb + when: debian_schooltool_install and is_debian + tags: + - download + +- name: Create the font directory + file: path=/usr/share/fonts/truetype/ttf-ubuntu + state=directory + +- name: get the ttf-ubuntu-font-family + get_url: url={{ xsce_download_url }}/ubuntu-font-family-0.83.zip + dest={{ downloads_dir }} + tags: download2 + +- name: expand the ttf fonts to the right place + unarchive: src={{ downloads_dir }}/ubuntu-font-family-0.83.zip + dest=/usr/share/fonts/truetype/ttf-ubuntu/ + +- name: get the schooltool source + get_url: url={{ xsce_download_url }}/{{ schooltool_src }} + dest={{ downloads_dir }} + tags: download2 + +- name: expand source to dest + unarchive: src={{ downloads_dir }}/{{ schooltool_src }} + dest={{ xsce_base }} + +- name: create a link for schooltool + file: src={{ xsce_base }}/{{ schooltool_version }} + dest={{ xsce_base }}/schooltool + state=link + +- name: build the schooltool from source + shell: command='$( cd {{ xsce_base }}/schooltool; /usr/bin/make ) ' + diff --git a/roles/debian_schooltool/templates/buildout.cfg b/roles/debian_schooltool/templates/buildout.cfg new file mode 100644 index 000000000..4a22a90ac --- /dev/null +++ b/roles/debian_schooltool/templates/buildout.cfg @@ -0,0 +1,26 @@ +[buildout] +extends = base.cfg +develop = . + +[versions] +# Unset versions of packages you want to develop +schooltool = + +[package] +eggs += schooltool + schooltool.gradebook + schooltool.lyceum.journal + schooltool.intervention + +[test] +eggs = schooltool [test] + +# To run selenium tests: +# - Download standalone selenium server from +# http://code.google.com/p/selenium/downloads/list +# - Start the server: "java -jar selenium-server-standalone-2.7.0.jar" +# - Uncomment the lines below: +# +#selenium.default = html_unit +#selenium.html_unit.web_driver = remote +#selenium.html_unit.capabilities = HTMLUNITWITHJS diff --git a/roles/docker/defaults/main.yml b/roles/docker/defaults/main.yml new file mode 100644 index 000000000..dcc3c942f --- /dev/null +++ b/roles/docker/defaults/main.yml @@ -0,0 +1,2 @@ +docker_install: True +docker_enabled: False diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml new file mode 100644 index 000000000..6e9cf96cc --- /dev/null +++ b/roles/docker/tasks/main.yml @@ -0,0 +1,54 @@ +- name: Install docker + package: name={{ item }} + state=present + with_items: + - docker + - python-docker-py + when: docker_install + tags: download + +- name: put the systemd startup file in place + template: src=docker.service + dest=/etc/systemd/system/ + owner=root + group=root + mode=0644 + +- name: create the socket for docker + template: src=docker.socket + dest=/etc/systemd/system/ + owner=root + group=root + mode=0644 + +- name: Create a folder for systemd unit files that are docker containers + file: path=/etc/systemd/system/docker.service.d + owner=root + group=root + mode=0644 + state=directory + +- name: Enable docker + service: name=docker + state=started + enabled=true + when: docker_enabled + +- name: Disable docker + service: name=docker + state=stopped + enabled=false + when: not docker_enabled + +- name: add docker to service list + ini_file: dest='{{ service_filelist }}' + section=docker + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: name + value: Docker Container + - option: description + value: '"Docker allows a person to package an application with all of its dependencies into a standardized unit for software development."' + - option: enabled + value: "{{ docker_enabled }}" diff --git a/roles/docker/templates/docker.service b/roles/docker/templates/docker.service new file mode 100644 index 000000000..f10b1cfeb --- /dev/null +++ b/roles/docker/templates/docker.service @@ -0,0 +1,26 @@ +[unit] +Description=Docker Application Container Engine +Documentation=https://docs.docker.com +After=network.target docker.socket +Requires=docker.socket + +[Service] +Type=notify +# the default is not to use systemd for cgroups because the delegate issues still +# exists and systemd currently does not support the cgroup feature set required +# for containers run by docker +ExecStart=/usr/bin/docker daemon +MountFlags=slave +LimitNOFILE=1048576 +LimitNPROC=1048576 +LimitCORE=infinity +# Uncomment TasksMax if your systemd version supports it. +# Only systemd 226 and above support this version. +#TasksMax=infinity +TimeoutStartSec=0 +# set delegate yes so that systemd does not reset the cgroups of docker containers +Delegate=yes + +[Install] +WantedBy=multi-user.target + diff --git a/roles/docker/templates/docker.socket b/roles/docker/templates/docker.socket new file mode 100644 index 000000000..7a868d7ff --- /dev/null +++ b/roles/docker/templates/docker.socket @@ -0,0 +1,13 @@ +[unit] +Description=Docker Socket for the API +PartOf=docker.service + +[Socket] +ListenStream=/var/run/docker.sock +SocketMode=0660 +SocketUser=root +SocketGroup=docker + +[Install] +WantedBy=sockets.target + diff --git a/roles/dokuwiki/README.rst b/roles/dokuwiki/README.rst new file mode 100644 index 000000000..039fa93fd --- /dev/null +++ b/roles/dokuwiki/README.rst @@ -0,0 +1,36 @@ +=============== +Dokuwiki README +=============== + +DokuWiki is a simple to use and highly versatile Open Source wiki software that +doesn't require a database. It is loved by users for its clean and readable +syntax. The ease of maintenance, backup and integration makes it an +administrator's favorite. Built in access controls and authentication connectors +make DokuWiki especially useful in the enterprise context and the large number of +plugins contributed by its vibrant community allow for a broad range of use cases +beyond a traditional wiki. + +http://dokuwiki.org/ + +After Installation +------------------ + +Head to http://schoolserver.lan/wiki. The webpage will probably throw up an error +saying you haven't run install.php yet, with a link to it. Click the link to be +taken to the install page which does the initial configuration of the wiki. After +this, you should be all set! + +Locations +--------- + +Everything is copied to the /opt/dokuwiki folder. An apache configuration file is +installed in the usual conf.d directory. + +Parameters +---------- +None yet other than the basic enabled/disabled. Haven't really tested if they work. + +Todo +---- +* Preinstall some popular plugins. +* Additional XSCE customizations. diff --git a/roles/dokuwiki/defaults/main.yml b/roles/dokuwiki/defaults/main.yml new file mode 100644 index 000000000..b038f0208 --- /dev/null +++ b/roles/dokuwiki/defaults/main.yml @@ -0,0 +1,4 @@ +dokuwiki_url: /wiki +dokuwiki_install: True +dokuwiki_enabled: False +dokuwiki_version: "dokuwiki-2014-09-29.tgz" diff --git a/roles/dokuwiki/tasks/install.yml b/roles/dokuwiki/tasks/install.yml new file mode 100644 index 000000000..83f09472c --- /dev/null +++ b/roles/dokuwiki/tasks/install.yml @@ -0,0 +1,34 @@ +- name: Get the Dokuwiki software + get_url: url="{{ xsce_download_url }}/{{ dokuwiki_version }}" dest={{ downloads_dir}}/ + when: not {{ use_cache }} and not {{ no_network }} + tags: + - download2 + +- name: Copy it to permanent location /library + unarchive: src={{ downloads_dir}}/{{ dokuwiki_version }} dest=/library + +- name: Rename /library/dokuwiki* to /library/dokuwiki + shell: if [ ! -d /library/dokuwiki ]; then mv /library/dokuwiki* /library/dokuwiki; fi + +- name: Install config file for dokuwiki in Apache + template: src=dokuwiki.conf.j2 dest=/etc/{{ apache_config_dir }}/dokuwiki.conf + when: dokuwiki_enabled + +- name: enable the dokuwiki + file: path=/etc/apache2/sites-enabled/dokuwiki.conf + src=/etc/apache2/sites-available/dokuwiki.conf + state=link + when: dokuwiki_enabled and is_debian + +- name: disable the dokuwiki + file: path=/etc/apache2/sites-enabled/dokuwiki.conf + state=absent + when: not dokuwiki_enabled and is_debian + + +- name: Change permissions on engine directory so apache can write + file: path=/library/dokuwiki owner={{ apache_data }} mode=0755 state=directory recurse=yes + +- name: Restart apache, so it picks up the new aliases + service: name={{ apache_service }} state=restarted + diff --git a/roles/dokuwiki/tasks/main.yml b/roles/dokuwiki/tasks/main.yml new file mode 100644 index 000000000..9b08d1705 --- /dev/null +++ b/roles/dokuwiki/tasks/main.yml @@ -0,0 +1,18 @@ +- name: Include the install playbook + include: install.yml + when: dokuwiki_install + +- name: Add dokuwiki to service list + ini_file: dest='{{ service_filelist }}' + section=dokuwiki + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: name + value: dokuwiki + - option: description + value: '"DokuWiki is a simple to use and highly versatile Open Source wiki software that does not require a database. "' + - option: installed + value: "{{ dokuwiki_install }}" + - option: enabled + value: "{{ dokuwiki_enabled }}" diff --git a/roles/dokuwiki/templates/dokuwiki.conf.j2 b/roles/dokuwiki/templates/dokuwiki.conf.j2 new file mode 100644 index 000000000..efb80af0f --- /dev/null +++ b/roles/dokuwiki/templates/dokuwiki.conf.j2 @@ -0,0 +1,8 @@ +RewriteEngine on + +Alias {{ dokuwiki_url }} /library/dokuwiki + + Options Indexes FollowSymLinks + AllowOverride All + Require all granted + diff --git a/roles/ejabberd/tasks/main.yml b/roles/ejabberd/tasks/main.yml new file mode 100644 index 000000000..32e441eb9 --- /dev/null +++ b/roles/ejabberd/tasks/main.yml @@ -0,0 +1,79 @@ +- name: Install ejabberd packages + package: name={{ item }} + state=present + with_items: + - ejabberd-2.1.11 + tags: + - download + when: not is_debian + +- name: Install ejabberd packages + package: name={{ item }} + state=present + with_items: + - ejabberd + tags: + - download + when: is_debian + +- name: Configure ejabberd + template: backup=yes + src={{ item.src }} + dest={{ item.dest }} + owner=root + group=root + mode={{ item.mode }} + with_items: + - { src: 'ejabberd-xs.cfg.j2', dest: '/etc/ejabberd/ejabberd-xs.cfg' , mode: '0644' } + - { src: 'ejabberdctl.cfg.j2', dest: '/etc/ejabberd/ejabberdctl.cfg', mode: '0644' } + - { src: 'ejabberd-xs', dest: '/etc/sysconfig/ejabberd-xs', mode: '0755' } +# - { src: 'ejabberd-domain-config', dest: '/etc/sysconfig/olpc-scripts/domain_config.d/ejabberd', mode: '0755'} +# - { src: 'ejabberd', dest: '/etc/sysconfig/olpc-scripts/domain_config.d/ejabberd' , mode: '0755' } + - { src: 'ejabberd-xs.service.j2', dest: '/etc/systemd/system/ejabberd-xs.service', mode: '0755' } + - { src: 'xs-ejabberd-srg', dest: '/usr/bin/xs-ejabberd-srg' , mode: '0755' } + - { src: '10-ejabberdmoodle', dest: '/etc/sudoers.d/10-ejabberdmoodle', mode: '0440' } + - { src: 'ejabberd.tmpfiles', dest: '/etc/tmpfiles.d/ejabberd.conf', mode: '0640' } + register: ejabberd_config + +- name: Put the startup script in place - debian + template: src='ejabberd-xs.init' + dest='/etc/init.d/ejabberd-xs' + when: is_debian + +- name: Put the startup script in place - non debian + template: src='ejabberd-xs.init' + dest='/usr/libexec/ejabberd-xs' + when: not is_debian + +- name: Remove ejabberd_domain if domain changes + file: path=/etc/sysconfig/ejabberd_domain_name + state=absent + when: ejabberd_config.changed + +- name: Enable ejabberd service + file: src=/etc/systemd/system/ejabberd-xs.service + dest=/etc/systemd/system/multi-user.target.wants/ejabberd-xs.service + owner=root + group=root + state=link + +- name: Start ejabberd service + service: name=ejabberd-xs + state=restarted + enabled=yes + when: ejabberd_config.changed and ejabberd_enabled + +- name: Wait for ejabberd service start + wait_for: port=5280 + delay=15 + state=started + timeout=300 + when: ejabberd_config.changed and ejabberd_enabled + +- name: Create online group + shell: ejabberdctl srg_create Online "schoolserver" Online "Online_Users" Online + when: ejabberd_config.changed + +- name: Add all users to online group + shell: ejabberdctl srg_user_add '@online@' "schoolserver" Online "schoolserver" + when: ejabberd_config.changed diff --git a/roles/ejabberd/templates/10-ejabberdmoodle b/roles/ejabberd/templates/10-ejabberdmoodle new file mode 100644 index 000000000..a45c61c36 --- /dev/null +++ b/roles/ejabberd/templates/10-ejabberdmoodle @@ -0,0 +1,12 @@ +## +## 10-ejabberdmoodle +## for ejabberd-moodle interaction +## + +# allow the apache user to invoke ejabberdctl and start/stop/condrestart +Defaults:apache !requiretty +Cmnd_Alias EJABBERDCTL = /usr/sbin/ejabberdctl +Cmnd_Alias EJABBERDINIT = /etc/init.d/ejabberd start , /etc/init.d/ejabberd stop , /etc/init.d/ejabberd condrestart + +apache ALL = (ejabberd) NOPASSWD: EJABBERDCTL +apache ALL = (root) NOPASSWD: EJABBERDINIT diff --git a/roles/ejabberd/templates/ejabberd b/roles/ejabberd/templates/ejabberd new file mode 100755 index 000000000..4d6c9e825 --- /dev/null +++ b/roles/ejabberd/templates/ejabberd @@ -0,0 +1,62 @@ +#!/bin/sh -e + +# +# ejabberd now handles domain changes in the initrd script +# +SERVICE_NAME=ejabberd-xs + +CONFIG_LIST="/etc/ejabberd/ejabberd-xs.cfg" + +# taken from ejabberd spec %post +# taken from ejabberd spec %post +#function do-cert(){ +# (cd /etc/ejabberd +# if [ ! -f ejabberd.pem ] +# then +# echo "Generating SSL certificate /etc/ejabberd/ejabberd.pem..." +# HOSTNAME=$(hostname -s) +# DOMAINNAME=$(hostname -d) +# openssl req -new -x509 -days 36500 -nodes -out ejabberd.pem -keyout ejabberd.pem > /dev/null 2>&1 << +++ +# . +# . +# . +# $DOMAINNAME +# $HOSTNAME +# ejabberd +# root@$HOSTNAME.$DOMAINNAME +# +++ +# chown ejabberd:ejabberd ejabberd.pem +# chmod 600 ejabberd.pem +# fi) +#} + +# This is the suffix which original versions of modified files will have +BACKUP_SUFFIX=old + +short_host=`hostname -s` +new_name=$short_host.$1 + +for config in $CONFIG_LIST; +do + if [ -e $config.in ]; then + if [ -e $config ]; then + mv $config $config.$BACKUP_SUFFIX + fi + sed -e s/{{ xsce_hostname }}/$new_name/ $config.in > $config ; + else + echo WARNING: Skipped $config - template file is missing! + fi +done + +#if [ -e /etc/ejabberd/ejabberd.pem.$1 ]; then +# rm /etc/ejabberd/ejabberd.pem.$1 +#fi +#mv /etc/ejabberd/ejabberd.pem /etc/ejabberd/ejabberd.pem.$1 +#do-cert + +# Since for the community edition, we don't really expect all modules to be present +# Just exit, and expect the user to do a restart + +exit 0 + + diff --git a/roles/ejabberd/templates/ejabberd-xs b/roles/ejabberd/templates/ejabberd-xs new file mode 100755 index 000000000..627260af5 --- /dev/null +++ b/roles/ejabberd/templates/ejabberd-xs @@ -0,0 +1,13 @@ +## Settings for ejabberd + +## Where should ejabberd find its configuration file? +# +CONFIG_FILE=/etc/ejabberd/ejabberd-xs.cfg + +## ULIMIT_MAX_FILES alters the number of files that ejabberd is +## allowed to have open at once. If it is unset the system default +## (usually 1024) will be used. ejabberd will want over twice as many +## open files as it has active connections, so if you have a few +## hundred or more users you will want to set this. +# +ULIMIT_MAX_FILES=40000 diff --git a/roles/ejabberd/templates/ejabberd-xs.cfg.j2 b/roles/ejabberd/templates/ejabberd-xs.cfg.j2 new file mode 100644 index 000000000..42b2e8fc2 --- /dev/null +++ b/roles/ejabberd/templates/ejabberd-xs.cfg.j2 @@ -0,0 +1,454 @@ +%%% +%%% ejabberd configuration file +%%% + +%%% The parameters used in this configuration file are explained in more detail +%%% in the ejabberd Installation and Operation Guide. +%%% Please consult the Guide in case of doubts, it is included in +%%% your copy of ejabberd, and is also available online at +%%% http://www.process-one.net/en/ejabberd/docs/ + +%%% This configuration file contains Erlang terms. +%%% In case you want to understand the syntax, here are the concepts: +%%% +%%% - The character to comment a line is % +%%% +%%% - Each term ends in a dot, for example: +%%% override_global. +%%% +%%% - A tuple has a fixed definition, its elements are +%%% enclosed in {}, and separated with commas: +%%% {loglevel, 4}. +%%% +%%% - A list can have as many elements as you want, +%%% and is enclosed in [], for example: +%%% [http_poll, web_admin, tls] +%%% +%%% - A keyword of ejabberd is a word in lowercase. +%%% The strings are enclosed in "" and can have spaces, dots... +%%% {language, "en"}. +%%% {ldap_rootdn, "dc=example,dc=com"}. +%%% +%%% - This term includes a tuple, a keyword, a list and two strings: +%%% {hosts, ["jabber.example.net", "im.example.com"]}. +%%% + + +%%% ======================= +%%% OVERRIDE STORED OPTIONS + +%% +%% Override the old values stored in the database. +%% + +%% +%% Override global options (shared by all ejabberd nodes in a cluster). +%% +override_global. + +%% +%% Override local options (specific for this particular ejabberd node). +%% +override_local. + +%% +%% Remove the Access Control Lists before new ones are added. +%% +override_acls. + + +%%% ========= +%%% DEBUGGING + +%% +%% loglevel: Verbosity of log files generated by ejabberd. +%% 0: No ejabberd log at all (not recommended) +%% 1: Critical +%% 2: Error +%% 3: Warning +%% 4: Info +%% 5: Debug +%% +{loglevel, 4}. + +%% +%% watchdog_admins: If an ejabberd process consumes too much memory, +%% send live notifications to those Jabber accounts. +%% +%%{watchdog_admins, ["bob@example.com"]}. + + +%%% ================ +%%% SERVED HOSTNAMES + +%% +%% hosts: Domains served by ejabberd. +%% You can define one or several, for example: +%% {hosts, ["example.net", "example.com", "example.org"]}. +%% +{hosts, ["{{ xsce_hostname }}.{{ xsce_domain }}"]}. + +%% +%% route_subdomains: Delegate subdomains to other Jabber server. +%% For example, if this ejabberd serves example.org and you want +%% to allow communication with a Jabber server called im.example.org. +%% +%%{route_subdomains, s2s}. + + +%%% =============== +%%% LISTENING PORTS + +%% +%% listen: Which ports will ejabberd listen, which service handles it +%% and what options to start it with. +%% +{listen, + [ + + {5222, ejabberd_c2s, [ + + %% + %% If TLS is compiled and you installed a SSL + %% certificate, put the correct path to the + %% file and uncomment this line: + %% + %%{certfile, "/path/t/etc/ejabberd/ejabberd.pem"}, starttls, + inet6, + {access, c2s}, + {shaper, c2s_shaper}, + {max_stanza_size, 524288} + ]} + + %% + %% To enable the old SSL connection method in port 5223: + %% + , {5223, ejabberd_c2s, [ + inet6, + {access, c2s}, + {shaper, c2s_shaper}, + tls, {certfile, "/etc/ejabberd/ejabberd.pem"}, + {max_stanza_size, 524288} + ]} + + %% , {5269, ejabberd_s2s_in, [ + %% {shaper, s2s_shaper}, + %% {max_stanza_size, 131072} + %% ]}, + + %% + %% ejabberd_service: Interact with external components (transports...) + %% + %% , {8888, ejabberd_service, [ + %% {access, all}, + %% {shaper_rule, fast}, + %% {ip, {127, 0, 0, 1}}, + %% {hosts, ["icq.example.org", "sms.example.org"], + %% [{password, "secret"}] + %% } + %% ]} + + , {5280, ejabberd_http, [ + inet6, + http_poll, + web_admin + ]} + + ]}. + +%% +%% s2s_use_starttls: Enable STARTTLS + Dialback for S2S connections. +%% Allowed values are: true or false. +%% You must specify a certificate file. +%% +%%{s2s_use_starttls, true}. + +%% +%% s2s_certfile: Specify a certificate file. +%% +%%{s2s_certfile, "/path/t/etc/ejabberd/ejabberd.pem"}. + +%% +%% domain_certfile: Specify a different certificate for each served hostname. +%% +%%{domain_certfile, "example.org", "/path/to/example_org.pem"}. +%%{domain_certfile, "example.com", "/path/to/example_com.pem"}. + +%% +%% S2S whitelist or blacklist +%% +%% Default s2s policy for undefined hosts. +%% +{s2s_default_policy, deny}. + +%% +%% Allow or deny communication with specific servers. +%% +%%{{ '{{' }}s2s_host, "goodhost.org"}, allow}. +%%{{ '{{' }}s2s_host, "badhost.org"}, deny}. + + +%%% ============== +%%% AUTHENTICATION + +%% +%% auth_method: Method used to authenticate the users. +%% The default method is the internal. +%% If you want to use a different method, +%% comment this line and enable the correct ones. +%% +{auth_method, internal}. + +%% +%% Authentication using external script +%% Make sure the script is executable by ejabberd. +%% +%%{auth_method, external}. +%%{extauth_program, "/path/to/authentication/script"}. + +%% +%% Authentication using ODBC +%% Remember to setup a database in the next section. +%% +%%{auth_method, odbc}. + +%% +%% Authentication using PAM +%% +%%{auth_method, pam}. +%%{pam_service, "pamservicename"}. + +%% +%% Authentication using LDAP +%% +%%{auth_method, ldap}. +%% +%% List of LDAP servers: +%%{ldap_servers, ["localhost"]}. +%% +%% LDAP attribute that holds user ID: +%%{ldap_uids, [{"mail", "%u@mail.example.org"}]}. +%% +%% Search base of LDAP directory: +%%{ldap_base, "dc=example,dc=com"}. +%% +%% LDAP manager: +%%{ldap_rootdn, "dc=example,dc=com"}. +%% +%% Password to LDAP manager: +%%{ldap_password, "******"}. + +%% +%% Anonymous login support: +%% auth_method: anonymous +%% anonymous_protocol: sasl_anon | login_anon | both +%% allow_multiple_connections: true | false +%% +%%{host_config, "public.example.org", [{auth_method, anonymous}, +%% {allow_multiple_connections, false}, +%% {anonymous_protocol, sasl_anon}]}. +%% +%% To use both anonymous and internal authentication: +%% +%%{host_config, "public.example.org", [{auth_method, [internal, anonymous]}]}. + + +%%% ============== +%%% DATABASE SETUP + +%% ejabberd uses by default the internal Mnesia database, +%% so you can avoid this section. +%% This section provides configuration examples in case +%% you want to use other database backends. +%% Please consult the ejabberd Guide for details about database creation. + +%% +%% MySQL server: +%% +%%{odbc_server, {mysql, "server", "database", "username", "password"}}. +%% +%% If you want to specify the port: +%%{odbc_server, {mysql, "server", 1234, "database", "username", "password"}}. + +%% +%% PostgreSQL server: +%% +%%{odbc_server, {pgsql, "server", "database", "username", "password"}}. +%% +%% If you want to specify the port: +%%{odbc_server, {pgsql, "server", 1234, "database", "username", "password"}}. +%% +%% If you use PostgreSQL, have a large database, and need a +%% faster but inexact replacement for "select count(*) from users" +%% +%%{pgsql_users_number_estimate, true}. + +%% +%% ODBC compatible or MSSQL server: +%% +%%{odbc_server, "DSN=ejabberd;UID=ejabberd;PWD=ejabberd"}. + + +%%% =============== +%%% TRAFFIC SHAPERS + +%% +%% The "normal" shaper limits traffic speed to 1.000 B/s +%% +{shaper, normal, {maxrate, 1000}}. + +%% +%% The "fast" shaper limits traffic speed to 50.000 B/s +%% +{shaper, fast, {maxrate, 50000}}. + + +%%% ==================== +%%% ACCESS CONTROL LISTS + +%% +%% The 'admin' ACL grants administrative privileges to Jabber accounts. +%% You can put as many accounts as you want. +%% +%%{acl, admin, {user, "aleksey", "localhost"}}. +%%{acl, admin, {user, "ermine", "example.org"}}. +{acl, admin, {user, "admin", "{{ xsce_hostname }}.{{ xsce_domain }}"}}. + +%% +%% Blocked users +%% +%%{acl, blocked, {user, "baduser", "example.org"}}. +%%{acl, blocked, {user, "test"}}. + +%% +%% Local users: dont modify this line. +%% +{acl, local, {user_regexp, ""}}. + +%% +%% More examples of ACLs +%% +%%{acl, jabberorg, {server, "jabber.org"}}. +%%{acl, aleksey, {user, "aleksey", "jabber.ru"}}. +%%{acl, test, {user_regexp, "^test"}}. +%%{acl, test, {user_glob, "test*"}}. + + +%%% ============ +%%% ACCESS RULES + +%% Define the maximum number of time a single user is allowed to connect: +{access, max_user_sessions, [{10, all}]}. + +%% This rule allows access only for local users: +{access, local, [{allow, local}]}. + +%% Only non-blocked users can use c2s connections: +{access, c2s, [{deny, blocked}, + {allow, all}]}. + +%% For all users except admins used "normal" shaper +{access, c2s_shaper, [{none, admin}, + {fast, all}]}. + +%% For all S2S connections used "fast" shaper +{access, s2s_shaper, [{fast, all}]}. + +%% Only admins can send announcement messages: +{access, announce, [{allow, admin}]}. + +%% Only admins can use configuration interface: +{access, configure, [{allow, admin}]}. + +%% Admins of this server are also admins of MUC service: +{access, muc_admin, [{allow, admin}]}. + +%% All users are allowed to use MUC service: +{access, muc, [{allow, all}]}. + +%% Every username can be registered via in-band registration: +%% To disable in-band registration, replace 'allow' with 'deny'. +{access, register, [{allow, all}]}. + +%% Allow repeat registration from the same client (necessary for testing) +%% Set to a positive integer (or comment out) to restrict with a timeout. +%% (infinity means zero; 0 does not work) +% {registration_timeout, infinity}. + +%% Everybody can create pubsub nodes +{access, pubsub_createnode, [{allow, all}]}. + + +%%% ================ +%%% DEFAULT LANGUAGE + +%% +%% language: Default language used for server messages. +%% +{language, "en"}. + + +%%% ======= +%%% MODULES + +%% +%% Modules enabled in all ejabberd virtual hosts. +%% +{modules, + [ + {mod_adhoc, []}, + {mod_announce, [{access, announce}]}, % requires mod_adhoc + {mod_caps, []}, + {mod_configure,[]}, % requires mod_adhoc + {mod_admin_extra, []}, + {mod_disco, []}, + %%{mod_echo, [{host, "echo.localhost"}]}, + {mod_irc, []}, + {mod_last, []}, + {mod_muc, [ + {host, "conference.@HOST@"}, + {access, muc}, + {access_create, muc}, + {access_persistent, muc}, + {access_admin, muc_admin} + ]}, + %%{mod_muc_log,[]}, + {mod_offline, []}, + {mod_privacy, []}, + {mod_private, []}, + %%{mod_proxy65,[]}, + {mod_pubsub, [{access_createnode, pubsub_createnode}, + {plugins, ["default", "pep"]} + ]}, + {mod_register, [ + %% + %% After successful registration, the user receives + %% a message with this subject and body. + %% + %%{welcome_message, {"Welcome!", + %% "Welcome to this Jabber server."}}, + + %% + %% When a user registers, send a notification to + %% these Jabber accounts. + %% + %%{registration_watchers, ["admin1@example.org"]}, + + {access, register} + ]}, + {mod_roster, []}, + %%{mod_service_log,[]}, + {mod_shared_roster,[]}, + {mod_stats, []}, + {mod_time, []}, + {mod_vcard, []}, + {mod_version, []} + ]}. + + +%%% $Id: ejabberd.cfg.example 988 2007-11-26 21:29:14Z badlop $ + +%%% Local Variables: +%%% mode: erlang +%%% End: +%%% vim: set filetype=erlang tabstop=8: diff --git a/roles/ejabberd/templates/ejabberd-xs.init b/roles/ejabberd/templates/ejabberd-xs.init new file mode 100755 index 000000000..9585e2ada --- /dev/null +++ b/roles/ejabberd/templates/ejabberd-xs.init @@ -0,0 +1,222 @@ +#!/bin/bash +# +# ejabberd Start and stop ejabberd. + +# chkconfig: - 40 60 +# description: ejabberd +# processname: ejabberd +# pidfile: /var/run/ejabberd/ejabberd.pid + +### BEGIN INIT INFO +# Provides: ejabberd +# Required-Start: network +# Required-Stop: network +# Default-Start: +# Default-Stop: 0 1 6 +# Short-Description: Start and stop ejabberd +# Description: A distributed, fault-tolerant Jabber/XMPP server +### END INIT INFO + +. /etc/rc.d/init.d/functions + +if [ -r /etc/sysconfig/ejabberd-xs ]; then + . /etc/sysconfig/ejabberd-xs +fi + +if [ ! "$CONFIG_FILE" ]; then + CONFIG_FILE=/etc/ejabberd/ejabberd.cfg +fi + +# /var/run is tmpfs in fc18, so need to create every time +mkdir -p /var/run/ejabberd +chown ejabberd:ejabberd /var/run/ejabberd + +# avoid using consolehelper, call ejabberdctl directly +progctl=/usr/sbin/ejabberdctl + +SYS_DOMAIN_FILE=/etc/sysconfig/xs_domain_name +OUR_DOMAIN_FILE=/etc/sysconfig/ejabberd_domain_name + +check_domain_configured() { + if [ ! -e /etc/sysconfig/xs_domain_name ]; then + echo "Domain not configured yet" > /dev/stderr + exit 1; + fi + + domain=`cat "$SYS_DOMAIN_FILE" ` + if [ "$domain" == "random.xs.laptop.org" ]; then + echo "Domain not configured yet" > /dev/stderr + exit 1; + fi + + #hostname=`hostname -f` + hostname=`hostname ` + if [ "$hostname" == "localhost.localdomain" ]; then + echo "Domain not configured yet" > /dev/stderr + fi + +# if [ "$hostname" != "schoolserver.$domain" ]; then +# echo "Domain changed -- restart to enable ejabberd" > /dev/stderr +# fi + + short_host=`hostname -s` + node_name=`cat $OUR_DOMAIN_FILE` + +# if [ ! -e "$OUR_DOMAIN_FILE" ] || ! cmp "$SYS_DOMAIN_FILE" "$OUR_DOMAIN_FILE" ; then + if [ ! -e "$OUR_DOMAIN_FILE" ] ; then + update_domain + fi +} + +update_domain() { + + BACKUP_SUFFIX=old + + if [ -e $CONFIG_FILE ]; then + cp $CONFIG_FILE $CONFIG_FILE.$BACKUP_SUFFIX || exit 1 + fi + + new_name=$short_host.$domain + + #(sed -e s/@@BASEDNSNAME2@@/$new_name/ $CONFIG_FILE.in > $CONFIG_FILE.tmp ) && mv $CONFIG_FILE.tmp $CONFIG_FILE || exit 1 + + # If we are changing the domain, we must clear the DB. + if [ -e /var/lib/ejabberd/online_src_created ] ; then + rm -f /var/lib/ejabberd/online_src_created + fi + if [ -d /var/lib/ejabberd/spool/ ]; then + rm -f /var/lib/ejabberd/spool/* + fi + + # Mark as done - + # cp "$SYS_DOMAIN_FILE" "$OUR_DOMAIN_FILE" + echo "$domain" > "$OUR_DOMAIN_FILE" +} + +setup_online_srg() { + + if [ -e /var/lib/ejabberd/online_src_created ]; then + return 0 + fi; + + # give ejabberd a bit of time to startup on XO-1 HW :-) + sleep 10; + + short_host=`hostname -s` + domain=`cat "$SYS_DOMAIN_FILE"` + + # Note: grep -q exits as soon as the match is found, which ejabberdctl + # doesn't like. So we send the output to /dev/null instead - more + # portable too. + # + # ejabberdctl should handle SIGPIPE without messing up, but that's + # a minor problem anyway. + # + if ! ejabberdctl srg_list "$short_host.$domain" | grep '^Online$' > /dev/null ; then + # ejabberdctl doesn't like spaces in the description field. + # backslashes work - but escaping is better left alone for now :-) + ejabberdctl srg_create Online "$short_host.$domain" \ + Online "Created_by_ejabberd_init" Online + [ $? -eq 0 ] || return 1 + fi + + if ! ejabberdctl srg_get_info Online "$short_host.$domain" | grep '^online_users: true$' > /dev/null ; then + ejabberdctl srg_user_add '@online@' "$short_host.$domain" \ + Online "$short_host.$domain" + [ $? -eq 0 ] || return 1 + fi + + # mark success + touch /var/lib/ejabberd/online_src_created +} + +is_running() { + /sbin/runuser -s /bin/bash - ejabberd -c "$progctl status" &>/dev/null +} + +start() { + echo -n $"Starting ejabberd: " + #if [ "$ULIMIT_MAX_FILES" ]; then + # ulimit -n $ULIMIT_MAX_FILES + #fi + + check_domain_configured + + # check whether ejabberd was already started + if is_running; then + echo -n "already running" && warning && echo + return 0 + fi + + daemon --user=ejabberd $progctl start --config $CONFIG_FILE \ + --ctl-config /etc/ejabberd/ejabberdctl.cfg \ + --logs "/var/log/ejabberd" \ + --spool "/var/lib/ejabberd/spool" \ + 2>/dev/null + RETVAL=$? + [ $RETVAL -eq 0 ] && touch /var/lock/subsys/ejabberd + echo + + # it takes some time to actually start necessary nodes + sleep 5 + + # Ignore the return val of setup_online_srg + # ==> startup even if the SRG setup had errors. + set +e; + setup_online_srg + + return $RETVAL +} + +stop() { + # Stop daemons. + echo -n "Shutting down ejabberd: " + + # check whether ejabberd was already stopped + if ! is_running; then + echo -n "already stopped" && warning && echo + return 0 + fi + + daemon $progctl stop 2>/dev/null + RETVAL=$? + [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/ejabberd + echo + + # it takes some time to actually stop necessary nodes + sleep 5 + + return $RETVAL +} + +restart() { + stop + sleep 5 + start +} + +# See how we were called. +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart|force-reload) + restart + ;; + condrestart|try-restart) + [ -f /var/lock/subsys/ejabberd ] && restart || : + ;; + status) + $progctl status + ;; + *) + echo "Usage: ejabberd {start|stop|restart|force-reload|condrestart|try-restart|status}" + exit 2 +esac + +exit $RETVAL + + diff --git a/roles/ejabberd/templates/ejabberd-xs.service.j2 b/roles/ejabberd/templates/ejabberd-xs.service.j2 new file mode 100755 index 000000000..73a9b9ea3 --- /dev/null +++ b/roles/ejabberd/templates/ejabberd-xs.service.j2 @@ -0,0 +1,17 @@ +[Unit] +Description=A distributed, fault-tolerant Jabber/XMPP server +After=network.target local-fs.target + +[Service] +Type=oneshot +User=root +Group=root +LimitNOFILE=50000 +RestartSec=5 +EnvironmentFile=/etc/sysconfig/ejabberd-xs +ExecStart=/usr/libexec/ejabberd-xs start +ExecStop=/usr/libexec/ejabberd-xs stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/roles/ejabberd/templates/ejabberd.tmpfiles b/roles/ejabberd/templates/ejabberd.tmpfiles new file mode 100644 index 000000000..e8b7b9a5b --- /dev/null +++ b/roles/ejabberd/templates/ejabberd.tmpfiles @@ -0,0 +1,2 @@ +d /run/lock/ejabberdctl 0750 ejabberd ejabberd +d /var/run/ejabberd 0750 ejabberd ejabberd diff --git a/roles/ejabberd/templates/ejabberdctl.cfg.j2 b/roles/ejabberd/templates/ejabberdctl.cfg.j2 new file mode 100755 index 000000000..5d3d972e1 --- /dev/null +++ b/roles/ejabberd/templates/ejabberdctl.cfg.j2 @@ -0,0 +1,154 @@ +# +# In this file you can configure options that are passed by ejabberdctl +# to the erlang runtime system when starting ejabberd +# + +#' POLL: Kernel polling ([true|false]) +# +# The kernel polling option requires support in the kernel. +# Additionally, you need to enable this feature while compiling Erlang. +# +# Default: true +# +#POLL=true + +#. +#' SMP: SMP support ([enable|auto|disable]) +# +# Explanation in Erlang/OTP documentation: +# enable: starts the Erlang runtime system with SMP support enabled. +# This may fail if no runtime system with SMP support is available. +# auto: starts the Erlang runtime system with SMP support enabled if it +# is available and more than one logical processor are detected. +# disable: starts a runtime system without SMP support. +# +# Default: auto +# +#SMP=auto + +#. +#' ERL_MAX_PORTS: Maximum number of simultaneously open Erlang ports +# +# ejabberd consumes two or three ports for every connection, either +# from a client or from another Jabber server. So take this into +# account when setting this limit. +# +# Default: 32000 +# Maximum: 268435456 +# +#ERL_MAX_PORTS=32000 + +#. +#' FIREWALL_WINDOW: Range of allowed ports to pass through a firewall +# +# If Ejabberd is configured to run in cluster, and a firewall is blocking ports, +# it's possible to make Erlang use a defined range of port (instead of dynamic +# ports) for node communication. +# +# Default: not defined +# Example: 4200-4210 +# +#FIREWALL_WINDOW= + +#. +#' INET_DIST_INTERFACE: IP address where this Erlang node listens other nodes +# +# This communication is used by ejabberdctl command line tool, +# and in a cluster of several ejabberd nodes. +# Notice that the IP address must be specified in the Erlang syntax. +# +# Default: {127,0,0,1} +# +#INET_DIST_INTERFACE={127,0,0,1} + +#. +#' ERL_EPMD_ADDRESS: IP addresses where epmd listens for connections +# +# IMPORTANT: This option works only in Erlang/OTP R14B03 and newer. +# +# This environment variable may be set to a comma-separated +# list of IP addresses, in which case the epmd daemon +# will listen only on the specified address(es) and on the +# loopback address (which is implicitly added to the list if it +# has not been specified). The default behaviour is to listen on +# all available IP addresses. +# +# Default: 0.0.0.0 +# +#ERL_EPMD_ADDRESS=127.0.0.1 + +#. +#' ERL_PROCESSES: Maximum number of Erlang processes +# +# Erlang consumes a lot of lightweight processes. If there is a lot of activity +# on ejabberd so that the maximum number of processes is reached, people will +# experience greater latency times. As these processes are implemented in +# Erlang, and therefore not related to the operating system processes, you do +# not have to worry about allowing a huge number of them. +# +# Default: 250000 +# Maximum: 268435456 +# +#ERL_PROCESSES=250000 + +#. +#' ERL_MAX_ETS_TABLES: Maximum number of ETS and Mnesia tables +# +# The number of concurrent ETS and Mnesia tables is limited. When the limit is +# reached, errors will appear in the logs: +# ** Too many db tables ** +# You can safely increase this limit when starting ejabberd. It impacts memory +# consumption but the difference will be quite small. +# +# Default: 1400 +# +#ERL_MAX_ETS_TABLES=1400 + +#. +#' ERL_OPTIONS: Additional Erlang options +# +# The next variable allows to specify additional options passed to erlang while +# starting ejabberd. Some useful options are -noshell, -detached, -heart. When +# ejabberd is started from an init.d script options -noshell and -detached are +# added implicitly. See erl(1) for more info. +# +# It might be useful to add "-pa /usr/local/lib/ejabberd/ebin" if you +# want to add local modules in this path. +# +# Default: "" +# +#ERL_OPTIONS="" + +#. +#' ERLANG_NODE: Erlang node name +# +# The next variable allows to explicitly specify erlang node for ejabberd +# It can be given in different formats: +# ERLANG_NODE=ejabberd +# Lets erlang add hostname to the node (ejabberd uses short name in this case) +# ERLANG_NODE=ejabberd@hostname +# Erlang uses node name as is (so make sure that hostname is a real +# machine hostname or you'll not be able to control ejabberd) +# ERLANG_NODE=ejabberd@hostname.domainname +# The same as previous, but erlang will use long hostname +# (see erl (1) manual for details) +# +# Default: ejabberd@localhost +# +#ERLANG_NODE=ejabberd@localhost + +#. +#' EJABBERD_PID_PATH: ejabberd PID file +# +# Indicate the full path to the ejabberd Process identifier (PID) file. +# If this variable is defined, ejabberd writes the PID file when starts, +# and deletes it when stops. +# Remember to create the directory and grant write permission to ejabberd. +# +# Default: don't write PID file +# +EJABBERD_PID_PATH=/var/run/ejabberd/ejabberd.pid + +#. +#' +# vim: foldmarker=#',#. foldmethod=marker: diff --git a/roles/ejabberd/templates/xs-ejabberd-srg b/roles/ejabberd/templates/xs-ejabberd-srg new file mode 100755 index 000000000..4f3b5bc32 --- /dev/null +++ b/roles/ejabberd/templates/xs-ejabberd-srg @@ -0,0 +1,46 @@ +#!/bin/bash + +progctl=/usr/sbin/ejabberdctl + +SYS_DOMAIN_FILE=/etc/sysconfig/xs_domain_name +OUR_DOMAIN_FILE=/etc/sysconfig/ejabberd_domain_name + +setup_online_srg() { + + if [ -e /var/lib/ejabberd/online_src_created ]; then + return 0 + fi; + + # give ejabberd a bit of time to startup on XO-1 HW :-) + sleep 10; + + short_host=`hostname -s` + domain=`cat "$SYS_DOMAIN_FILE"` + + # Note: grep -q exits as soon as the match is found, which ejabberdctl + # doesn't like. So we send the output to /dev/null instead - more + # portable too. + # + # ejabberdctl should handle SIGPIPE without messing up, but that's + # a minor problem anyway. + # + if ! ejabberdctl srg_list "$short_host.$domain" | grep '^Online$' > /dev/null ; then + # ejabberdctl doesn't like spaces in the description field. + # backslashes work - but escaping is better left alone for now :-) + ejabberdctl srg_create Online "$short_host.$domain" \ + Online "Created_by_ejabberd_init" Online + [ $? -eq 0 ] || return 1 + fi + + if ! ejabberdctl srg_get_info Online "$short_host.$domain" | grep '^online_users: true$' > /dev/null ; then + ejabberdctl srg_user_add '@online@' "$short_host.$domain" \ + Online "$short_host.$domain" + [ $? -eq 0 ] || return 1 + fi + + # mark success + touch /var/lib/ejabberd/online_src_created +} + +setup_online_srg + diff --git a/roles/elgg/README.rst b/roles/elgg/README.rst new file mode 100644 index 000000000..0adcc580f --- /dev/null +++ b/roles/elgg/README.rst @@ -0,0 +1,49 @@ +=========== +ELGG README +=========== + +Elgg is an award-winning social networking engine, delivering the building blocks +that enable businesses, schools, universities and associations to create their own +fully-featured social networks and applications. + +http://elgg.org/ + +After Installation +------------------ + +Go to http://schoolserver.lan/elgg and log on as Admin with password changeme. + +Change the following: + +* Administrator password + +* Title to appear on elgg screens and any other settings as desired. + +Locations +--------- + +- The uploaded files are expected to be in /library/elgg +- The URL is /elgg + +Parameters +---------- + +Please review vars/main.yml as the installation parameters have +some constraints. + +Users and Passwords +------------------- + +There are a number of seemilingly similar user names and passwords in this installation: + +* dbuser - the mysql user that elgg uses to access the database. This is a local variable + the name of which corresponds to that in the elgg settings.php file. + +* dbpassword - password for dbuser. This is also a local variable + the name of which corresponds to that in the elgg settings.php file. + +* elgg_mysql_password - this is the global name for dbpassword in default_vars.yml. + +* elgg_admin_user - the elgg (not mysql) user that is the administrator. + +* elgg_admin_password - the password for elgg_admin_user. \ No newline at end of file diff --git a/roles/elgg/defaults/main.yml b/roles/elgg/defaults/main.yml new file mode 100644 index 000000000..8a617ccb4 --- /dev/null +++ b/roles/elgg/defaults/main.yml @@ -0,0 +1,23 @@ +elgg_xx: elgg +elgg_version: "1.12.12" + +# elgg_mysql_password: defined in default_vars +elgg_url: /elgg +elgg_upload_path: /library/elgg +elgg_install: True +elgg_enabled: False + +# following variables used in elgg engine/settings.php template +timezone: America/New_York +dbuser: Admin +dbpassword: changeme +dbname: elggdb +dbhost: localhost +dbprefix: elgg_ + +# The following variables must be in sync with template/elggdb.sql.j2 +# If you change them, you will probably have to rebuild the database. +# They can be changed from the administrative interface once elgg is installed. + +elgg_admin_user: Admin +elgg_admin_password: changeme diff --git a/roles/elgg/meta/main.yml b/roles/elgg/meta/main.yml new file mode 100644 index 000000000..94e49405f --- /dev/null +++ b/roles/elgg/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - { role: mysql } diff --git a/roles/elgg/tasks/main.yml b/roles/elgg/tasks/main.yml new file mode 100644 index 000000000..807916348 --- /dev/null +++ b/roles/elgg/tasks/main.yml @@ -0,0 +1,125 @@ +- name: download current version from our copy + shell: wget {{ xsce_download_url }}/elgg-{{ elgg_version }}.zip -c -P {{ downloads_dir }} + when: not {{ use_cache }} and not {{ no_network }} + tags: + - download2 + +- name: Determine if software is already expanded + stat: path=/opt/elgg/index.php + register: elgg + +# use unzip and shell until unarchive works again +# unarchive: dest=/opt/ +# src={{ downloads_dir }}/elgg-{{ elgg_version }}.zip + +- name: Expand it to our location + shell: "/usr/bin/unzip -o {{ downloads_dir }}/elgg-{{ elgg_version }}.zip -d /opt" + when: elgg.stat.exists is defined and not elgg.stat.exists + +- name: change ownership + file: path=/opt/elgg-{{elgg_version }} + owner=apache + recurse=yes + +- name: Create a link to the versioned elgg folder + file: src=./elgg-{{ elgg_version }} + dest=/opt/elgg + state=link + force=true + +# elggdb.sql obtained with mysqldump --skip-add-drop-table elggdb > elggdb.sql + +- name: Create file to load database + template: src=elggdb.sql.j2 + dest=/tmp/elggdb.sql + +- name: Create a mysql database for elgg + mysql_db: name={{ dbname }} + when: mysql_enabled and elgg_enabled + register: create_elgg_database + +- name: Load elgg database dump + mysql_db: name={{ dbname }} + state=import + target=/tmp/elggdb.sql + when: mysql_enabled and elgg_enabled and create_elgg_database.changed + +- name: Remove database dump after load + file: name=/tmp/elggdb.sql state=absent + +- name: Create a user to access the elgg database + mysql_user: name={{ dbuser }} host={{ item }} password={{ dbpassword }} priv=*.*:ALL + with_items: + - 127.0.0.1 + - ::1 + - localhost + when: mysql_enabled and elgg_enabled + +- name: If the TZ is not set in env, set it to UTC + set_fact: local_tz='UTC' + when: local_tz == "" + +# The name of this file changed from 1.9 to 1.10. +- name: Copy default .htaccess to the root directory of elgg tree + copy: src="/opt/{{ elgg_xx }}/install/config/htaccess.dist" + dest="/opt/{{ elgg_xx }}/.htaccess" + mode=0644 + owner=apache + group=root + +- name: Modify .htaccess to have RewriteBase as our directory + lineinfile: backup=yes + dest="/opt/{{ elgg_xx }}/.htaccess" + state=present + insertafter='^#RewriteBase' + line="RewriteBase {{ elgg_url }}/" + +#regexp='^#RewriteBase' + +#- tar up a mysqldump of freshly installed database and use it in the install to avoid the startup form, which worries me a lot. (/var/lib/mysql/elggdb) + +#- use template to fix up settings in engine/settings.php with our variables substituted into engine/settings.example.php +- name: Substitute our parameters in engine/settings.example.php + template: src="settings.php.j2" + dest="/opt/{{ elgg_xx }}/engine/settings.php" + owner={{ apache_user }} + +- name: Install config file for elgg in Apache + template: src=elgg.conf dest=/etc/{{ apache_config_dir }}/elgg.conf + when: mysql_enabled and elgg_enabled + +- name: enable elgg + file: path=/etc/apache2/sites-enabled/elgg.conf + src=/etc/apache2/sites-available/elgg.conf + state=link + when: elgg_enabled and is_debian + +- name: disable elgg + file: path=/etc/apache2/sites-enabled/elgg.conf + state=absent + when: not elgg_enabled and is_debian + +- name: Change permissions on engine directory so apache can write + file: path=/opt/elgg/engine/ owner={{ apache_data }} mode=0755 state=directory + +- name: Create an upload directory that Apache can write in or elgg + file: path={{ elgg_upload_path }} state=directory owner={{ apache_data }} + +- name: add elgg to service list + ini_file: dest='{{ service_filelist }}' + section=elgg + option='{{ item.option }}' + value='{{ item.value }}' + with_items: + - option: name + value: elgg-social-netwoking + - option: description + value: '"Elgg is an award-winning social networking engine, delivering the building blocks that enable businesses, schools, universities and associations to create their own fully-featured social networks and applications"' + - option: path + value: /opt/elgg + - option: enabled + value: "{{ elgg_enabled }}" + +- name: Restart apache, so it picks up the new aliases + service: name={{ apache_service }} state=restarted + diff --git a/roles/elgg/templates/elgg.conf b/roles/elgg/templates/elgg.conf new file mode 100644 index 000000000..48f90166c --- /dev/null +++ b/roles/elgg/templates/elgg.conf @@ -0,0 +1,7 @@ +RewriteEngine on + +Alias /elgg /opt/elgg + + AllowOverride all + require all granted + diff --git a/roles/elgg/templates/elggdb.sql.j2 b/roles/elgg/templates/elggdb.sql.j2 new file mode 100644 index 000000000..ff3a043b7 --- /dev/null +++ b/roles/elgg/templates/elggdb.sql.j2 @@ -0,0 +1,718 @@ +-- MySQL dump 10.14 Distrib 5.5.47-MariaDB, for Linux (x86_64) +-- +-- Host: localhost Database: elggdb +-- ------------------------------------------------------ +-- Server version 5.5.47-MariaDB + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `elgg_access_collection_membership` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_access_collection_membership` ( + `user_guid` int(11) NOT NULL, + `access_collection_id` int(11) NOT NULL, + PRIMARY KEY (`user_guid`,`access_collection_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_access_collection_membership` +-- + +LOCK TABLES `elgg_access_collection_membership` WRITE; +/*!40000 ALTER TABLE `elgg_access_collection_membership` DISABLE KEYS */; +/*!40000 ALTER TABLE `elgg_access_collection_membership` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_access_collections` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_access_collections` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` text NOT NULL, + `owner_guid` bigint(20) unsigned NOT NULL, + `site_guid` bigint(20) unsigned NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + KEY `owner_guid` (`owner_guid`), + KEY `site_guid` (`site_guid`) +) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_access_collections` +-- + +LOCK TABLES `elgg_access_collections` WRITE; +/*!40000 ALTER TABLE `elgg_access_collections` DISABLE KEYS */; +/*!40000 ALTER TABLE `elgg_access_collections` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_annotations` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_annotations` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `entity_guid` bigint(20) unsigned NOT NULL, + `name_id` int(11) NOT NULL, + `value_id` int(11) NOT NULL, + `value_type` enum('integer','text') NOT NULL, + `owner_guid` bigint(20) unsigned NOT NULL, + `access_id` int(11) NOT NULL, + `time_created` int(11) NOT NULL, + `enabled` enum('yes','no') NOT NULL DEFAULT 'yes', + PRIMARY KEY (`id`), + KEY `entity_guid` (`entity_guid`), + KEY `name_id` (`name_id`), + KEY `value_id` (`value_id`), + KEY `owner_guid` (`owner_guid`), + KEY `access_id` (`access_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_annotations` +-- + +LOCK TABLES `elgg_annotations` WRITE; +/*!40000 ALTER TABLE `elgg_annotations` DISABLE KEYS */; +/*!40000 ALTER TABLE `elgg_annotations` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_api_users` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_api_users` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `site_guid` bigint(20) unsigned DEFAULT NULL, + `api_key` varchar(40) DEFAULT NULL, + `secret` varchar(40) NOT NULL, + `active` int(1) DEFAULT '1', + PRIMARY KEY (`id`), + UNIQUE KEY `api_key` (`api_key`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_api_users` +-- + +LOCK TABLES `elgg_api_users` WRITE; +/*!40000 ALTER TABLE `elgg_api_users` DISABLE KEYS */; +/*!40000 ALTER TABLE `elgg_api_users` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_config` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_config` ( + `name` varchar(255) NOT NULL, + `value` text NOT NULL, + `site_guid` int(11) NOT NULL, + PRIMARY KEY (`name`,`site_guid`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_config` +-- + +LOCK TABLES `elgg_config` WRITE; +/*!40000 ALTER TABLE `elgg_config` DISABLE KEYS */; +INSERT INTO `elgg_config` VALUES ('view','s:7:\"default\";',1),('language','s:2:\"en\";',1),('default_access','s:1:\"2\";',1),('allow_registration','b:1;',1),('walled_garden','b:0;',1),('allow_user_default_access','s:0:\"\";',1),('default_limit','i:10;',1),('search_ft_min_word_len','s:1:\"4\";',1),('search_ft_max_word_len','s:2:\"84\";',1); +/*!40000 ALTER TABLE `elgg_config` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_datalists` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_datalists` ( + `name` varchar(255) NOT NULL, + `value` text NOT NULL, + PRIMARY KEY (`name`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_datalists` +-- + +LOCK TABLES `elgg_datalists` WRITE; +/*!40000 ALTER TABLE `elgg_datalists` DISABLE KEYS */; +INSERT INTO `elgg_datalists` VALUES ('installed','1475289209'),('dataroot','/library/elgg/'),('default_site','1'),('version','2015041400'),('simplecache_enabled','1'),('system_cache_enabled','1'),('simplecache_lastupdate','1475289209'),('path','/opt/elgg-1.12.12/'),('processed_upgrades','a:62:{i:0;s:14:\"2008100701.php\";i:1;s:14:\"2008101303.php\";i:2;s:14:\"2009022701.php\";i:3;s:14:\"2009041701.php\";i:4;s:14:\"2009070101.php\";i:5;s:14:\"2009102801.php\";i:6;s:14:\"2010010501.php\";i:7;s:14:\"2010033101.php\";i:8;s:14:\"2010040201.php\";i:9;s:14:\"2010052601.php\";i:10;s:14:\"2010060101.php\";i:11;s:14:\"2010060401.php\";i:12;s:14:\"2010061501.php\";i:13;s:14:\"2010062301.php\";i:14;s:14:\"2010062302.php\";i:15;s:14:\"2010070301.php\";i:16;s:14:\"2010071001.php\";i:17;s:14:\"2010071002.php\";i:18;s:14:\"2010111501.php\";i:19;s:14:\"2010121601.php\";i:20;s:14:\"2010121602.php\";i:21;s:14:\"2010121701.php\";i:22;s:14:\"2010123101.php\";i:23;s:14:\"2011010101.php\";i:24;s:61:\"2011021800-1.8_svn-goodbye_walled_garden-083121a656d06894.php\";i:25;s:61:\"2011022000-1.8_svn-custom_profile_fields-390ac967b0bb5665.php\";i:26;s:60:\"2011030700-1.8_svn-blog_status_metadata-4645225d7b440876.php\";i:27;s:51:\"2011031300-1.8_svn-twitter_api-12b832a5a7a3e1bd.php\";i:28;s:57:\"2011031600-1.8_svn-datalist_grows_up-0b8aec5a55cc1e1c.php\";i:29;s:61:\"2011032000-1.8_svn-widgets_arent_plugins-61836261fa280a5c.php\";i:30;s:59:\"2011032200-1.8_svn-admins_like_widgets-7f19d2783c1680d3.php\";i:31;s:14:\"2011052801.php\";i:32;s:60:\"2011061200-1.8b1-sites_need_a_site_guid-6d9dcbf46c0826cc.php\";i:33;s:62:\"2011092500-1.8.0.1-forum_reply_river_view-5758ce8d86ac56ce.php\";i:34;s:54:\"2011123100-1.8.2-fix_friend_river-b17e7ff8345c2269.php\";i:35;s:53:\"2011123101-1.8.2-fix_blog_status-b14c2a0e7b9e7d55.php\";i:36;s:50:\"2012012000-1.8.3-ip_in_syslog-87fe0f068cf62428.php\";i:37;s:50:\"2012012100-1.8.3-system_cache-93100e7d55a24a11.php\";i:38;s:59:\"2012041800-1.8.3-dont_filter_passwords-c0ca4a18b38ae2bc.php\";i:39;s:58:\"2012041801-1.8.3-multiple_user_tokens-852225f7fd89f6c5.php\";i:40;s:59:\"2013010200-1.9.0_dev-river_target_guid-66cbcae057cfa3ad.php\";i:41;s:62:\"2013010400-1.9.0_dev-comments_to_entities-faba94768b055b08.php\";i:42;s:61:\"2013021000-1.9.0_dev-web_services_plugin-85a61b4884b9b9e3.php\";i:43;s:60:\"2013022000-1.9.0-datadir_dates_to_guids-efb02ff11b9d6444.php\";i:44;s:59:\"2013030600-1.8.13-update_user_location-8999eb8bf1bdd9a3.php\";i:45;s:62:\"2013051700-1.8.15-add_missing_group_index-52a63a3a3ffaced2.php\";i:46;s:53:\"2013052900-1.8.15-ipv6_in_syslog-f5c2cc0196e9e731.php\";i:47;s:50:\"2013060900-1.8.15-site_secret-404fc165cf9e0ac9.php\";i:48;s:63:\"2013062200-1.9.0_dev-new_remember_me_table-da1bfc6f36c7952e.php\";i:49;s:54:\"2013062700-1.9.0_dev-add_db_queue-e6af82afc6d3eee3.php\";i:50;s:50:\"2014012000-1.8.18-remember_me-9a8a433685cf7be9.php\";i:51;s:61:\"2014031100-1.9.0_dev-elgg_upgrade_object-5577af53c93abd1a.php\";i:52;s:55:\"2014032200-1.9.0_dev-tinymce_to_ck-bbd2daa1912deaef.php\";i:53;s:60:\"2014042500-1.9.0_dev-site-notifications-0aae171afb7a00d8.php\";i:54;s:61:\"2014050600-1.9.0_dev-replies_to_entities-094ea0e36bc027d3.php\";i:55;s:60:\"2014070600-1.9.0_rc.3-river_enabled_col-bef9e6f0533ac338.php\";i:56;s:60:\"2014090900-1.9.0-fix_processed_upgrades-183ad189c71872d8.php\";i:57;s:62:\"2014111600-1.9.4-recheck_comments_upgrade-9da270072a5b0cad.php\";i:58;s:58:\"2014111800-1.10.0-add_new_hash_column-536087bbb2dbc82b.php\";i:59;s:56:\"2014130300-1.10.0-add_default_limit-fcef9e7ce01e26a4.php\";i:60;s:62:\"2015031300-1.11.0_dev-comment-access-sync-50c9764e5845315c.php\";i:61;s:59:\"2015041400-1.11.0_dev-trim_metastrings-d9a9fdfa28a981a3.php\";}'),('admin_registered','1'),('__site_secret__','zEtnDchxCARZxpQunLzmbcv6BOOpOMh9'); +/*!40000 ALTER TABLE `elgg_datalists` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_entities` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_entities` ( + `guid` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `type` enum('object','user','group','site') NOT NULL, + `subtype` int(11) DEFAULT NULL, + `owner_guid` bigint(20) unsigned NOT NULL, + `site_guid` bigint(20) unsigned NOT NULL, + `container_guid` bigint(20) unsigned NOT NULL, + `access_id` int(11) NOT NULL, + `time_created` int(11) NOT NULL, + `time_updated` int(11) NOT NULL, + `last_action` int(11) NOT NULL DEFAULT '0', + `enabled` enum('yes','no') NOT NULL DEFAULT 'yes', + PRIMARY KEY (`guid`), + KEY `type` (`type`), + KEY `subtype` (`subtype`), + KEY `owner_guid` (`owner_guid`), + KEY `site_guid` (`site_guid`), + KEY `container_guid` (`container_guid`), + KEY `access_id` (`access_id`), + KEY `time_created` (`time_created`), + KEY `time_updated` (`time_updated`) +) ENGINE=MyISAM AUTO_INCREMENT=44 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_entities` +-- + +LOCK TABLES `elgg_entities` WRITE; +/*!40000 ALTER TABLE `elgg_entities` DISABLE KEYS */; +INSERT INTO `elgg_entities` VALUES (1,'site',0,0,1,0,2,1475289209,1475289209,1475289209,'yes'),(2,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(3,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(4,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(5,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(6,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(7,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(8,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(9,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(10,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(11,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(12,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(13,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(14,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(15,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(16,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(17,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(18,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(19,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(20,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(21,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(22,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(23,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(24,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(25,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(26,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(27,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(28,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(29,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(30,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(31,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(32,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(33,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(34,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(35,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(36,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(37,'object',1,1,1,1,2,1475289209,1475289209,1475289209,'yes'),(38,'user',0,0,1,0,2,1475289252,1475289252,1475289252,'yes'),(39,'object',3,38,1,38,0,1475289252,1475289252,1475289252,'yes'),(40,'object',3,38,1,38,0,1475289252,1475289252,1475289252,'yes'),(41,'object',3,38,1,38,0,1475289252,1475289252,1475289252,'yes'),(42,'object',3,38,1,38,0,1475289252,1475289252,1475289252,'yes'),(43,'object',3,38,1,38,0,1475289252,1475289252,1475289252,'yes'); +/*!40000 ALTER TABLE `elgg_entities` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_entity_relationships` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_entity_relationships` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `guid_one` bigint(20) unsigned NOT NULL, + `relationship` varchar(50) NOT NULL, + `guid_two` bigint(20) unsigned NOT NULL, + `time_created` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `guid_one` (`guid_one`,`relationship`,`guid_two`), + KEY `relationship` (`relationship`), + KEY `guid_two` (`guid_two`) +) ENGINE=MyISAM AUTO_INCREMENT=25 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_entity_relationships` +-- + +LOCK TABLES `elgg_entity_relationships` WRITE; +/*!40000 ALTER TABLE `elgg_entity_relationships` DISABLE KEYS */; +INSERT INTO `elgg_entity_relationships` VALUES (1,2,'active_plugin',1,1475289209),(2,3,'active_plugin',1,1475289209),(3,4,'active_plugin',1,1475289209),(4,6,'active_plugin',1,1475289209),(5,13,'active_plugin',1,1475289209),(6,14,'active_plugin',1,1475289209),(7,15,'active_plugin',1,1475289209),(8,16,'active_plugin',1,1475289209),(9,17,'active_plugin',1,1475289209),(10,19,'active_plugin',1,1475289209),(11,20,'active_plugin',1,1475289209),(12,22,'active_plugin',1,1475289209),(13,23,'active_plugin',1,1475289209),(14,24,'active_plugin',1,1475289209),(15,25,'active_plugin',1,1475289209),(16,26,'active_plugin',1,1475289209),(17,27,'active_plugin',1,1475289209),(18,28,'active_plugin',1,1475289209),(19,29,'active_plugin',1,1475289209),(20,30,'active_plugin',1,1475289209),(21,33,'active_plugin',1,1475289209),(22,35,'active_plugin',1,1475289209),(23,37,'active_plugin',1,1475289209),(24,38,'member_of_site',1,1475289252); +/*!40000 ALTER TABLE `elgg_entity_relationships` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_entity_subtypes` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_entity_subtypes` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `type` enum('object','user','group','site') NOT NULL, + `subtype` varchar(50) NOT NULL, + `class` varchar(50) NOT NULL DEFAULT '', + PRIMARY KEY (`id`), + UNIQUE KEY `type` (`type`,`subtype`) +) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_entity_subtypes` +-- + +LOCK TABLES `elgg_entity_subtypes` WRITE; +/*!40000 ALTER TABLE `elgg_entity_subtypes` DISABLE KEYS */; +INSERT INTO `elgg_entity_subtypes` VALUES (1,'object','plugin','ElggPlugin'),(2,'object','file','ElggFile'),(3,'object','widget','ElggWidget'),(4,'object','comment','ElggComment'),(5,'object','elgg_upgrade','ElggUpgrade'),(6,'object','blog','ElggBlog'),(7,'object','discussion_reply','ElggDiscussionReply'),(8,'object','thewire','ElggWire'); +/*!40000 ALTER TABLE `elgg_entity_subtypes` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_geocode_cache` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_geocode_cache` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `location` varchar(128) DEFAULT NULL, + `lat` varchar(20) DEFAULT NULL, + `long` varchar(20) DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `location` (`location`) +) ENGINE=MEMORY DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_geocode_cache` +-- + +LOCK TABLES `elgg_geocode_cache` WRITE; +/*!40000 ALTER TABLE `elgg_geocode_cache` DISABLE KEYS */; +/*!40000 ALTER TABLE `elgg_geocode_cache` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_groups_entity` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_groups_entity` ( + `guid` bigint(20) unsigned NOT NULL, + `name` text NOT NULL, + `description` text NOT NULL, + PRIMARY KEY (`guid`), + KEY `name` (`name`(50)), + KEY `description` (`description`(50)), + FULLTEXT KEY `name_2` (`name`,`description`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_groups_entity` +-- + +LOCK TABLES `elgg_groups_entity` WRITE; +/*!40000 ALTER TABLE `elgg_groups_entity` DISABLE KEYS */; +/*!40000 ALTER TABLE `elgg_groups_entity` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_hmac_cache` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_hmac_cache` ( + `hmac` varchar(255) NOT NULL, + `ts` int(11) NOT NULL, + PRIMARY KEY (`hmac`), + KEY `ts` (`ts`) +) ENGINE=MEMORY DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_hmac_cache` +-- + +LOCK TABLES `elgg_hmac_cache` WRITE; +/*!40000 ALTER TABLE `elgg_hmac_cache` DISABLE KEYS */; +/*!40000 ALTER TABLE `elgg_hmac_cache` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_metadata` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_metadata` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `entity_guid` bigint(20) unsigned NOT NULL, + `name_id` int(11) NOT NULL, + `value_id` int(11) NOT NULL, + `value_type` enum('integer','text') NOT NULL, + `owner_guid` bigint(20) unsigned NOT NULL, + `access_id` int(11) NOT NULL, + `time_created` int(11) NOT NULL, + `enabled` enum('yes','no') NOT NULL DEFAULT 'yes', + PRIMARY KEY (`id`), + KEY `entity_guid` (`entity_guid`), + KEY `name_id` (`name_id`), + KEY `value_id` (`value_id`), + KEY `owner_guid` (`owner_guid`), + KEY `access_id` (`access_id`) +) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_metadata` +-- + +LOCK TABLES `elgg_metadata` WRITE; +/*!40000 ALTER TABLE `elgg_metadata` DISABLE KEYS */; +INSERT INTO `elgg_metadata` VALUES (1,1,1,2,'text',0,2,1475289209,'yes'),(2,38,3,4,'text',38,2,1475289252,'yes'),(3,38,5,4,'text',0,2,1475289252,'yes'),(4,38,6,7,'text',0,2,1475289252,'yes'); +/*!40000 ALTER TABLE `elgg_metadata` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_metastrings` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_metastrings` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `string` text NOT NULL, + PRIMARY KEY (`id`), + KEY `string` (`string`(50)) +) ENGINE=MyISAM AUTO_INCREMENT=13 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_metastrings` +-- + +LOCK TABLES `elgg_metastrings` WRITE; +/*!40000 ALTER TABLE `elgg_metastrings` DISABLE KEYS */; +INSERT INTO `elgg_metastrings` VALUES (1,'email'),(2,'admin@schoolserver.lan'),(3,'notification:method:email'),(4,'1'),(5,'validated'),(6,'validated_method'),(7,'admin_user'),(8,'toId'),(9,'38'),(10,'readYet'),(11,'0'),(12,'msg'); +/*!40000 ALTER TABLE `elgg_metastrings` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_objects_entity` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_objects_entity` ( + `guid` bigint(20) unsigned NOT NULL, + `title` text NOT NULL, + `description` text NOT NULL, + PRIMARY KEY (`guid`), + FULLTEXT KEY `title` (`title`,`description`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_objects_entity` +-- + +LOCK TABLES `elgg_objects_entity` WRITE; +/*!40000 ALTER TABLE `elgg_objects_entity` DISABLE KEYS */; +INSERT INTO `elgg_objects_entity` VALUES (2,'aalborg_theme',''),(3,'blog',''),(4,'bookmarks',''),(5,'categories',''),(6,'ckeditor',''),(7,'custom_index',''),(8,'dashboard',''),(9,'developers',''),(10,'diagnostics',''),(11,'embed',''),(12,'externalpages',''),(13,'file',''),(14,'garbagecollector',''),(15,'groups',''),(16,'htmlawed',''),(17,'invitefriends',''),(18,'legacy_urls',''),(19,'likes',''),(20,'logbrowser',''),(21,'login_as',''),(22,'logrotate',''),(23,'members',''),(24,'messageboard',''),(25,'messages',''),(26,'notifications',''),(27,'pages',''),(28,'profile',''),(29,'reportedcontent',''),(30,'search',''),(31,'site_notifications',''),(32,'tagcloud',''),(33,'thewire',''),(34,'twitter_api',''),(35,'uservalidationbyemail',''),(36,'web_services',''),(37,'zaudio',''),(39,'',''),(40,'',''),(41,'',''),(42,'',''),(43,'',''); +/*!40000 ALTER TABLE `elgg_objects_entity` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_private_settings` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_private_settings` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `entity_guid` int(11) NOT NULL, + `name` varchar(128) NOT NULL, + `value` text NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `entity_guid` (`entity_guid`,`name`), + KEY `name` (`name`), + KEY `value` (`value`(50)) +) ENGINE=MyISAM AUTO_INCREMENT=58 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_private_settings` +-- + +LOCK TABLES `elgg_private_settings` WRITE; +/*!40000 ALTER TABLE `elgg_private_settings` DISABLE KEYS */; +INSERT INTO `elgg_private_settings` VALUES (1,2,'elgg:internal:priority','36'),(2,3,'elgg:internal:priority','1'),(3,4,'elgg:internal:priority','2'),(4,5,'elgg:internal:priority','3'),(5,6,'elgg:internal:priority','4'),(6,7,'elgg:internal:priority','5'),(7,8,'elgg:internal:priority','6'),(8,9,'elgg:internal:priority','7'),(9,10,'elgg:internal:priority','8'),(10,11,'elgg:internal:priority','9'),(11,12,'elgg:internal:priority','10'),(12,13,'elgg:internal:priority','11'),(13,14,'elgg:internal:priority','12'),(14,15,'elgg:internal:priority','13'),(15,16,'elgg:internal:priority','14'),(16,17,'elgg:internal:priority','15'),(17,18,'elgg:internal:priority','16'),(18,19,'elgg:internal:priority','17'),(19,20,'elgg:internal:priority','18'),(20,21,'elgg:internal:priority','19'),(21,22,'elgg:internal:priority','20'),(22,23,'elgg:internal:priority','21'),(23,24,'elgg:internal:priority','22'),(24,25,'elgg:internal:priority','23'),(25,26,'elgg:internal:priority','24'),(26,27,'elgg:internal:priority','25'),(27,28,'elgg:internal:priority','26'),(28,29,'elgg:internal:priority','27'),(29,30,'elgg:internal:priority','28'),(30,31,'elgg:internal:priority','29'),(31,32,'elgg:internal:priority','30'),(32,33,'elgg:internal:priority','31'),(33,34,'elgg:internal:priority','32'),(34,35,'elgg:internal:priority','33'),(35,36,'elgg:internal:priority','34'),(36,37,'elgg:internal:priority','35'),(37,33,'limit','140'),(38,39,'handler','control_panel'),(39,39,'context','admin'),(40,39,'column','1'),(41,39,'order','0'),(42,40,'handler','admin_welcome'),(43,40,'context','admin'),(44,40,'order','10'),(45,40,'column','1'),(46,41,'handler','online_users'),(47,41,'context','admin'),(48,41,'column','2'),(49,41,'order','0'),(50,42,'handler','new_users'),(51,42,'context','admin'),(52,42,'order','10'),(53,42,'column','2'),(54,43,'handler','content_stats'),(55,43,'context','admin'),(56,43,'order','20'),(57,43,'column','2'); +/*!40000 ALTER TABLE `elgg_private_settings` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_queue` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_queue` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `name` varchar(255) NOT NULL, + `data` mediumblob NOT NULL, + `timestamp` int(11) NOT NULL, + `worker` varchar(32) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `name` (`name`), + KEY `retrieve` (`timestamp`,`worker`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_queue` +-- + +LOCK TABLES `elgg_queue` WRITE; +/*!40000 ALTER TABLE `elgg_queue` DISABLE KEYS */; +/*!40000 ALTER TABLE `elgg_queue` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_river` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_river` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `type` varchar(8) NOT NULL, + `subtype` varchar(32) NOT NULL, + `action_type` varchar(32) NOT NULL, + `access_id` int(11) NOT NULL, + `view` text NOT NULL, + `subject_guid` int(11) NOT NULL, + `object_guid` int(11) NOT NULL, + `target_guid` int(11) NOT NULL, + `annotation_id` int(11) NOT NULL, + `posted` int(11) NOT NULL, + `enabled` enum('yes','no') NOT NULL DEFAULT 'yes', + PRIMARY KEY (`id`), + KEY `type` (`type`), + KEY `action_type` (`action_type`), + KEY `access_id` (`access_id`), + KEY `subject_guid` (`subject_guid`), + KEY `object_guid` (`object_guid`), + KEY `target_guid` (`target_guid`), + KEY `annotation_id` (`annotation_id`), + KEY `posted` (`posted`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_river` +-- + +LOCK TABLES `elgg_river` WRITE; +/*!40000 ALTER TABLE `elgg_river` DISABLE KEYS */; +/*!40000 ALTER TABLE `elgg_river` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_sites_entity` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_sites_entity` ( + `guid` bigint(20) unsigned NOT NULL, + `name` text NOT NULL, + `description` text NOT NULL, + `url` varchar(255) NOT NULL, + PRIMARY KEY (`guid`), + UNIQUE KEY `url` (`url`), + FULLTEXT KEY `name` (`name`,`description`,`url`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_sites_entity` +-- + +LOCK TABLES `elgg_sites_entity` WRITE; +/*!40000 ALTER TABLE `elgg_sites_entity` DISABLE KEYS */; +INSERT INTO `elgg_sites_entity` VALUES (1,'My New Community','','http://schoolserver.lan/elgg/'); +/*!40000 ALTER TABLE `elgg_sites_entity` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_system_log` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_system_log` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `object_id` int(11) NOT NULL, + `object_class` varchar(50) NOT NULL, + `object_type` varchar(50) NOT NULL, + `object_subtype` varchar(50) NOT NULL, + `event` varchar(50) NOT NULL, + `performed_by_guid` int(11) NOT NULL, + `owner_guid` int(11) NOT NULL, + `access_id` int(11) NOT NULL, + `enabled` enum('yes','no') NOT NULL DEFAULT 'yes', + `time_created` int(11) NOT NULL, + `ip_address` varchar(46) NOT NULL, + PRIMARY KEY (`id`), + KEY `object_id` (`object_id`), + KEY `object_class` (`object_class`), + KEY `object_type` (`object_type`), + KEY `object_subtype` (`object_subtype`), + KEY `event` (`event`), + KEY `performed_by_guid` (`performed_by_guid`), + KEY `access_id` (`access_id`), + KEY `time_created` (`time_created`), + KEY `river_key` (`object_type`,`object_subtype`,`event`) +) ENGINE=MyISAM AUTO_INCREMENT=58 DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_system_log` +-- + +LOCK TABLES `elgg_system_log` WRITE; +/*!40000 ALTER TABLE `elgg_system_log` DISABLE KEYS */; +INSERT INTO `elgg_system_log` VALUES (1,2,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(2,3,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(3,4,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(4,5,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(5,6,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(6,7,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(7,8,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(8,9,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(9,10,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(10,11,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(11,12,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(12,13,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(13,14,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(14,15,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(15,16,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(16,17,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(17,18,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(18,19,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(19,20,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(20,21,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(21,22,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(22,23,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(23,24,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(24,25,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(25,26,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(26,27,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(27,28,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(28,29,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(29,30,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(30,31,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(31,32,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(32,33,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(33,34,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(34,35,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(35,36,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(36,37,'ElggPlugin','object','plugin','create',0,1,2,'yes',1475289209,'172.18.100.205'),(37,1,'ElggRelationship','relationship','active_plugin','create',0,0,2,'yes',1475289209,'172.18.100.205'),(38,24,'ElggRelationship','relationship','member_of_site','create',0,0,2,'yes',1475289252,'172.18.100.205'),(39,38,'ElggUser','user','','create',0,0,2,'yes',1475289252,'172.18.100.205'),(40,2,'ElggMetadata','metadata','notification:method:email','create',0,38,2,'yes',1475289252,'172.18.100.205'),(41,39,'ElggWidget','object','widget','create',0,38,2,'yes',1475289252,'172.18.100.205'),(42,40,'ElggWidget','object','widget','create',0,38,2,'yes',1475289252,'172.18.100.205'),(43,41,'ElggWidget','object','widget','create',0,38,2,'yes',1475289252,'172.18.100.205'),(44,42,'ElggWidget','object','widget','create',0,38,2,'yes',1475289252,'172.18.100.205'),(45,43,'ElggWidget','object','widget','create',0,38,2,'yes',1475289252,'172.18.100.205'),(46,38,'ElggUser','user','','make_admin',0,0,2,'yes',1475289252,'172.18.100.205'),(47,3,'ElggMetadata','metadata','validated','create',0,0,2,'yes',1475289252,'172.18.100.205'),(48,4,'ElggMetadata','metadata','validated_method','create',0,0,2,'yes',1475289252,'172.18.100.205'),(49,38,'ElggUser','user','','login:before',0,0,2,'yes',1475289252,'172.18.100.205'),(50,38,'ElggUser','user','','login',38,0,2,'yes',1475289252,'172.18.100.205'),(51,38,'ElggUser','user','','login:after',38,0,2,'yes',1475289252,'172.18.100.205'),(52,38,'ElggUser','user','','logout:before',38,0,2,'yes',1475289302,'172.18.100.205'),(53,38,'ElggUser','user','','logout',38,0,2,'yes',1475289302,'172.18.100.205'),(54,38,'ElggUser','user','','logout:after',0,0,2,'yes',1475289302,'172.18.100.205'),(55,38,'ElggUser','user','','login:before',0,0,2,'yes',1475289313,'172.18.100.205'),(56,38,'ElggUser','user','','login',38,0,2,'yes',1475289313,'172.18.100.205'),(57,38,'ElggUser','user','','login:after',38,0,2,'yes',1475289313,'172.18.100.205'); +/*!40000 ALTER TABLE `elgg_system_log` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_users_apisessions` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_users_apisessions` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `user_guid` bigint(20) unsigned NOT NULL, + `site_guid` bigint(20) unsigned NOT NULL, + `token` varchar(40) DEFAULT NULL, + `expires` int(11) NOT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `user_guid` (`user_guid`,`site_guid`), + KEY `token` (`token`) +) ENGINE=MEMORY DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_users_apisessions` +-- + +LOCK TABLES `elgg_users_apisessions` WRITE; +/*!40000 ALTER TABLE `elgg_users_apisessions` DISABLE KEYS */; +/*!40000 ALTER TABLE `elgg_users_apisessions` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_users_entity` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_users_entity` ( + `guid` bigint(20) unsigned NOT NULL, + `name` text NOT NULL, + `username` varchar(128) NOT NULL DEFAULT '', + `password` varchar(32) NOT NULL DEFAULT '' COMMENT 'Legacy password hashes', + `salt` varchar(8) NOT NULL DEFAULT '' COMMENT 'Legacy password salts', + `password_hash` varchar(255) NOT NULL DEFAULT '', + `email` text NOT NULL, + `language` varchar(6) NOT NULL DEFAULT '', + `banned` enum('yes','no') NOT NULL DEFAULT 'no', + `admin` enum('yes','no') NOT NULL DEFAULT 'no', + `last_action` int(11) NOT NULL DEFAULT '0', + `prev_last_action` int(11) NOT NULL DEFAULT '0', + `last_login` int(11) NOT NULL DEFAULT '0', + `prev_last_login` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`guid`), + UNIQUE KEY `username` (`username`), + KEY `password` (`password`), + KEY `email` (`email`(50)), + KEY `last_action` (`last_action`), + KEY `last_login` (`last_login`), + KEY `admin` (`admin`), + FULLTEXT KEY `name` (`name`), + FULLTEXT KEY `name_2` (`name`,`username`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_users_entity` +-- + +LOCK TABLES `elgg_users_entity` WRITE; +/*!40000 ALTER TABLE `elgg_users_entity` DISABLE KEYS */; +INSERT INTO `elgg_users_entity` VALUES (38,'School Server','Admin','','','$2y$10$zlirLmRcu5JMpj8NA/Tir.MY4DJQqvK7dAck0ujfBlmFW2UWwCZ/y','admin@schoolserver.lan','en','no','yes',1475289554,1475289554,1475289313,1475289252); +/*!40000 ALTER TABLE `elgg_users_entity` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_users_remember_me_cookies` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_users_remember_me_cookies` ( + `code` varchar(32) NOT NULL, + `guid` bigint(20) unsigned NOT NULL, + `timestamp` int(11) unsigned NOT NULL, + PRIMARY KEY (`code`), + KEY `timestamp` (`timestamp`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_users_remember_me_cookies` +-- + +LOCK TABLES `elgg_users_remember_me_cookies` WRITE; +/*!40000 ALTER TABLE `elgg_users_remember_me_cookies` DISABLE KEYS */; +/*!40000 ALTER TABLE `elgg_users_remember_me_cookies` ENABLE KEYS */; +UNLOCK TABLES; + +-- +-- Table structure for table `elgg_users_sessions` +-- + +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `elgg_users_sessions` ( + `session` varchar(255) NOT NULL, + `ts` int(11) unsigned NOT NULL DEFAULT '0', + `data` mediumblob, + PRIMARY KEY (`session`), + KEY `ts` (`ts`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +/*!40101 SET character_set_client = @saved_cs_client */; + +-- +-- Dumping data for table `elgg_users_sessions` +-- + +LOCK TABLES `elgg_users_sessions` WRITE; +/*!40000 ALTER TABLE `elgg_users_sessions` DISABLE KEYS */; +INSERT INTO `elgg_users_sessions` VALUES ('l74sjfekegmkddl6i5ji36pci7',1475289303,'_sf2_attributes|a:2:{s:14:\"__elgg_session\";s:22:\"EczXso_g6GlfGaa0T7DO98\";s:3:\"msg\";a:0:{}}_sf2_flashes|a:0:{}_sf2_meta|a:3:{s:1:\"u\";i:1475289302;s:1:\"c\";i:1475289302;s:1:\"l\";s:1:\"0\";}'),('3gof2j0qojcjhh1mmrd8vmms66',1475289554,'_sf2_attributes|a:3:{s:14:\"__elgg_session\";s:22:\"EczXso_g6GlfGaa0T7DO98\";s:3:\"msg\";a:0:{}s:4:\"guid\";i:38;}_sf2_flashes|a:0:{}_sf2_meta|a:3:{s:1:\"u\";i:1475289554;s:1:\"c\";i:1475289302;s:1:\"l\";s:1:\"0\";}'); +/*!40000 ALTER TABLE `elgg_users_sessions` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2016-10-01 9:53:53 diff --git a/roles/elgg/templates/settings.php.j2 b/roles/elgg/templates/settings.php.j2 new file mode 100644 index 000000000..a9124440e --- /dev/null +++ b/roles/elgg/templates/settings.php.j2 @@ -0,0 +1,212 @@ +dbuser + */ +$CONFIG->dbuser = '{{dbuser}}'; + +/** + * The database password + * + * @global string $CONFIG->dbpass + */ +$CONFIG->dbpass = '{{dbpassword}}'; + +/** + * The database name + * + * @global string $CONFIG->dbname + */ +$CONFIG->dbname = '{{dbname}}'; + +/** + * The database host. + * + * For most installations, this is 'localhost' + * + * @global string $CONFIG->dbhost + */ +$CONFIG->dbhost = '{{dbhost}}'; + +/** + * The database prefix + * + * This prefix will be appended to all Elgg tables. If you're sharing + * a database with other applications, use a database prefix to namespace tables + * in order to avoid table name collisions. + * + * @global string $CONFIG->dbprefix + */ +$CONFIG->dbprefix = '{{dbprefix}}'; + +/** + * Multiple database connections + * + * Elgg supports master/slave MySQL configurations. The master should be set as + * the 'write' connection and the slave(s) as the 'read' connection(s). + * + * To use, uncomment the below configuration and update for your site. + */ +//$CONFIG->db['split'] = true; + +//$CONFIG->db['write']['dbuser'] = ""; +//$CONFIG->db['write']['dbpass'] = ""; +//$CONFIG->db['write']['dbname'] = ""; +//$CONFIG->db['write']['dbhost'] = ""; + +//$CONFIG->db['read'][0]['dbuser'] = ""; +//$CONFIG->db['read'][0]['dbpass'] = ""; +//$CONFIG->db['read'][0]['dbname'] = ""; +//$CONFIG->db['read'][0]['dbhost'] = ""; +//$CONFIG->db['read'][1]['dbuser'] = ""; +//$CONFIG->db['read'][1]['dbpass'] = ""; +//$CONFIG->db['read'][1]['dbname'] = ""; +//$CONFIG->db['read'][1]['dbhost'] = ""; + +/** + * Memcache setup (optional) + * This is where you may optionally set up memcache. + * + * Requirements: + * 1) One or more memcache servers (http://www.danga.com/memcached/) + * 2) PHP memcache wrapper (http://php.net/manual/en/memcache.setup.php) + * + * Note: Multiple server support is only available on server 1.2.1 + * or higher with PECL library > 2.0.0 + */ +//$CONFIG->memcache = true; +// +//$CONFIG->memcache_servers = array ( +// array('server1', 11211), +// array('server2', 11211) +//); + + +/** + * Better caching performance + * + * Configuring the location of your data directory and enabling simplecache in + * the settings.php file improves caching performance. It allows Elgg to skip + * connecting to the database when serving cached JavaScript and CSS files. If + * you uncomment and configure these settings, you will not be able to change + * them from the Elgg advanced settings page. + */ +//$CONFIG->dataroot = ""; +//$CONFIG->simplecache_enabled = true; + + +/** + * Cookie configuration + * + * Elgg uses 2 cookies: a PHP session cookie and an extended login cookie + * (also called the remember me cookie). See the PHP manual for documentation on + * each of these parameters. Possible options: + * + * - Set the session name to share the session across applications. + * - Set the path because Elgg is not installed in the root of the web directory. + * - Set the secure option to true if you only serve the site over HTTPS. + * - Set the expire option on the remember me cookie to change its lifetime + * + * To use, uncomment the appropriate sections below and update for your site. + * + * @global array $CONFIG->cookies + */ +// get the default parameters from php.ini +//$CONFIG->cookies['session'] = session_get_cookie_params(); +//$CONFIG->cookies['session']['name'] = "Elgg"; +// optionally overwrite the defaults from php.ini below +//$CONFIG->cookies['session']['path'] = "/"; +//$CONFIG->cookies['session']['domain'] = ""; +//$CONFIG->cookies['session']['secure'] = false; +//$CONFIG->cookies['session']['httponly'] = false; + +// extended session cookie +//$CONFIG->cookies['remember_me'] = session_get_cookie_params(); +//$CONFIG->cookies['remember_me']['name'] = "elggperm"; +//$CONFIG->cookies['remember_me']['expire'] = strtotime("+30 days"); +// optionally overwrite the defaults from php.ini below +//$CONFIG->cookies['remember_me']['path'] = "/"; +//$CONFIG->cookies['remember_me']['domain'] = ""; +//$CONFIG->cookies['remember_me']['secure'] = false; +//$CONFIG->cookies['remember_me']['httponly'] = false; + + +/** + * Use non-standard headers for broken MTAs. + * + * The default header EOL for headers is \r\n. This causes problems + * on some broken MTAs. Setting this to true will cause Elgg to use + * \n, which will fix some problems sending email on broken MTAs. + * + * @global bool $CONFIG->broken_mta + */ +$CONFIG->broken_mta = false; + +/** + * Disable the database query cache + * + * Elgg stores each query and its results in a query cache. + * On large sites or long-running scripts, this cache can grow to be + * large. To disable query caching, set this to true. + * + * @global bool $CONFIG->db_disable_query_cache + */ +$CONFIG->db_disable_query_cache = false; + +/** + * Minimum password length + * + * This value is used when validating a user's password during registration. + * + * @global int $CONFIG->min_password_length + */ +$CONFIG->min_password_length = 6; + +/** + * This is an optional script used to override Elgg's default handling of + * uncaught exceptions. + * + * This should be an absolute file path to a php script that will be called + * any time an uncaught exception is thrown. + * + * The script will have access to the following variables as part of the scope + * global $CONFIG + * $exception - the unhandled exception + * + * @warning - the database may not be available + * + * @global string $CONFIG->exception_include + */ +$CONFIG->exception_include = ''; diff --git a/roles/gateway/README.rst b/roles/gateway/README.rst new file mode 100644 index 000000000..6d7279198 --- /dev/null +++ b/roles/gateway/README.rst @@ -0,0 +1,46 @@ +============== +Gateway README +============== + +Under the heading of Gateway are a number of services that provide dhcp addresses and NAT to the lan +and filter wan access both in terms of content and bandwidth. + +LAN +--- + +The LAN is managed by the dhcpd service and by iptables. The configuration of iptables is complicated +and works as follows: + +/etc/systemd/system/iptables.service calls +/etc/sysconfig/iptables-config which calls +/usr/bin/xs-gen-iptables +and saves the resultant configuration to /etc/sysconfig/iptables +it then supplies additional rules to iptables + +As of March 2014 the following files are obsolete + +/etc/sysconfig/olpc-scripts/iptables-xs + +/etc/sysconfig/olpc-scripts/ip6tables-xs + +Filters +------- + +Content is filtered by squid and dansguardian and there are ansible variables that control them. + +There is a white list file, sites.whitelist.txt. URL patterns not in this file will not be accessible. + +An additional rule to block https has been added to iptables, also controlled by an ansible variable. + +**N.B. https blocking and whitelist checking are disabled by default** + +To enable whitelist checking and/or https blocking edit + +#Gateway Filters +gw_squid_whitelist: False +gw_block_https: False + +changing False to True where appropriate and then run runtags facts, gateway + +Bandwidth is filtered by wondershaper. + diff --git a/roles/gateway/tasks/main.yml b/roles/gateway/tasks/main.yml new file mode 100644 index 000000000..ca15722ca --- /dev/null +++ b/roles/gateway/tasks/main.yml @@ -0,0 +1 @@ +-name: placekeeper diff --git a/roles/httpd/files/html/assets/lang_codes.json b/roles/httpd/files/html/assets/lang_codes.json new file mode 100755 index 000000000..9f3c6602a --- /dev/null +++ b/roles/httpd/files/html/assets/lang_codes.json @@ -0,0 +1 @@ +{"aar":{"iso2":"aa","engname":"Afar","locname":"Afar"}, "abk":{"iso2":"ab","engname":"Abkhazian","locname":"Аҧсуа"}, "ace":{"iso2":"ace","engname":"Acehnese","locname":"Bahsa Acèh"}, "afr":{"iso2":"af","engname":"Afrikaans","locname":"Afrikaans"}, "aka":{"iso2":"ak","engname":"Akan","locname":"Akana"}, "als":{"iso2":"als","engname":"Alemannic","locname":"Alemannisch"}, "amh":{"iso2":"am","engname":"Amharic","locname":"አማርኛ"}, "ang":{"iso2":"ang","engname":"Anglo-Saxon","locname":"Englisc"}, "ara":{"iso2":"ar","engname":"Arabic","locname":"العربية"}, "arc":{"iso2":"arc","engname":"Aramaic","locname":"ܐܪܡܝܐ"}, "arg":{"iso2":"an","engname":"Aragonese","locname":"Aragonés"}, "arz":{"iso2":"arz","engname":"Egyptian Arabic","locname":"مصرى (Maṣri)"}, "asm":{"iso2":"as","engname":"Assamese","locname":"অসমীয়া"}, "ast":{"iso2":"ast","engname":"Asturian","locname":"Asturianu"}, "ava":{"iso2":"av","engname":"Avar","locname":"Авар"}, "aym":{"iso2":"ay","engname":"Aymara","locname":"Aymar"}, "aze":{"iso2":"az","engname":"Azerbaijani","locname":"Azərbaycanca"}, "bak":{"iso2":"ba","engname":"Bashkir","locname":"Башҡорт"}, "bam":{"iso2":"bm","engname":"Bambara","locname":"Bamanankan"}, "bar":{"iso2":"bar","engname":"Bavarian","locname":"Boarisch"}, "bat-smg":{"iso2":"bat-smg","engname":"Samogitian","locname":"Žemaitėška"}, "bcl":{"iso2":"bcl","engname":"Central Bicolano","locname":"Bikol"}, "bel":{"iso2":"be","engname":"Belarusian","locname":"Беларуская"}, "ben":{"iso2":"bn","engname":"Bengali","locname":"বাংলা"}, "be-x-old":{"iso2":"be-x-old","engname":"Belarusian (Taraškievica)","locname":"Беларуская (тарашкевіца)"}, "bho":{"iso2":"bh","engname":"Bihari","locname":"भोजपुरी"}, "bis":{"iso2":"bi","engname":"Bislama","locname":"Bislama"}, "bjn":{"iso2":"bjn","engname":"Banjar","locname":"Bahasa Banjar"}, "bod":{"iso2":"bo","engname":"Tibetan","locname":"བོད་སྐད"}, "bos":{"iso2":"bs","engname":"Bosnian","locname":"Bosanski"}, "bpy":{"iso2":"bpy","engname":"Bishnupriya Manipuri","locname":"ইমার ঠার/বিষ্ণুপ্রিয়া মণিপুরী"}, "bre":{"iso2":"br","engname":"Breton","locname":"Brezhoneg"}, "bug":{"iso2":"bug","engname":"Buginese","locname":"Basa Ugi"}, "bul":{"iso2":"bg","engname":"Bulgarian","locname":"Български"}, "bxr":{"iso2":"bxr","engname":"Buryat (Russia)","locname":"Буряад"}, "cat":{"iso2":"ca","engname":"Catalan","locname":"Català"}, "cbk-zam":{"iso2":"cbk-zam","engname":"Zamboanga Chavacano","locname":"Chavacano de Zamboanga"}, "cdo":{"iso2":"cdo","engname":"Min Dong","locname":"Mìng-dĕ̤ng-ngṳ̄"}, "ceb":{"iso2":"ceb","engname":"Cebuano","locname":"Sinugboanong Binisaya"}, "ces":{"iso2":"cs","engname":"Czech","locname":"Čeština"}, "cha":{"iso2":"ch","engname":"Chamorro","locname":"Chamoru"}, "che":{"iso2":"ce","engname":"Chechen","locname":"Нохчийн"}, "cho":{"iso2":"cho","engname":"Choctaw","locname":"Choctaw"}, "chr":{"iso2":"chr","engname":"Cherokee","locname":"ᏣᎳᎩ"}, "chu":{"iso2":"cu","engname":"Old Church Slavonic","locname":"Словѣньскъ"}, "chv":{"iso2":"cv","engname":"Chuvash","locname":"Чăваш"}, "chy":{"iso2":"chy","engname":"Cheyenne","locname":"Tsetsêhestâhese"}, "ckb":{"iso2":"ckb","engname":"Sorani","locname":"Soranî / کوردی"}, "cnm":{"iso2":"zh","engname":"Chinese","locname":"中文"}, "cor":{"iso2":"kw","engname":"Cornish","locname":"Kernewek/Karnuack"}, "cos":{"iso2":"co","engname":"Corsican","locname":"Corsu"}, "cre":{"iso2":"cr","engname":"Cree","locname":"Nehiyaw"}, "crh":{"iso2":"crh","engname":"Crimean Tatar","locname":"Qırımtatarca"}, "csb":{"iso2":"csb","engname":"Kashubian","locname":"Kaszëbsczi"}, "cym":{"iso2":"cy","engname":"Welsh","locname":"Cymraeg"}, "dan":{"iso2":"da","engname":"Danish","locname":"Dansk"}, "de":{"iso2":"de","engname":"German","locname":"Deutsch"}, "deu":{"iso2":"de","engname":"German","locname":"Deutsch"}, "diq":{"iso2":"diq","engname":"Zazaki","locname":"Zazaki"}, "div":{"iso2":"dv","engname":"Divehi","locname":"ދިވެހިބަސް"}, "dsb":{"iso2":"dsb","engname":"Lower Sorbian","locname":"Dolnoserbski"}, "dzo":{"iso2":"dz","engname":"Dzongkha","locname":"ཇོང་ཁ"}, "ell":{"iso2":"el","engname":"Greek","locname":"Ελληνικά"}, "eml":{"iso2":"eml","engname":"Emilian-Romagnol","locname":"Emiliàn e rumagnòl"}, "en":{"iso2":"en","engname":"English","locname":"English"}, "eng":{"iso2":"en","engname":"English","locname":"English"}, "epo":{"iso2":"eo","engname":"Esperanto","locname":"Esperanto"}, "est":{"iso2":"et","engname":"Estonian","locname":"Eesti"}, "eus":{"iso2":"eu","engname":"Basque","locname":"Euskara"}, "ewe":{"iso2":"ee","engname":"Ewe","locname":"Eʋegbe"}, "ext":{"iso2":"ext","engname":"Extremaduran","locname":"Estremeñu"}, "fao":{"iso2":"fo","engname":"Faroese","locname":"Føroyskt"}, "fas":{"iso2":"fa","engname":"Persian","locname":"فارسی"}, "fij":{"iso2":"fj","engname":"Fijian","locname":"Na Vosa Vakaviti"}, "fin":{"iso2":"fi","engname":"Finnish","locname":"Suomi"}, "fiu-vro":{"iso2":"fiu-vro","engname":"Võro","locname":"Võro"}, "fra":{"iso2":"fr","engname":"French","locname":"Français"}, "frp":{"iso2":"frp","engname":"Franco-Provençal/Arpitan","locname":"Arpitan"}, "frr":{"iso2":"frr","engname":"North Frisian","locname":"Nordfriisk"}, "fry":{"iso2":"fy","engname":"West Frisian","locname":"Frysk"}, "ful":{"iso2":"ff","engname":"Fula","locname":"Fulfulde"}, "fur":{"iso2":"fur","engname":"Friulian","locname":"Furlan"}, "gag":{"iso2":"gag","engname":"Gagauz","locname":"Gagauz"}, "gan":{"iso2":"gan","engname":"Gan","locname":"贛語"}, "gla":{"iso2":"gd","engname":"Scottish Gaelic","locname":"Gàidhlig"}, "gle":{"iso2":"ga","engname":"Irish","locname":"Gaeilge"}, "glg":{"iso2":"gl","engname":"Galician","locname":"Galego"}, "glk":{"iso2":"glk","engname":"Gilaki","locname":"گیلکی"}, "glv":{"iso2":"gv","engname":"Manx","locname":"Gaelg"}, "got":{"iso2":"got","engname":"Gothic","locname":"𐌲𐌿𐍄𐌹𐍃𐌺"}, "grn":{"iso2":"gn","engname":"Guarani","locname":"Avañe'ẽ"}, "gsw":{"iso2":"de","engname":"German","locname":"Deutsch"}, "guj":{"iso2":"gu","engname":"Gujarati","locname":"ગુજરાતી"}, "hak":{"iso2":"hak","engname":"Hakka","locname":"Hak-kâ-fa / 客家話"}, "hat":{"iso2":"ht","engname":"Haitian","locname":"Krèyol ayisyen"}, "hau":{"iso2":"ha","engname":"Hausa","locname":"هَوُسَ"}, "haw":{"iso2":"haw","engname":"Hawaiian","locname":"Hawai`i"}, "heb":{"iso2":"he","engname":"Hebrew","locname":"עברית"}, "her":{"iso2":"hz","engname":"Herero","locname":"Otsiherero"}, "hif":{"iso2":"hif","engname":"Fiji Hindi","locname":"Fiji Hindi"}, "hin":{"iso2":"hi","engname":"Hindi","locname":"हिन्दी"}, "hmo":{"iso2":"ho","engname":"Hiri Motu","locname":"Hiri Motu"}, "hrv":{"iso2":"hr","engname":"Croatian","locname":"Hrvatski"}, "hsb":{"iso2":"hsb","engname":"Upper Sorbian","locname":"Hornjoserbsce"}, "hun":{"iso2":"hu","engname":"Hungarian","locname":"Magyar"}, "hye":{"iso2":"hy","engname":"Armenian","locname":"Հայերեն"}, "ibo":{"iso2":"ig","engname":"Igbo","locname":"Igbo"}, "ido":{"iso2":"io","engname":"Ido","locname":"Ido"}, "iii":{"iso2":"ii","engname":"Sichuan Yi","locname":"ꆇꉙ"}, "iku":{"iso2":"iu","engname":"Inuktitut","locname":"ᐃᓄᒃᑎᑐᑦ"}, "ile":{"iso2":"ie","engname":"Interlingue","locname":"Interlingue"}, "ilo":{"iso2":"ilo","engname":"Ilokano","locname":"Ilokano"}, "ina":{"iso2":"ia","engname":"Interlingua","locname":"Interlingua"}, "ind":{"iso2":"id","engname":"Indonesian","locname":"Bahasa Indonesia"}, "ipk":{"iso2":"ik","engname":"Inupiak","locname":"Iñupiak"}, "isl":{"iso2":"is","engname":"Icelandic","locname":"Íslenska"}, "ita":{"iso2":"it","engname":"Italian","locname":"Italiano"}, "jav":{"iso2":"jv","engname":"Javanese","locname":"Basa Jawa"}, "jbo":{"iso2":"jbo","engname":"Lojban","locname":"Lojban"}, "jpn":{"iso2":"ja","engname":"Japanese","locname":"日本語"}, "kaa":{"iso2":"kaa","engname":"Karakalpak","locname":"Qaraqalpaqsha"}, "kab":{"iso2":"kab","engname":"Kabyle","locname":"Taqbaylit"}, "kal":{"iso2":"kl","engname":"Greenlandic","locname":"Kalaallisut"}, "kan":{"iso2":"kn","engname":"Kannada","locname":"ಕನ್ನಡ"}, "kas":{"iso2":"ks","engname":"Kashmiri","locname":"कश्मीरी / كشميري"}, "kat":{"iso2":"ka","engname":"Georgian","locname":"ქართული"}, "kau":{"iso2":"kr","engname":"Kanuri","locname":"Kanuri"}, "kaz":{"iso2":"kk","engname":"Kazakh","locname":"Қазақша"}, "kbd":{"iso2":"kbd","engname":"Kabardian Circassian","locname":"Адыгэбзэ (Adighabze)"}, "khm":{"iso2":"km","engname":"Khmer","locname":"ភាសាខ្មែរ"}, "kik":{"iso2":"ki","engname":"Kikuyu","locname":"Gĩkũyũ"}, "kin":{"iso2":"rw","engname":"Kinyarwanda","locname":"Ikinyarwanda"}, "kir":{"iso2":"ky","engname":"Kirghiz","locname":"Кыргызча"}, "koi":{"iso2":"koi","engname":"Komi-Permyak","locname":"Перем Коми (Perem Komi)"}, "kom":{"iso2":"kv","engname":"Komi","locname":"Коми"}, "kon":{"iso2":"kg","engname":"Kongo","locname":"KiKongo"}, "kor":{"iso2":"ko","engname":"Korean","locname":"한국어"}, "krc":{"iso2":"krc","engname":"Karachay-Balkar","locname":"Къарачай-Малкъар (Qarachay-Malqar)"}, "ksh":{"iso2":"ksh","engname":"Ripuarian","locname":"Ripoarisch"}, "kua":{"iso2":"kj","engname":"Kuanyama","locname":"Kuanyama"}, "kur":{"iso2":"ku","engname":"Kurdish","locname":"Kurdî / كوردی"}, "lad":{"iso2":"lad","engname":"Ladino","locname":"Dzhudezmo"}, "lao":{"iso2":"lo","engname":"Lao","locname":"ລາວ"}, "lat":{"iso2":"la","engname":"Latin","locname":"Latina"}, "lav":{"iso2":"lv","engname":"Latvian","locname":"Latviešu"}, "lbe":{"iso2":"lbe","engname":"Lak","locname":"Лакку"}, "lez":{"iso2":"lez","engname":"Lezgian","locname":"Лезги чІал (Lezgi č’al)"}, "lij":{"iso2":"lij","engname":"Ligurian","locname":"Líguru"}, "lim":{"iso2":"li","engname":"Limburgish","locname":"Limburgs"}, "lin":{"iso2":"ln","engname":"Lingala","locname":"Lingala"}, "lit":{"iso2":"lt","engname":"Lithuanian","locname":"Lietuvių"}, "lmo":{"iso2":"lmo","engname":"Lombard","locname":"Lumbaart"}, "ltg":{"iso2":"ltg","engname":"Latgalian","locname":"Latgaļu"}, "ltz":{"iso2":"lb","engname":"Luxembourgish","locname":"Lëtzebuergesch"}, "lug":{"iso2":"lg","engname":"Luganda","locname":"Luganda"}, "mah":{"iso2":"mh","engname":"Marshallese","locname":"Ebon"}, "mai":{"iso2":"mai","engname":"Maithili","locname":"मैथिली"}, "mal":{"iso2":"ml","engname":"Malayalam","locname":"മലയാളം"}, "map-bms":{"iso2":"map-bms","engname":"Banyumasan","locname":"Basa Banyumasan"}, "mar":{"iso2":"mr","engname":"Marathi","locname":"मराठी"}, "mdf":{"iso2":"mdf","engname":"Moksha","locname":"Мокшень (Mokshanj Kälj)"}, "mhr":{"iso2":"mhr","engname":"Meadow Mari","locname":"Олык Марий (Olyk Marij)"}, "min":{"iso2":"min","engname":"Minangkabau","locname":"Minangkabau"}, "mkd":{"iso2":"mk","engname":"Macedonian","locname":"Македонски"}, "mlg":{"iso2":"mg","engname":"Malagasy","locname":"Malagasy"}, "mlt":{"iso2":"mt","engname":"Maltese","locname":"Malti"}, "mo":{"iso2":"mo","engname":"Moldovan","locname":"Молдовеняскэ"}, "mon":{"iso2":"mn","engname":"Mongolian","locname":"Монгол"}, "mri":{"iso2":"mi","engname":"Maori","locname":"Māori"}, "mrj":{"iso2":"mrj","engname":"Hill Mari","locname":"Кырык Мары (Kyryk Mary)"}, "msa":{"iso2":"ms","engname":"Malay","locname":"Bahasa Melayu"}, "mul":{"iso2":"mul","engname":"Multiple","locname":"Multiple"}, "mus":{"iso2":"mus","engname":"Muscogee","locname":"Muskogee"}, "mwl":{"iso2":"mwl","engname":"Mirandese","locname":"Mirandés"}, "mya":{"iso2":"my","engname":"Burmese","locname":"မြန်မာဘာသာ"}, "myv":{"iso2":"myv","engname":"Erzya","locname":"Эрзянь (Erzjanj Kelj)"}, "mzn":{"iso2":"mzn","engname":"Mazandarani","locname":"مَزِروني"}, "nah":{"iso2":"nah","engname":"Nahuatl","locname":"Nāhuatl"}, "nap":{"iso2":"nap","engname":"Neapolitan","locname":"Nnapulitano"}, "nau":{"iso2":"na","engname":"Nauruan","locname":"dorerin Naoero"}, "nav":{"iso2":"nv","engname":"Navajo","locname":"Diné bizaad"}, "ndo":{"iso2":"ng","engname":"Ndonga","locname":"Oshiwambo"}, "nds":{"iso2":"nds","engname":"Low Saxon","locname":"Plattdüütsch"}, "nds-nl":{"iso2":"nds-nl","engname":"Dutch Low Saxon","locname":"Nedersaksisch"}, "nep":{"iso2":"ne","engname":"Nepali","locname":"नेपाली"}, "new":{"iso2":"new","engname":"Newar / Nepal Bhasa","locname":"नेपाल भाषा"}, "nid":{"iso2":"nid","engname":"Ngandi","locname":"Ngandi"}, "nld":{"iso2":"nl","engname":"Dutch","locname":"Nederlands"}, "nno":{"iso2":"nn","engname":"Norwegian (Nynorsk)","locname":"Nynorsk"}, "nob":{"iso2":"no","engname":"Norwegian (Bokmål)","locname":"Norsk (Bokmål)"}, "nor":{"iso2":"no","engname":"Norwegian (Bokmål)","locname":"Norsk (Bokmål)"}, "nov":{"iso2":"nov","engname":"Novial","locname":"Novial"}, "nrm":{"iso2":"nrm","engname":"Norman","locname":"Nouormand/Normaund"}, "nso":{"iso2":"nso","engname":"Northern Sotho","locname":"Sepedi"}, "nya":{"iso2":"ny","engname":"Chichewa","locname":"Chichewa"}, "oci":{"iso2":"oc","engname":"Occitan","locname":"Occitan"}, "ori":{"iso2":"or","engname":"Oriya","locname":"ଓଡ଼ିଆ"}, "orm":{"iso2":"om","engname":"Oromo","locname":"Oromoo"}, "oss":{"iso2":"os","engname":"Ossetian","locname":"Иронау"}, "pag":{"iso2":"pag","engname":"Pangasinan","locname":"Pangasinan"}, "pam":{"iso2":"pam","engname":"Kapampangan","locname":"Kapampangan"}, "pan":{"iso2":"pa","engname":"Punjabi","locname":"ਪੰਜਾਬੀ"}, "pap":{"iso2":"pap","engname":"Papiamentu","locname":"Papiamentu"}, "pcd":{"iso2":"pcd","engname":"Picard","locname":"Picard"}, "pdc":{"iso2":"pdc","engname":"Pennsylvania German","locname":"Deitsch"}, "pfl":{"iso2":"pfl","engname":"Palatinate German","locname":"Pälzisch"}, "pih":{"iso2":"pih","engname":"Norfolk","locname":"Norfuk"}, "pli":{"iso2":"pi","engname":"Pali","locname":"पाऴि"}, "pms":{"iso2":"pms","engname":"Piedmontese","locname":"Piemontèis"}, "pnb":{"iso2":"pnb","engname":"Western Panjabi","locname":"شاہ مکھی پنجابی (Shāhmukhī Pañjābī)"}, "pnt":{"iso2":"pnt","engname":"Pontic","locname":"Ποντιακά"}, "pol":{"iso2":"pl","engname":"Polish","locname":"Polski"}, "por":{"iso2":"pt","engname":"Portuguese","locname":"Português"}, "pus":{"iso2":"ps","engname":"Pashto","locname":"پښتو"}, "que":{"iso2":"qu","engname":"Quechua","locname":"Runa Simi"}, "rmy":{"iso2":"rmy","engname":"Romani","locname":"romani - रोमानी"}, "roa-rup":{"iso2":"roa-rup","engname":"Aromanian","locname":"Armãneashce"}, "roa-tara":{"iso2":"roa-tara","engname":"Tarantino","locname":"Tarandíne"}, "roh":{"iso2":"rm","engname":"Romansh","locname":"Rumantsch"}, "ron":{"iso2":"ro","engname":"Romanian","locname":"Română"}, "ru":{"iso2":"ru","engname":"Russian","locname":"Русский"}, "rue":{"iso2":"rue","engname":"Rusyn","locname":"Русиньскый"}, "run":{"iso2":"rn","engname":"Kirundi","locname":"Kirundi"}, "rus":{"iso2":"ru","engname":"Russian","locname":"Русский"}, "sag":{"iso2":"sg","engname":"Sango","locname":"Sängö"}, "sah":{"iso2":"sah","engname":"Sakha","locname":"Саха тыла (Saxa Tyla)"}, "san":{"iso2":"sa","engname":"Sanskrit","locname":"संस्कृतम्"}, "scn":{"iso2":"scn","engname":"Sicilian","locname":"Sicilianu"}, "sco":{"iso2":"sco","engname":"Scots","locname":"Scots"}, "sh":{"iso2":"sh","engname":"Serbo-Croatian","locname":"Srpskohrvatski / Српскохрватски"}, "simple":{"iso2":"simple","engname":"Simple English","locname":"Simple English"}, "sin":{"iso2":"si","engname":"Sinhalese","locname":"සිංහල"}, "slk":{"iso2":"sk","engname":"Slovak","locname":"Slovenčina"}, "slv":{"iso2":"sl","engname":"Slovenian","locname":"Slovenščina"}, "sme":{"iso2":"se","engname":"Northern Sami","locname":"Sámegiella"}, "smo":{"iso2":"sm","engname":"Samoan","locname":"Gagana Samoa"}, "sna":{"iso2":"sn","engname":"Shona","locname":"chiShona"}, "snd":{"iso2":"sd","engname":"Sindhi","locname":"سنڌي، سندھی ، सिन्ध"}, "som":{"iso2":"so","engname":"Somali","locname":"Soomaali"}, "sot":{"iso2":"st","engname":"Sesotho","locname":"Sesotho"}, "spa":{"iso2":"es","engname":"Spanish","locname":"Español"}, "sqi":{"iso2":"sq","engname":"Albanian","locname":"Shqip"}, "srd":{"iso2":"sc","engname":"Sardinian","locname":"Sardu"}, "srn":{"iso2":"srn","engname":"Sranan","locname":"Sranantongo"}, "srp":{"iso2":"sr","engname":"Serbian","locname":"Српски / Srpski"}, "ssw":{"iso2":"ss","engname":"Swati","locname":"SiSwati"}, "stq":{"iso2":"stq","engname":"Saterland Frisian","locname":"Seeltersk"}, "sun":{"iso2":"su","engname":"Sundanese","locname":"Basa Sunda"}, "swa":{"iso2":"sw","engname":"Swahili","locname":"Kiswahili"}, "swe":{"iso2":"sv","engname":"Swedish","locname":"Svenska"}, "szl":{"iso2":"szl","engname":"Silesian","locname":"Ślůnski"}, "tah":{"iso2":"ty","engname":"Tahitian","locname":"Reo Mā`ohi"}, "tam":{"iso2":"ta","engname":"Tamil","locname":"தமிழ்"}, "tat":{"iso2":"tt","engname":"Tatar","locname":"Tatarça / Татарча"}, "tel":{"iso2":"te","engname":"Telugu","locname":"తెలుగు"}, "tet":{"iso2":"tet","engname":"Tetum","locname":"Tetun"}, "tgk":{"iso2":"tg","engname":"Tajik","locname":"Тоҷикӣ"}, "tgl":{"iso2":"tl","engname":"Tagalog","locname":"Tagalog"}, "tha":{"iso2":"th","engname":"Thai","locname":"ไทย"}, "tir":{"iso2":"ti","engname":"Tigrinya","locname":"ትግርኛ"}, "ton":{"iso2":"to","engname":"Tongan","locname":"faka Tonga"}, "tpi":{"iso2":"tpi","engname":"Tok Pisin","locname":"Tok Pisin"}, "tsn":{"iso2":"tn","engname":"Tswana","locname":"Setswana"}, "tso":{"iso2":"ts","engname":"Tsonga","locname":"Xitsonga"}, "tuk":{"iso2":"tk","engname":"Turkmen","locname":"تركمن / Туркмен"}, "tum":{"iso2":"tum","engname":"Tumbuka","locname":"chiTumbuka"}, "tur":{"iso2":"tr","engname":"Turkish","locname":"Türkçe"}, "twi":{"iso2":"tw","engname":"Twi","locname":"Twi"}, "tyv":{"iso2":"tyv","engname":"Tuvan","locname":"Тыва"}, "udm":{"iso2":"udm","engname":"Udmurt","locname":"Удмурт кыл"}, "uig":{"iso2":"ug","engname":"Uyghur","locname":"ئۇيغۇر تىلى"}, "ukr":{"iso2":"uk","engname":"Ukrainian","locname":"Українська"}, "urd":{"iso2":"ur","engname":"Urdu","locname":"اردو"}, "uzb":{"iso2":"uz","engname":"Uzbek","locname":"O‘zbek"}, "vec":{"iso2":"vec","engname":"Venetian","locname":"Vèneto"}, "ven":{"iso2":"ve","engname":"Venda","locname":"Tshivenda"}, "vep":{"iso2":"vep","engname":"Vepsian","locname":"Vepsän"}, "vie":{"iso2":"vi","engname":"Vietnamese","locname":"Tiếng Việt"}, "vls":{"iso2":"vls","engname":"West Flemish","locname":"West-Vlams"}, "vol":{"iso2":"vo","engname":"Volapük","locname":"Volapük"}, "war":{"iso2":"war","engname":"Waray-Waray","locname":"Winaray"}, "wln":{"iso2":"wa","engname":"Walloon","locname":"Walon"}, "wol":{"iso2":"wo","engname":"Wolof","locname":"Wolof"}, "wuu":{"iso2":"wuu","engname":"Wu","locname":"吴语"}, "xal":{"iso2":"xal","engname":"Kalmyk","locname":"Хальмг"}, "xho":{"iso2":"xh","engname":"Xhosa","locname":"isiXhosa"}, "xmf":{"iso2":"xmf","engname":"Mingrelian","locname":"მარგალური (Margaluri)"}, "yid":{"iso2":"yi","engname":"Yiddish","locname":"ייִדיש"}, "yor":{"iso2":"yo","engname":"Yoruba","locname":"Yorùbá"}, "zea":{"iso2":"zea","engname":"Zeelandic","locname":"Zeêuws"}, "zha":{"iso2":"za","engname":"Zhuang","locname":"Cuengh"}, "zh-classical":{"iso2":"zh-classical","engname":"Classical Chinese","locname":"古文 / 文言文"}, "zh-min-nan":{"iso2":"zh-min-nan","engname":"Min Nan","locname":"Bân-lâm-gú"}, "zho":{"iso2":"zh","engname":"Chinese","locname":"中文"}, "zh-yue":{"iso2":"zh-yue","engname":"Cantonese","locname":"粵語"}, "zul":{"iso2":"zu","engname":"Zulu","locname":"isiZulu"}} \ No newline at end of file diff --git a/roles/httpd/files/html/credits.html b/roles/httpd/files/html/credits.html new file mode 100755 index 000000000..858a8ccf8 --- /dev/null +++ b/roles/httpd/files/html/credits.html @@ -0,0 +1,45 @@ + + + + + + +Credits + + + +

Internet-in-a-Box Credits

+ + The XSCE School Server known as Internet-in-a-Box includes a variety of educational and other content and applications which are attributed as follows:

+ + All Wikipedia content is available for free at www.wikipedia.org.
+ All other Wikimedia content is available for free via links at www.wikimedia.org.
+ All Khan Academy content is available for free at www.khanacademy.org.
+ All CK-12 content is available for free at www.ck-12.org.
+ All PhET Interactive Simulations content is available for free at phet.colorado.edu.
+ All MedLine content is available for free at www.nlm.nih.gov/medlineplus.
+ All Hesperian content is available for free at www.hesperian.org.
+ All Gutenberg content is available for free at www.gutenberg.org.
+ All OLPC content is available for free at www.laptop.org.
+ All MIT Scratch content is available for free at scratch.mit.edu.
+ All UNESCO's IICBA content is available for free at www.eng.unesco-iicba.org.
+ All Math Expression content is available for free at www.mathexpression.com.
+ All Music Theory content is available for free at www.musictheory.net.

+ + Internet-in-a-Box also includes the work of content aggregators which we gratefully acknowledge:

+ + RACHEL is a curation of selected offline content at www.rachel.worldpossible.org.
+ Kiwix is a Zim server and repository of Wikimedia and other content in a compressed Zim file format at www.kiwix.org.
+ KA Lite is a server and repository of Khan Academy content in various languages at learningequality.org/ka-lite.

+ + Internet-in-a-Box also contains a number of applications each of which has its own attribution information which is included.

+ + This Internet-in-a-Box distribution resides at github.com/XSCE/xsce.

+ + It is licensed under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

+ + Licensing information may be found at github.com/XSCE/xsce/blob/master/LICENSE.
+ + + + diff --git a/roles/httpd/files/html/css/bootstrap-theme.css b/roles/httpd/files/html/css/bootstrap-theme.css new file mode 100755 index 000000000..f860bbc06 --- /dev/null +++ b/roles/httpd/files/html/css/bootstrap-theme.css @@ -0,0 +1,442 @@ +/*! + * Bootstrap v3.2.0 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +.btn-default, +.btn-primary, +.btn-success, +.btn-info, +.btn-warning, +.btn-danger { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075); +} +.btn-default:active, +.btn-primary:active, +.btn-success:active, +.btn-info:active, +.btn-warning:active, +.btn-danger:active, +.btn-default.active, +.btn-primary.active, +.btn-success.active, +.btn-info.active, +.btn-warning.active, +.btn-danger.active { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn:active, +.btn.active { + background-image: none; +} +.btn-default { + text-shadow: 0 1px 0 #fff; + background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0)); + background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #dbdbdb; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus { + background-color: #e0e0e0; + background-position: 0 -15px; +} +.btn-default:active, +.btn-default.active { + background-color: #e0e0e0; + border-color: #dbdbdb; +} +.btn-default:disabled, +.btn-default[disabled] { + background-color: #e0e0e0; + background-image: none; +} +.btn-primary { + background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%); + background-image: -o-linear-gradient(top, #428bca 0%, #2d6ca2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#2d6ca2)); + background-image: linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #2b669a; +} +.btn-primary:hover, +.btn-primary:focus { + background-color: #2d6ca2; + background-position: 0 -15px; +} +.btn-primary:active, +.btn-primary.active { + background-color: #2d6ca2; + border-color: #2b669a; +} +.btn-primary:disabled, +.btn-primary[disabled] { + background-color: #2d6ca2; + background-image: none; +} +.btn-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #3e8f3e; +} +.btn-success:hover, +.btn-success:focus { + background-color: #419641; + background-position: 0 -15px; +} +.btn-success:active, +.btn-success.active { + background-color: #419641; + border-color: #3e8f3e; +} +.btn-success:disabled, +.btn-success[disabled] { + background-color: #419641; + background-image: none; +} +.btn-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #28a4c9; +} +.btn-info:hover, +.btn-info:focus { + background-color: #2aabd2; + background-position: 0 -15px; +} +.btn-info:active, +.btn-info.active { + background-color: #2aabd2; + border-color: #28a4c9; +} +.btn-info:disabled, +.btn-info[disabled] { + background-color: #2aabd2; + background-image: none; +} +.btn-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #e38d13; +} +.btn-warning:hover, +.btn-warning:focus { + background-color: #eb9316; + background-position: 0 -15px; +} +.btn-warning:active, +.btn-warning.active { + background-color: #eb9316; + border-color: #e38d13; +} +.btn-warning:disabled, +.btn-warning[disabled] { + background-color: #eb9316; + background-image: none; +} +.btn-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-color: #b92c28; +} +.btn-danger:hover, +.btn-danger:focus { + background-color: #c12e2a; + background-position: 0 -15px; +} +.btn-danger:active, +.btn-danger.active { + background-color: #c12e2a; + border-color: #b92c28; +} +.btn-danger:disabled, +.btn-danger[disabled] { + background-color: #c12e2a; + background-image: none; +} +.thumbnail, +.img-thumbnail { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #e8e8e8; + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + background-color: #357ebd; + background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%); + background-image: -o-linear-gradient(top, #428bca 0%, #357ebd 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#357ebd)); + background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); + background-repeat: repeat-x; +} +.navbar-default { + background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8)); + background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075); +} +.navbar-default .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%); + background-image: -o-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f3f3f3)); + background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075); +} +.navbar-brand, +.navbar-nav > li > a { + text-shadow: 0 1px 0 rgba(255, 255, 255, .25); +} +.navbar-inverse { + background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222)); + background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); + background-repeat: repeat-x; +} +.navbar-inverse .navbar-nav > .active > a { + background-image: -webkit-linear-gradient(top, #222 0%, #282828 100%); + background-image: -o-linear-gradient(top, #222 0%, #282828 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#222), to(#282828)); + background-image: linear-gradient(to bottom, #222 0%, #282828 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0); + background-repeat: repeat-x; + -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); + box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25); +} +.navbar-inverse .navbar-brand, +.navbar-inverse .navbar-nav > li > a { + text-shadow: 0 -1px 0 rgba(0, 0, 0, .25); +} +.navbar-static-top, +.navbar-fixed-top, +.navbar-fixed-bottom { + border-radius: 0; +} +.alert { + text-shadow: 0 1px 0 rgba(255, 255, 255, .2); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05); +} +.alert-success { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); + background-repeat: repeat-x; + border-color: #b2dba1; +} +.alert-info { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); + background-repeat: repeat-x; + border-color: #9acfea; +} +.alert-warning { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); + background-repeat: repeat-x; + border-color: #f5e79e; +} +.alert-danger { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3)); + background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); + background-repeat: repeat-x; + border-color: #dca7a7; +} +.progress { + background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar { + background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%); + background-image: -o-linear-gradient(top, #428bca 0%, #3071a9 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#3071a9)); + background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-success { + background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44)); + background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-info { + background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5)); + background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-warning { + background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f)); + background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-danger { + background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c)); + background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); + background-repeat: repeat-x; +} +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.list-group { + border-radius: 4px; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075); + box-shadow: 0 1px 2px rgba(0, 0, 0, .075); +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + text-shadow: 0 -1px 0 #3071a9; + background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%); + background-image: -o-linear-gradient(top, #428bca 0%, #3278b3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#3278b3)); + background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0); + background-repeat: repeat-x; + border-color: #3278b3; +} +.panel { + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05); + box-shadow: 0 1px 2px rgba(0, 0, 0, .05); +} +.panel-default > .panel-heading { + background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8)); + background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); + background-repeat: repeat-x; +} +.panel-primary > .panel-heading { + background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%); + background-image: -o-linear-gradient(top, #428bca 0%, #357ebd 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#428bca), to(#357ebd)); + background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); + background-repeat: repeat-x; +} +.panel-success > .panel-heading { + background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6)); + background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); + background-repeat: repeat-x; +} +.panel-info > .panel-heading { + background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3)); + background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); + background-repeat: repeat-x; +} +.panel-warning > .panel-heading { + background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc)); + background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); + background-repeat: repeat-x; +} +.panel-danger > .panel-heading { + background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc)); + background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); + background-repeat: repeat-x; +} +.well { + background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); + background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5)); + background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); + background-repeat: repeat-x; + border-color: #dcdcdc; + -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1); +} +/*# sourceMappingURL=bootstrap-theme.css.map */ diff --git a/roles/httpd/files/html/css/bootstrap-theme.css.map b/roles/httpd/files/html/css/bootstrap-theme.css.map new file mode 100755 index 000000000..4cc41ab00 --- /dev/null +++ b/roles/httpd/files/html/css/bootstrap-theme.css.map @@ -0,0 +1 @@ +{"version":3,"file":"bootstrap-theme.css","sources":["less/theme.less","less/mixins/vendor-prefixes.less","bootstrap-theme.css","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":"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","sourcesContent":["\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n // Reset the shadow\n &:active,\n &.active {\n .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners\n background-repeat: repeat-x;\n border-color: darken(@btn-color, 14%);\n\n &:hover,\n &:focus {\n background-color: darken(@btn-color, 12%);\n background-position: 0 -15px;\n }\n\n &:active,\n &.active {\n background-color: darken(@btn-color, 12%);\n border-color: darken(@btn-color, 14%);\n }\n\n &:disabled,\n &[disabled] {\n background-color: darken(@btn-color, 12%);\n background-image: none;\n }\n}\n\n// Common styles\n.btn {\n // Remove the gradient for the pressed/active state\n &:active,\n &.active {\n background-image: none;\n }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-info { .btn-styles(@btn-info-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger { .btn-styles(@btn-danger-bg); }\n\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n border-radius: @navbar-border-radius;\n @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n .box-shadow(@shadow);\n\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: darken(@navbar-default-bg, 5%); @end-color: darken(@navbar-default-bg, 2%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n\n .navbar-nav > .active > a {\n #gradient > .vertical(@start-color: @navbar-inverse-bg; @end-color: lighten(@navbar-inverse-bg, 2.5%));\n .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n }\n\n .navbar-brand,\n .navbar-nav > li > a {\n text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n border-radius: 0;\n}\n\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n text-shadow: 0 1px 0 rgba(255,255,255,.2);\n @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success { .alert-styles(@alert-success-bg); }\n.alert-info { .alert-styles(@alert-info-bg); }\n.alert-warning { .alert-styles(@alert-warning-bg); }\n.alert-danger { .alert-styles(@alert-danger-bg); }\n\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger { .progress-bar-styles(@progress-bar-danger-bg); }\n\n// Reset the striped class because our mixins don't do multiple gradients and\n// the above custom styles override the new `.progress-bar-striped` in v3.2.0.\n.progress-bar-striped {\n #gradient > .striped();\n}\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n border-radius: @border-radius-base;\n .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n border-color: darken(@list-group-active-border, 7.5%);\n}\n\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n border-color: darken(@well-bg, 10%);\n @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n .box-shadow(@shadow);\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n &::-moz-placeholder { color: @color; // Firefox\n opacity: 1; } // See https://github.com/twbs/bootstrap/pull/11526\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n",null,"// Gradients\n\n#gradient {\n\n // Horizontal gradient, from left to right\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(left, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n // Vertical gradient, from top to bottom\n //\n // Creates two color stops, start and end, by specifying a color and position for each color stop.\n // Color stops are not available in IE9 and below.\n .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(top, @start-color @start-percent, @end-color @end-percent); // Opera 12\n background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n background-repeat: repeat-x;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n }\n\n .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n background-repeat: repeat-x;\n background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n background-image: -o-linear-gradient(@deg, @start-color, @end-color); // Opera 12\n background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n }\n .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: -o-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n background-repeat: no-repeat;\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n }\n .radial(@inner-color: #555; @outer-color: #333) {\n background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n background-image: radial-gradient(circle, @inner-color, @outer-color);\n background-repeat: no-repeat;\n }\n .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: -o-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n }\n}\n","// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n\n.reset-filter() {\n filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n"]} \ No newline at end of file diff --git a/roles/httpd/files/html/css/bootstrap-theme.min.css b/roles/httpd/files/html/css/bootstrap-theme.min.css new file mode 100755 index 000000000..2e97597c8 --- /dev/null +++ b/roles/httpd/files/html/css/bootstrap-theme.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.2.0 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */.btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn:active,.btn.active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default:disabled,.btn-default[disabled]{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:-o-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#2d6ca2));background-image:linear-gradient(to bottom,#428bca 0,#2d6ca2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#2b669a}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-primary:disabled,.btn-primary[disabled]{background-color:#2d6ca2;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-success:disabled,.btn-success[disabled]{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.btn-info:disabled,.btn-info[disabled]{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-warning:disabled,.btn-warning[disabled]{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.btn-danger:disabled,.btn-danger[disabled]{background-color:#c12e2a;background-image:none}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-color:#357ebd;background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:-o-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#357ebd));background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f3f3f3));background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:-o-linear-gradient(top,#222 0,#282828 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#222),to(#282828));background-image:linear-gradient(to bottom,#222 0,#282828 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:-o-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#3071a9));background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:-o-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#3278b3));background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);background-repeat:repeat-x;border-color:#3278b3}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:-o-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#428bca),to(#357ebd));background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} \ No newline at end of file diff --git a/roles/httpd/files/html/css/bootstrap.css b/roles/httpd/files/html/css/bootstrap.css new file mode 100755 index 000000000..037dd0561 --- /dev/null +++ b/roles/httpd/files/html/css/bootstrap.css @@ -0,0 +1,6203 @@ +/*! + * Bootstrap v3.2.0 (http://getbootstrap.com) + * Copyright 2011-2014 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ + +/*! normalize.css v3.0.1 | MIT License | git.io/normalize */ +html { + font-family: sans-serif; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} +body { + margin: 0; +} +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section, +summary { + display: block; +} +audio, +canvas, +progress, +video { + display: inline-block; + vertical-align: baseline; +} +audio:not([controls]) { + display: none; + height: 0; +} +[hidden], +template { + display: none; +} +a { + background: transparent; +} +a:active, +a:hover { + outline: 0; +} +abbr[title] { + border-bottom: 1px dotted; +} +b, +strong { + font-weight: bold; +} +dfn { + font-style: italic; +} +h1 { + margin: .67em 0; + font-size: 2em; +} +mark { + color: #000; + background: #ff0; +} +small { + font-size: 80%; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sup { + top: -.5em; +} +sub { + bottom: -.25em; +} +img { + border: 0; +} +svg:not(:root) { + overflow: hidden; +} +figure { + margin: 1em 40px; +} +hr { + height: 0; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} +pre { + overflow: auto; +} +code, +kbd, +pre, +samp { + font-family: monospace, monospace; + font-size: 1em; +} +button, +input, +optgroup, +select, +textarea { + margin: 0; + font: inherit; + color: inherit; +} +button { + overflow: visible; +} +button, +select { + text-transform: none; +} +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + cursor: pointer; +} +button[disabled], +html input[disabled] { + cursor: default; +} +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} +input { + line-height: normal; +} +input[type="checkbox"], +input[type="radio"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + padding: 0; +} +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + height: auto; +} +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} +input[type="search"]::-webkit-search-cancel-button, +input[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} +fieldset { + padding: .35em .625em .75em; + margin: 0 2px; + border: 1px solid #c0c0c0; +} +legend { + padding: 0; + border: 0; +} +textarea { + overflow: auto; +} +optgroup { + font-weight: bold; +} +table { + border-spacing: 0; + border-collapse: collapse; +} +td, +th { + padding: 0; +} +@media print { + * { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + -webkit-box-shadow: none !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + select { + background: #fff !important; + } + .navbar { + display: none; + } + .table td, + .table th { + background-color: #fff !important; + } + .btn > .caret, + .dropup > .btn > .caret { + border-top-color: #000 !important; + } + .label { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table-bordered th, + .table-bordered td { + border: 1px solid #ddd !important; + } +} +@font-face { + font-family: 'Glyphicons Halflings'; + + src: url('../fonts/glyphicons-halflings-regular.eot'); + src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg'); +} +.glyphicon { + position: relative; + top: 1px; + display: inline-block; + font-family: 'Glyphicons Halflings'; + font-style: normal; + font-weight: normal; + line-height: 1; + + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +.glyphicon-asterisk:before { + content: "\2a"; +} +.glyphicon-plus:before { + content: "\2b"; +} +.glyphicon-euro:before { + content: "\20ac"; +} +.glyphicon-minus:before { + content: "\2212"; +} +.glyphicon-cloud:before { + content: "\2601"; +} +.glyphicon-envelope:before { + content: "\2709"; +} +.glyphicon-pencil:before { + content: "\270f"; +} +.glyphicon-glass:before { + content: "\e001"; +} +.glyphicon-music:before { + content: "\e002"; +} +.glyphicon-search:before { + content: "\e003"; +} +.glyphicon-heart:before { + content: "\e005"; +} +.glyphicon-star:before { + content: "\e006"; +} +.glyphicon-star-empty:before { + content: "\e007"; +} +.glyphicon-user:before { + content: "\e008"; +} +.glyphicon-film:before { + content: "\e009"; +} +.glyphicon-th-large:before { + content: "\e010"; +} +.glyphicon-th:before { + content: "\e011"; +} +.glyphicon-th-list:before { + content: "\e012"; +} +.glyphicon-ok:before { + content: "\e013"; +} +.glyphicon-remove:before { + content: "\e014"; +} +.glyphicon-zoom-in:before { + content: "\e015"; +} +.glyphicon-zoom-out:before { + content: "\e016"; +} +.glyphicon-off:before { + content: "\e017"; +} +.glyphicon-signal:before { + content: "\e018"; +} +.glyphicon-cog:before { + content: "\e019"; +} +.glyphicon-trash:before { + content: "\e020"; +} +.glyphicon-home:before { + content: "\e021"; +} +.glyphicon-file:before { + content: "\e022"; +} +.glyphicon-time:before { + content: "\e023"; +} +.glyphicon-road:before { + content: "\e024"; +} +.glyphicon-download-alt:before { + content: "\e025"; +} +.glyphicon-download:before { + content: "\e026"; +} +.glyphicon-upload:before { + content: "\e027"; +} +.glyphicon-inbox:before { + content: "\e028"; +} +.glyphicon-play-circle:before { + content: "\e029"; +} +.glyphicon-repeat:before { + content: "\e030"; +} +.glyphicon-refresh:before { + content: "\e031"; +} +.glyphicon-list-alt:before { + content: "\e032"; +} +.glyphicon-lock:before { + content: "\e033"; +} +.glyphicon-flag:before { + content: "\e034"; +} +.glyphicon-headphones:before { + content: "\e035"; +} +.glyphicon-volume-off:before { + content: "\e036"; +} +.glyphicon-volume-down:before { + content: "\e037"; +} +.glyphicon-volume-up:before { + content: "\e038"; +} +.glyphicon-qrcode:before { + content: "\e039"; +} +.glyphicon-barcode:before { + content: "\e040"; +} +.glyphicon-tag:before { + content: "\e041"; +} +.glyphicon-tags:before { + content: "\e042"; +} +.glyphicon-book:before { + content: "\e043"; +} +.glyphicon-bookmark:before { + content: "\e044"; +} +.glyphicon-print:before { + content: "\e045"; +} +.glyphicon-camera:before { + content: "\e046"; +} +.glyphicon-font:before { + content: "\e047"; +} +.glyphicon-bold:before { + content: "\e048"; +} +.glyphicon-italic:before { + content: "\e049"; +} +.glyphicon-text-height:before { + content: "\e050"; +} +.glyphicon-text-width:before { + content: "\e051"; +} +.glyphicon-align-left:before { + content: "\e052"; +} +.glyphicon-align-center:before { + content: "\e053"; +} +.glyphicon-align-right:before { + content: "\e054"; +} +.glyphicon-align-justify:before { + content: "\e055"; +} +.glyphicon-list:before { + content: "\e056"; +} +.glyphicon-indent-left:before { + content: "\e057"; +} +.glyphicon-indent-right:before { + content: "\e058"; +} +.glyphicon-facetime-video:before { + content: "\e059"; +} +.glyphicon-picture:before { + content: "\e060"; +} +.glyphicon-map-marker:before { + content: "\e062"; +} +.glyphicon-adjust:before { + content: "\e063"; +} +.glyphicon-tint:before { + content: "\e064"; +} +.glyphicon-edit:before { + content: "\e065"; +} +.glyphicon-share:before { + content: "\e066"; +} +.glyphicon-check:before { + content: "\e067"; +} +.glyphicon-move:before { + content: "\e068"; +} +.glyphicon-step-backward:before { + content: "\e069"; +} +.glyphicon-fast-backward:before { + content: "\e070"; +} +.glyphicon-backward:before { + content: "\e071"; +} +.glyphicon-play:before { + content: "\e072"; +} +.glyphicon-pause:before { + content: "\e073"; +} +.glyphicon-stop:before { + content: "\e074"; +} +.glyphicon-forward:before { + content: "\e075"; +} +.glyphicon-fast-forward:before { + content: "\e076"; +} +.glyphicon-step-forward:before { + content: "\e077"; +} +.glyphicon-eject:before { + content: "\e078"; +} +.glyphicon-chevron-left:before { + content: "\e079"; +} +.glyphicon-chevron-right:before { + content: "\e080"; +} +.glyphicon-plus-sign:before { + content: "\e081"; +} +.glyphicon-minus-sign:before { + content: "\e082"; +} +.glyphicon-remove-sign:before { + content: "\e083"; +} +.glyphicon-ok-sign:before { + content: "\e084"; +} +.glyphicon-question-sign:before { + content: "\e085"; +} +.glyphicon-info-sign:before { + content: "\e086"; +} +.glyphicon-screenshot:before { + content: "\e087"; +} +.glyphicon-remove-circle:before { + content: "\e088"; +} +.glyphicon-ok-circle:before { + content: "\e089"; +} +.glyphicon-ban-circle:before { + content: "\e090"; +} +.glyphicon-arrow-left:before { + content: "\e091"; +} +.glyphicon-arrow-right:before { + content: "\e092"; +} +.glyphicon-arrow-up:before { + content: "\e093"; +} +.glyphicon-arrow-down:before { + content: "\e094"; +} +.glyphicon-share-alt:before { + content: "\e095"; +} +.glyphicon-resize-full:before { + content: "\e096"; +} +.glyphicon-resize-small:before { + content: "\e097"; +} +.glyphicon-exclamation-sign:before { + content: "\e101"; +} +.glyphicon-gift:before { + content: "\e102"; +} +.glyphicon-leaf:before { + content: "\e103"; +} +.glyphicon-fire:before { + content: "\e104"; +} +.glyphicon-eye-open:before { + content: "\e105"; +} +.glyphicon-eye-close:before { + content: "\e106"; +} +.glyphicon-warning-sign:before { + content: "\e107"; +} +.glyphicon-plane:before { + content: "\e108"; +} +.glyphicon-calendar:before { + content: "\e109"; +} +.glyphicon-random:before { + content: "\e110"; +} +.glyphicon-comment:before { + content: "\e111"; +} +.glyphicon-magnet:before { + content: "\e112"; +} +.glyphicon-chevron-up:before { + content: "\e113"; +} +.glyphicon-chevron-down:before { + content: "\e114"; +} +.glyphicon-retweet:before { + content: "\e115"; +} +.glyphicon-shopping-cart:before { + content: "\e116"; +} +.glyphicon-folder-close:before { + content: "\e117"; +} +.glyphicon-folder-open:before { + content: "\e118"; +} +.glyphicon-resize-vertical:before { + content: "\e119"; +} +.glyphicon-resize-horizontal:before { + content: "\e120"; +} +.glyphicon-hdd:before { + content: "\e121"; +} +.glyphicon-bullhorn:before { + content: "\e122"; +} +.glyphicon-bell:before { + content: "\e123"; +} +.glyphicon-certificate:before { + content: "\e124"; +} +.glyphicon-thumbs-up:before { + content: "\e125"; +} +.glyphicon-thumbs-down:before { + content: "\e126"; +} +.glyphicon-hand-right:before { + content: "\e127"; +} +.glyphicon-hand-left:before { + content: "\e128"; +} +.glyphicon-hand-up:before { + content: "\e129"; +} +.glyphicon-hand-down:before { + content: "\e130"; +} +.glyphicon-circle-arrow-right:before { + content: "\e131"; +} +.glyphicon-circle-arrow-left:before { + content: "\e132"; +} +.glyphicon-circle-arrow-up:before { + content: "\e133"; +} +.glyphicon-circle-arrow-down:before { + content: "\e134"; +} +.glyphicon-globe:before { + content: "\e135"; +} +.glyphicon-wrench:before { + content: "\e136"; +} +.glyphicon-tasks:before { + content: "\e137"; +} +.glyphicon-filter:before { + content: "\e138"; +} +.glyphicon-briefcase:before { + content: "\e139"; +} +.glyphicon-fullscreen:before { + content: "\e140"; +} +.glyphicon-dashboard:before { + content: "\e141"; +} +.glyphicon-paperclip:before { + content: "\e142"; +} +.glyphicon-heart-empty:before { + content: "\e143"; +} +.glyphicon-link:before { + content: "\e144"; +} +.glyphicon-phone:before { + content: "\e145"; +} +.glyphicon-pushpin:before { + content: "\e146"; +} +.glyphicon-usd:before { + content: "\e148"; +} +.glyphicon-gbp:before { + content: "\e149"; +} +.glyphicon-sort:before { + content: "\e150"; +} +.glyphicon-sort-by-alphabet:before { + content: "\e151"; +} +.glyphicon-sort-by-alphabet-alt:before { + content: "\e152"; +} +.glyphicon-sort-by-order:before { + content: "\e153"; +} +.glyphicon-sort-by-order-alt:before { + content: "\e154"; +} +.glyphicon-sort-by-attributes:before { + content: "\e155"; +} +.glyphicon-sort-by-attributes-alt:before { + content: "\e156"; +} +.glyphicon-unchecked:before { + content: "\e157"; +} +.glyphicon-expand:before { + content: "\e158"; +} +.glyphicon-collapse-down:before { + content: "\e159"; +} +.glyphicon-collapse-up:before { + content: "\e160"; +} +.glyphicon-log-in:before { + content: "\e161"; +} +.glyphicon-flash:before { + content: "\e162"; +} +.glyphicon-log-out:before { + content: "\e163"; +} +.glyphicon-new-window:before { + content: "\e164"; +} +.glyphicon-record:before { + content: "\e165"; +} +.glyphicon-save:before { + content: "\e166"; +} +.glyphicon-open:before { + content: "\e167"; +} +.glyphicon-saved:before { + content: "\e168"; +} +.glyphicon-import:before { + content: "\e169"; +} +.glyphicon-export:before { + content: "\e170"; +} +.glyphicon-send:before { + content: "\e171"; +} +.glyphicon-floppy-disk:before { + content: "\e172"; +} +.glyphicon-floppy-saved:before { + content: "\e173"; +} +.glyphicon-floppy-remove:before { + content: "\e174"; +} +.glyphicon-floppy-save:before { + content: "\e175"; +} +.glyphicon-floppy-open:before { + content: "\e176"; +} +.glyphicon-credit-card:before { + content: "\e177"; +} +.glyphicon-transfer:before { + content: "\e178"; +} +.glyphicon-cutlery:before { + content: "\e179"; +} +.glyphicon-header:before { + content: "\e180"; +} +.glyphicon-compressed:before { + content: "\e181"; +} +.glyphicon-earphone:before { + content: "\e182"; +} +.glyphicon-phone-alt:before { + content: "\e183"; +} +.glyphicon-tower:before { + content: "\e184"; +} +.glyphicon-stats:before { + content: "\e185"; +} +.glyphicon-sd-video:before { + content: "\e186"; +} +.glyphicon-hd-video:before { + content: "\e187"; +} +.glyphicon-subtitles:before { + content: "\e188"; +} +.glyphicon-sound-stereo:before { + content: "\e189"; +} +.glyphicon-sound-dolby:before { + content: "\e190"; +} +.glyphicon-sound-5-1:before { + content: "\e191"; +} +.glyphicon-sound-6-1:before { + content: "\e192"; +} +.glyphicon-sound-7-1:before { + content: "\e193"; +} +.glyphicon-copyright-mark:before { + content: "\e194"; +} +.glyphicon-registration-mark:before { + content: "\e195"; +} +.glyphicon-cloud-download:before { + content: "\e197"; +} +.glyphicon-cloud-upload:before { + content: "\e198"; +} +.glyphicon-tree-conifer:before { + content: "\e199"; +} +.glyphicon-tree-deciduous:before { + content: "\e200"; +} +* { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +*:before, +*:after { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +html { + font-size: 10px; + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); +} +body { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 1.42857143; + color: #333; + background-color: #fff; +} +input, +button, +select, +textarea { + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +a { + color: #428bca; + text-decoration: none; +} +a:hover, +a:focus { + color: #2a6496; + text-decoration: underline; +} +a:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +figure { + margin: 0; +} +img { + vertical-align: middle; +} +.img-responsive, +.thumbnail > img, +.thumbnail a > img, +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + width: 100% \9; + max-width: 100%; + height: auto; +} +.img-rounded { + border-radius: 6px; +} +.img-thumbnail { + display: inline-block; + width: 100% \9; + max-width: 100%; + height: auto; + padding: 4px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.img-circle { + border-radius: 50%; +} +hr { + margin-top: 20px; + margin-bottom: 20px; + border: 0; + border-top: 1px solid #eee; +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + margin: 0; + overflow: visible; + clip: auto; +} +h1, +h2, +h3, +h4, +h5, +h6, +.h1, +.h2, +.h3, +.h4, +.h5, +.h6 { + font-family: inherit; + font-weight: 500; + line-height: 1.1; + color: inherit; +} +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small, +.h1 small, +.h2 small, +.h3 small, +.h4 small, +.h5 small, +.h6 small, +h1 .small, +h2 .small, +h3 .small, +h4 .small, +h5 .small, +h6 .small, +.h1 .small, +.h2 .small, +.h3 .small, +.h4 .small, +.h5 .small, +.h6 .small { + font-weight: normal; + line-height: 1; + color: #777; +} +h1, +.h1, +h2, +.h2, +h3, +.h3 { + margin-top: 20px; + margin-bottom: 10px; +} +h1 small, +.h1 small, +h2 small, +.h2 small, +h3 small, +.h3 small, +h1 .small, +.h1 .small, +h2 .small, +.h2 .small, +h3 .small, +.h3 .small { + font-size: 65%; +} +h4, +.h4, +h5, +.h5, +h6, +.h6 { + margin-top: 10px; + margin-bottom: 10px; +} +h4 small, +.h4 small, +h5 small, +.h5 small, +h6 small, +.h6 small, +h4 .small, +.h4 .small, +h5 .small, +.h5 .small, +h6 .small, +.h6 .small { + font-size: 75%; +} +h1, +.h1 { + font-size: 36px; +} +h2, +.h2 { + font-size: 30px; +} +h3, +.h3 { + font-size: 24px; +} +h4, +.h4 { + font-size: 18px; +} +h5, +.h5 { + font-size: 14px; +} +h6, +.h6 { + font-size: 12px; +} +p { + margin: 0 0 10px; +} +.lead { + margin-bottom: 20px; + font-size: 16px; + font-weight: 300; + line-height: 1.4; +} +@media (min-width: 768px) { + .lead { + font-size: 21px; + } +} +small, +.small { + font-size: 85%; +} +cite { + font-style: normal; +} +mark, +.mark { + padding: .2em; + background-color: #fcf8e3; +} +.text-left { + text-align: left; +} +.text-right { + text-align: right; +} +.text-center { + text-align: center; +} +.text-justify { + text-align: justify; +} +.text-nowrap { + white-space: nowrap; +} +.text-lowercase { + text-transform: lowercase; +} +.text-uppercase { + text-transform: uppercase; +} +.text-capitalize { + text-transform: capitalize; +} +.text-muted { + color: #777; +} +.text-primary { + color: #428bca; +} +a.text-primary:hover { + color: #3071a9; +} +.text-success { + color: #3c763d; +} +a.text-success:hover { + color: #2b542c; +} +.text-info { + color: #31708f; +} +a.text-info:hover { + color: #245269; +} +.text-warning { + color: #8a6d3b; +} +a.text-warning:hover { + color: #66512c; +} +.text-danger { + color: #a94442; +} +a.text-danger:hover { + color: #843534; +} +.bg-primary { + color: #fff; + background-color: #428bca; +} +a.bg-primary:hover { + background-color: #3071a9; +} +.bg-success { + background-color: #dff0d8; +} +a.bg-success:hover { + background-color: #c1e2b3; +} +.bg-info { + background-color: #d9edf7; +} +a.bg-info:hover { + background-color: #afd9ee; +} +.bg-warning { + background-color: #fcf8e3; +} +a.bg-warning:hover { + background-color: #f7ecb5; +} +.bg-danger { + background-color: #f2dede; +} +a.bg-danger:hover { + background-color: #e4b9b9; +} +.page-header { + padding-bottom: 9px; + margin: 40px 0 20px; + border-bottom: 1px solid #eee; +} +ul, +ol { + margin-top: 0; + margin-bottom: 10px; +} +ul ul, +ol ul, +ul ol, +ol ol { + margin-bottom: 0; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + margin-left: -5px; + list-style: none; +} +.list-inline > li { + display: inline-block; + padding-right: 5px; + padding-left: 5px; +} +dl { + margin-top: 0; + margin-bottom: 20px; +} +dt, +dd { + line-height: 1.42857143; +} +dt { + font-weight: bold; +} +dd { + margin-left: 0; +} +@media (min-width: 768px) { + .dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; + } + .dl-horizontal dd { + margin-left: 180px; + } +} +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #777; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +blockquote { + padding: 10px 20px; + margin: 0 0 20px; + font-size: 17.5px; + border-left: 5px solid #eee; +} +blockquote p:last-child, +blockquote ul:last-child, +blockquote ol:last-child { + margin-bottom: 0; +} +blockquote footer, +blockquote small, +blockquote .small { + display: block; + font-size: 80%; + line-height: 1.42857143; + color: #777; +} +blockquote footer:before, +blockquote small:before, +blockquote .small:before { + content: '\2014 \00A0'; +} +.blockquote-reverse, +blockquote.pull-right { + padding-right: 15px; + padding-left: 0; + text-align: right; + border-right: 5px solid #eee; + border-left: 0; +} +.blockquote-reverse footer:before, +blockquote.pull-right footer:before, +.blockquote-reverse small:before, +blockquote.pull-right small:before, +.blockquote-reverse .small:before, +blockquote.pull-right .small:before { + content: ''; +} +.blockquote-reverse footer:after, +blockquote.pull-right footer:after, +.blockquote-reverse small:after, +blockquote.pull-right small:after, +.blockquote-reverse .small:after, +blockquote.pull-right .small:after { + content: '\00A0 \2014'; +} +blockquote:before, +blockquote:after { + content: ""; +} +address { + margin-bottom: 20px; + font-style: normal; + line-height: 1.42857143; +} +code, +kbd, +pre, +samp { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; +} +code { + padding: 2px 4px; + font-size: 90%; + color: #c7254e; + background-color: #f9f2f4; + border-radius: 4px; +} +kbd { + padding: 2px 4px; + font-size: 90%; + color: #fff; + background-color: #333; + border-radius: 3px; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25); +} +kbd kbd { + padding: 0; + font-size: 100%; + -webkit-box-shadow: none; + box-shadow: none; +} +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 1.42857143; + color: #333; + word-break: break-all; + word-wrap: break-word; + background-color: #f5f5f5; + border: 1px solid #ccc; + border-radius: 4px; +} +pre code { + padding: 0; + font-size: inherit; + color: inherit; + white-space: pre-wrap; + background-color: transparent; + border-radius: 0; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 768px) { + .container { + width: 750px; + } +} +@media (min-width: 992px) { + .container { + width: 970px; + } +} +@media (min-width: 1200px) { + .container { + width: 1170px; + } +} +.container-fluid { + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +.row { + margin-right: -15px; + margin-left: -15px; +} +.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { + position: relative; + min-height: 1px; + padding-right: 15px; + padding-left: 15px; +} +.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { + float: left; +} +.col-xs-12 { + width: 100%; +} +.col-xs-11 { + width: 91.66666667%; +} +.col-xs-10 { + width: 83.33333333%; +} +.col-xs-9 { + width: 75%; +} +.col-xs-8 { + width: 66.66666667%; +} +.col-xs-7 { + width: 58.33333333%; +} +.col-xs-6 { + width: 50%; +} +.col-xs-5 { + width: 41.66666667%; +} +.col-xs-4 { + width: 33.33333333%; +} +.col-xs-3 { + width: 25%; +} +.col-xs-2 { + width: 16.66666667%; +} +.col-xs-1 { + width: 8.33333333%; +} +.col-xs-pull-12 { + right: 100%; +} +.col-xs-pull-11 { + right: 91.66666667%; +} +.col-xs-pull-10 { + right: 83.33333333%; +} +.col-xs-pull-9 { + right: 75%; +} +.col-xs-pull-8 { + right: 66.66666667%; +} +.col-xs-pull-7 { + right: 58.33333333%; +} +.col-xs-pull-6 { + right: 50%; +} +.col-xs-pull-5 { + right: 41.66666667%; +} +.col-xs-pull-4 { + right: 33.33333333%; +} +.col-xs-pull-3 { + right: 25%; +} +.col-xs-pull-2 { + right: 16.66666667%; +} +.col-xs-pull-1 { + right: 8.33333333%; +} +.col-xs-pull-0 { + right: auto; +} +.col-xs-push-12 { + left: 100%; +} +.col-xs-push-11 { + left: 91.66666667%; +} +.col-xs-push-10 { + left: 83.33333333%; +} +.col-xs-push-9 { + left: 75%; +} +.col-xs-push-8 { + left: 66.66666667%; +} +.col-xs-push-7 { + left: 58.33333333%; +} +.col-xs-push-6 { + left: 50%; +} +.col-xs-push-5 { + left: 41.66666667%; +} +.col-xs-push-4 { + left: 33.33333333%; +} +.col-xs-push-3 { + left: 25%; +} +.col-xs-push-2 { + left: 16.66666667%; +} +.col-xs-push-1 { + left: 8.33333333%; +} +.col-xs-push-0 { + left: auto; +} +.col-xs-offset-12 { + margin-left: 100%; +} +.col-xs-offset-11 { + margin-left: 91.66666667%; +} +.col-xs-offset-10 { + margin-left: 83.33333333%; +} +.col-xs-offset-9 { + margin-left: 75%; +} +.col-xs-offset-8 { + margin-left: 66.66666667%; +} +.col-xs-offset-7 { + margin-left: 58.33333333%; +} +.col-xs-offset-6 { + margin-left: 50%; +} +.col-xs-offset-5 { + margin-left: 41.66666667%; +} +.col-xs-offset-4 { + margin-left: 33.33333333%; +} +.col-xs-offset-3 { + margin-left: 25%; +} +.col-xs-offset-2 { + margin-left: 16.66666667%; +} +.col-xs-offset-1 { + margin-left: 8.33333333%; +} +.col-xs-offset-0 { + margin-left: 0; +} +@media (min-width: 768px) { + .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { + float: left; + } + .col-sm-12 { + width: 100%; + } + .col-sm-11 { + width: 91.66666667%; + } + .col-sm-10 { + width: 83.33333333%; + } + .col-sm-9 { + width: 75%; + } + .col-sm-8 { + width: 66.66666667%; + } + .col-sm-7 { + width: 58.33333333%; + } + .col-sm-6 { + width: 50%; + } + .col-sm-5 { + width: 41.66666667%; + } + .col-sm-4 { + width: 33.33333333%; + } + .col-sm-3 { + width: 25%; + } + .col-sm-2 { + width: 16.66666667%; + } + .col-sm-1 { + width: 8.33333333%; + } + .col-sm-pull-12 { + right: 100%; + } + .col-sm-pull-11 { + right: 91.66666667%; + } + .col-sm-pull-10 { + right: 83.33333333%; + } + .col-sm-pull-9 { + right: 75%; + } + .col-sm-pull-8 { + right: 66.66666667%; + } + .col-sm-pull-7 { + right: 58.33333333%; + } + .col-sm-pull-6 { + right: 50%; + } + .col-sm-pull-5 { + right: 41.66666667%; + } + .col-sm-pull-4 { + right: 33.33333333%; + } + .col-sm-pull-3 { + right: 25%; + } + .col-sm-pull-2 { + right: 16.66666667%; + } + .col-sm-pull-1 { + right: 8.33333333%; + } + .col-sm-pull-0 { + right: auto; + } + .col-sm-push-12 { + left: 100%; + } + .col-sm-push-11 { + left: 91.66666667%; + } + .col-sm-push-10 { + left: 83.33333333%; + } + .col-sm-push-9 { + left: 75%; + } + .col-sm-push-8 { + left: 66.66666667%; + } + .col-sm-push-7 { + left: 58.33333333%; + } + .col-sm-push-6 { + left: 50%; + } + .col-sm-push-5 { + left: 41.66666667%; + } + .col-sm-push-4 { + left: 33.33333333%; + } + .col-sm-push-3 { + left: 25%; + } + .col-sm-push-2 { + left: 16.66666667%; + } + .col-sm-push-1 { + left: 8.33333333%; + } + .col-sm-push-0 { + left: auto; + } + .col-sm-offset-12 { + margin-left: 100%; + } + .col-sm-offset-11 { + margin-left: 91.66666667%; + } + .col-sm-offset-10 { + margin-left: 83.33333333%; + } + .col-sm-offset-9 { + margin-left: 75%; + } + .col-sm-offset-8 { + margin-left: 66.66666667%; + } + .col-sm-offset-7 { + margin-left: 58.33333333%; + } + .col-sm-offset-6 { + margin-left: 50%; + } + .col-sm-offset-5 { + margin-left: 41.66666667%; + } + .col-sm-offset-4 { + margin-left: 33.33333333%; + } + .col-sm-offset-3 { + margin-left: 25%; + } + .col-sm-offset-2 { + margin-left: 16.66666667%; + } + .col-sm-offset-1 { + margin-left: 8.33333333%; + } + .col-sm-offset-0 { + margin-left: 0; + } +} +@media (min-width: 992px) { + .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { + float: left; + } + .col-md-12 { + width: 100%; + } + .col-md-11 { + width: 91.66666667%; + } + .col-md-10 { + width: 83.33333333%; + } + .col-md-9 { + width: 75%; + } + .col-md-8 { + width: 66.66666667%; + } + .col-md-7 { + width: 58.33333333%; + } + .col-md-6 { + width: 50%; + } + .col-md-5 { + width: 41.66666667%; + } + .col-md-4 { + width: 33.33333333%; + } + .col-md-3 { + width: 25%; + } + .col-md-2 { + width: 16.66666667%; + } + .col-md-1 { + width: 8.33333333%; + } + .col-md-pull-12 { + right: 100%; + } + .col-md-pull-11 { + right: 91.66666667%; + } + .col-md-pull-10 { + right: 83.33333333%; + } + .col-md-pull-9 { + right: 75%; + } + .col-md-pull-8 { + right: 66.66666667%; + } + .col-md-pull-7 { + right: 58.33333333%; + } + .col-md-pull-6 { + right: 50%; + } + .col-md-pull-5 { + right: 41.66666667%; + } + .col-md-pull-4 { + right: 33.33333333%; + } + .col-md-pull-3 { + right: 25%; + } + .col-md-pull-2 { + right: 16.66666667%; + } + .col-md-pull-1 { + right: 8.33333333%; + } + .col-md-pull-0 { + right: auto; + } + .col-md-push-12 { + left: 100%; + } + .col-md-push-11 { + left: 91.66666667%; + } + .col-md-push-10 { + left: 83.33333333%; + } + .col-md-push-9 { + left: 75%; + } + .col-md-push-8 { + left: 66.66666667%; + } + .col-md-push-7 { + left: 58.33333333%; + } + .col-md-push-6 { + left: 50%; + } + .col-md-push-5 { + left: 41.66666667%; + } + .col-md-push-4 { + left: 33.33333333%; + } + .col-md-push-3 { + left: 25%; + } + .col-md-push-2 { + left: 16.66666667%; + } + .col-md-push-1 { + left: 8.33333333%; + } + .col-md-push-0 { + left: auto; + } + .col-md-offset-12 { + margin-left: 100%; + } + .col-md-offset-11 { + margin-left: 91.66666667%; + } + .col-md-offset-10 { + margin-left: 83.33333333%; + } + .col-md-offset-9 { + margin-left: 75%; + } + .col-md-offset-8 { + margin-left: 66.66666667%; + } + .col-md-offset-7 { + margin-left: 58.33333333%; + } + .col-md-offset-6 { + margin-left: 50%; + } + .col-md-offset-5 { + margin-left: 41.66666667%; + } + .col-md-offset-4 { + margin-left: 33.33333333%; + } + .col-md-offset-3 { + margin-left: 25%; + } + .col-md-offset-2 { + margin-left: 16.66666667%; + } + .col-md-offset-1 { + margin-left: 8.33333333%; + } + .col-md-offset-0 { + margin-left: 0; + } +} +@media (min-width: 1200px) { + .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { + float: left; + } + .col-lg-12 { + width: 100%; + } + .col-lg-11 { + width: 91.66666667%; + } + .col-lg-10 { + width: 83.33333333%; + } + .col-lg-9 { + width: 75%; + } + .col-lg-8 { + width: 66.66666667%; + } + .col-lg-7 { + width: 58.33333333%; + } + .col-lg-6 { + width: 50%; + } + .col-lg-5 { + width: 41.66666667%; + } + .col-lg-4 { + width: 33.33333333%; + } + .col-lg-3 { + width: 25%; + } + .col-lg-2 { + width: 16.66666667%; + } + .col-lg-1 { + width: 8.33333333%; + } + .col-lg-pull-12 { + right: 100%; + } + .col-lg-pull-11 { + right: 91.66666667%; + } + .col-lg-pull-10 { + right: 83.33333333%; + } + .col-lg-pull-9 { + right: 75%; + } + .col-lg-pull-8 { + right: 66.66666667%; + } + .col-lg-pull-7 { + right: 58.33333333%; + } + .col-lg-pull-6 { + right: 50%; + } + .col-lg-pull-5 { + right: 41.66666667%; + } + .col-lg-pull-4 { + right: 33.33333333%; + } + .col-lg-pull-3 { + right: 25%; + } + .col-lg-pull-2 { + right: 16.66666667%; + } + .col-lg-pull-1 { + right: 8.33333333%; + } + .col-lg-pull-0 { + right: auto; + } + .col-lg-push-12 { + left: 100%; + } + .col-lg-push-11 { + left: 91.66666667%; + } + .col-lg-push-10 { + left: 83.33333333%; + } + .col-lg-push-9 { + left: 75%; + } + .col-lg-push-8 { + left: 66.66666667%; + } + .col-lg-push-7 { + left: 58.33333333%; + } + .col-lg-push-6 { + left: 50%; + } + .col-lg-push-5 { + left: 41.66666667%; + } + .col-lg-push-4 { + left: 33.33333333%; + } + .col-lg-push-3 { + left: 25%; + } + .col-lg-push-2 { + left: 16.66666667%; + } + .col-lg-push-1 { + left: 8.33333333%; + } + .col-lg-push-0 { + left: auto; + } + .col-lg-offset-12 { + margin-left: 100%; + } + .col-lg-offset-11 { + margin-left: 91.66666667%; + } + .col-lg-offset-10 { + margin-left: 83.33333333%; + } + .col-lg-offset-9 { + margin-left: 75%; + } + .col-lg-offset-8 { + margin-left: 66.66666667%; + } + .col-lg-offset-7 { + margin-left: 58.33333333%; + } + .col-lg-offset-6 { + margin-left: 50%; + } + .col-lg-offset-5 { + margin-left: 41.66666667%; + } + .col-lg-offset-4 { + margin-left: 33.33333333%; + } + .col-lg-offset-3 { + margin-left: 25%; + } + .col-lg-offset-2 { + margin-left: 16.66666667%; + } + .col-lg-offset-1 { + margin-left: 8.33333333%; + } + .col-lg-offset-0 { + margin-left: 0; + } +} +table { + background-color: transparent; +} +th { + text-align: left; +} +.table { + width: 100%; + max-width: 100%; + margin-bottom: 20px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 8px; + line-height: 1.42857143; + vertical-align: top; + border-top: 1px solid #ddd; +} +.table > thead > tr > th { + vertical-align: bottom; + border-bottom: 2px solid #ddd; +} +.table > caption + thead > tr:first-child > th, +.table > colgroup + thead > tr:first-child > th, +.table > thead:first-child > tr:first-child > th, +.table > caption + thead > tr:first-child > td, +.table > colgroup + thead > tr:first-child > td, +.table > thead:first-child > tr:first-child > td { + border-top: 0; +} +.table > tbody + tbody { + border-top: 2px solid #ddd; +} +.table .table { + background-color: #fff; +} +.table-condensed > thead > tr > th, +.table-condensed > tbody > tr > th, +.table-condensed > tfoot > tr > th, +.table-condensed > thead > tr > td, +.table-condensed > tbody > tr > td, +.table-condensed > tfoot > tr > td { + padding: 5px; +} +.table-bordered { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > tbody > tr > th, +.table-bordered > tfoot > tr > th, +.table-bordered > thead > tr > td, +.table-bordered > tbody > tr > td, +.table-bordered > tfoot > tr > td { + border: 1px solid #ddd; +} +.table-bordered > thead > tr > th, +.table-bordered > thead > tr > td { + border-bottom-width: 2px; +} +.table-striped > tbody > tr:nth-child(odd) > td, +.table-striped > tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} +.table-hover > tbody > tr:hover > td, +.table-hover > tbody > tr:hover > th { + background-color: #f5f5f5; +} +table col[class*="col-"] { + position: static; + display: table-column; + float: none; +} +table td[class*="col-"], +table th[class*="col-"] { + position: static; + display: table-cell; + float: none; +} +.table > thead > tr > td.active, +.table > tbody > tr > td.active, +.table > tfoot > tr > td.active, +.table > thead > tr > th.active, +.table > tbody > tr > th.active, +.table > tfoot > tr > th.active, +.table > thead > tr.active > td, +.table > tbody > tr.active > td, +.table > tfoot > tr.active > td, +.table > thead > tr.active > th, +.table > tbody > tr.active > th, +.table > tfoot > tr.active > th { + background-color: #f5f5f5; +} +.table-hover > tbody > tr > td.active:hover, +.table-hover > tbody > tr > th.active:hover, +.table-hover > tbody > tr.active:hover > td, +.table-hover > tbody > tr:hover > .active, +.table-hover > tbody > tr.active:hover > th { + background-color: #e8e8e8; +} +.table > thead > tr > td.success, +.table > tbody > tr > td.success, +.table > tfoot > tr > td.success, +.table > thead > tr > th.success, +.table > tbody > tr > th.success, +.table > tfoot > tr > th.success, +.table > thead > tr.success > td, +.table > tbody > tr.success > td, +.table > tfoot > tr.success > td, +.table > thead > tr.success > th, +.table > tbody > tr.success > th, +.table > tfoot > tr.success > th { + background-color: #dff0d8; +} +.table-hover > tbody > tr > td.success:hover, +.table-hover > tbody > tr > th.success:hover, +.table-hover > tbody > tr.success:hover > td, +.table-hover > tbody > tr:hover > .success, +.table-hover > tbody > tr.success:hover > th { + background-color: #d0e9c6; +} +.table > thead > tr > td.info, +.table > tbody > tr > td.info, +.table > tfoot > tr > td.info, +.table > thead > tr > th.info, +.table > tbody > tr > th.info, +.table > tfoot > tr > th.info, +.table > thead > tr.info > td, +.table > tbody > tr.info > td, +.table > tfoot > tr.info > td, +.table > thead > tr.info > th, +.table > tbody > tr.info > th, +.table > tfoot > tr.info > th { + background-color: #d9edf7; +} +.table-hover > tbody > tr > td.info:hover, +.table-hover > tbody > tr > th.info:hover, +.table-hover > tbody > tr.info:hover > td, +.table-hover > tbody > tr:hover > .info, +.table-hover > tbody > tr.info:hover > th { + background-color: #c4e3f3; +} +.table > thead > tr > td.warning, +.table > tbody > tr > td.warning, +.table > tfoot > tr > td.warning, +.table > thead > tr > th.warning, +.table > tbody > tr > th.warning, +.table > tfoot > tr > th.warning, +.table > thead > tr.warning > td, +.table > tbody > tr.warning > td, +.table > tfoot > tr.warning > td, +.table > thead > tr.warning > th, +.table > tbody > tr.warning > th, +.table > tfoot > tr.warning > th { + background-color: #fcf8e3; +} +.table-hover > tbody > tr > td.warning:hover, +.table-hover > tbody > tr > th.warning:hover, +.table-hover > tbody > tr.warning:hover > td, +.table-hover > tbody > tr:hover > .warning, +.table-hover > tbody > tr.warning:hover > th { + background-color: #faf2cc; +} +.table > thead > tr > td.danger, +.table > tbody > tr > td.danger, +.table > tfoot > tr > td.danger, +.table > thead > tr > th.danger, +.table > tbody > tr > th.danger, +.table > tfoot > tr > th.danger, +.table > thead > tr.danger > td, +.table > tbody > tr.danger > td, +.table > tfoot > tr.danger > td, +.table > thead > tr.danger > th, +.table > tbody > tr.danger > th, +.table > tfoot > tr.danger > th { + background-color: #f2dede; +} +.table-hover > tbody > tr > td.danger:hover, +.table-hover > tbody > tr > th.danger:hover, +.table-hover > tbody > tr.danger:hover > td, +.table-hover > tbody > tr:hover > .danger, +.table-hover > tbody > tr.danger:hover > th { + background-color: #ebcccc; +} +@media screen and (max-width: 767px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-x: auto; + overflow-y: hidden; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: -ms-autohiding-scrollbar; + border: 1px solid #ddd; + } + .table-responsive > .table { + margin-bottom: 0; + } + .table-responsive > .table > thead > tr > th, + .table-responsive > .table > tbody > tr > th, + .table-responsive > .table > tfoot > tr > th, + .table-responsive > .table > thead > tr > td, + .table-responsive > .table > tbody > tr > td, + .table-responsive > .table > tfoot > tr > td { + white-space: nowrap; + } + .table-responsive > .table-bordered { + border: 0; + } + .table-responsive > .table-bordered > thead > tr > th:first-child, + .table-responsive > .table-bordered > tbody > tr > th:first-child, + .table-responsive > .table-bordered > tfoot > tr > th:first-child, + .table-responsive > .table-bordered > thead > tr > td:first-child, + .table-responsive > .table-bordered > tbody > tr > td:first-child, + .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; + } + .table-responsive > .table-bordered > thead > tr > th:last-child, + .table-responsive > .table-bordered > tbody > tr > th:last-child, + .table-responsive > .table-bordered > tfoot > tr > th:last-child, + .table-responsive > .table-bordered > thead > tr > td:last-child, + .table-responsive > .table-bordered > tbody > tr > td:last-child, + .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; + } + .table-responsive > .table-bordered > tbody > tr:last-child > th, + .table-responsive > .table-bordered > tfoot > tr:last-child > th, + .table-responsive > .table-bordered > tbody > tr:last-child > td, + .table-responsive > .table-bordered > tfoot > tr:last-child > td { + border-bottom: 0; + } +} +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: inherit; + color: #333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} +label { + display: inline-block; + max-width: 100%; + margin-bottom: 5px; + font-weight: bold; +} +input[type="search"] { + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + line-height: normal; +} +input[type="file"] { + display: block; +} +input[type="range"] { + display: block; + width: 100%; +} +select[multiple], +select[size] { + height: auto; +} +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +output { + display: block; + padding-top: 7px; + font-size: 14px; + line-height: 1.42857143; + color: #555; +} +.form-control { + display: block; + width: 100%; + height: 34px; + padding: 6px 12px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s; + -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +.form-control:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6); +} +.form-control::-moz-placeholder { + color: #777; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #777; +} +.form-control::-webkit-input-placeholder { + color: #777; +} +.form-control[disabled], +.form-control[readonly], +fieldset[disabled] .form-control { + cursor: not-allowed; + background-color: #eee; + opacity: 1; +} +textarea.form-control { + height: auto; +} +input[type="search"] { + -webkit-appearance: none; +} +input[type="date"], +input[type="time"], +input[type="datetime-local"], +input[type="month"] { + line-height: 34px; + line-height: 1.42857143 \0; +} +input[type="date"].input-sm, +input[type="time"].input-sm, +input[type="datetime-local"].input-sm, +input[type="month"].input-sm { + line-height: 30px; +} +input[type="date"].input-lg, +input[type="time"].input-lg, +input[type="datetime-local"].input-lg, +input[type="month"].input-lg { + line-height: 46px; +} +.form-group { + margin-bottom: 15px; +} +.radio, +.checkbox { + position: relative; + display: block; + min-height: 20px; + margin-top: 10px; + margin-bottom: 10px; +} +.radio label, +.checkbox label { + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + cursor: pointer; +} +.radio input[type="radio"], +.radio-inline input[type="radio"], +.checkbox input[type="checkbox"], +.checkbox-inline input[type="checkbox"] { + position: absolute; + margin-top: 4px \9; + margin-left: -20px; +} +.radio + .radio, +.checkbox + .checkbox { + margin-top: -5px; +} +.radio-inline, +.checkbox-inline { + display: inline-block; + padding-left: 20px; + margin-bottom: 0; + font-weight: normal; + vertical-align: middle; + cursor: pointer; +} +.radio-inline + .radio-inline, +.checkbox-inline + .checkbox-inline { + margin-top: 0; + margin-left: 10px; +} +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"].disabled, +input[type="checkbox"].disabled, +fieldset[disabled] input[type="radio"], +fieldset[disabled] input[type="checkbox"] { + cursor: not-allowed; +} +.radio-inline.disabled, +.checkbox-inline.disabled, +fieldset[disabled] .radio-inline, +fieldset[disabled] .checkbox-inline { + cursor: not-allowed; +} +.radio.disabled label, +.checkbox.disabled label, +fieldset[disabled] .radio label, +fieldset[disabled] .checkbox label { + cursor: not-allowed; +} +.form-control-static { + padding-top: 7px; + padding-bottom: 7px; + margin-bottom: 0; +} +.form-control-static.input-lg, +.form-control-static.input-sm { + padding-right: 0; + padding-left: 0; +} +.input-sm, +.form-horizontal .form-group-sm .form-control { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-sm { + height: 30px; + line-height: 30px; +} +textarea.input-sm, +select[multiple].input-sm { + height: auto; +} +.input-lg, +.form-horizontal .form-group-lg .form-control { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +select.input-lg { + height: 46px; + line-height: 46px; +} +textarea.input-lg, +select[multiple].input-lg { + height: auto; +} +.has-feedback { + position: relative; +} +.has-feedback .form-control { + padding-right: 42.5px; +} +.form-control-feedback { + position: absolute; + top: 25px; + right: 0; + z-index: 2; + display: block; + width: 34px; + height: 34px; + line-height: 34px; + text-align: center; +} +.input-lg + .form-control-feedback { + width: 46px; + height: 46px; + line-height: 46px; +} +.input-sm + .form-control-feedback { + width: 30px; + height: 30px; + line-height: 30px; +} +.has-success .help-block, +.has-success .control-label, +.has-success .radio, +.has-success .checkbox, +.has-success .radio-inline, +.has-success .checkbox-inline { + color: #3c763d; +} +.has-success .form-control { + border-color: #3c763d; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-success .form-control:focus { + border-color: #2b542c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168; +} +.has-success .input-group-addon { + color: #3c763d; + background-color: #dff0d8; + border-color: #3c763d; +} +.has-success .form-control-feedback { + color: #3c763d; +} +.has-warning .help-block, +.has-warning .control-label, +.has-warning .radio, +.has-warning .checkbox, +.has-warning .radio-inline, +.has-warning .checkbox-inline { + color: #8a6d3b; +} +.has-warning .form-control { + border-color: #8a6d3b; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-warning .form-control:focus { + border-color: #66512c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b; +} +.has-warning .input-group-addon { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #8a6d3b; +} +.has-warning .form-control-feedback { + color: #8a6d3b; +} +.has-error .help-block, +.has-error .control-label, +.has-error .radio, +.has-error .checkbox, +.has-error .radio-inline, +.has-error .checkbox-inline { + color: #a94442; +} +.has-error .form-control { + border-color: #a94442; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); +} +.has-error .form-control:focus { + border-color: #843534; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483; +} +.has-error .input-group-addon { + color: #a94442; + background-color: #f2dede; + border-color: #a94442; +} +.has-error .form-control-feedback { + color: #a94442; +} +.has-feedback label.sr-only ~ .form-control-feedback { + top: 0; +} +.help-block { + display: block; + margin-top: 5px; + margin-bottom: 10px; + color: #737373; +} +@media (min-width: 768px) { + .form-inline .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .input-group { + display: inline-table; + vertical-align: middle; + } + .form-inline .input-group .input-group-addon, + .form-inline .input-group .input-group-btn, + .form-inline .input-group .form-control { + width: auto; + } + .form-inline .input-group > .form-control { + width: 100%; + } + .form-inline .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio, + .form-inline .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .form-inline .radio label, + .form-inline .checkbox label { + padding-left: 0; + } + .form-inline .radio input[type="radio"], + .form-inline .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .form-inline .has-feedback .form-control-feedback { + top: 0; + } +} +.form-horizontal .radio, +.form-horizontal .checkbox, +.form-horizontal .radio-inline, +.form-horizontal .checkbox-inline { + padding-top: 7px; + margin-top: 0; + margin-bottom: 0; +} +.form-horizontal .radio, +.form-horizontal .checkbox { + min-height: 27px; +} +.form-horizontal .form-group { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .form-horizontal .control-label { + padding-top: 7px; + margin-bottom: 0; + text-align: right; + } +} +.form-horizontal .has-feedback .form-control-feedback { + top: 0; + right: 15px; +} +@media (min-width: 768px) { + .form-horizontal .form-group-lg .control-label { + padding-top: 14.3px; + } +} +@media (min-width: 768px) { + .form-horizontal .form-group-sm .control-label { + padding-top: 6px; + } +} +.btn { + display: inline-block; + padding: 6px 12px; + margin-bottom: 0; + font-size: 14px; + font-weight: normal; + line-height: 1.42857143; + text-align: center; + white-space: nowrap; + vertical-align: middle; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.btn:focus, +.btn:active:focus, +.btn.active:focus { + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} +.btn:hover, +.btn:focus { + color: #333; + text-decoration: none; +} +.btn:active, +.btn.active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn.disabled, +.btn[disabled], +fieldset[disabled] .btn { + pointer-events: none; + cursor: not-allowed; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + box-shadow: none; + opacity: .65; +} +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus, +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + background-image: none; +} +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #fff; + border-color: #ccc; +} +.btn-default .badge { + color: #fff; + background-color: #333; +} +.btn-primary { + color: #fff; + background-color: #428bca; + border-color: #357ebd; +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #3071a9; + border-color: #285e8e; +} +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + background-image: none; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #428bca; + border-color: #357ebd; +} +.btn-primary .badge { + color: #428bca; + background-color: #fff; +} +.btn-success { + color: #fff; + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #449d44; + border-color: #398439; +} +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + background-image: none; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #5cb85c; + border-color: #4cae4c; +} +.btn-success .badge { + color: #5cb85c; + background-color: #fff; +} +.btn-info { + color: #fff; + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #31b0d5; + border-color: #269abc; +} +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + background-image: none; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #5bc0de; + border-color: #46b8da; +} +.btn-info .badge { + color: #5bc0de; + background-color: #fff; +} +.btn-warning { + color: #fff; + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #ec971f; + border-color: #d58512; +} +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + background-image: none; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #f0ad4e; + border-color: #eea236; +} +.btn-warning .badge { + color: #f0ad4e; + background-color: #fff; +} +.btn-danger { + color: #fff; + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #c9302c; + border-color: #ac2925; +} +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + background-image: none; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #d9534f; + border-color: #d43f3a; +} +.btn-danger .badge { + color: #d9534f; + background-color: #fff; +} +.btn-link { + font-weight: normal; + color: #428bca; + cursor: pointer; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #2a6496; + text-decoration: underline; + background-color: transparent; +} +.btn-link[disabled]:hover, +fieldset[disabled] .btn-link:hover, +.btn-link[disabled]:focus, +fieldset[disabled] .btn-link:focus { + color: #777; + text-decoration: none; +} +.btn-lg, +.btn-group-lg > .btn { + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +.btn-sm, +.btn-group-sm > .btn { + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-xs, +.btn-group-xs > .btn { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 5px; +} +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} +.fade { + opacity: 0; + -webkit-transition: opacity .15s linear; + -o-transition: opacity .15s linear; + transition: opacity .15s linear; +} +.fade.in { + opacity: 1; +} +.collapse { + display: none; +} +.collapse.in { + display: block; +} +tr.collapse.in { + display: table-row; +} +tbody.collapse.in { + display: table-row-group; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height .35s ease; + -o-transition: height .35s ease; + transition: height .35s ease; +} +.caret { + display: inline-block; + width: 0; + height: 0; + margin-left: 2px; + vertical-align: middle; + border-top: 4px solid; + border-right: 4px solid transparent; + border-left: 4px solid transparent; +} +.dropdown { + position: relative; +} +.dropdown-toggle:focus { + outline: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + font-size: 14px; + text-align: left; + list-style: none; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .15); + border-radius: 4px; + -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); + box-shadow: 0 6px 12px rgba(0, 0, 0, .175); +} +.dropdown-menu.pull-right { + right: 0; + left: auto; +} +.dropdown-menu .divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 1.42857143; + color: #333; + white-space: nowrap; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + color: #262626; + text-decoration: none; + background-color: #f5f5f5; +} +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #fff; + text-decoration: none; + background-color: #428bca; + outline: 0; +} +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #777; +} +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: not-allowed; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); +} +.open > .dropdown-menu { + display: block; +} +.open > a { + outline: 0; +} +.dropdown-menu-right { + right: 0; + left: auto; +} +.dropdown-menu-left { + right: auto; + left: 0; +} +.dropdown-header { + display: block; + padding: 3px 20px; + font-size: 12px; + line-height: 1.42857143; + color: #777; + white-space: nowrap; +} +.dropdown-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 990; +} +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + content: ""; + border-top: 0; + border-bottom: 4px solid; +} +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} +@media (min-width: 768px) { + .navbar-right .dropdown-menu { + right: 0; + left: auto; + } + .navbar-right .dropdown-menu-left { + right: auto; + left: 0; + } +} +.btn-group, +.btn-group-vertical { + position: relative; + display: inline-block; + vertical-align: middle; +} +.btn-group > .btn, +.btn-group-vertical > .btn { + position: relative; + float: left; +} +.btn-group > .btn:hover, +.btn-group-vertical > .btn:hover, +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus, +.btn-group > .btn:active, +.btn-group-vertical > .btn:active, +.btn-group > .btn.active, +.btn-group-vertical > .btn.active { + z-index: 2; +} +.btn-group > .btn:focus, +.btn-group-vertical > .btn:focus { + outline: 0; +} +.btn-group .btn + .btn, +.btn-group .btn + .btn-group, +.btn-group .btn-group + .btn, +.btn-group .btn-group + .btn-group { + margin-left: -1px; +} +.btn-toolbar { + margin-left: -5px; +} +.btn-toolbar .btn-group, +.btn-toolbar .input-group { + float: left; +} +.btn-toolbar > .btn, +.btn-toolbar > .btn-group, +.btn-toolbar > .input-group { + margin-left: 5px; +} +.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { + border-radius: 0; +} +.btn-group > .btn:first-child { + margin-left: 0; +} +.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn:last-child:not(:first-child), +.btn-group > .dropdown-toggle:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group > .btn-group { + float: left; +} +.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group > .btn-group:first-child > .btn:last-child, +.btn-group > .btn-group:first-child > .dropdown-toggle { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn-group:last-child > .btn:first-child { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} +.btn-group > .btn + .dropdown-toggle { + padding-right: 8px; + padding-left: 8px; +} +.btn-group > .btn-lg + .dropdown-toggle { + padding-right: 12px; + padding-left: 12px; +} +.btn-group.open .dropdown-toggle { + -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); + box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125); +} +.btn-group.open .dropdown-toggle.btn-link { + -webkit-box-shadow: none; + box-shadow: none; +} +.btn .caret { + margin-left: 0; +} +.btn-lg .caret { + border-width: 5px 5px 0; + border-bottom-width: 0; +} +.dropup .btn-lg .caret { + border-width: 0 5px 5px; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group, +.btn-group-vertical > .btn-group > .btn { + display: block; + float: none; + width: 100%; + max-width: 100%; +} +.btn-group-vertical > .btn-group > .btn { + float: none; +} +.btn-group-vertical > .btn + .btn, +.btn-group-vertical > .btn + .btn-group, +.btn-group-vertical > .btn-group + .btn, +.btn-group-vertical > .btn-group + .btn-group { + margin-top: -1px; + margin-left: 0; +} +.btn-group-vertical > .btn:not(:first-child):not(:last-child) { + border-radius: 0; +} +.btn-group-vertical > .btn:first-child:not(:last-child) { + border-top-right-radius: 4px; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn:last-child:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-left-radius: 4px; +} +.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { + border-radius: 0; +} +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, +.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.btn-group-justified { + display: table; + width: 100%; + table-layout: fixed; + border-collapse: separate; +} +.btn-group-justified > .btn, +.btn-group-justified > .btn-group { + display: table-cell; + float: none; + width: 1%; +} +.btn-group-justified > .btn-group .btn { + width: 100%; +} +.btn-group-justified > .btn-group .dropdown-menu { + left: auto; +} +[data-toggle="buttons"] > .btn > input[type="radio"], +[data-toggle="buttons"] > .btn > input[type="checkbox"] { + position: absolute; + z-index: -1; + filter: alpha(opacity=0); + opacity: 0; +} +.input-group { + position: relative; + display: table; + border-collapse: separate; +} +.input-group[class*="col-"] { + float: none; + padding-right: 0; + padding-left: 0; +} +.input-group .form-control { + position: relative; + z-index: 2; + float: left; + width: 100%; + margin-bottom: 0; +} +.input-group-lg > .form-control, +.input-group-lg > .input-group-addon, +.input-group-lg > .input-group-btn > .btn { + height: 46px; + padding: 10px 16px; + font-size: 18px; + line-height: 1.33; + border-radius: 6px; +} +select.input-group-lg > .form-control, +select.input-group-lg > .input-group-addon, +select.input-group-lg > .input-group-btn > .btn { + height: 46px; + line-height: 46px; +} +textarea.input-group-lg > .form-control, +textarea.input-group-lg > .input-group-addon, +textarea.input-group-lg > .input-group-btn > .btn, +select[multiple].input-group-lg > .form-control, +select[multiple].input-group-lg > .input-group-addon, +select[multiple].input-group-lg > .input-group-btn > .btn { + height: auto; +} +.input-group-sm > .form-control, +.input-group-sm > .input-group-addon, +.input-group-sm > .input-group-btn > .btn { + height: 30px; + padding: 5px 10px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} +select.input-group-sm > .form-control, +select.input-group-sm > .input-group-addon, +select.input-group-sm > .input-group-btn > .btn { + height: 30px; + line-height: 30px; +} +textarea.input-group-sm > .form-control, +textarea.input-group-sm > .input-group-addon, +textarea.input-group-sm > .input-group-btn > .btn, +select[multiple].input-group-sm > .form-control, +select[multiple].input-group-sm > .input-group-addon, +select[multiple].input-group-sm > .input-group-btn > .btn { + height: auto; +} +.input-group-addon, +.input-group-btn, +.input-group .form-control { + display: table-cell; +} +.input-group-addon:not(:first-child):not(:last-child), +.input-group-btn:not(:first-child):not(:last-child), +.input-group .form-control:not(:first-child):not(:last-child) { + border-radius: 0; +} +.input-group-addon, +.input-group-btn { + width: 1%; + white-space: nowrap; + vertical-align: middle; +} +.input-group-addon { + padding: 6px 12px; + font-size: 14px; + font-weight: normal; + line-height: 1; + color: #555; + text-align: center; + background-color: #eee; + border: 1px solid #ccc; + border-radius: 4px; +} +.input-group-addon.input-sm { + padding: 5px 10px; + font-size: 12px; + border-radius: 3px; +} +.input-group-addon.input-lg { + padding: 10px 16px; + font-size: 18px; + border-radius: 6px; +} +.input-group-addon input[type="radio"], +.input-group-addon input[type="checkbox"] { + margin-top: 0; +} +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group > .btn, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group-btn:last-child > .btn-group:not(:last-child) > .btn { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group-addon:first-child { + border-right: 0; +} +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group > .btn, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child), +.input-group-btn:first-child > .btn-group:not(:first-child) > .btn { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group-addon:last-child { + border-left: 0; +} +.input-group-btn { + position: relative; + font-size: 0; + white-space: nowrap; +} +.input-group-btn > .btn { + position: relative; +} +.input-group-btn > .btn + .btn { + margin-left: -1px; +} +.input-group-btn > .btn:hover, +.input-group-btn > .btn:focus, +.input-group-btn > .btn:active { + z-index: 2; +} +.input-group-btn:first-child > .btn, +.input-group-btn:first-child > .btn-group { + margin-right: -1px; +} +.input-group-btn:last-child > .btn, +.input-group-btn:last-child > .btn-group { + margin-left: -1px; +} +.nav { + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav > li { + position: relative; + display: block; +} +.nav > li > a { + position: relative; + display: block; + padding: 10px 15px; +} +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eee; +} +.nav > li.disabled > a { + color: #777; +} +.nav > li.disabled > a:hover, +.nav > li.disabled > a:focus { + color: #777; + text-decoration: none; + cursor: not-allowed; + background-color: transparent; +} +.nav .open > a, +.nav .open > a:hover, +.nav .open > a:focus { + background-color: #eee; + border-color: #428bca; +} +.nav .nav-divider { + height: 1px; + margin: 9px 0; + overflow: hidden; + background-color: #e5e5e5; +} +.nav > li > a > img { + max-width: none; +} +.nav-tabs { + border-bottom: 1px solid #ddd; +} +.nav-tabs > li { + float: left; + margin-bottom: -1px; +} +.nav-tabs > li > a { + margin-right: 2px; + line-height: 1.42857143; + border: 1px solid transparent; + border-radius: 4px 4px 0 0; +} +.nav-tabs > li > a:hover { + border-color: #eee #eee #ddd; +} +.nav-tabs > li.active > a, +.nav-tabs > li.active > a:hover, +.nav-tabs > li.active > a:focus { + color: #555; + cursor: default; + background-color: #fff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} +.nav-tabs.nav-justified { + width: 100%; + border-bottom: 0; +} +.nav-tabs.nav-justified > li { + float: none; +} +.nav-tabs.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-tabs.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-tabs.nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs.nav-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs.nav-justified > .active > a, +.nav-tabs.nav-justified > .active > a:hover, +.nav-tabs.nav-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs.nav-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs.nav-justified > .active > a, + .nav-tabs.nav-justified > .active > a:hover, + .nav-tabs.nav-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.nav-pills > li { + float: left; +} +.nav-pills > li > a { + border-radius: 4px; +} +.nav-pills > li + li { + margin-left: 2px; +} +.nav-pills > li.active > a, +.nav-pills > li.active > a:hover, +.nav-pills > li.active > a:focus { + color: #fff; + background-color: #428bca; +} +.nav-stacked > li { + float: none; +} +.nav-stacked > li + li { + margin-top: 2px; + margin-left: 0; +} +.nav-justified { + width: 100%; +} +.nav-justified > li { + float: none; +} +.nav-justified > li > a { + margin-bottom: 5px; + text-align: center; +} +.nav-justified > .dropdown .dropdown-menu { + top: auto; + left: auto; +} +@media (min-width: 768px) { + .nav-justified > li { + display: table-cell; + width: 1%; + } + .nav-justified > li > a { + margin-bottom: 0; + } +} +.nav-tabs-justified { + border-bottom: 0; +} +.nav-tabs-justified > li > a { + margin-right: 0; + border-radius: 4px; +} +.nav-tabs-justified > .active > a, +.nav-tabs-justified > .active > a:hover, +.nav-tabs-justified > .active > a:focus { + border: 1px solid #ddd; +} +@media (min-width: 768px) { + .nav-tabs-justified > li > a { + border-bottom: 1px solid #ddd; + border-radius: 4px 4px 0 0; + } + .nav-tabs-justified > .active > a, + .nav-tabs-justified > .active > a:hover, + .nav-tabs-justified > .active > a:focus { + border-bottom-color: #fff; + } +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar { + position: relative; + min-height: 50px; + margin-bottom: 20px; + border: 1px solid transparent; +} +@media (min-width: 768px) { + .navbar { + border-radius: 4px; + } +} +@media (min-width: 768px) { + .navbar-header { + float: left; + } +} +.navbar-collapse { + padding-right: 15px; + padding-left: 15px; + overflow-x: visible; + -webkit-overflow-scrolling: touch; + border-top: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1); +} +.navbar-collapse.in { + overflow-y: auto; +} +@media (min-width: 768px) { + .navbar-collapse { + width: auto; + border-top: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-collapse.collapse { + display: block !important; + height: auto !important; + padding-bottom: 0; + overflow: visible !important; + } + .navbar-collapse.in { + overflow-y: visible; + } + .navbar-fixed-top .navbar-collapse, + .navbar-static-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + padding-right: 0; + padding-left: 0; + } +} +.navbar-fixed-top .navbar-collapse, +.navbar-fixed-bottom .navbar-collapse { + max-height: 340px; +} +@media (max-width: 480px) and (orientation: landscape) { + .navbar-fixed-top .navbar-collapse, + .navbar-fixed-bottom .navbar-collapse { + max-height: 200px; + } +} +.container > .navbar-header, +.container-fluid > .navbar-header, +.container > .navbar-collapse, +.container-fluid > .navbar-collapse { + margin-right: -15px; + margin-left: -15px; +} +@media (min-width: 768px) { + .container > .navbar-header, + .container-fluid > .navbar-header, + .container > .navbar-collapse, + .container-fluid > .navbar-collapse { + margin-right: 0; + margin-left: 0; + } +} +.navbar-static-top { + z-index: 1000; + border-width: 0 0 1px; +} +@media (min-width: 768px) { + .navbar-static-top { + border-radius: 0; + } +} +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + -webkit-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +@media (min-width: 768px) { + .navbar-fixed-top, + .navbar-fixed-bottom { + border-radius: 0; + } +} +.navbar-fixed-top { + top: 0; + border-width: 0 0 1px; +} +.navbar-fixed-bottom { + bottom: 0; + margin-bottom: 0; + border-width: 1px 0 0; +} +.navbar-brand { + float: left; + height: 50px; + padding: 15px 15px; + font-size: 18px; + line-height: 20px; +} +.navbar-brand:hover, +.navbar-brand:focus { + text-decoration: none; +} +@media (min-width: 768px) { + .navbar > .container .navbar-brand, + .navbar > .container-fluid .navbar-brand { + margin-left: -15px; + } +} +.navbar-toggle { + position: relative; + float: right; + padding: 9px 10px; + margin-top: 8px; + margin-right: 15px; + margin-bottom: 8px; + background-color: transparent; + background-image: none; + border: 1px solid transparent; + border-radius: 4px; +} +.navbar-toggle:focus { + outline: 0; +} +.navbar-toggle .icon-bar { + display: block; + width: 22px; + height: 2px; + border-radius: 1px; +} +.navbar-toggle .icon-bar + .icon-bar { + margin-top: 4px; +} +@media (min-width: 768px) { + .navbar-toggle { + display: none; + } +} +.navbar-nav { + margin: 7.5px -15px; +} +.navbar-nav > li > a { + padding-top: 10px; + padding-bottom: 10px; + line-height: 20px; +} +@media (max-width: 767px) { + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-nav .open .dropdown-menu > li > a, + .navbar-nav .open .dropdown-menu .dropdown-header { + padding: 5px 15px 5px 25px; + } + .navbar-nav .open .dropdown-menu > li > a { + line-height: 20px; + } + .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-nav .open .dropdown-menu > li > a:focus { + background-image: none; + } +} +@media (min-width: 768px) { + .navbar-nav { + float: left; + margin: 0; + } + .navbar-nav > li { + float: left; + } + .navbar-nav > li > a { + padding-top: 15px; + padding-bottom: 15px; + } + .navbar-nav.navbar-right:last-child { + margin-right: -15px; + } +} +@media (min-width: 768px) { + .navbar-left { + float: left !important; + } + .navbar-right { + float: right !important; + } +} +.navbar-form { + padding: 10px 15px; + margin-top: 8px; + margin-right: -15px; + margin-bottom: 8px; + margin-left: -15px; + border-top: 1px solid transparent; + border-bottom: 1px solid transparent; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1); +} +@media (min-width: 768px) { + .navbar-form .form-group { + display: inline-block; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .navbar-form .input-group { + display: inline-table; + vertical-align: middle; + } + .navbar-form .input-group .input-group-addon, + .navbar-form .input-group .input-group-btn, + .navbar-form .input-group .form-control { + width: auto; + } + .navbar-form .input-group > .form-control { + width: 100%; + } + .navbar-form .control-label { + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio, + .navbar-form .checkbox { + display: inline-block; + margin-top: 0; + margin-bottom: 0; + vertical-align: middle; + } + .navbar-form .radio label, + .navbar-form .checkbox label { + padding-left: 0; + } + .navbar-form .radio input[type="radio"], + .navbar-form .checkbox input[type="checkbox"] { + position: relative; + margin-left: 0; + } + .navbar-form .has-feedback .form-control-feedback { + top: 0; + } +} +@media (max-width: 767px) { + .navbar-form .form-group { + margin-bottom: 5px; + } +} +@media (min-width: 768px) { + .navbar-form { + width: auto; + padding-top: 0; + padding-bottom: 0; + margin-right: 0; + margin-left: 0; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + .navbar-form.navbar-right:last-child { + margin-right: -15px; + } +} +.navbar-nav > li > .dropdown-menu { + margin-top: 0; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.navbar-btn { + margin-top: 8px; + margin-bottom: 8px; +} +.navbar-btn.btn-sm { + margin-top: 10px; + margin-bottom: 10px; +} +.navbar-btn.btn-xs { + margin-top: 14px; + margin-bottom: 14px; +} +.navbar-text { + margin-top: 15px; + margin-bottom: 15px; +} +@media (min-width: 768px) { + .navbar-text { + float: left; + margin-right: 15px; + margin-left: 15px; + } + .navbar-text.navbar-right:last-child { + margin-right: 0; + } +} +.navbar-default { + background-color: #f8f8f8; + border-color: #e7e7e7; +} +.navbar-default .navbar-brand { + color: #777; +} +.navbar-default .navbar-brand:hover, +.navbar-default .navbar-brand:focus { + color: #5e5e5e; + background-color: transparent; +} +.navbar-default .navbar-text { + color: #777; +} +.navbar-default .navbar-nav > li > a { + color: #777; +} +.navbar-default .navbar-nav > li > a:hover, +.navbar-default .navbar-nav > li > a:focus { + color: #333; + background-color: transparent; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:hover, +.navbar-default .navbar-nav > .active > a:focus { + color: #555; + background-color: #e7e7e7; +} +.navbar-default .navbar-nav > .disabled > a, +.navbar-default .navbar-nav > .disabled > a:hover, +.navbar-default .navbar-nav > .disabled > a:focus { + color: #ccc; + background-color: transparent; +} +.navbar-default .navbar-toggle { + border-color: #ddd; +} +.navbar-default .navbar-toggle:hover, +.navbar-default .navbar-toggle:focus { + background-color: #ddd; +} +.navbar-default .navbar-toggle .icon-bar { + background-color: #888; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #e7e7e7; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + color: #555; + background-color: #e7e7e7; +} +@media (max-width: 767px) { + .navbar-default .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { + color: #333; + background-color: transparent; + } + .navbar-default .navbar-nav .open .dropdown-menu > .active > a, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #555; + background-color: #e7e7e7; + } + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #ccc; + background-color: transparent; + } +} +.navbar-default .navbar-link { + color: #777; +} +.navbar-default .navbar-link:hover { + color: #333; +} +.navbar-default .btn-link { + color: #777; +} +.navbar-default .btn-link:hover, +.navbar-default .btn-link:focus { + color: #333; +} +.navbar-default .btn-link[disabled]:hover, +fieldset[disabled] .navbar-default .btn-link:hover, +.navbar-default .btn-link[disabled]:focus, +fieldset[disabled] .navbar-default .btn-link:focus { + color: #ccc; +} +.navbar-inverse { + background-color: #222; + border-color: #080808; +} +.navbar-inverse .navbar-brand { + color: #777; +} +.navbar-inverse .navbar-brand:hover, +.navbar-inverse .navbar-brand:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-text { + color: #777; +} +.navbar-inverse .navbar-nav > li > a { + color: #777; +} +.navbar-inverse .navbar-nav > li > a:hover, +.navbar-inverse .navbar-nav > li > a:focus { + color: #fff; + background-color: transparent; +} +.navbar-inverse .navbar-nav > .active > a, +.navbar-inverse .navbar-nav > .active > a:hover, +.navbar-inverse .navbar-nav > .active > a:focus { + color: #fff; + background-color: #080808; +} +.navbar-inverse .navbar-nav > .disabled > a, +.navbar-inverse .navbar-nav > .disabled > a:hover, +.navbar-inverse .navbar-nav > .disabled > a:focus { + color: #444; + background-color: transparent; +} +.navbar-inverse .navbar-toggle { + border-color: #333; +} +.navbar-inverse .navbar-toggle:hover, +.navbar-inverse .navbar-toggle:focus { + background-color: #333; +} +.navbar-inverse .navbar-toggle .icon-bar { + background-color: #fff; +} +.navbar-inverse .navbar-collapse, +.navbar-inverse .navbar-form { + border-color: #101010; +} +.navbar-inverse .navbar-nav > .open > a, +.navbar-inverse .navbar-nav > .open > a:hover, +.navbar-inverse .navbar-nav > .open > a:focus { + color: #fff; + background-color: #080808; +} +@media (max-width: 767px) { + .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { + border-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu .divider { + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { + color: #777; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { + color: #fff; + background-color: transparent; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { + color: #fff; + background-color: #080808; + } + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, + .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { + color: #444; + background-color: transparent; + } +} +.navbar-inverse .navbar-link { + color: #777; +} +.navbar-inverse .navbar-link:hover { + color: #fff; +} +.navbar-inverse .btn-link { + color: #777; +} +.navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link:focus { + color: #fff; +} +.navbar-inverse .btn-link[disabled]:hover, +fieldset[disabled] .navbar-inverse .btn-link:hover, +.navbar-inverse .btn-link[disabled]:focus, +fieldset[disabled] .navbar-inverse .btn-link:focus { + color: #444; +} +.breadcrumb { + padding: 8px 15px; + margin-bottom: 20px; + list-style: none; + background-color: #f5f5f5; + border-radius: 4px; +} +.breadcrumb > li { + display: inline-block; +} +.breadcrumb > li + li:before { + padding: 0 5px; + color: #ccc; + content: "/\00a0"; +} +.breadcrumb > .active { + color: #777; +} +.pagination { + display: inline-block; + padding-left: 0; + margin: 20px 0; + border-radius: 4px; +} +.pagination > li { + display: inline; +} +.pagination > li > a, +.pagination > li > span { + position: relative; + float: left; + padding: 6px 12px; + margin-left: -1px; + line-height: 1.42857143; + color: #428bca; + text-decoration: none; + background-color: #fff; + border: 1px solid #ddd; +} +.pagination > li:first-child > a, +.pagination > li:first-child > span { + margin-left: 0; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; +} +.pagination > li:last-child > a, +.pagination > li:last-child > span { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} +.pagination > li > a:hover, +.pagination > li > span:hover, +.pagination > li > a:focus, +.pagination > li > span:focus { + color: #2a6496; + background-color: #eee; + border-color: #ddd; +} +.pagination > .active > a, +.pagination > .active > span, +.pagination > .active > a:hover, +.pagination > .active > span:hover, +.pagination > .active > a:focus, +.pagination > .active > span:focus { + z-index: 2; + color: #fff; + cursor: default; + background-color: #428bca; + border-color: #428bca; +} +.pagination > .disabled > span, +.pagination > .disabled > span:hover, +.pagination > .disabled > span:focus, +.pagination > .disabled > a, +.pagination > .disabled > a:hover, +.pagination > .disabled > a:focus { + color: #777; + cursor: not-allowed; + background-color: #fff; + border-color: #ddd; +} +.pagination-lg > li > a, +.pagination-lg > li > span { + padding: 10px 16px; + font-size: 18px; +} +.pagination-lg > li:first-child > a, +.pagination-lg > li:first-child > span { + border-top-left-radius: 6px; + border-bottom-left-radius: 6px; +} +.pagination-lg > li:last-child > a, +.pagination-lg > li:last-child > span { + border-top-right-radius: 6px; + border-bottom-right-radius: 6px; +} +.pagination-sm > li > a, +.pagination-sm > li > span { + padding: 5px 10px; + font-size: 12px; +} +.pagination-sm > li:first-child > a, +.pagination-sm > li:first-child > span { + border-top-left-radius: 3px; + border-bottom-left-radius: 3px; +} +.pagination-sm > li:last-child > a, +.pagination-sm > li:last-child > span { + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; +} +.pager { + padding-left: 0; + margin: 20px 0; + text-align: center; + list-style: none; +} +.pager li { + display: inline; +} +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 15px; +} +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #eee; +} +.pager .next > a, +.pager .next > span { + float: right; +} +.pager .previous > a, +.pager .previous > span { + float: left; +} +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #777; + cursor: not-allowed; + background-color: #fff; +} +.label { + display: inline; + padding: .2em .6em .3em; + font-size: 75%; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: .25em; +} +a.label:hover, +a.label:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +.label:empty { + display: none; +} +.btn .label { + position: relative; + top: -1px; +} +.label-default { + background-color: #777; +} +.label-default[href]:hover, +.label-default[href]:focus { + background-color: #5e5e5e; +} +.label-primary { + background-color: #428bca; +} +.label-primary[href]:hover, +.label-primary[href]:focus { + background-color: #3071a9; +} +.label-success { + background-color: #5cb85c; +} +.label-success[href]:hover, +.label-success[href]:focus { + background-color: #449d44; +} +.label-info { + background-color: #5bc0de; +} +.label-info[href]:hover, +.label-info[href]:focus { + background-color: #31b0d5; +} +.label-warning { + background-color: #f0ad4e; +} +.label-warning[href]:hover, +.label-warning[href]:focus { + background-color: #ec971f; +} +.label-danger { + background-color: #d9534f; +} +.label-danger[href]:hover, +.label-danger[href]:focus { + background-color: #c9302c; +} +.badge { + display: inline-block; + min-width: 10px; + padding: 3px 7px; + font-size: 12px; + font-weight: bold; + line-height: 1; + color: #fff; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + background-color: #777; + border-radius: 10px; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.btn-xs .badge { + top: 0; + padding: 1px 5px; +} +a.badge:hover, +a.badge:focus { + color: #fff; + text-decoration: none; + cursor: pointer; +} +a.list-group-item.active > .badge, +.nav-pills > .active > a > .badge { + color: #428bca; + background-color: #fff; +} +.nav-pills > li > a > .badge { + margin-left: 3px; +} +.jumbotron { + padding: 30px; + margin-bottom: 30px; + color: inherit; + background-color: #eee; +} +.jumbotron h1, +.jumbotron .h1 { + color: inherit; +} +.jumbotron p { + margin-bottom: 15px; + font-size: 21px; + font-weight: 200; +} +.jumbotron > hr { + border-top-color: #d5d5d5; +} +.container .jumbotron { + border-radius: 6px; +} +.jumbotron .container { + max-width: 100%; +} +@media screen and (min-width: 768px) { + .jumbotron { + padding-top: 48px; + padding-bottom: 48px; + } + .container .jumbotron { + padding-right: 60px; + padding-left: 60px; + } + .jumbotron h1, + .jumbotron .h1 { + font-size: 63px; + } +} +.thumbnail { + display: block; + padding: 4px; + margin-bottom: 20px; + line-height: 1.42857143; + background-color: #fff; + border: 1px solid #ddd; + border-radius: 4px; + -webkit-transition: all .2s ease-in-out; + -o-transition: all .2s ease-in-out; + transition: all .2s ease-in-out; +} +.thumbnail > img, +.thumbnail a > img { + margin-right: auto; + margin-left: auto; +} +a.thumbnail:hover, +a.thumbnail:focus, +a.thumbnail.active { + border-color: #428bca; +} +.thumbnail .caption { + padding: 9px; + color: #333; +} +.alert { + padding: 15px; + margin-bottom: 20px; + border: 1px solid transparent; + border-radius: 4px; +} +.alert h4 { + margin-top: 0; + color: inherit; +} +.alert .alert-link { + font-weight: bold; +} +.alert > p, +.alert > ul { + margin-bottom: 0; +} +.alert > p + p { + margin-top: 5px; +} +.alert-dismissable, +.alert-dismissible { + padding-right: 35px; +} +.alert-dismissable .close, +.alert-dismissible .close { + position: relative; + top: -2px; + right: -21px; + color: inherit; +} +.alert-success { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.alert-success hr { + border-top-color: #c9e2b3; +} +.alert-success .alert-link { + color: #2b542c; +} +.alert-info { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.alert-info hr { + border-top-color: #a6e1ec; +} +.alert-info .alert-link { + color: #245269; +} +.alert-warning { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.alert-warning hr { + border-top-color: #f7e1b5; +} +.alert-warning .alert-link { + color: #66512c; +} +.alert-danger { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.alert-danger hr { + border-top-color: #e4b9c0; +} +.alert-danger .alert-link { + color: #843534; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@-o-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f5f5f5; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); +} +.progress-bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + line-height: 20px; + color: #fff; + text-align: center; + background-color: #428bca; + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); + -webkit-transition: width .6s ease; + -o-transition: width .6s ease; + transition: width .6s ease; +} +.progress-striped .progress-bar, +.progress-bar-striped { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + background-size: 40px 40px; +} +.progress.active .progress-bar, +.progress-bar.active { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} +.progress-bar[aria-valuenow="1"], +.progress-bar[aria-valuenow="2"] { + min-width: 30px; +} +.progress-bar[aria-valuenow="0"] { + min-width: 30px; + color: #777; + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + box-shadow: none; +} +.progress-bar-success { + background-color: #5cb85c; +} +.progress-striped .progress-bar-success { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-info { + background-color: #5bc0de; +} +.progress-striped .progress-bar-info { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-warning { + background-color: #f0ad4e; +} +.progress-striped .progress-bar-warning { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.progress-bar-danger { + background-color: #d9534f; +} +.progress-striped .progress-bar-danger { + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent); +} +.media, +.media-body { + overflow: hidden; + zoom: 1; +} +.media, +.media .media { + margin-top: 15px; +} +.media:first-child { + margin-top: 0; +} +.media-object { + display: block; +} +.media-heading { + margin: 0 0 5px; +} +.media > .pull-left { + margin-right: 10px; +} +.media > .pull-right { + margin-left: 10px; +} +.media-list { + padding-left: 0; + list-style: none; +} +.list-group { + padding-left: 0; + margin-bottom: 20px; +} +.list-group-item { + position: relative; + display: block; + padding: 10px 15px; + margin-bottom: -1px; + background-color: #fff; + border: 1px solid #ddd; +} +.list-group-item:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; +} +.list-group-item:last-child { + margin-bottom: 0; + border-bottom-right-radius: 4px; + border-bottom-left-radius: 4px; +} +.list-group-item > .badge { + float: right; +} +.list-group-item > .badge + .badge { + margin-right: 5px; +} +a.list-group-item { + color: #555; +} +a.list-group-item .list-group-item-heading { + color: #333; +} +a.list-group-item:hover, +a.list-group-item:focus { + color: #555; + text-decoration: none; + background-color: #f5f5f5; +} +.list-group-item.disabled, +.list-group-item.disabled:hover, +.list-group-item.disabled:focus { + color: #777; + background-color: #eee; +} +.list-group-item.disabled .list-group-item-heading, +.list-group-item.disabled:hover .list-group-item-heading, +.list-group-item.disabled:focus .list-group-item-heading { + color: inherit; +} +.list-group-item.disabled .list-group-item-text, +.list-group-item.disabled:hover .list-group-item-text, +.list-group-item.disabled:focus .list-group-item-text { + color: #777; +} +.list-group-item.active, +.list-group-item.active:hover, +.list-group-item.active:focus { + z-index: 2; + color: #fff; + background-color: #428bca; + border-color: #428bca; +} +.list-group-item.active .list-group-item-heading, +.list-group-item.active:hover .list-group-item-heading, +.list-group-item.active:focus .list-group-item-heading, +.list-group-item.active .list-group-item-heading > small, +.list-group-item.active:hover .list-group-item-heading > small, +.list-group-item.active:focus .list-group-item-heading > small, +.list-group-item.active .list-group-item-heading > .small, +.list-group-item.active:hover .list-group-item-heading > .small, +.list-group-item.active:focus .list-group-item-heading > .small { + color: inherit; +} +.list-group-item.active .list-group-item-text, +.list-group-item.active:hover .list-group-item-text, +.list-group-item.active:focus .list-group-item-text { + color: #e1edf7; +} +.list-group-item-success { + color: #3c763d; + background-color: #dff0d8; +} +a.list-group-item-success { + color: #3c763d; +} +a.list-group-item-success .list-group-item-heading { + color: inherit; +} +a.list-group-item-success:hover, +a.list-group-item-success:focus { + color: #3c763d; + background-color: #d0e9c6; +} +a.list-group-item-success.active, +a.list-group-item-success.active:hover, +a.list-group-item-success.active:focus { + color: #fff; + background-color: #3c763d; + border-color: #3c763d; +} +.list-group-item-info { + color: #31708f; + background-color: #d9edf7; +} +a.list-group-item-info { + color: #31708f; +} +a.list-group-item-info .list-group-item-heading { + color: inherit; +} +a.list-group-item-info:hover, +a.list-group-item-info:focus { + color: #31708f; + background-color: #c4e3f3; +} +a.list-group-item-info.active, +a.list-group-item-info.active:hover, +a.list-group-item-info.active:focus { + color: #fff; + background-color: #31708f; + border-color: #31708f; +} +.list-group-item-warning { + color: #8a6d3b; + background-color: #fcf8e3; +} +a.list-group-item-warning { + color: #8a6d3b; +} +a.list-group-item-warning .list-group-item-heading { + color: inherit; +} +a.list-group-item-warning:hover, +a.list-group-item-warning:focus { + color: #8a6d3b; + background-color: #faf2cc; +} +a.list-group-item-warning.active, +a.list-group-item-warning.active:hover, +a.list-group-item-warning.active:focus { + color: #fff; + background-color: #8a6d3b; + border-color: #8a6d3b; +} +.list-group-item-danger { + color: #a94442; + background-color: #f2dede; +} +a.list-group-item-danger { + color: #a94442; +} +a.list-group-item-danger .list-group-item-heading { + color: inherit; +} +a.list-group-item-danger:hover, +a.list-group-item-danger:focus { + color: #a94442; + background-color: #ebcccc; +} +a.list-group-item-danger.active, +a.list-group-item-danger.active:hover, +a.list-group-item-danger.active:focus { + color: #fff; + background-color: #a94442; + border-color: #a94442; +} +.list-group-item-heading { + margin-top: 0; + margin-bottom: 5px; +} +.list-group-item-text { + margin-bottom: 0; + line-height: 1.3; +} +.panel { + margin-bottom: 20px; + background-color: #fff; + border: 1px solid transparent; + border-radius: 4px; + -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: 0 1px 1px rgba(0, 0, 0, .05); +} +.panel-body { + padding: 15px; +} +.panel-heading { + padding: 10px 15px; + border-bottom: 1px solid transparent; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel-heading > .dropdown .dropdown-toggle { + color: inherit; +} +.panel-title { + margin-top: 0; + margin-bottom: 0; + font-size: 16px; + color: inherit; +} +.panel-title > a { + color: inherit; +} +.panel-footer { + padding: 10px 15px; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .list-group { + margin-bottom: 0; +} +.panel > .list-group .list-group-item { + border-width: 1px 0; + border-radius: 0; +} +.panel > .list-group:first-child .list-group-item:first-child { + border-top: 0; + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .list-group:last-child .list-group-item:last-child { + border-bottom: 0; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel-heading + .list-group .list-group-item:first-child { + border-top-width: 0; +} +.list-group + .panel-footer { + border-top-width: 0; +} +.panel > .table, +.panel > .table-responsive > .table, +.panel > .panel-collapse > .table { + margin-bottom: 0; +} +.panel > .table:first-child, +.panel > .table-responsive:first-child > .table:first-child { + border-top-left-radius: 3px; + border-top-right-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { + border-top-left-radius: 3px; +} +.panel > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, +.panel > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, +.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, +.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { + border-top-right-radius: 3px; +} +.panel > .table:last-child, +.panel > .table-responsive:last-child > .table:last-child { + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { + border-bottom-left-radius: 3px; +} +.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, +.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, +.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, +.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { + border-bottom-right-radius: 3px; +} +.panel > .panel-body + .table, +.panel > .panel-body + .table-responsive { + border-top: 1px solid #ddd; +} +.panel > .table > tbody:first-child > tr:first-child th, +.panel > .table > tbody:first-child > tr:first-child td { + border-top: 0; +} +.panel > .table-bordered, +.panel > .table-responsive > .table-bordered { + border: 0; +} +.panel > .table-bordered > thead > tr > th:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:first-child, +.panel > .table-bordered > tbody > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, +.panel > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, +.panel > .table-bordered > thead > tr > td:first-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:first-child, +.panel > .table-bordered > tbody > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, +.panel > .table-bordered > tfoot > tr > td:first-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { + border-left: 0; +} +.panel > .table-bordered > thead > tr > th:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > th:last-child, +.panel > .table-bordered > tbody > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, +.panel > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, +.panel > .table-bordered > thead > tr > td:last-child, +.panel > .table-responsive > .table-bordered > thead > tr > td:last-child, +.panel > .table-bordered > tbody > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, +.panel > .table-bordered > tfoot > tr > td:last-child, +.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { + border-right: 0; +} +.panel > .table-bordered > thead > tr:first-child > td, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > td, +.panel > .table-bordered > tbody > tr:first-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, +.panel > .table-bordered > thead > tr:first-child > th, +.panel > .table-responsive > .table-bordered > thead > tr:first-child > th, +.panel > .table-bordered > tbody > tr:first-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { + border-bottom: 0; +} +.panel > .table-bordered > tbody > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, +.panel > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, +.panel > .table-bordered > tbody > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, +.panel > .table-bordered > tfoot > tr:last-child > th, +.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { + border-bottom: 0; +} +.panel > .table-responsive { + margin-bottom: 0; + border: 0; +} +.panel-group { + margin-bottom: 20px; +} +.panel-group .panel { + margin-bottom: 0; + border-radius: 4px; +} +.panel-group .panel + .panel { + margin-top: 5px; +} +.panel-group .panel-heading { + border-bottom: 0; +} +.panel-group .panel-heading + .panel-collapse > .panel-body { + border-top: 1px solid #ddd; +} +.panel-group .panel-footer { + border-top: 0; +} +.panel-group .panel-footer + .panel-collapse .panel-body { + border-bottom: 1px solid #ddd; +} +.panel-default { + border-color: #ddd; +} +.panel-default > .panel-heading { + color: #333; + background-color: #f5f5f5; + border-color: #ddd; +} +.panel-default > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ddd; +} +.panel-default > .panel-heading .badge { + color: #f5f5f5; + background-color: #333; +} +.panel-default > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ddd; +} +.panel-primary { + border-color: #428bca; +} +.panel-primary > .panel-heading { + color: #fff; + background-color: #428bca; + border-color: #428bca; +} +.panel-primary > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #428bca; +} +.panel-primary > .panel-heading .badge { + color: #428bca; + background-color: #fff; +} +.panel-primary > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #428bca; +} +.panel-success { + border-color: #d6e9c6; +} +.panel-success > .panel-heading { + color: #3c763d; + background-color: #dff0d8; + border-color: #d6e9c6; +} +.panel-success > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #d6e9c6; +} +.panel-success > .panel-heading .badge { + color: #dff0d8; + background-color: #3c763d; +} +.panel-success > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #d6e9c6; +} +.panel-info { + border-color: #bce8f1; +} +.panel-info > .panel-heading { + color: #31708f; + background-color: #d9edf7; + border-color: #bce8f1; +} +.panel-info > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #bce8f1; +} +.panel-info > .panel-heading .badge { + color: #d9edf7; + background-color: #31708f; +} +.panel-info > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #bce8f1; +} +.panel-warning { + border-color: #faebcc; +} +.panel-warning > .panel-heading { + color: #8a6d3b; + background-color: #fcf8e3; + border-color: #faebcc; +} +.panel-warning > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #faebcc; +} +.panel-warning > .panel-heading .badge { + color: #fcf8e3; + background-color: #8a6d3b; +} +.panel-warning > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #faebcc; +} +.panel-danger { + border-color: #ebccd1; +} +.panel-danger > .panel-heading { + color: #a94442; + background-color: #f2dede; + border-color: #ebccd1; +} +.panel-danger > .panel-heading + .panel-collapse > .panel-body { + border-top-color: #ebccd1; +} +.panel-danger > .panel-heading .badge { + color: #f2dede; + background-color: #a94442; +} +.panel-danger > .panel-footer + .panel-collapse > .panel-body { + border-bottom-color: #ebccd1; +} +.embed-responsive { + position: relative; + display: block; + height: 0; + padding: 0; + overflow: hidden; +} +.embed-responsive .embed-responsive-item, +.embed-responsive iframe, +.embed-responsive embed, +.embed-responsive object { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} +.embed-responsive.embed-responsive-16by9 { + padding-bottom: 56.25%; +} +.embed-responsive.embed-responsive-4by3 { + padding-bottom: 75%; +} +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05); +} +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, .15); +} +.well-lg { + padding: 24px; + border-radius: 6px; +} +.well-sm { + padding: 9px; + border-radius: 3px; +} +.close { + float: right; + font-size: 21px; + font-weight: bold; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + filter: alpha(opacity=20); + opacity: .2; +} +.close:hover, +.close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + filter: alpha(opacity=50); + opacity: .5; +} +button.close { + -webkit-appearance: none; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; +} +.modal-open { + overflow: hidden; +} +.modal { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1050; + display: none; + overflow: hidden; + -webkit-overflow-scrolling: touch; + outline: 0; +} +.modal.fade .modal-dialog { + -webkit-transition: -webkit-transform .3s ease-out; + -o-transition: -o-transform .3s ease-out; + transition: transform .3s ease-out; + -webkit-transform: translate3d(0, -25%, 0); + -o-transform: translate3d(0, -25%, 0); + transform: translate3d(0, -25%, 0); +} +.modal.in .modal-dialog { + -webkit-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal-dialog { + position: relative; + width: auto; + margin: 10px; +} +.modal-content { + position: relative; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + outline: 0; + -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); + box-shadow: 0 3px 9px rgba(0, 0, 0, .5); +} +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000; +} +.modal-backdrop.fade { + filter: alpha(opacity=0); + opacity: 0; +} +.modal-backdrop.in { + filter: alpha(opacity=50); + opacity: .5; +} +.modal-header { + min-height: 16.42857143px; + padding: 15px; + border-bottom: 1px solid #e5e5e5; +} +.modal-header .close { + margin-top: -2px; +} +.modal-title { + margin: 0; + line-height: 1.42857143; +} +.modal-body { + position: relative; + padding: 15px; +} +.modal-footer { + padding: 15px; + text-align: right; + border-top: 1px solid #e5e5e5; +} +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 768px) { + .modal-dialog { + width: 600px; + margin: 30px auto; + } + .modal-content { + -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + box-shadow: 0 5px 15px rgba(0, 0, 0, .5); + } + .modal-sm { + width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg { + width: 900px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + font-size: 12px; + line-height: 1.4; + visibility: visible; + filter: alpha(opacity=0); + opacity: 0; +} +.tooltip.in { + filter: alpha(opacity=90); + opacity: .9; +} +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} +.tooltip-inner { + max-width: 200px; + padding: 3px 8px; + color: #fff; + text-align: center; + text-decoration: none; + background-color: #000; + border-radius: 4px; +} +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-left .tooltip-arrow { + bottom: 0; + left: 5px; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.top-right .tooltip-arrow { + right: 5px; + bottom: 0; + border-width: 5px 5px 0; + border-top-color: #000; +} +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-width: 5px 5px 5px 0; + border-right-color: #000; +} +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-width: 5px 0 5px 5px; + border-left-color: #000; +} +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-left .tooltip-arrow { + top: 0; + left: 5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.tooltip.bottom-right .tooltip-arrow { + top: 0; + right: 5px; + border-width: 0 5px 5px; + border-bottom-color: #000; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #fff; + -webkit-background-clip: padding-box; + background-clip: padding-box; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, .2); + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2); + box-shadow: 0 5px 10px rgba(0, 0, 0, .2); +} +.popover.top { + margin-top: -10px; +} +.popover.right { + margin-left: 10px; +} +.popover.bottom { + margin-top: 10px; +} +.popover.left { + margin-left: -10px; +} +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-radius: 5px 5px 0 0; +} +.popover-content { + padding: 9px 14px; +} +.popover > .arrow, +.popover > .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} +.popover > .arrow { + border-width: 11px; +} +.popover > .arrow:after { + content: ""; + border-width: 10px; +} +.popover.top > .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, .25); + border-bottom-width: 0; +} +.popover.top > .arrow:after { + bottom: 1px; + margin-left: -10px; + content: " "; + border-top-color: #fff; + border-bottom-width: 0; +} +.popover.right > .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, .25); + border-left-width: 0; +} +.popover.right > .arrow:after { + bottom: -10px; + left: 1px; + content: " "; + border-right-color: #fff; + border-left-width: 0; +} +.popover.bottom > .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-top-width: 0; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, .25); +} +.popover.bottom > .arrow:after { + top: 1px; + margin-left: -10px; + content: " "; + border-top-width: 0; + border-bottom-color: #fff; +} +.popover.left > .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-right-width: 0; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, .25); +} +.popover.left > .arrow:after { + right: 1px; + bottom: -10px; + content: " "; + border-right-width: 0; + border-left-color: #fff; +} +.carousel { + position: relative; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: .6s ease-in-out left; + -o-transition: .6s ease-in-out left; + transition: .6s ease-in-out left; +} +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + line-height: 1; +} +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} +.carousel-inner > .active { + left: 0; +} +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} +.carousel-inner > .next { + left: 100%; +} +.carousel-inner > .prev { + left: -100%; +} +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} +.carousel-inner > .active.left { + left: -100%; +} +.carousel-inner > .active.right { + left: 100%; +} +.carousel-control { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 15%; + font-size: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); + filter: alpha(opacity=50); + opacity: .5; +} +.carousel-control.left { + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control.right { + right: 0; + left: auto; + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5))); + background-image: linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); + background-repeat: repeat-x; +} +.carousel-control:hover, +.carousel-control:focus { + color: #fff; + text-decoration: none; + filter: alpha(opacity=90); + outline: 0; + opacity: .9; +} +.carousel-control .icon-prev, +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-left, +.carousel-control .glyphicon-chevron-right { + position: absolute; + top: 50%; + z-index: 5; + display: inline-block; +} +.carousel-control .icon-prev, +.carousel-control .glyphicon-chevron-left { + left: 50%; + margin-left: -10px; +} +.carousel-control .icon-next, +.carousel-control .glyphicon-chevron-right { + right: 50%; + margin-right: -10px; +} +.carousel-control .icon-prev, +.carousel-control .icon-next { + width: 20px; + height: 20px; + margin-top: -10px; + font-family: serif; +} +.carousel-control .icon-prev:before { + content: '\2039'; +} +.carousel-control .icon-next:before { + content: '\203a'; +} +.carousel-indicators { + position: absolute; + bottom: 10px; + left: 50%; + z-index: 15; + width: 60%; + padding-left: 0; + margin-left: -30%; + text-align: center; + list-style: none; +} +.carousel-indicators li { + display: inline-block; + width: 10px; + height: 10px; + margin: 1px; + text-indent: -999px; + cursor: pointer; + background-color: #000 \9; + background-color: rgba(0, 0, 0, 0); + border: 1px solid #fff; + border-radius: 10px; +} +.carousel-indicators .active { + width: 12px; + height: 12px; + margin: 0; + background-color: #fff; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; + text-shadow: 0 1px 2px rgba(0, 0, 0, .6); +} +.carousel-caption .btn { + text-shadow: none; +} +@media screen and (min-width: 768px) { + .carousel-control .glyphicon-chevron-left, + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-prev, + .carousel-control .icon-next { + width: 30px; + height: 30px; + margin-top: -15px; + font-size: 30px; + } + .carousel-control .glyphicon-chevron-left, + .carousel-control .icon-prev { + margin-left: -15px; + } + .carousel-control .glyphicon-chevron-right, + .carousel-control .icon-next { + margin-right: -15px; + } + .carousel-caption { + right: 20%; + left: 20%; + padding-bottom: 30px; + } + .carousel-indicators { + bottom: 20px; + } +} +.clearfix:before, +.clearfix:after, +.dl-horizontal dd:before, +.dl-horizontal dd:after, +.container:before, +.container:after, +.container-fluid:before, +.container-fluid:after, +.row:before, +.row:after, +.form-horizontal .form-group:before, +.form-horizontal .form-group:after, +.btn-toolbar:before, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:before, +.btn-group-vertical > .btn-group:after, +.nav:before, +.nav:after, +.navbar:before, +.navbar:after, +.navbar-header:before, +.navbar-header:after, +.navbar-collapse:before, +.navbar-collapse:after, +.pager:before, +.pager:after, +.panel-body:before, +.panel-body:after, +.modal-footer:before, +.modal-footer:after { + display: table; + content: " "; +} +.clearfix:after, +.dl-horizontal dd:after, +.container:after, +.container-fluid:after, +.row:after, +.form-horizontal .form-group:after, +.btn-toolbar:after, +.btn-group-vertical > .btn-group:after, +.nav:after, +.navbar:after, +.navbar-header:after, +.navbar-collapse:after, +.pager:after, +.panel-body:after, +.modal-footer:after { + clear: both; +} +.center-block { + display: block; + margin-right: auto; + margin-left: auto; +} +.pull-right { + float: right !important; +} +.pull-left { + float: left !important; +} +.hide { + display: none !important; +} +.show { + display: block !important; +} +.invisible { + visibility: hidden; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.hidden { + display: none !important; + visibility: hidden !important; +} +.affix { + position: fixed; + -webkit-transform: translate3d(0, 0, 0); + -o-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +@-ms-viewport { + width: device-width; +} +.visible-xs, +.visible-sm, +.visible-md, +.visible-lg { + display: none !important; +} +.visible-xs-block, +.visible-xs-inline, +.visible-xs-inline-block, +.visible-sm-block, +.visible-sm-inline, +.visible-sm-inline-block, +.visible-md-block, +.visible-md-inline, +.visible-md-inline-block, +.visible-lg-block, +.visible-lg-inline, +.visible-lg-inline-block { + display: none !important; +} +@media (max-width: 767px) { + .visible-xs { + display: block !important; + } + table.visible-xs { + display: table; + } + tr.visible-xs { + display: table-row !important; + } + th.visible-xs, + td.visible-xs { + display: table-cell !important; + } +} +@media (max-width: 767px) { + .visible-xs-block { + display: block !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline { + display: inline !important; + } +} +@media (max-width: 767px) { + .visible-xs-inline-block { + display: inline-block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm { + display: block !important; + } + table.visible-sm { + display: table; + } + tr.visible-sm { + display: table-row !important; + } + th.visible-sm, + td.visible-sm { + display: table-cell !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-block { + display: block !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline { + display: inline !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .visible-sm-inline-block { + display: inline-block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md { + display: block !important; + } + table.visible-md { + display: table; + } + tr.visible-md { + display: table-row !important; + } + th.visible-md, + td.visible-md { + display: table-cell !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-block { + display: block !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline { + display: inline !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .visible-md-inline-block { + display: inline-block !important; + } +} +@media (min-width: 1200px) { + .visible-lg { + display: block !important; + } + table.visible-lg { + display: table; + } + tr.visible-lg { + display: table-row !important; + } + th.visible-lg, + td.visible-lg { + display: table-cell !important; + } +} +@media (min-width: 1200px) { + .visible-lg-block { + display: block !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline { + display: inline !important; + } +} +@media (min-width: 1200px) { + .visible-lg-inline-block { + display: inline-block !important; + } +} +@media (max-width: 767px) { + .hidden-xs { + display: none !important; + } +} +@media (min-width: 768px) and (max-width: 991px) { + .hidden-sm { + display: none !important; + } +} +@media (min-width: 992px) and (max-width: 1199px) { + .hidden-md { + display: none !important; + } +} +@media (min-width: 1200px) { + .hidden-lg { + display: none !important; + } +} +.visible-print { + display: none !important; +} +@media print { + .visible-print { + display: block !important; + } + table.visible-print { + display: table; + } + tr.visible-print { + display: table-row !important; + } + th.visible-print, + td.visible-print { + display: table-cell !important; + } +} +.visible-print-block { + display: none !important; +} +@media print { + .visible-print-block { + display: block !important; + } +} +.visible-print-inline { + display: none !important; +} +@media print { + .visible-print-inline { + display: inline !important; + } +} +.visible-print-inline-block { + display: none !important; +} +@media print { + .visible-print-inline-block { + display: inline-block !important; + } +} +@media print { + .hidden-print { + display: none !important; + } +} +/*# sourceMappingURL=bootstrap.css.map */ diff --git a/roles/httpd/files/html/css/bootstrap.css.map b/roles/httpd/files/html/css/bootstrap.css.map new file mode 100755 index 000000000..bfb561689 --- /dev/null +++ b/roles/httpd/files/html/css/bootstrap.css.map @@ -0,0 +1 @@ +{"version":3,"file":"bootstrap.css","sources":["bootstrap.css","less/normalize.less","less/print.less","less/glyphicons.less","less/scaffolding.less","less/mixins/vendor-prefixes.less","less/mixins/tab-focus.less","less/mixins/image.less","less/type.less","less/mixins/text-emphasis.less","less/mixins/background-variant.less","less/mixins/text-overflow.less","less/code.less","less/grid.less","less/mixins/grid.less","less/mixins/grid-framework.less","less/tables.less","less/mixins/table-row.less","less/forms.less","less/mixins/forms.less","less/buttons.less","less/mixins/buttons.less","less/mixins/opacity.less","less/component-animations.less","less/dropdowns.less","less/mixins/nav-divider.less","less/mixins/reset-filter.less","less/button-groups.less","less/mixins/border-radius.less","less/input-groups.less","less/navs.less","less/navbar.less","less/mixins/nav-vertical-align.less","less/utilities.less","less/breadcrumbs.less","less/pagination.less","less/mixins/pagination.less","less/pager.less","less/labels.less","less/mixins/labels.less","less/badges.less","less/jumbotron.less","less/thumbnails.less","less/alerts.less","less/mixins/alerts.less","less/progress-bars.less","less/mixins/gradients.less","less/mixins/progress-bar.less","less/media.less","less/list-group.less","less/mixins/list-group.less","less/panels.less","less/mixins/panels.less","less/responsive-embed.less","less/wells.less","less/close.less","less/modals.less","less/tooltip.less","less/popovers.less","less/carousel.less","less/mixins/clearfix.less","less/mixins/center-block.less","less/mixins/hide-text.less","less/responsive-utilities.less","less/mixins/responsive-visibility.less"],"names":[],"mappings":"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;EAAW,kBAAA;EHoR9C;AGnRmC;EAAW,kBAAA;EHsR9C;AGrRmC;EAAW,kBAAA;EHwR9C;AGvRmC;EAAW,kBAAA;EH0R9C;AGzRmC;EAAW,kBAAA;EH4R9C;AG3RmC;EAAW,kBAAA;EH8R9C;AG7RmC;EAAW,kBAAA;EHgS9C;AG/RmC;EAAW,kBAAA;EHkS9C;AGjSmC;EAAW,kBAAA;EHoS9C;AGnSmC;EAAW,kBAAA;EHsS9C;AGrSmC;EAAW,kBAAA;EHwS9C;AGvSmC;EAAW,kBAAA;EH0S9C;AGzSmC;EAAW,kBAAA;EH4S9C;AG3SmC;EAAW,kBAAA;EH8S9C;AG7SmC;EAAW,kBAAA;EHgT9C;AG/SmC;EAAW,kBAAA;EHkT9C;AGjTmC;EAAW,kBAAA;EHoT9C;AGnTmC;EAAW,kBAAA;EHsT9C;AGrTmC;EAAW,kBAAA;EHwT9C;AGvTmC;EAAW,kBAAA;EH0T9C;AGzTmC;EAAW,kBAAA;EH4T9C;AG3TmC;EAAW,kBAAA;EH8T9C;AG7TmC;EAAW,kBAAA;EHgU9C;AG/TmC;EAAW,kBAAA;EHkU9C;AGjUmC;EAAW,kBAAA;EHoU9C;AGnUmC;EAAW,kBAAA;EHsU9C;AGrUmC;EAAW,kBAAA;EHwU9C;AGvUmC;EAAW,kBAAA;EH0U9C;AGzUmC;EAAW,kBAAA;EH4U9C;AG3UmC;EAAW,kBAAA;EH8U9C;AG7UmC;EAAW,kBAAA;EHgV9C;AG/UmC;EAAW,kBAAA;EHkV9C;AGjVmC;EAAW,kBAAA;EHoV9C;AGnVmC;EAAW,kBAAA;EHsV9C;AGrVmC;EAAW,kBAAA;EHwV9C;AGvVmC;EAAW,kBAAA;EH0V9C;AGzVmC;EAAW,kBAAA;EH4V9C;AG3VmC;EAAW,kBAAA;EH8V9C;AG7VmC;EAAW,kBAAA;EHgW9C;AG/VmC;EAAW,kBAAA;EHkW9C;AGjWmC;EAAW,kBAAA;EHoW9C;AGnWmC;EAAW,kBAAA;EHsW9C;AGrWmC;EAAW,kBAAA;EHwW9C;AGvWmC;EAAW,kBAAA;EH0W9C;AGzWmC;EAAW,kBAAA;EH4W9C;AG3WmC;EAAW,kBAAA;EH8W9C;AG7WmC;EAAW,kBAAA;EHgX9C;AG/WmC;EAAW,kBAAA;EHkX9C;AGjXmC;EAAW,kBAAA;EHoX9C;AGnXmC;EAAW,kBAAA;EHsX9C;AGrXmC;EAAW,kBAAA;EHwX9C;AGvXmC;EAAW,kBAAA;EH0X9C;AGzXmC;EAAW,kBAAA;EH4X9C;AG3XmC;EAAW,kBAAA;EH8X9C;AG7XmC;EAAW,kBAAA;EHgY9C;AG/XmC;EAAW,kBAAA;EHkY9C;AGjYmC;EAAW,kBAAA;EHoY9C;AGnYmC;EAAW,kBAAA;EHsY9C;AGrYmC;EAAW,kBAAA;EHwY9C;AGvYmC;EAAW,kBAAA;EH0Y9C;AGzYmC;EAAW,kBAAA;EH4Y9C;AG3YmC;EAAW,kBAAA;EH8Y9C;AG7YmC;EAAW,kBAAA;EHgZ9C;AG/YmC;EAAW,kBAAA;EHkZ9C;AGjZmC;EAAW,kBAAA;EHoZ9C;AGnZmC;EAAW,kBAAA;EHsZ9C;AGrZmC;EAAW,kBAAA;EHwZ9C;AGvZmC;EAAW,kBAAA;EH0Z9C;AGzZmC;EAAW,kBAAA;EH4Z9C;AG3ZmC;EAAW,kBAAA;EH8Z9C;AG7ZmC;EAAW,kBAAA;EHga9C;AG/ZmC;EAAW,kBAAA;EHka9C;AGjamC;EAAW,kBAAA;EHoa9C;AGnamC;EAAW,kBAAA;EHsa9C;AGramC;EAAW,kBAAA;EHwa9C;AGvamC;EAAW,kBAAA;EH0a9C;AGzamC;EAAW,kBAAA;EH4a9C;AG3amC;EAAW,kBAAA;EH8a9C;AG7amC;EAAW,kBAAA;EHgb9C;AG/amC;EAAW,kBAAA;EHkb9C;AGjbmC;EAAW,kBAAA;EHob9C;AGnbmC;EAAW,kBAAA;EHsb9C;AGrbmC;EAAW,kBAAA;EHwb9C;AGvbmC;EAAW,kBAAA;EH0b9C;AGzbmC;EAAW,kBAAA;EH4b9C;AG3bmC;EAAW,kBAAA;EH8b9C;AG7bmC;EAAW,kBAAA;EHgc9C;AG/bmC;EAAW,kBAAA;EHkc9C;AGjcmC;EAAW,kBAAA;EHoc9C;AGncmC;EAAW,kBAAA;EHsc9C;AGrcmC;EAAW,kBAAA;EHwc9C;AGvcmC;EAAW,kBAAA;EH0c9C;AGzcmC;EAAW,kBAAA;EH4c9C;AG3cmC;EAAW,kBAAA;EH8c9C;AG7cmC;EAAW,kBAAA;EHgd9C;AG/cmC;EAAW,kBAAA;EHkd9C;AGjdmC;EAAW,kBAAA;EHod9C;AGndmC;EAAW,kBAAA;EHsd9C;AGrdmC;EAAW,kBAAA;EHwd9C;AGvdmC;EAAW,kBAAA;EH0d9C;AGzdmC;EAAW,kBAAA;EH4d9C;AG3dmC;EAAW,kBAAA;EH8d9C;AG7dmC;EAAW,kBAAA;EHge9C;AG/dmC;EAAW,kBAAA;EHke9C;AGjemC;EAAW,kBAAA;EHoe9C;AGnemC;EAAW,kBAAA;EHse9C;AGremC;EAAW,kBAAA;EHwe9C;AGvemC;EAAW,kBAAA;EH0e9C;AGzemC;EAAW,kBAAA;EH4e9C;AG3emC;EAAW,kBAAA;EH8e9C;AG7emC;EAAW,kBAAA;EHgf9C;AG/emC;EAAW,kBAAA;EHkf9C;AGjfmC;EAAW,kBAAA;EHof9C;AGnfmC;EAAW,kBAAA;EHsf9C;AGrfmC;EAAW,kBAAA;EHwf9C;AGvfmC;EAAW,kBAAA;EH0f9C;AGzfmC;EAAW,kBAAA;EH4f9C;AG3fmC;EAAW,kBAAA;EH8f9C;AG7fmC;EAAW,kBAAA;EHggB9C;AG/fmC;EAAW,kBAAA;EHkgB9C;AGjgBmC;EAAW,kBAAA;EHogB9C;AGngBmC;EAAW,kBAAA;EHsgB9C;AGrgBmC;EAAW,kBAAA;EHwgB9C;AGvgBmC;EAAW,kBAAA;EH0gB9C;AGzgBmC;EAAW,kBAAA;EH4gB9C;AG3gBmC;EAAW,kBAAA;EH8gB9C;AG7gBmC;EAAW,kBAAA;EHghB9C;AG/gBmC;EAAW,kBAAA;EHkhB9C;AGjhBmC;EAAW,kBAAA;EHohB9C;AGnhBmC;EAAW,kBAAA;EHshB9C;AGrhBmC;EAAW,kBAAA;EHwhB9C;AGvhBmC;EAAW,kBAAA;EH0hB9C;AGzhBmC;EAAW,kBAAA;EH4hB9C;AG3hBmC;EAAW,kBAAA;EH8hB9C;AG7hBmC;EAAW,kBAAA;EHgiB9C;AG/hBmC;EAAW,kBAAA;EHkiB9C;AGjiBmC;EAAW,kBAAA;EHoiB9C;AGniBmC;EAAW,kBAAA;EHsiB9C;AGriBmC;EAAW,kBAAA;EHwiB9C;AGviBmC;EAAW,kBAAA;EH0iB9C;AGziBmC;EAAW,kBAAA;EH4iB9C;AG3iBmC;EAAW,kBAAA;EH8iB9C;AG7iBmC;EA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A;Efk8CH;Ae97CC;EACE,YAAA;Efg8CH;Ael7CC;EACE,mBAAA;Efo7CH;Aer7CC;EACE,2BAAA;Efu7CH;Aex7CC;EACE,2BAAA;Ef07CH;Ae37CC;EACE,kBAAA;Ef67CH;Ae97CC;EACE,2BAAA;Efg8CH;Aej8CC;EACE,2BAAA;Efm8CH;Aep8CC;EACE,kBAAA;Efs8CH;Aev8CC;EACE,2BAAA;Efy8CH;Ae18CC;EACE,2BAAA;Ef48CH;Ae78CC;EACE,kBAAA;Ef+8CH;Aeh9CC;EACE,2BAAA;Efk9CH;Aen9CC;EACE,0BAAA;Efq9CH;Aet9CC;EACE,iBAAA;Efw9CH;Aa59CD;EE9BI;IACE,aAAA;If6/CH;Eet/CD;IACE,aAAA;Ifw/CD;Eez/CD;IACE,qBAAA;If2/CD;Ee5/CD;IACE,qBAAA;If8/CD;Ee//CD;IACE,YAAA;IfigDD;EelgDD;IACE,qBAAA;IfogDD;EergDD;IACE,qBAAA;IfugDD;EexgDD;IACE,YAAA;If0gDD;Ee3gDD;IACE,qBAAA;If6gDD;Ee9gDD;IACE,qBAAA;IfghDD;EejhDD;IACE,YAAA;IfmhDD;EephDD;IACE,qBAAA;IfshDD;EevhDD;IACE,oBAAA;IfyhDD;Ee3gDD;IACE,aAAA;If6gDD;Ee9gDD;IACE,qBAAA;IfghDD;EejhDD;IACE,qBAAA;IfmhDD;EephDD;IACE,YAAA;IfshDD;EevhDD;IACE,qBAAA;IfyhDD;Ee1hDD;IACE,qBAAA;If4hDD;Ee7hDD;IACE,YAAA;If+hDD;EehiDD;IACE,qBAAA;IfkiDD;EeniDD;IACE,qBAAA;IfqiDD;EetiDD;IACE,YAAA;IfwiDD;EeziDD;IACE,qBAAA;If2iDD;Ee5iDD;IACE,oBAAA;If8iDD;Ee1iDD;IACE,aAAA;If4iDD;Ee5jDD;IACE,YAAA;If8jDD;Ee/jDD;IACE,oBAAA;IfikDD;EelkDD;IACE,oBAAA;IfokDD;EerkDD;IACE,WAAA;IfukDD;EexkDD;IACE,oBAAA;If0kDD;Ee3kDD;IACE,oBAAA;If6kDD;Ee9kDD;IACE,WAAA;IfglDD;EejlDD;IACE,oBAAA;IfmlDD;EeplDD;IACE,oBAAA;IfslDD;EevlDD;IACE,WAAA;IfylDD;Ee1lDD;IACE,oBAAA;If4lDD;Ee7lDD;IACE,mBAAA;If+lDD;Ee3lDD;IACE,YAAA;If6lDD;Ee/kDD;IACE,mBAAA;IfilDD;EellDD;IACE,2BAAA;IfolDD;EerlDD;IACE,2BAAA;IfulDD;EexlDD;IACE,kBAAA;If0lDD;Ee3lDD;IACE,2BAAA;If6lDD;Ee9lDD;IACE,2BAAA;IfgmDD;EejmDD;IACE,kBAAA;IfmmDD;EepmDD;IACE,2BAAA;IfsmDD;EevmDD;IACE,2BAAA;IfymDD;Ee1mDD;IACE,kBAAA;If4mDD;Ee7mDD;IACE,2BAAA;If+mDD;EehnDD;IACE,0BAAA;IfknDD;EennDD;IACE,iBAAA;IfqnDD;EACF;AajnDD;EEvCI;IACE,aAAA;If2pDH;EeppDD;IACE,aAAA;IfspDD;EevpDD;IACE,qBAAA;IfypDD;Ee1pDD;IACE,qBAAA;If4pDD;Ee7pDD;IACE,YAAA;If+pDD;EehqDD;IACE,qBAAA;IfkqDD;EenqDD;IACE,qBAAA;IfqqDD;EetqDD;IACE,YAAA;IfwqDD;EezqDD;IACE,qBAAA;If2qDD;Ee5qDD;IACE,qBAAA;If8qDD;Ee/qDD;IACE,YAAA;IfirDD;EelrDD;IACE,qBAAA;IforDD;EerrDD;IACE,oBAAA;IfurDD;EezqDD;IACE,aAAA;If2qDD;Ee5qDD;IACE,qBAAA;If8qDD;Ee/qDD;IACE,qBAAA;IfirDD;EelrDD;IACE,YAAA;IforDD;EerrDD;IACE,qBAAA;IfurDD;EexrDD;IACE,qBAAA;If0rDD;Ee3rDD;IACE,YAAA;If6rDD;Ee9rDD;IACE,qBAAA;IfgsDD;EejsDD;IACE,qBAAA;IfmsDD;EepsDD;IACE,YAAA;IfssDD;EevsDD;IACE,qBAAA;IfysDD;Ee1sDD;IACE,oBAAA;If4sDD;EexsDD;IACE,aAAA;If0sDD;Ee1tDD;IACE,YAAA;If4tDD;Ee7tDD;IACE,oBAAA;If+tDD;EehuDD;IACE,oBAAA;IfkuDD;EenuDD;IACE,WAAA;IfquDD;EetuDD;IACE,oBAAA;IfwuDD;EezuDD;IACE,oBAAA;If2uDD;Ee5uDD;IACE,WAAA;If8uDD;Ee/uDD;IACE,oBAAA;IfivDD;EelvDD;IACE,oBAAA;IfovDD;EervDD;IACE,WAAA;IfuvDD;EexvDD;IACE,oBAAA;If0vDD;Ee3vDD;IACE,mBAAA;If6vDD;EezvDD;IACE,YAAA;If2vDD;Ee7uDD;IACE,mBAAA;If+uDD;EehvDD;IACE,2BAAA;IfkvDD;EenvDD;IACE,2BAAA;IfqvDD;EetvDD;IACE,kBAAA;IfwvDD;EezvDD;IACE,2BAAA;If2vDD;Ee5vDD;IACE,2BAAA;If8vDD;Ee/vDD;IACE,kBAAA;IfiwDD;EelwDD;IACE,2BAAA;IfowDD;EerwDD;IACE,2BAAA;IfuwDD;EexwDD;IACE,kBAAA;If0wDD;Ee3wDD;IACE,2BAAA;If6wDD;Ee9wDD;IACE,0BAAA;IfgxDD;EejxDD;IACE,iBAAA;IfmxDD;EACF;AaxwDD;EE9CI;IACE,aAAA;IfyzDH;EelzDD;IACE,aAAA;IfozDD;EerzDD;IACE,qBAAA;IfuzDD;EexzDD;IACE,qBAAA;If0zDD;Ee3zDD;IACE,YAAA;If6zDD;Ee9zDD;IACE,qBAAA;Ifg0DD;Eej0DD;IACE,qBAAA;Ifm0DD;Eep0DD;IACE,YAAA;Ifs0DD;Eev0DD;IACE,qBAAA;Ify0DD;Ee10DD;IACE,qBAAA;If40DD;Ee70DD;IACE,YAAA;If+0DD;Eeh1DD;IACE,qBAAA;Ifk1DD;Een1DD;IACE,oBAAA;Ifq1DD;Eev0DD;IACE,aAAA;Ify0DD;Ee10DD;IACE,qBAAA;If40DD;Ee70DD;IACE,qBAAA;If+0DD;Eeh1DD;IACE,YAAA;Ifk1DD;Een1DD;IACE,qBAAA;Ifq1DD;Eet1DD;IACE,qBAAA;Ifw1DD;Eez1DD;IACE,YAAA;If21DD;Ee51DD;IACE,qBAAA;If81DD;Ee/1DD;IACE,qBAAA;Ifi2DD;Eel2DD;IACE,YAAA;Ifo2DD;Eer2DD;IACE,qBAAA;Ifu2DD;Eex2DD;IACE,oBAAA;If02DD;Eet2DD;IACE,aAAA;Ifw2DD;Eex3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AAA;EACI,uBAAA;ErBqsFT;AoB9qFD;EClBI,gBAAA;EACA,2BAAA;ErBmsFH;AoB/qFD;ECrDE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBuuFD;AqBruFC;;;;;EAKE,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBuuFP;AqBruFC;;;EAGE,wBAAA;ErBuuFH;AqBluFG;;;;;;;;;;;;;;;EAKE,2BAAA;EACI,uBAAA;ErB8uFT;AoBptFD;ECrBI,gBAAA;EACA,2BAAA;ErB4uFH;AoBptFD;ECzDE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBgxFD;AqB9wFC;;;;;EAKE,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBgxFP;AqB9wFC;;;EAGE,wBAAA;ErBgxFH;AqB3wFG;;;;;;;;;;;;;;;EAKE,2BAAA;EACI,uBAAA;ErBuxFT;AoBzvFD;ECzBI,gBAAA;EACA,2BAAA;ErBqxFH;AoBzvFD;EC7DE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErByzFD;AqBvzFC;;;;;EAKE,gBAAA;EACA,2BAAA;EACI,uBAAA;ErByzFP;AqBvzFC;;;EAGE,wBAAA;ErByzFH;AqBpzFG;;;;;;;;;;;;;;;EAKE,2BAAA;EACI,uBAAA;ErBg0FT;AoB9xFD;EC7BI,gBAAA;EACA,2BAAA;ErB8zFH;AoB9xFD;ECjEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErBk2FD;AqBh2FC;;;;;EAKE,gBAAA;EACA,2BAAA;EACI,uBAAA;ErBk2FP;AqBh2FC;;;EAGE,wBAAA;ErBk2FH;AqB71FG;;;;;;;;;;;;;;;EAKE,2BAAA;EACI,uBAAA;ErBy2FT;AoBn0FD;ECjCI,gBAAA;EACA,2BAAA;ErBu2FH;AoBn0FD;ECrEE,gBAAA;EACA,2BAAA;EACA,uBAAA;ErB24FD;AqBz4FC;;;;;EAKE,gBAAA;EACA,2BAAA;EACI,uBAAA;ErB24FP;AqBz4FC;;;EAGE,wBAAA;ErB24FH;AqBt4FG;;;;;;;;;;;;;;;EAKE,2BAAA;EACI,uBAAA;ErBk5FT;AoBx2FD;ECrCI,gBAAA;EACA,2BAAA;ErBg5FH;AoBn2FD;EACE,gBAAA;EACA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","sourcesContent":[null,"/*! normalize.css v3.0.1 | MIT License | git.io/normalize */\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS text size adjust after orientation change, without disabling\n// user zoom.\n//\n\nhtml {\n font-family: sans-serif; // 1\n -ms-text-size-adjust: 100%; // 2\n -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n margin: 0;\n}\n\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined for any HTML5 element in IE 8/9.\n// Correct `block` display not defined for `details` or `summary` in IE 10/11 and Firefox.\n// Correct `block` display not defined for `main` in IE 11.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nnav,\nsection,\nsummary {\n display: block;\n}\n\n//\n// 1. Correct `inline-block` display not defined in IE 8/9.\n// 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.\n//\n\naudio,\ncanvas,\nprogress,\nvideo {\n display: inline-block; // 1\n vertical-align: baseline; // 2\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n display: none;\n height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9/10.\n// Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n display: none;\n}\n\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n background: transparent;\n}\n\n//\n// Improve readability when focused and also mouse hovered in all browsers.\n//\n\na:active,\na:hover {\n outline: 0;\n}\n\n// Text-level semantics\n// ==========================================================================\n\n//\n// Address styling not present in IE 8/9/10/11, Safari, and Chrome.\n//\n\nabbr[title] {\n border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari, and Chrome.\n//\n\nb,\nstrong {\n font-weight: bold;\n}\n\n//\n// Address styling not present in Safari and Chrome.\n//\n\ndfn {\n font-style: italic;\n}\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari, and Chrome.\n//\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n background: #ff0;\n color: #000;\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsup {\n top: -0.5em;\n}\n\nsub {\n bottom: -0.25em;\n}\n\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9/10.\n//\n\nimg {\n border: 0;\n}\n\n//\n// Correct overflow not hidden in IE 9/10/11.\n//\n\nsvg:not(:root) {\n overflow: hidden;\n}\n\n// Grouping content\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari.\n//\n\nfigure {\n margin: 1em 40px;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n -moz-box-sizing: content-box;\n box-sizing: content-box;\n height: 0;\n}\n\n//\n// Contain overflow in all browsers.\n//\n\npre {\n overflow: auto;\n}\n\n//\n// Address odd `em`-unit font size rendering in all browsers.\n//\n\ncode,\nkbd,\npre,\nsamp {\n font-family: monospace, monospace;\n font-size: 1em;\n}\n\n// Forms\n// ==========================================================================\n\n//\n// Known limitation: by default, Chrome and Safari on OS X allow very limited\n// styling of `select`, unless a `border` property is set.\n//\n\n//\n// 1. Correct color not being inherited.\n// Known issue: affects color of disabled elements.\n// 2. Correct font properties not being inherited.\n// 3. Address margins set differently in Firefox 4+, Safari, and Chrome.\n//\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n color: inherit; // 1\n font: inherit; // 2\n margin: 0; // 3\n}\n\n//\n// Address `overflow` set to `hidden` in IE 8/9/10/11.\n//\n\nbutton {\n overflow: visible;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.\n// Correct `select` style inheritance in Firefox.\n//\n\nbutton,\nselect {\n text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n// and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n// `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n -webkit-appearance: button; // 2\n cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n cursor: default;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\ninput {\n line-height: normal;\n}\n\n//\n// It's recommended that you don't attempt to style these elements.\n// Firefox's implementation doesn't respect box-sizing, padding, or width.\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n box-sizing: border-box; // 1\n padding: 0; // 2\n}\n\n//\n// Fix the cursor style for Chrome's increment/decrement buttons. For certain\n// `font-size` values of the `input`, it causes the cursor style of the\n// decrement button to change from `default` to `text`.\n//\n\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari and Chrome\n// (include `-moz` to future-proof).\n//\n\ninput[type=\"search\"] {\n -webkit-appearance: textfield; // 1\n -moz-box-sizing: content-box;\n -webkit-box-sizing: content-box; // 2\n box-sizing: content-box;\n}\n\n//\n// Remove inner padding and search cancel button in Safari and Chrome on OS X.\n// Safari (but not Chrome) clips the cancel button when the search input has\n// padding (and `textfield` appearance).\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n border: 1px solid #c0c0c0;\n margin: 0 2px;\n padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9/10/11.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n border: 0; // 1\n padding: 0; // 2\n}\n\n//\n// Remove default vertical scrollbar in IE 8/9/10/11.\n//\n\ntextarea {\n overflow: auto;\n}\n\n//\n// Don't inherit the `font-weight` (applied by a rule above).\n// NOTE: the default cannot safely be changed in Chrome and Safari on OS X.\n//\n\noptgroup {\n font-weight: bold;\n}\n\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\ntd,\nth {\n padding: 0;\n}\n","//\n// Basic print styles\n// --------------------------------------------------\n// Source: https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css\n\n@media print {\n\n * {\n text-shadow: none !important;\n color: #000 !important; // Black prints faster: h5bp.com/s\n background: transparent !important;\n box-shadow: none !important;\n }\n\n a,\n a:visited {\n text-decoration: underline;\n }\n\n a[href]:after {\n content: \" (\" attr(href) \")\";\n }\n\n abbr[title]:after {\n content: \" (\" attr(title) \")\";\n }\n\n // Don't show links for images, or javascript/internal links\n a[href^=\"javascript:\"]:after,\n a[href^=\"#\"]:after {\n content: \"\";\n }\n\n pre,\n blockquote {\n border: 1px solid #999;\n page-break-inside: avoid;\n }\n\n thead {\n display: table-header-group; // h5bp.com/t\n }\n\n tr,\n img {\n page-break-inside: avoid;\n }\n\n img {\n max-width: 100% !important;\n }\n\n p,\n h2,\n h3 {\n orphans: 3;\n widows: 3;\n }\n\n h2,\n h3 {\n page-break-after: avoid;\n }\n\n // Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245\n // Once fixed, we can just straight up remove this.\n select {\n background: #fff !important;\n }\n\n // Bootstrap components\n .navbar {\n display: none;\n }\n .table {\n td,\n th {\n background-color: #fff !important;\n }\n }\n .btn,\n .dropup > .btn {\n > .caret {\n border-top-color: #000 !important;\n }\n }\n .label {\n border: 1px solid #000;\n }\n\n .table {\n border-collapse: collapse !important;\n }\n .table-bordered {\n th,\n td {\n border: 1px solid #ddd !important;\n }\n }\n\n}\n","//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// Star\n\n// Import the fonts\n@font-face {\n font-family: 'Glyphicons Halflings';\n src: url('@{icon-font-path}@{icon-font-name}.eot');\n src: url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype'),\n url('@{icon-font-path}@{icon-font-name}.woff') format('woff'),\n url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype'),\n url('@{icon-font-path}@{icon-font-name}.svg#@{icon-font-svg-id}') format('svg');\n}\n\n// Catchall baseclass\n.glyphicon {\n position: relative;\n top: 1px;\n display: inline-block;\n font-family: 'Glyphicons Halflings';\n font-style: normal;\n font-weight: normal;\n line-height: 1;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\n// Individual icons\n.glyphicon-asterisk { &:before { content: \"\\2a\"; } }\n.glyphicon-plus { &:before { content: \"\\2b\"; } }\n.glyphicon-euro { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil { &:before { content: \"\\270f\"; } }\n.glyphicon-glass { &:before { content: \"\\e001\"; } }\n.glyphicon-music { &:before { content: \"\\e002\"; } }\n.glyphicon-search { &:before { content: \"\\e003\"; } }\n.glyphicon-heart { &:before { content: \"\\e005\"; } }\n.glyphicon-star { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty { &:before { content: \"\\e007\"; } }\n.glyphicon-user { &:before { content: \"\\e008\"; } }\n.glyphicon-film { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large { &:before { content: \"\\e010\"; } }\n.glyphicon-th { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list { &:before { content: \"\\e012\"; } }\n.glyphicon-ok { &:before { content: \"\\e013\"; } }\n.glyphicon-remove { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out { &:before { content: \"\\e016\"; } }\n.glyphicon-off { &:before { content: \"\\e017\"; } }\n.glyphicon-signal { &:before { content: \"\\e018\"; } }\n.glyphicon-cog { &:before { content: \"\\e019\"; } }\n.glyphicon-trash { &:before { content: \"\\e020\"; } }\n.glyphicon-home { &:before { content: \"\\e021\"; } }\n.glyphicon-file { &:before { content: \"\\e022\"; } }\n.glyphicon-time { &:before { content: \"\\e023\"; } }\n.glyphicon-road { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt { &:before { content: \"\\e025\"; } }\n.glyphicon-download { &:before { content: \"\\e026\"; } }\n.glyphicon-upload { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt { &:before { content: \"\\e032\"; } }\n.glyphicon-lock { &:before { content: \"\\e033\"; } }\n.glyphicon-flag { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode { &:before { content: \"\\e040\"; } }\n.glyphicon-tag { &:before { content: \"\\e041\"; } }\n.glyphicon-tags { &:before { content: \"\\e042\"; } }\n.glyphicon-book { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark { &:before { content: \"\\e044\"; } }\n.glyphicon-print { &:before { content: \"\\e045\"; } }\n.glyphicon-camera { &:before { content: \"\\e046\"; } }\n.glyphicon-font { &:before { content: \"\\e047\"; } }\n.glyphicon-bold { &:before { content: \"\\e048\"; } }\n.glyphicon-italic { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify { &:before { content: \"\\e055\"; } }\n.glyphicon-list { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video { &:before { content: \"\\e059\"; } }\n.glyphicon-picture { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust { &:before { content: \"\\e063\"; } }\n.glyphicon-tint { &:before { content: \"\\e064\"; } }\n.glyphicon-edit { &:before { content: \"\\e065\"; } }\n.glyphicon-share { &:before { content: \"\\e066\"; } }\n.glyphicon-check { &:before { content: \"\\e067\"; } }\n.glyphicon-move { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward { &:before { content: \"\\e070\"; } }\n.glyphicon-backward { &:before { content: \"\\e071\"; } }\n.glyphicon-play { &:before { content: \"\\e072\"; } }\n.glyphicon-pause { &:before { content: \"\\e073\"; } }\n.glyphicon-stop { &:before { content: \"\\e074\"; } }\n.glyphicon-forward { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward { &:before { content: \"\\e077\"; } }\n.glyphicon-eject { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign { &:before { content: \"\\e101\"; } }\n.glyphicon-gift { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf { &:before { content: \"\\e103\"; } }\n.glyphicon-fire { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign { &:before { content: \"\\e107\"; } }\n.glyphicon-plane { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar { &:before { content: \"\\e109\"; } }\n.glyphicon-random { &:before { content: \"\\e110\"; } }\n.glyphicon-comment { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn { &:before { content: \"\\e122\"; } }\n.glyphicon-bell { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down { &:before { content: \"\\e134\"; } }\n.glyphicon-globe { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks { &:before { content: \"\\e137\"; } }\n.glyphicon-filter { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty { &:before { content: \"\\e143\"; } }\n.glyphicon-link { &:before { content: \"\\e144\"; } }\n.glyphicon-phone { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin { &:before { content: \"\\e146\"; } }\n.glyphicon-usd { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp { &:before { content: \"\\e149\"; } }\n.glyphicon-sort { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked { &:before { content: \"\\e157\"; } }\n.glyphicon-expand { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in { &:before { content: \"\\e161\"; } }\n.glyphicon-flash { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window { &:before { content: \"\\e164\"; } }\n.glyphicon-record { &:before { content: \"\\e165\"; } }\n.glyphicon-save { &:before { content: \"\\e166\"; } }\n.glyphicon-open { &:before { content: \"\\e167\"; } }\n.glyphicon-saved { &:before { content: \"\\e168\"; } }\n.glyphicon-import { &:before { content: \"\\e169\"; } }\n.glyphicon-export { &:before { content: \"\\e170\"; } }\n.glyphicon-send { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery { &:before { content: \"\\e179\"; } }\n.glyphicon-header { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt { &:before { content: \"\\e183\"; } }\n.glyphicon-tower { &:before { content: \"\\e184\"; } }\n.glyphicon-stats { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1 { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1 { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1 { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous { &:before { content: \"\\e200\"; } }\n","//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n//\n// Heads up! This reset may cause conflicts with some third-party widgets.\n// For recommendations on resolving such conflicts, see\n// http://getbootstrap.com/getting-started/#third-box-sizing\n* {\n .box-sizing(border-box);\n}\n*:before,\n*:after {\n .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n font-size: 10px;\n -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n font-family: @font-family-base;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @text-color;\n background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n font-family: inherit;\n font-size: inherit;\n line-height: inherit;\n}\n\n\n// Links\n\na {\n color: @link-color;\n text-decoration: none;\n\n &:hover,\n &:focus {\n color: @link-hover-color;\n text-decoration: underline;\n }\n\n &:focus {\n .tab-focus();\n }\n}\n\n\n// Figures\n//\n// We reset this here because previously Normalize had no `figure` margins. This\n// ensures we don't break anyone's use of the element.\n\nfigure {\n margin: 0;\n}\n\n\n// Images\n\nimg {\n vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n padding: @thumbnail-padding;\n line-height: @line-height-base;\n background-color: @thumbnail-bg;\n border: 1px solid @thumbnail-border;\n border-radius: @thumbnail-border-radius;\n .transition(all .2s ease-in-out);\n\n // Keep them at most 100% wide\n .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n margin-top: @line-height-computed;\n margin-bottom: @line-height-computed;\n border: 0;\n border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0,0,0,0);\n border: 0;\n}\n\n// Use in conjunction with .sr-only to only display content when it's focused.\n// Useful for \"Skip to main content\" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1\n// Credit: HTML5 Boilerplate\n\n.sr-only-focusable {\n &:active,\n &:focus {\n position: static;\n width: auto;\n height: auto;\n margin: 0;\n overflow: visible;\n clip: auto;\n }\n}\n","// Vendor Prefixes\n//\n// All vendor mixins are deprecated as of v3.2.0 due to the introduction of\n// Autoprefixer in our Gruntfile. They will be removed in v4.\n\n// - Animations\n// - Backface visibility\n// - Box shadow\n// - Box sizing\n// - Content columns\n// - Hyphens\n// - Placeholder text\n// - Transformations\n// - Transitions\n// - User Select\n\n\n// Animations\n.animation(@animation) {\n -webkit-animation: @animation;\n -o-animation: @animation;\n animation: @animation;\n}\n.animation-name(@name) {\n -webkit-animation-name: @name;\n animation-name: @name;\n}\n.animation-duration(@duration) {\n -webkit-animation-duration: @duration;\n animation-duration: @duration;\n}\n.animation-timing-function(@timing-function) {\n -webkit-animation-timing-function: @timing-function;\n animation-timing-function: @timing-function;\n}\n.animation-delay(@delay) {\n -webkit-animation-delay: @delay;\n animation-delay: @delay;\n}\n.animation-iteration-count(@iteration-count) {\n -webkit-animation-iteration-count: @iteration-count;\n animation-iteration-count: @iteration-count;\n}\n.animation-direction(@direction) {\n -webkit-animation-direction: @direction;\n animation-direction: @direction;\n}\n.animation-fill-mode(@fill-mode) {\n -webkit-animation-fill-mode: @fill-mode;\n animation-fill-mode: @fill-mode;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n\n.backface-visibility(@visibility){\n -webkit-backface-visibility: @visibility;\n -moz-backface-visibility: @visibility;\n backface-visibility: @visibility;\n}\n\n// Drop shadows\n//\n// Note: Deprecated `.box-shadow()` as of v3.1.0 since all of Bootstrap's\n// supported browsers that have box shadow capabilities now support it.\n\n.box-shadow(@shadow) {\n -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n box-shadow: @shadow;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n -webkit-box-sizing: @boxmodel;\n -moz-box-sizing: @boxmodel;\n box-sizing: @boxmodel;\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n -webkit-column-count: @column-count;\n -moz-column-count: @column-count;\n column-count: @column-count;\n -webkit-column-gap: @column-gap;\n -moz-column-gap: @column-gap;\n column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n word-wrap: break-word;\n -webkit-hyphens: @mode;\n -moz-hyphens: @mode;\n -ms-hyphens: @mode; // IE10+\n -o-hyphens: @mode;\n hyphens: @mode;\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n &::-moz-placeholder { color: @color; // Firefox\n opacity: 1; } // See https://github.com/twbs/bootstrap/pull/11526\n &:-ms-input-placeholder { color: @color; } // Internet Explorer 10+\n &::-webkit-input-placeholder { color: @color; } // Safari and Chrome\n}\n\n// Transformations\n.scale(@ratio) {\n -webkit-transform: scale(@ratio);\n -ms-transform: scale(@ratio); // IE9 only\n -o-transform: scale(@ratio);\n transform: scale(@ratio);\n}\n.scale(@ratioX; @ratioY) {\n -webkit-transform: scale(@ratioX, @ratioY);\n -ms-transform: scale(@ratioX, @ratioY); // IE9 only\n -o-transform: scale(@ratioX, @ratioY);\n transform: scale(@ratioX, @ratioY);\n}\n.scaleX(@ratio) {\n -webkit-transform: scaleX(@ratio);\n -ms-transform: scaleX(@ratio); // IE9 only\n -o-transform: scaleX(@ratio);\n transform: scaleX(@ratio);\n}\n.scaleY(@ratio) {\n -webkit-transform: scaleY(@ratio);\n -ms-transform: scaleY(@ratio); // IE9 only\n -o-transform: scaleY(@ratio);\n transform: scaleY(@ratio);\n}\n.skew(@x; @y) {\n -webkit-transform: skewX(@x) skewY(@y);\n -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n -o-transform: skewX(@x) skewY(@y);\n transform: skewX(@x) skewY(@y);\n}\n.translate(@x; @y) {\n -webkit-transform: translate(@x, @y);\n -ms-transform: translate(@x, @y); // IE9 only\n -o-transform: translate(@x, @y);\n transform: translate(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n -webkit-transform: translate3d(@x, @y, @z);\n transform: translate3d(@x, @y, @z);\n}\n.rotate(@degrees) {\n -webkit-transform: rotate(@degrees);\n -ms-transform: rotate(@degrees); // IE9 only\n -o-transform: rotate(@degrees);\n transform: rotate(@degrees);\n}\n.rotateX(@degrees) {\n -webkit-transform: rotateX(@degrees);\n -ms-transform: rotateX(@degrees); // IE9 only\n -o-transform: rotateX(@degrees);\n transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n -webkit-transform: rotateY(@degrees);\n -ms-transform: rotateY(@degrees); // IE9 only\n -o-transform: rotateY(@degrees);\n transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n -webkit-perspective: @perspective;\n -moz-perspective: @perspective;\n perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n -webkit-perspective-origin: @perspective;\n -moz-perspective-origin: @perspective;\n perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n -webkit-transform-origin: @origin;\n -moz-transform-origin: @origin;\n -ms-transform-origin: @origin; // IE9 only\n transform-origin: @origin;\n}\n\n\n// Transitions\n\n.transition(@transition) {\n -webkit-transition: @transition;\n -o-transition: @transition;\n transition: @transition;\n}\n.transition-property(@transition-property) {\n -webkit-transition-property: @transition-property;\n transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n -webkit-transition-delay: @transition-delay;\n transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n -webkit-transition-duration: @transition-duration;\n transition-duration: @transition-duration;\n}\n.transition-timing-function(@timing-function) {\n -webkit-transition-timing-function: @timing-function;\n transition-timing-function: @timing-function;\n}\n.transition-transform(@transition) {\n -webkit-transition: -webkit-transform @transition;\n -moz-transition: -moz-transform @transition;\n -o-transition: -o-transform @transition;\n transition: transform @transition;\n}\n\n\n// User select\n// For selecting text on the page\n\n.user-select(@select) {\n -webkit-user-select: @select;\n -moz-user-select: @select;\n -ms-user-select: @select; // IE10+\n user-select: @select;\n}\n","// WebKit-style focus\n\n.tab-focus() {\n // Default\n outline: thin dotted;\n // WebKit\n outline: 5px auto -webkit-focus-ring-color;\n outline-offset: -2px;\n}\n","// Image Mixins\n// - Responsive image\n// - Retina image\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n.img-responsive(@display: block) {\n display: @display;\n width: 100% \\9; // Force IE10 and below to size SVG images correctly\n max-width: 100%; // Part 1: Set a maximum relative to the parent\n height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// Retina image\n//\n// Short retina mixin for setting background-image and -size. Note that the\n// spelling of `min--moz-device-pixel-ratio` is intentional.\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n background-image: url(\"@{file-1x}\");\n\n @media\n only screen and (-webkit-min-device-pixel-ratio: 2),\n only screen and ( min--moz-device-pixel-ratio: 2),\n only screen and ( -o-min-device-pixel-ratio: 2/1),\n only screen and ( min-device-pixel-ratio: 2),\n only screen and ( min-resolution: 192dpi),\n only screen and ( min-resolution: 2dppx) {\n background-image: url(\"@{file-2x}\");\n background-size: @width-1x @height-1x;\n }\n}\n","//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n font-family: @headings-font-family;\n font-weight: @headings-font-weight;\n line-height: @headings-line-height;\n color: @headings-color;\n\n small,\n .small {\n font-weight: normal;\n line-height: 1;\n color: @headings-small-color;\n }\n}\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n margin-top: @line-height-computed;\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 65%;\n }\n}\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n margin-top: (@line-height-computed / 2);\n margin-bottom: (@line-height-computed / 2);\n\n small,\n .small {\n font-size: 75%;\n }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n margin-bottom: @line-height-computed;\n font-size: floor((@font-size-base * 1.15));\n font-weight: 300;\n line-height: 1.4;\n\n @media (min-width: @screen-sm-min) {\n font-size: (@font-size-base * 1.5);\n }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: (12px small font / 14px base font) * 100% = about 85%\nsmall,\n.small {\n font-size: floor((100% * @font-size-small / @font-size-base));\n}\n\n// Undo browser default styling\ncite {\n font-style: normal;\n}\n\nmark,\n.mark {\n background-color: @state-warning-bg;\n padding: .2em;\n}\n\n// Alignment\n.text-left { text-align: left; }\n.text-right { text-align: right; }\n.text-center { text-align: center; }\n.text-justify { text-align: justify; }\n.text-nowrap { white-space: nowrap; }\n\n// Transformation\n.text-lowercase { text-transform: lowercase; }\n.text-uppercase { text-transform: uppercase; }\n.text-capitalize { text-transform: capitalize; }\n\n// Contextual colors\n.text-muted {\n color: @text-muted;\n}\n.text-primary {\n .text-emphasis-variant(@brand-primary);\n}\n.text-success {\n .text-emphasis-variant(@state-success-text);\n}\n.text-info {\n .text-emphasis-variant(@state-info-text);\n}\n.text-warning {\n .text-emphasis-variant(@state-warning-text);\n}\n.text-danger {\n .text-emphasis-variant(@state-danger-text);\n}\n\n// Contextual backgrounds\n// For now we'll leave these alongside the text classes until v4 when we can\n// safely shift things around (per SemVer rules).\n.bg-primary {\n // Given the contrast here, this is the only class to have its color inverted\n // automatically.\n color: #fff;\n .bg-variant(@brand-primary);\n}\n.bg-success {\n .bg-variant(@state-success-bg);\n}\n.bg-info {\n .bg-variant(@state-info-bg);\n}\n.bg-warning {\n .bg-variant(@state-warning-bg);\n}\n.bg-danger {\n .bg-variant(@state-danger-bg);\n}\n\n\n// Page header\n// -------------------------\n\n.page-header {\n padding-bottom: ((@line-height-computed / 2) - 1);\n margin: (@line-height-computed * 2) 0 @line-height-computed;\n border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// -------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n margin-top: 0;\n margin-bottom: (@line-height-computed / 2);\n ul,\n ol {\n margin-bottom: 0;\n }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n padding-left: 0;\n list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n .list-unstyled();\n margin-left: -5px;\n\n > li {\n display: inline-block;\n padding-left: 5px;\n padding-right: 5px;\n }\n}\n\n// Description Lists\ndl {\n margin-top: 0; // Remove browser default\n margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n line-height: @line-height-base;\n}\ndt {\n font-weight: bold;\n}\ndd {\n margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n.dl-horizontal {\n dd {\n &:extend(.clearfix all); // Clear the floated `dt` if an empty `dd` is present\n }\n\n @media (min-width: @grid-float-breakpoint) {\n dt {\n float: left;\n width: (@dl-horizontal-offset - 20);\n clear: left;\n text-align: right;\n .text-overflow();\n }\n dd {\n margin-left: @dl-horizontal-offset;\n }\n }\n}\n\n\n// Misc\n// -------------------------\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n cursor: help;\n border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n font-size: 90%;\n text-transform: uppercase;\n}\n\n// Blockquotes\nblockquote {\n padding: (@line-height-computed / 2) @line-height-computed;\n margin: 0 0 @line-height-computed;\n font-size: @blockquote-font-size;\n border-left: 5px solid @blockquote-border-color;\n\n p,\n ul,\n ol {\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n // Note: Deprecated small and .small as of v3.1.0\n // Context: https://github.com/twbs/bootstrap/issues/11660\n footer,\n small,\n .small {\n display: block;\n font-size: 80%; // back to default font-size\n line-height: @line-height-base;\n color: @blockquote-small-color;\n\n &:before {\n content: '\\2014 \\00A0'; // em dash, nbsp\n }\n }\n}\n\n// Opposite alignment of blockquote\n//\n// Heads up: `blockquote.pull-right` has been deprecated as of v3.1.0.\n.blockquote-reverse,\nblockquote.pull-right {\n padding-right: 15px;\n padding-left: 0;\n border-right: 5px solid @blockquote-border-color;\n border-left: 0;\n text-align: right;\n\n // Account for citation\n footer,\n small,\n .small {\n &:before { content: ''; }\n &:after {\n content: '\\00A0 \\2014'; // nbsp, em dash\n }\n }\n}\n\n// Quotes\nblockquote:before,\nblockquote:after {\n content: \"\";\n}\n\n// Addresses\naddress {\n margin-bottom: @line-height-computed;\n font-style: normal;\n line-height: @line-height-base;\n}\n","// Typography\n\n.text-emphasis-variant(@color) {\n color: @color;\n a&:hover {\n color: darken(@color, 10%);\n }\n}\n","// Contextual backgrounds\n\n.bg-variant(@color) {\n background-color: @color;\n a&:hover {\n background-color: darken(@color, 10%);\n }\n}\n","// Text overflow\n// Requires inline-block or block for proper styling\n\n.text-overflow() {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n padding: 2px 4px;\n font-size: 90%;\n color: @code-color;\n background-color: @code-bg;\n border-radius: @border-radius-base;\n}\n\n// User input typically entered via keyboard\nkbd {\n padding: 2px 4px;\n font-size: 90%;\n color: @kbd-color;\n background-color: @kbd-bg;\n border-radius: @border-radius-small;\n box-shadow: inset 0 -1px 0 rgba(0,0,0,.25);\n\n kbd {\n padding: 0;\n font-size: 100%;\n box-shadow: none;\n }\n}\n\n// Blocks of code\npre {\n display: block;\n padding: ((@line-height-computed - 1) / 2);\n margin: 0 0 (@line-height-computed / 2);\n font-size: (@font-size-base - 1); // 14px to 13px\n line-height: @line-height-base;\n word-break: break-all;\n word-wrap: break-word;\n color: @pre-color;\n background-color: @pre-bg;\n border: 1px solid @pre-border-color;\n border-radius: @border-radius-base;\n\n // Account for some code outputs that place code tags in pre tags\n code {\n padding: 0;\n font-size: inherit;\n color: inherit;\n white-space: pre-wrap;\n background-color: transparent;\n border-radius: 0;\n }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n max-height: @pre-scrollable-max-height;\n overflow-y: scroll;\n}\n","//\n// Grid system\n// --------------------------------------------------\n\n\n// Container widths\n//\n// Set the container width, and override it for fixed navbars in media queries.\n\n.container {\n .container-fixed();\n\n @media (min-width: @screen-sm-min) {\n width: @container-sm;\n }\n @media (min-width: @screen-md-min) {\n width: @container-md;\n }\n @media (min-width: @screen-lg-min) {\n width: @container-lg;\n }\n}\n\n\n// Fluid container\n//\n// Utilizes the mixin meant for fixed width containers, but without any defined\n// width for fluid, full width layouts.\n\n.container-fluid {\n .container-fixed();\n}\n\n\n// Row\n//\n// Rows contain and clear the floats of your columns.\n\n.row {\n .make-row();\n}\n\n\n// Columns\n//\n// Common styles for small and large grid columns\n\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid(xs);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n .make-grid(sm);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n .make-grid(md);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n .make-grid(lg);\n}\n","// Grid system\n//\n// Generate semantic grid columns with these mixins.\n\n// Centered container element\n.container-fixed(@gutter: @grid-gutter-width) {\n margin-right: auto;\n margin-left: auto;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n &:extend(.clearfix all);\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n margin-left: (@gutter / -2);\n margin-right: (@gutter / -2);\n &:extend(.clearfix all);\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n float: left;\n width: percentage((@columns / @grid-columns));\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n}\n.make-xs-column-offset(@columns) {\n margin-left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-push(@columns) {\n left: percentage((@columns / @grid-columns));\n}\n.make-xs-column-pull(@columns) {\n right: percentage((@columns / @grid-columns));\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-sm-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-offset(@columns) {\n @media (min-width: @screen-sm-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-push(@columns) {\n @media (min-width: @screen-sm-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-sm-column-pull(@columns) {\n @media (min-width: @screen-sm-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-md-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-offset(@columns) {\n @media (min-width: @screen-md-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-push(@columns) {\n @media (min-width: @screen-md-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-md-column-pull(@columns) {\n @media (min-width: @screen-md-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n position: relative;\n min-height: 1px;\n padding-left: (@gutter / 2);\n padding-right: (@gutter / 2);\n\n @media (min-width: @screen-lg-min) {\n float: left;\n width: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-offset(@columns) {\n @media (min-width: @screen-lg-min) {\n margin-left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-push(@columns) {\n @media (min-width: @screen-lg-min) {\n left: percentage((@columns / @grid-columns));\n }\n}\n.make-lg-column-pull(@columns) {\n @media (min-width: @screen-lg-min) {\n right: percentage((@columns / @grid-columns));\n }\n}\n","// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n // Common styles for all sizes of grid columns, widths 1-12\n .col(@index) when (@index = 1) { // initial\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n position: relative;\n // Prevent columns from collapsing when empty\n min-height: 1px;\n // Inner gutter via padding\n padding-left: (@grid-gutter-width / 2);\n padding-right: (@grid-gutter-width / 2);\n }\n }\n .col(1); // kickstart it\n}\n\n.float-grid-columns(@class) {\n .col(@index) when (@index = 1) { // initial\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), @item);\n }\n .col(@index, @list) when (@index =< @grid-columns) { // general\n @item: ~\".col-@{class}-@{index}\";\n .col((@index + 1), ~\"@{list}, @{item}\");\n }\n .col(@index, @list) when (@index > @grid-columns) { // terminal\n @{list} {\n float: left;\n }\n }\n .col(1); // kickstart it\n}\n\n.calc-grid-column(@index, @class, @type) when (@type = width) and (@index > 0) {\n .col-@{class}-@{index} {\n width: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index > 0) {\n .col-@{class}-push-@{index} {\n left: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = push) and (@index = 0) {\n .col-@{class}-push-0 {\n left: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index > 0) {\n .col-@{class}-pull-@{index} {\n right: percentage((@index / @grid-columns));\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = pull) and (@index = 0) {\n .col-@{class}-pull-0 {\n right: auto;\n }\n}\n.calc-grid-column(@index, @class, @type) when (@type = offset) {\n .col-@{class}-offset-@{index} {\n margin-left: percentage((@index / @grid-columns));\n }\n}\n\n// Basic looping in LESS\n.loop-grid-columns(@index, @class, @type) when (@index >= 0) {\n .calc-grid-column(@index, @class, @type);\n // next iteration\n .loop-grid-columns((@index - 1), @class, @type);\n}\n\n// Create grid for specific class\n.make-grid(@class) {\n .float-grid-columns(@class);\n .loop-grid-columns(@grid-columns, @class, width);\n .loop-grid-columns(@grid-columns, @class, pull);\n .loop-grid-columns(@grid-columns, @class, push);\n .loop-grid-columns(@grid-columns, @class, offset);\n}\n","//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n background-color: @table-bg;\n}\nth {\n text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n width: 100%;\n max-width: 100%;\n margin-bottom: @line-height-computed;\n // Cells\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-cell-padding;\n line-height: @line-height-base;\n vertical-align: top;\n border-top: 1px solid @table-border-color;\n }\n }\n }\n // Bottom align for column headings\n > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid @table-border-color;\n }\n // Remove top border from thead by default\n > caption + thead,\n > colgroup + thead,\n > thead:first-child {\n > tr:first-child {\n > th,\n > td {\n border-top: 0;\n }\n }\n }\n // Account for multiple tbody instances\n > tbody + tbody {\n border-top: 2px solid @table-border-color;\n }\n\n // Nesting\n .table {\n background-color: @body-bg;\n }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n padding: @table-condensed-cell-padding;\n }\n }\n }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n border: 1px solid @table-border-color;\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n border: 1px solid @table-border-color;\n }\n }\n }\n > thead > tr {\n > th,\n > td {\n border-bottom-width: 2px;\n }\n }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n > tbody > tr:nth-child(odd) {\n > td,\n > th {\n background-color: @table-bg-accent;\n }\n }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n > tbody > tr:hover {\n > td,\n > th {\n background-color: @table-bg-hover;\n }\n }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-column;\n}\ntable {\n td,\n th {\n &[class*=\"col-\"] {\n position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n float: none;\n display: table-cell;\n }\n }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(info; @state-info-bg);\n.table-row-variant(warning; @state-warning-bg);\n.table-row-variant(danger; @state-danger-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n.table-responsive {\n @media screen and (max-width: @screen-xs-max) {\n width: 100%;\n margin-bottom: (@line-height-computed * 0.75);\n overflow-y: hidden;\n overflow-x: auto;\n -ms-overflow-style: -ms-autohiding-scrollbar;\n border: 1px solid @table-border-color;\n -webkit-overflow-scrolling: touch;\n\n // Tighten up spacing\n > .table {\n margin-bottom: 0;\n\n // Ensure the content doesn't wrap\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th,\n > td {\n white-space: nowrap;\n }\n }\n }\n }\n\n // Special overrides for the bordered tables\n > .table-bordered {\n border: 0;\n\n // Nuke the appropriate borders so that the parent can handle them\n > thead,\n > tbody,\n > tfoot {\n > tr {\n > th:first-child,\n > td:first-child {\n border-left: 0;\n }\n > th:last-child,\n > td:last-child {\n border-right: 0;\n }\n }\n }\n\n // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n // chances are there will be only one `tr` in a `thead` and that would\n // remove the border altogether.\n > tbody,\n > tfoot {\n > tr:last-child {\n > th,\n > td {\n border-bottom: 0;\n }\n }\n }\n\n }\n }\n}\n","// Tables\n\n.table-row-variant(@state; @background) {\n // Exact selectors below required to override `.table-striped` and prevent\n // inheritance to nested tables.\n .table > thead > tr,\n .table > tbody > tr,\n .table > tfoot > tr {\n > td.@{state},\n > th.@{state},\n &.@{state} > td,\n &.@{state} > th {\n background-color: @background;\n }\n }\n\n // Hover states for `.table-hover`\n // Note: this is not available for cells or rows within `thead` or `tfoot`.\n .table-hover > tbody > tr {\n > td.@{state}:hover,\n > th.@{state}:hover,\n &.@{state}:hover > td,\n &:hover > .@{state},\n &.@{state}:hover > th {\n background-color: darken(@background, 5%);\n }\n }\n}\n","//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n padding: 0;\n margin: 0;\n border: 0;\n // Chrome and Firefox set a `min-width: min-content;` on fieldsets,\n // so we reset that to ensure it behaves more like a standard block element.\n // See https://github.com/twbs/bootstrap/issues/12359.\n min-width: 0;\n}\n\nlegend {\n display: block;\n width: 100%;\n padding: 0;\n margin-bottom: @line-height-computed;\n font-size: (@font-size-base * 1.5);\n line-height: inherit;\n color: @legend-color;\n border: 0;\n border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n display: inline-block;\n max-width: 100%; // Force IE8 to wrap long content (see https://github.com/twbs/bootstrap/issues/13141)\n margin-bottom: 5px;\n font-weight: bold;\n}\n\n\n// Normalize form controls\n//\n// While most of our form styles require extra classes, some basic normalization\n// is required to ensure optimum display with or without those classes to better\n// address browser inconsistencies.\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n margin: 4px 0 0;\n margin-top: 1px \\9; // IE8-9\n line-height: normal;\n}\n\n// Set the height of file controls to match text inputs\ninput[type=\"file\"] {\n display: block;\n}\n\n// Make range inputs behave like textual form controls\ninput[type=\"range\"] {\n display: block;\n width: 100%;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n height: auto;\n}\n\n// Focus for file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n .tab-focus();\n}\n\n// Adjust output element\noutput {\n display: block;\n padding-top: (@padding-base-vertical + 1);\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n display: block;\n width: 100%;\n height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n padding: @padding-base-vertical @padding-base-horizontal;\n font-size: @font-size-base;\n line-height: @line-height-base;\n color: @input-color;\n background-color: @input-bg;\n background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n border: 1px solid @input-border;\n border-radius: @input-border-radius;\n .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n // Customize the `:focus` state to imitate native WebKit styles.\n .form-control-focus();\n\n // Placeholder\n .placeholder();\n\n // Disabled and read-only inputs\n //\n // HTML5 says that controls under a fieldset > legend:first-child won't be\n // disabled if the fieldset is disabled. Due to implementation difficulty, we\n // don't honor that edge case; we style them as disabled anyway.\n &[disabled],\n &[readonly],\n fieldset[disabled] & {\n cursor: not-allowed;\n background-color: @input-bg-disabled;\n opacity: 1; // iOS fix for unreadable disabled content\n }\n\n // Reset height for `textarea`s\n textarea& {\n height: auto;\n }\n}\n\n\n// Search inputs in iOS\n//\n// This overrides the extra rounded corners on search inputs in iOS so that our\n// `.form-control` class can properly style them. Note that this cannot simply\n// be added to `.form-control` as it's not specific enough. For details, see\n// https://github.com/twbs/bootstrap/issues/11586.\n\ninput[type=\"search\"] {\n -webkit-appearance: none;\n}\n\n\n// Special styles for iOS temporal inputs\n//\n// In Mobile Safari, setting `display: block` on temporal inputs causes the\n// text within the input to become vertically misaligned.\n// As a workaround, we set a pixel line-height that matches the\n// given height of the input. Since this fucks up everything else, we have to\n// appropriately reset it for Internet Explorer and the size variations.\n\ninput[type=\"date\"],\ninput[type=\"time\"],\ninput[type=\"datetime-local\"],\ninput[type=\"month\"] {\n line-height: @input-height-base;\n // IE8+ misaligns the text within date inputs, so we reset\n line-height: @line-height-base ~\"\\0\";\n\n &.input-sm {\n line-height: @input-height-small;\n }\n &.input-lg {\n line-height: @input-height-large;\n }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n margin-bottom: 15px;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n position: relative;\n display: block;\n min-height: @line-height-computed; // clear the floating input if there is no label text\n margin-top: 10px;\n margin-bottom: 10px;\n\n label {\n padding-left: 20px;\n margin-bottom: 0;\n font-weight: normal;\n cursor: pointer;\n }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n position: absolute;\n margin-left: -20px;\n margin-top: 4px \\9;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n display: inline-block;\n padding-left: 20px;\n margin-bottom: 0;\n vertical-align: middle;\n font-weight: normal;\n cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n margin-top: 0;\n margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n// Some special care is needed because