From 998d011cd308d2d959ccab1e5b8ea92cc732616f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Wed, 9 Oct 2013 15:40:23 +0200 Subject: [PATCH 0001/2686] Initial commit --- db/fic2014.sql | 100 + htdocs/.onyx | 1 + htdocs/index.php | 174 + onyx/ban.list | 0 onyx/cache/templates/cache/cache | 0 onyx/cache/templates/compile/compile | 0 onyx/config/sample.root.xml | 60 + onyx/db/sample.profile.php | 10 + onyx/include/common.php | 28 + onyx/include/functions.php | 96 + onyx/lang/en.xml | 5 + onyx/lang/fr/contact.json | 1 + onyx/lang/fr/erreurs.json | 1 + onyx/lang/fr/global.json | 1 + onyx/lang/fr/publication.json | 1 + onyx/lang/fr/register.json | 1 + onyx/lang/fr/tickets.json | 1 + onyx/lang/fr/userinfos.json | 1 + onyx/load.php | 167 + onyx/log/php.log | 0 onyx/modules/bbcode/main.php | 60 + onyx/modules/captcha/fonts/0.ttfdd | Bin 0 -> 24216 bytes onyx/modules/captcha/fonts/1.ttf | Bin 0 -> 69380 bytes onyx/modules/captcha/main.php | 121 + onyx/modules/captcha/mots.list | 3834 +++++++++++++++++ onyx/modules/chconfig/__config.class.php | 28 + onyx/modules/chconfig/chconfig.class.php | 110 + onyx/modules/chconfig/chmodules.class.php | 57 + onyx/modules/chconfig/main.php | 65 + onyx/modules/db/main.php | 28 + onyx/modules/db/mysql.class.php | 171 + onyx/modules/db/postgresql.class.php | 169 + onyx/modules/lang/main.php | 96 + onyx/modules/mail/class.phpmailer.php | 2320 ++++++++++ onyx/modules/mail/class.pop3.php | 407 ++ onyx/modules/mail/class.smtp.php | 814 ++++ .../mail/language/phpmailer.lang-ar.php | 26 + .../mail/language/phpmailer.lang-br.php | 23 + .../mail/language/phpmailer.lang-ca.php | 24 + .../mail/language/phpmailer.lang-ch.php | 24 + .../mail/language/phpmailer.lang-cz.php | 23 + .../mail/language/phpmailer.lang-de.php | 24 + .../mail/language/phpmailer.lang-dk.php | 23 + .../mail/language/phpmailer.lang-en.php | 23 + .../mail/language/phpmailer.lang-es.php | 23 + .../mail/language/phpmailer.lang-et.php | 24 + .../mail/language/phpmailer.lang-fi.php | 24 + .../mail/language/phpmailer.lang-fo.php | 25 + .../mail/language/phpmailer.lang-fr.php | 23 + .../mail/language/phpmailer.lang-hu.php | 23 + .../mail/language/phpmailer.lang-it.php | 26 + .../mail/language/phpmailer.lang-ja.php | 24 + .../mail/language/phpmailer.lang-nl.php | 23 + .../mail/language/phpmailer.lang-no.php | 23 + .../mail/language/phpmailer.lang-pl.php | 23 + .../mail/language/phpmailer.lang-ro.php | 24 + .../mail/language/phpmailer.lang-ru.php | 23 + .../mail/language/phpmailer.lang-se.php | 23 + .../mail/language/phpmailer.lang-tr.php | 24 + .../mail/language/phpmailer.lang-zh.php | 23 + .../mail/language/phpmailer.lang-zh_cn.php | 24 + onyx/modules/mail/main.php | 38 + onyx/modules/modules.xml | 93 + onyx/modules/pistage/main.php | 34 + onyx/modules/session/main.php | 20 + onyx/modules/session/mysql.class.php | 161 + onyx/modules/session/postgresql.class.php | 153 + onyx/modules/templates/config/config | 0 onyx/modules/templates/main.php | 29 + .../modules/templates/smarty/Smarty.class.php | 1520 +++++++ .../templates/smarty/SmartyBC.class.php | 460 ++ onyx/modules/templates/smarty/debug.tpl | 133 + .../templates/smarty/plugins/block.php.php | 27 + .../smarty/plugins/block.textformat.php | 113 + .../smarty/plugins/function.counter.php | 78 + .../smarty/plugins/function.cycle.php | 106 + .../smarty/plugins/function.fetch.php | 214 + .../plugins/function.html_checkboxes.php | 216 + .../smarty/plugins/function.html_image.php | 159 + .../smarty/plugins/function.html_options.php | 176 + .../smarty/plugins/function.html_radios.php | 200 + .../plugins/function.html_select_date.php | 394 ++ .../plugins/function.html_select_time.php | 366 ++ .../smarty/plugins/function.html_table.php | 177 + .../smarty/plugins/function.mailto.php | 152 + .../smarty/plugins/function.math.php | 87 + .../smarty/plugins/function.popup.php | 118 + .../smarty/plugins/function.popup_init.php | 38 + .../smarty/plugins/function.text.php | 33 + .../smarty/plugins/modifier.capitalize.php | 65 + .../templates/smarty/plugins/modifier.cat.php | 31 + .../plugins/modifier.count_characters.php | 29 + .../plugins/modifier.count_paragraphs.php | 26 + .../plugins/modifier.count_sentences.php | 27 + .../smarty/plugins/modifier.count_words.php | 25 + .../smarty/plugins/modifier.countdown.php | 33 + .../smarty/plugins/modifier.date_format.php | 65 + .../plugins/modifier.debug_print_var.php | 105 + .../smarty/plugins/modifier.default.php | 29 + .../smarty/plugins/modifier.download.php | 26 + .../smarty/plugins/modifier.ereg.php | 30 + .../smarty/plugins/modifier.escape.php | 188 + .../smarty/plugins/modifier.exploderes.php | 32 + .../smarty/plugins/modifier.gravatar.php | 29 + .../smarty/plugins/modifier.indent.php | 28 + .../smarty/plugins/modifier.lower.php | 30 + .../smarty/plugins/modifier.nl2br.php | 35 + .../templates/smarty/plugins/modifier.nom.php | 30 + .../smarty/plugins/modifier.noprint.php | 24 + .../smarty/plugins/modifier.regex_replace.php | 55 + .../smarty/plugins/modifier.replace.php | 33 + .../smarty/plugins/modifier.separenombre.php | 29 + .../plugins/modifier.separerNombres.php | 28 + .../plugins/modifier.separernombres.php | 28 + .../smarty/plugins/modifier.spacify.php | 27 + .../smarty/plugins/modifier.splitwords.php | 38 + .../smarty/plugins/modifier.sprintf.php | 43 + .../smarty/plugins/modifier.status.php | 106 + .../smarty/plugins/modifier.string_format.php | 27 + .../smarty/plugins/modifier.strip.php | 31 + .../smarty/plugins/modifier.strip_tags.php | 31 + .../smarty/plugins/modifier.temps.php | 45 + .../smarty/plugins/modifier.translatedate.php | 19 + .../smarty/plugins/modifier.truncate.php | 59 + .../smarty/plugins/modifier.txtcateg.php | 26 + .../smarty/plugins/modifier.ucfirst.php | 27 + .../smarty/plugins/modifier.upper.php | 30 + .../templates/smarty/plugins/modifier.url.php | 48 + .../smarty/plugins/modifier.wordwrap.php | 29 + .../smarty/plugins/modifiercompiler.cat.php | 30 + .../modifiercompiler.count_characters.php | 33 + .../modifiercompiler.count_paragraphs.php | 28 + .../modifiercompiler.count_sentences.php | 28 + .../plugins/modifiercompiler.count_words.php | 32 + .../plugins/modifiercompiler.default.php | 35 + .../plugins/modifiercompiler.escape.php | 125 + .../plugins/modifiercompiler.from_charset.php | 34 + .../plugins/modifiercompiler.indent.php | 32 + .../smarty/plugins/modifiercompiler.lower.php | 31 + .../plugins/modifiercompiler.noprint.php | 25 + .../modifiercompiler.string_format.php | 26 + .../smarty/plugins/modifiercompiler.strip.php | 33 + .../plugins/modifiercompiler.strip_tags.php | 33 + .../plugins/modifiercompiler.to_charset.php | 34 + .../plugins/modifiercompiler.unescape.php | 51 + .../smarty/plugins/modifiercompiler.upper.php | 30 + .../plugins/modifiercompiler.wordwrap.php | 46 + .../plugins/outputfilter.trimwhitespace.php | 94 + .../plugins/shared.escape_special_chars.php | 51 + .../plugins/shared.literal_compiler_param.php | 33 + .../smarty/plugins/shared.make_timestamp.php | 42 + .../smarty/plugins/shared.mb_str_replace.php | 55 + .../smarty/plugins/shared.mb_unicode.php | 48 + .../smarty/plugins/shared.mb_wordwrap.php | 83 + .../variablefilter.htmlspecialchars.php | 21 + .../sysplugins/smarty_cacheresource.php | 381 ++ .../smarty_cacheresource_custom.php | 237 + .../smarty_cacheresource_keyvaluestore.php | 463 ++ .../sysplugins/smarty_config_source.php | 95 + .../smarty_internal_cacheresource_file.php | 266 ++ .../smarty_internal_compile_append.php | 53 + .../smarty_internal_compile_assign.php | 88 + .../smarty_internal_compile_block.php | 277 ++ .../smarty_internal_compile_break.php | 77 + .../smarty_internal_compile_call.php | 130 + .../smarty_internal_compile_capture.php | 98 + .../smarty_internal_compile_config_load.php | 85 + .../smarty_internal_compile_continue.php | 78 + .../smarty_internal_compile_debug.php | 43 + .../smarty_internal_compile_eval.php | 73 + .../smarty_internal_compile_extends.php | 133 + .../smarty_internal_compile_for.php | 151 + .../smarty_internal_compile_foreach.php | 231 + .../smarty_internal_compile_function.php | 165 + .../sysplugins/smarty_internal_compile_if.php | 207 + .../smarty_internal_compile_include.php | 215 + .../smarty_internal_compile_include_php.php | 108 + .../smarty_internal_compile_insert.php | 142 + .../smarty_internal_compile_ldelim.php | 41 + .../smarty_internal_compile_nocache.php | 73 + ..._internal_compile_private_block_plugin.php | 87 + ...ternal_compile_private_function_plugin.php | 73 + ...arty_internal_compile_private_modifier.php | 140 + ..._compile_private_object_block_function.php | 88 + ...ternal_compile_private_object_function.php | 79 + ...ernal_compile_private_print_expression.php | 156 + ...ernal_compile_private_registered_block.php | 113 + ...al_compile_private_registered_function.php | 81 + ...ernal_compile_private_special_variable.php | 111 + .../smarty_internal_compile_rdelim.php | 41 + .../smarty_internal_compile_section.php | 203 + .../smarty_internal_compile_setfilter.php | 72 + .../smarty_internal_compile_while.php | 94 + .../smarty_internal_compilebase.php | 176 + .../sysplugins/smarty_internal_config.php | 302 ++ .../smarty_internal_config_file_compiler.php | 144 + .../smarty_internal_configfilelexer.php | 622 +++ .../smarty_internal_configfileparser.php | 921 ++++ .../sysplugins/smarty_internal_data.php | 551 +++ .../sysplugins/smarty_internal_debug.php | 206 + .../sysplugins/smarty_internal_filter.php | 89 + .../smarty_internal_filter_handler.php | 70 + .../smarty_internal_function_call_handler.php | 55 + .../smarty_internal_get_include_path.php | 48 + .../smarty_internal_nocache_insert.php | 53 + .../sysplugins/smarty_internal_parsetree.php | 395 ++ .../sysplugins/smarty_internal_register.php | 156 + .../smarty_internal_resource_eval.php | 94 + .../smarty_internal_resource_extends.php | 162 + .../smarty_internal_resource_file.php | 90 + .../smarty_internal_resource_php.php | 114 + .../smarty_internal_resource_registered.php | 95 + .../smarty_internal_resource_stream.php | 76 + .../smarty_internal_resource_string.php | 96 + ...smarty_internal_smartytemplatecompiler.php | 127 + .../sysplugins/smarty_internal_template.php | 692 +++ .../smarty_internal_templatebase.php | 811 ++++ .../smarty_internal_templatecompilerbase.php | 662 +++ .../smarty_internal_templatelexer.php | 1203 ++++++ .../smarty_internal_templateparser.php | 3254 ++++++++++++++ .../sysplugins/smarty_internal_utility.php | 830 ++++ .../sysplugins/smarty_internal_wrapper.php | 131 + .../sysplugins/smarty_internal_write_file.php | 88 + .../smarty/sysplugins/smarty_resource.php | 857 ++++ .../sysplugins/smarty_resource_custom.php | 96 + .../sysplugins/smarty_resource_recompiled.php | 36 + .../sysplugins/smarty_resource_uncompiled.php | 44 + .../smarty/sysplugins/smarty_security.php | 459 ++ onyx/require/cache.php | 35 + onyx/require/env.php | 49 + onyx/require/parse.php | 73 + onyx/require/str.php | 109 + onyx/tpl/bootstrap/bootstrap | 0 233 files changed, 36893 insertions(+) create mode 100644 db/fic2014.sql create mode 100644 htdocs/.onyx create mode 100644 htdocs/index.php create mode 100644 onyx/ban.list create mode 100644 onyx/cache/templates/cache/cache create mode 100644 onyx/cache/templates/compile/compile create mode 100644 onyx/config/sample.root.xml create mode 100644 onyx/db/sample.profile.php create mode 100644 onyx/include/common.php create mode 100644 onyx/include/functions.php create mode 100644 onyx/lang/en.xml create mode 100644 onyx/lang/fr/contact.json create mode 100644 onyx/lang/fr/erreurs.json create mode 100644 onyx/lang/fr/global.json create mode 100644 onyx/lang/fr/publication.json create mode 100644 onyx/lang/fr/register.json create mode 100644 onyx/lang/fr/tickets.json create mode 100644 onyx/lang/fr/userinfos.json create mode 100644 onyx/load.php create mode 100644 onyx/log/php.log create mode 100644 onyx/modules/bbcode/main.php create mode 100644 onyx/modules/captcha/fonts/0.ttfdd create mode 100644 onyx/modules/captcha/fonts/1.ttf create mode 100644 onyx/modules/captcha/main.php create mode 100755 onyx/modules/captcha/mots.list create mode 100644 onyx/modules/chconfig/__config.class.php create mode 100644 onyx/modules/chconfig/chconfig.class.php create mode 100644 onyx/modules/chconfig/chmodules.class.php create mode 100644 onyx/modules/chconfig/main.php create mode 100644 onyx/modules/db/main.php create mode 100644 onyx/modules/db/mysql.class.php create mode 100644 onyx/modules/db/postgresql.class.php create mode 100644 onyx/modules/lang/main.php create mode 100644 onyx/modules/mail/class.phpmailer.php create mode 100644 onyx/modules/mail/class.pop3.php create mode 100644 onyx/modules/mail/class.smtp.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-ar.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-br.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-ca.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-ch.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-cz.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-de.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-dk.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-en.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-es.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-et.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-fi.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-fo.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-fr.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-hu.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-it.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-ja.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-nl.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-no.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-pl.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-ro.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-ru.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-se.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-tr.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-zh.php create mode 100644 onyx/modules/mail/language/phpmailer.lang-zh_cn.php create mode 100644 onyx/modules/mail/main.php create mode 100644 onyx/modules/modules.xml create mode 100644 onyx/modules/pistage/main.php create mode 100644 onyx/modules/session/main.php create mode 100644 onyx/modules/session/mysql.class.php create mode 100644 onyx/modules/session/postgresql.class.php create mode 100644 onyx/modules/templates/config/config create mode 100644 onyx/modules/templates/main.php create mode 100644 onyx/modules/templates/smarty/Smarty.class.php create mode 100644 onyx/modules/templates/smarty/SmartyBC.class.php create mode 100644 onyx/modules/templates/smarty/debug.tpl create mode 100644 onyx/modules/templates/smarty/plugins/block.php.php create mode 100644 onyx/modules/templates/smarty/plugins/block.textformat.php create mode 100644 onyx/modules/templates/smarty/plugins/function.counter.php create mode 100644 onyx/modules/templates/smarty/plugins/function.cycle.php create mode 100644 onyx/modules/templates/smarty/plugins/function.fetch.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_checkboxes.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_image.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_options.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_radios.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_select_date.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_select_time.php create mode 100644 onyx/modules/templates/smarty/plugins/function.html_table.php create mode 100644 onyx/modules/templates/smarty/plugins/function.mailto.php create mode 100644 onyx/modules/templates/smarty/plugins/function.math.php create mode 100644 onyx/modules/templates/smarty/plugins/function.popup.php create mode 100644 onyx/modules/templates/smarty/plugins/function.popup_init.php create mode 100644 onyx/modules/templates/smarty/plugins/function.text.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.capitalize.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.cat.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.count_characters.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.count_paragraphs.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.count_sentences.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.count_words.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.countdown.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.date_format.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.debug_print_var.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.default.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.download.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.ereg.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.escape.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.exploderes.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.gravatar.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.indent.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.lower.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.nl2br.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.nom.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.noprint.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.regex_replace.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.replace.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.separenombre.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.separerNombres.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.separernombres.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.spacify.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.splitwords.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.sprintf.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.status.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.string_format.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.strip.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.strip_tags.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.temps.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.translatedate.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.truncate.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.txtcateg.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.ucfirst.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.upper.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.url.php create mode 100644 onyx/modules/templates/smarty/plugins/modifier.wordwrap.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.cat.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.count_characters.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.count_paragraphs.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.count_sentences.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.count_words.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.default.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.escape.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.from_charset.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.indent.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.lower.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.noprint.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.string_format.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.strip.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.strip_tags.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.to_charset.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.unescape.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.upper.php create mode 100644 onyx/modules/templates/smarty/plugins/modifiercompiler.wordwrap.php create mode 100644 onyx/modules/templates/smarty/plugins/outputfilter.trimwhitespace.php create mode 100644 onyx/modules/templates/smarty/plugins/shared.escape_special_chars.php create mode 100644 onyx/modules/templates/smarty/plugins/shared.literal_compiler_param.php create mode 100644 onyx/modules/templates/smarty/plugins/shared.make_timestamp.php create mode 100644 onyx/modules/templates/smarty/plugins/shared.mb_str_replace.php create mode 100644 onyx/modules/templates/smarty/plugins/shared.mb_unicode.php create mode 100644 onyx/modules/templates/smarty/plugins/shared.mb_wordwrap.php create mode 100644 onyx/modules/templates/smarty/plugins/variablefilter.htmlspecialchars.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_cacheresource.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_cacheresource_custom.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_cacheresource_keyvaluestore.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_config_source.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_cacheresource_file.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_append.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_assign.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_block.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_break.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_call.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_capture.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_config_load.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_continue.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_debug.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_eval.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_extends.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_for.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_foreach.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_function.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_if.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_include.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_include_php.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_insert.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_ldelim.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_nocache.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_block_plugin.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_function_plugin.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_modifier.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_object_block_function.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_object_function.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_print_expression.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_registered_block.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_registered_function.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_private_special_variable.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_rdelim.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_section.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_setfilter.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compile_while.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_compilebase.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_config.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_config_file_compiler.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_configfilelexer.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_configfileparser.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_data.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_debug.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_filter.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_filter_handler.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_function_call_handler.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_get_include_path.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_nocache_insert.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_parsetree.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_register.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_eval.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_extends.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_file.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_php.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_registered.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_stream.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_resource_string.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_smartytemplatecompiler.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_template.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_templatebase.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_templatecompilerbase.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_templatelexer.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_templateparser.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_utility.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_wrapper.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_internal_write_file.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_resource.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_resource_custom.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_resource_recompiled.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_resource_uncompiled.php create mode 100644 onyx/modules/templates/smarty/sysplugins/smarty_security.php create mode 100644 onyx/require/cache.php create mode 100644 onyx/require/env.php create mode 100644 onyx/require/parse.php create mode 100644 onyx/require/str.php create mode 100644 onyx/tpl/bootstrap/bootstrap diff --git a/db/fic2014.sql b/db/fic2014.sql new file mode 100644 index 00000000..38d9e326 --- /dev/null +++ b/db/fic2014.sql @@ -0,0 +1,100 @@ +-- phpMyAdmin SQL Dump +-- version 3.5.1 +-- http://www.phpmyadmin.net +-- +-- Host: localhost +-- Generation Time: Oct 09, 2013 at 03:38 PM +-- Server version: 5.5.32-log +-- PHP Version: 5.4.9--pl0-gentoo + +SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + +-- +-- Database: `fic2014` +-- + +-- -------------------------------------------------------- + +-- +-- Table structure for table `exercices` +-- + +CREATE TABLE IF NOT EXISTS `exercices` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id_theme` int(10) unsigned NOT NULL, + `name` varchar(255) COLLATE utf16_unicode_ci NOT NULL, + `difficulty` tinyint(3) unsigned NOT NULL, + `points` smallint(6) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `exercice_dependancies` +-- + +CREATE TABLE IF NOT EXISTS `exercice_dependancies` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id_exercice` int(10) unsigned NOT NULL, + `id_dependence` int(10) unsigned NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `sessions` +-- + +CREATE TABLE IF NOT EXISTS `sessions` ( + `session` binary(32) NOT NULL, + `uid` binary(16) NOT NULL, + `time` int(11) NOT NULL, + `ip` varbinary(16) NOT NULL, + `var` varchar(9999) COLLATE utf8_unicode_ci NOT NULL, + `level` tinyint(2) NOT NULL, + `active` enum('1','0') COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`session`) +) ENGINE=MEMORY DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `solved` +-- + +CREATE TABLE IF NOT EXISTS `solved` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id_user` int(10) unsigned NOT NULL, + `id_exercice` int(10) unsigned NOT NULL, + `time` datetime NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `themes` +-- + +CREATE TABLE IF NOT EXISTS `themes` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) COLLATE utf16_unicode_ci NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `users` +-- + +CREATE TABLE IF NOT EXISTS `users` ( + `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `username` varchar(255) COLLATE utf16_unicode_ci NOT NULL, + `password` binary(64) NOT NULL, + `auth_level` tinyint(1) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=1 ; diff --git a/htdocs/.onyx b/htdocs/.onyx new file mode 100644 index 00000000..9e6e10a7 --- /dev/null +++ b/htdocs/.onyx @@ -0,0 +1 @@ +../onyx/load.php diff --git a/htdocs/index.php b/htdocs/index.php new file mode 100644 index 00000000..ebe38cc3 --- /dev/null +++ b/htdocs/index.php @@ -0,0 +1,174 @@ +level > 0) +{ + if ($SESS->level&1) + { + switch($p) + { + case "adm_users": + include("admin/users.php"); + break; + } + } + + if ($SESS->level&2) + { + switch($p) + { + case "articles": + include("articles/articles.php"); + break; + + case "articles_prod": + include("articles/production.php"); + break; + } + } + + if ($SESS->level&4) + { + switch($p) + { + case "palettes": + include("articles/palettes.php"); + break; + + case "palettes_besoins": + include("articles/needs.php"); + break; + + case "prod_couts": + include("production/costs.php"); + break; + + case "stocks_besoins": + include("materials/needs.php"); + break; + + case "stocks_etat": + include("materials/etat.php"); + break; + + case "transport": + include("materials/transport.php"); + break; + } + } + + if ($SESS->level&16) + { + switch($p) + { + case "commandes": + include("materials/commandes.php"); + break; + + case "stocks_besoins": + include("materials/needs.php"); + break; + + case "transport": + include("materials/transport.php"); + break; + } + } + + if ($SESS->level&8) + { + switch($p) + { + case "prod_resume": + include("articles/needs.php"); + break; + + case "prod_entry": + include("production/entry.php"); + break; + } + } + + switch($p) + { + case "": + $_GET["p"] = ""; + case "accueil": + include("users/accueil.php"); + break; + + case "disconnect": + include("public/login.php"); + break; + } +} + +if (empty($page)) // Public pages +{ + switch($p) + { + case "": + $_GET["p"] = ""; + case "login": + include("public/login.php"); + break; + + case "forgotpasswd": + include("public/forgotpasswd.php"); + break; + + case "403": + $template->assign("err", 403); + $page = "404"; + break; + case "404": + $template->assign("err", 404); + $page = "404"; + break; + case "5mail": + include("mail.php"); + exit; + case "500": + $template->assign("err", 500); + $page = "404"; + break; + } +} + +if (empty($page)) +{ + $template->assign("err", 404); + $template->display("404.tpl"); +} +else +{ + $ALERTS = array(); + $nbAlert = @count($SESS->values["alerts"]); + if ($nbAlert > 0) + { + for ($i = 0; $i < $nbAlert; $i++) + { + if ($SESS->values["alerts"][$i]->page == $page) + { + $ALERTS[] = $SESS->values["alerts"][$i]; + unset($SESS->values["alerts"][$i]); + $i--; $nbAlert--; + $SESS->values["alerts"] = array_values($SESS->values["alerts"]); + } + } + $SESS->put(); + } + $template->assign("ALERTS", $ALERTS); + + $template->display($page.".tpl"); +} diff --git a/onyx/ban.list b/onyx/ban.list new file mode 100644 index 00000000..e69de29b diff --git a/onyx/cache/templates/cache/cache b/onyx/cache/templates/cache/cache new file mode 100644 index 00000000..e69de29b diff --git a/onyx/cache/templates/compile/compile b/onyx/cache/templates/compile/compile new file mode 100644 index 00000000..e69de29b diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml new file mode 100644 index 00000000..61d79f2e --- /dev/null +++ b/onyx/config/sample.root.xml @@ -0,0 +1,60 @@ + + + + ]]> + + + 0 + 1 + 6143 + Europe/Paris + + text/html;charset=utf-8 + + + 0 + 0 + 1 + 1 + 0 + 0 + 64M + 1 + + 1 + + fr_FR.UTF8 + fr.UTF8 + fr_FR.UTF-8 + fr.UTF-8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/onyx/db/sample.profile.php b/onyx/db/sample.profile.php new file mode 100644 index 00000000..1ad73643 --- /dev/null +++ b/onyx/db/sample.profile.php @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/onyx/include/common.php b/onyx/include/common.php new file mode 100644 index 00000000..05d87757 --- /dev/null +++ b/onyx/include/common.php @@ -0,0 +1,28 @@ +values["connected"]) && !defined("xCSRF")) + define("xCSRF", true); + +require_once("functions.php"); //Inclusion des principales fonctions + +//On charge la session +$SESS = new Session(); + +$template = new Template(); + +$template->assign("ERRmessage", false); +$template->assign("auth_lvl", $SESS->level); +$template->assign("SESS", $SESS->values); + +if (!empty($LANG)) + $template->assign("LANG", $LANG); + +//Evite les attaques CSRF +if ($SESS->level > 2 && !empty($_SERVER["HTTP_REFERER"]) && !(preg_match('#^http://'.$_SERVER['HTTP_HOST'].'#', $_SERVER["HTTP_REFERER"]) && defined("xCSRF"))) +{ + elog("Possibilité d'attaque CSRF\n".var_export($_REQUEST, TRUE), 2); + unset($_POST, $_GET); + $_GET = $_POST = array(); +} +?> \ No newline at end of file diff --git a/onyx/include/functions.php b/onyx/include/functions.php new file mode 100644 index 00000000..dfdd80f4 --- /dev/null +++ b/onyx/include/functions.php @@ -0,0 +1,96 @@ +AddAddress($to); + $mail->Subject = $subject; + $mail->Body = $body; + + return $mail->Send(); +} + +function erreur($message, $color = "error") +{ + global $template; + + $template->assign('ERRmessage', $message); + $template->assign('ERRcolor', $color); +} + +function format_url($string) +{ + $string = trim($string); + + if ( ctype_digit($string) ) + { + return $string; + } + else + { + // replace accented chars + $accents = '/&([A-Za-z]{1,2})(grave|acute|circ|cedil|uml|lig);/'; + $string_encoded = htmlentities($string,ENT_NOQUOTES,'UTF-8'); + + $string = preg_replace($accents,'$1',$string_encoded); + + // clean out the rest + $replace = array('([\40\'/])','([^a-zA-Z0-9-])','(-{2,})'); + $with = array('-','','-'); + $string = preg_replace($replace,$with,$string); + } + + return strtolower($string); +} + +function pagination($nbPages, $page, $link = "documents-recents-") +{ + $nbPages++; + $cntPages = array(); + if ($nbPages < 10) + { + for ($i = 1 ; $i <= $nbPages ; $i++) + $cntPages[] = $i; + } + else + { + for ($i = 1 ; $i <= 4 ; $i++) + $cntPages[] = $i; + if (6 != max(6, $page)) + $cntPages[] = "..."; + for ($i = max(6, $page) - 1 ; $i < min(max(6, $page) + 3, $nbPages - 2) ; $i++) + $cntPages[] = $i; + if ($nbPages - 2 != max(6, $page) + 3 && $nbPages - 2 != $i) + $cntPages[] = "..."; + for ($i = $nbPages - 2 ; $i <= $nbPages ; $i++) + $cntPages[] = $i; + } + + $out = ""; + foreach($cntPages as $p) + { + if ($p == "...") + $out .= " ... "; + else + $out .= ' '.$p.' '; + } + + return '<<'.$out.'>>'; +} + +function eregmenu($pattern, $string) +{ + return preg_match("#".$pattern."#ui", $string); +} + +?> \ No newline at end of file diff --git a/onyx/lang/en.xml b/onyx/lang/en.xml new file mode 100644 index 00000000..6f95bc53 --- /dev/null +++ b/onyx/lang/en.xml @@ -0,0 +1,5 @@ + + + Hello + Good bye + \ No newline at end of file diff --git a/onyx/lang/fr/contact.json b/onyx/lang/fr/contact.json new file mode 100644 index 00000000..6ee3fe78 --- /dev/null +++ b/onyx/lang/fr/contact.json @@ -0,0 +1 @@ +{"title":"Nous contacter","1":{"reponses":{"2":"Je suis acheteur","3":"Je suis vendeur","4":"Je suis annonceur","5":"Je souhaite signaler une faute d'orthographe ou un bug pr\u00e9sent sur le site"}},"2":{"intitule":"Raison de votre contact","reponses":{"2.1":"Je n'ai pas b\u00e9n\u00e9fici\u00e9 de mon document gratuit apr\u00e8s cinq achats","2.2":"Je n'ai pas re\u00e7u mon document apr\u00e8s paiement","2.3":"Je ne parviens pas \u00e0 me connecter \u00e0 mon compte","form2.4":"Je me suis fais voler mon compte","2.5":"Je n'arrive pas \u00e0 lire le document que j'ai achet\u00e9","2.6":"Autre"}},"2.1":{"intitule":"Si vous avez achet\u00e9 cinq documents sur Discis, nous vous offrons un document d'une valeur de 1,80 euros. Seuls les documents de cette valeur vous seront accessibles gratuitements apr\u00e8s l'achat de cinq documents.
\nPour b\u00e9n\u00e9ficier de cette offre, connectez-vous \u00e0 votre compte puis allez sur la page du document que vous souhaitez acqu\u00e9rir, celui-ci sera disponible gratuitement !\nNous ne faisons pas de remise sur les documents sup\u00e9rieurs \u00e0 1,80euros.","reponses":{"0":"Retourner \u00e0 l'accueil","2.1.1":"Apr\u00e8s avoir effectu\u00e9 les manipulations d\u00e9crites ci-dessus, je n'ai toujours pas obtenu mon document gratuit"}},"2.1.1":{"intitule":"Pour comptabiliser vos diff\u00e9rents achats, il est n\u00e9cessaire que vous poss\u00e9diez un compte et que vous y soyez connect\u00e9s lors de l'achat des documents.
Nous ne pouvons rien faire dans le cas contraire.
Si vous ne poss\u00e8dez pas de compte, vous ne pouvez malheuresement pas b\u00e9n\u00e9ficier de notre programme de fid\u00e9lit\u00e9.","reponses":{"0":"Retourner \u00e0 l'acceuil","form2.1.1.1":"Je poss\u00e8de un compte Discis et j'\u00e9tais connect\u00e9 lors de l'achat de mes documents"}},"2.3":{"intitule":"Si vous ne parvenez pas \u00e0 vous connecter \u00e0 votre compte, v\u00e9rifiez tout d'abord que ce probl\u00e8me n'est pas d'ordre g\u00e9n\u00e9ral en consultant notre blog des d\u00e9veloppeurs dans la rubrique probl\u00e8mes techniques.","reponses":{"0":"Retourner \u00e0 l'accueil","2.3.1":"Aucun probl\u00e8me n'est signal\u00e9 concernant les connections aux comptes utilisateurs sur le blog des d\u00e9veloppeurs"}},"2.3.1":{"intitule":"Vous pouvez r\u00e9cup\u00e9rer votre mot de pass en cliquant sur le lien \"mot de pass oubli\u00e9\" en dessous du formulaire de connection du compte. Un mail vous sera alors envoy\u00e9 sur l'adresse que vous nous avez fourni lors de votre inscription.","reponses":{"0":"Retourner \u00e0 l'accueil","2.5.1":"Je n'arrive pas \u00e0 utiliser 7-zip","form2.5.2":"Le fichier est illisibe et semble corrompu"}},"form2.4":["test","test2"],"3":{"intitule":"Raison de votre contacte","reponses":{"3.1":"Un de mes documents a \u00e9t\u00e9 plagi\u00e9","3.2":"Mes documents ne sont toujours pas publi\u00e9s","3.3":"Je n'ai toujours pas re\u00e7u mon paiement","3.4":"Je souhaite supprimer un document","3.5":"Je ne parviens pas \u00e0 me connecter \u00e0 mon compte","3.6":"Autre"}},"3.1":{"intitule":"Si vous vous \u00eates rendu compte que certains de vos documents ont \u00e9t\u00e9 plagi\u00e9s sur un site internet tiers, vous pouvez en g\u00e9n\u00e9ral contacter les webmasters du dit site via un formulaire de contact.\n Voici un mod\u00e8le de lettre que vous pouvez soumettre pour faire valoir vos droits :

\n

\nBonjour,

\nJe vous informe que le document [ins\u00e9rez le titre du document] disponible sur votre site internet \u00e0 cette adresse [ins\u00e9rez l'adresse du plagiat] est un document dont je suis l'auteur que j'ai publi\u00e9 sur le site internet discis.fr le [ins\u00e9rer la date de publication de votre document] \u00e0 l'adresse suivante : [ins\u00e9rer l'adresse discis de votre document]. Je vous demande de bien vouloir supprimer ce document plagi\u00e9 de votre base de donn\u00e9e.

\nCordialement<\/p>\nSi vous ne recevez aucune r\u00e9ponse d'ici deux semaines, cliquez sur le bouton ci-dessous.","reponses":{"0":"Retourner \u00e0 l'accueil","form3.1.1":"Le site internet du document plagi\u00e9 n'a pas r\u00e9pondu \u00e0 mon mail"}},"3.2":{"intitule":"Le temps de traitement de vos documents d\u00e9pend du nombre de documents que nous recevons. De plus, afin de garantir la vente de documents de qualit\u00e9s, nous prenons un certain temps \u00e0 lire un \u00e0 un chaque document re\u00e7u et \u00e0 le soumettre \u00e0 notre logiciel anti-plagiat.
Tout ceci prend beaucoup de temps et nous nous excusons par avance pour les d\u00e9lais qui peuvent \u00eatre longs dans certains cas.
Cependant, si votre document a \u00e9t\u00e9 envoy\u00e9 il y a plus d'un mois, il a sans doute \u00e9t\u00e9 \"oubli\u00e9\" par notre comit\u00e9 de lecture.","reponses":{"0":"Retourner \u00e0 l'accueil","form3.2.1":"Aucun probl\u00e8me n'est signal\u00e9 convernant des retards de paiement ce mois-ci sur le blog des d\u00e9veloppeurs"}}} \ No newline at end of file diff --git a/onyx/lang/fr/erreurs.json b/onyx/lang/fr/erreurs.json new file mode 100644 index 00000000..b975bbc0 --- /dev/null +++ b/onyx/lang/fr/erreurs.json @@ -0,0 +1 @@ +{"403":{"title":"Erreur 403","subtitle":"Accès réglementé","content":"Vous n'\u00eates pas autoris\u00e9 \u00e0 acc\u00e9der \u00e0 cette page."},"404":{"title":"Erreur 404","subtitle":"Page introuvable","content":"La page à laquelle vous tentez d'accéder n'existe pas ou l'adresse que vous avez tapée est incorrecte."},"500":{"title":"Erreur 500","subtitle":"Serveur indisponible","content":"Le serveur est actuellement dans l'incapacit\u00e9 de repondre \u00e0 votre requ\u00eate.

Veuillez recommencer plus tard."}} diff --git a/onyx/lang/fr/global.json b/onyx/lang/fr/global.json new file mode 100644 index 00000000..c8a47985 --- /dev/null +++ b/onyx/lang/fr/global.json @@ -0,0 +1 @@ +{"date":"d\/m\/Y \u00e0 H:i","rssfeed":"Flux Atom des nouvelles","forgotpsw":"Mot de passe oubli\u00e9 ...","continue":"Continuer","send":"Envoyer","login":{"connect":"Ok","disconnect":"D\u00e9connexion"},"menu":{"0":{"accueil":"Accueil","publier":"Publier","inscription":"S'inscrire","contact":"Contact"},"1":{"conditions-generales":"Conditions g\u00e9n\u00e9rales"},"2":{"accueil":"Accueil","mon-compte":"Mon compte","statistiques":"Statistiques","":"


","publier":"Publier","mes-documents-publies":"Mes documents publi\u00e9s","mes-documents-en-attente":"Mes documents en attente %s"," ":"
","contact":"Contact"},"4":{"kor-docs-en-correction":"Documents en correction %s","kor-docs-en-attente":"Documents en attente %s"},"6":{"adm-controldocs":"Documents \u00e0 controler %s","kor-docs-en-correction":"Documents en correction %s","kor-docs-en-attente":"Documents en attente %s","":"
","adm-prise-de-controle":"Prendre le controle d'un compte","adm-pubs":"Modifier les publicit\u00e9s","adm-news":"Modifier les news"," ":"
","tickets":"Tickets %s"}},"footer":{"annonceurs":"Annonceurs","conditions-generales":"Conditions g\u00e9n\u00e9rales","plan":"Plan du site"}} \ No newline at end of file diff --git a/onyx/lang/fr/publication.json b/onyx/lang/fr/publication.json new file mode 100644 index 00000000..7251a212 --- /dev/null +++ b/onyx/lang/fr/publication.json @@ -0,0 +1 @@ +{"titre0":"Publication de documents","mails":{"pubOk":{"subject":"[Discis] Publication de votre document","body":"Bonjour,\n\nNous avons le plaisir de vous informer que votre document %s, soumis \u00e0 notre \u00e9quipe le %s, vient d\u2019\u00eatre publi\u00e9 sur Discis.\nVotre document est propos\u00e9 \u00e0 la vente pour %s ; il est disponible \u00e0 cette adresse : http:\/\/www.discis.fr\/document-%s. Si vous d\u00e9sirez apporter des modifications \u00e0 votre document, connectez-vous dans votre espace personnel dans la rubrique \"Mes documents publi\u00e9s\" (http:\/\/www.discis.fr\/mes-documents-publies).\n\nCordialement,"},"pubMod":{"subject":"[Discis] Publication de votre document","body":"Bonjour,\n\nVotre document %s soumis le %s a retenu notre intention. Cependant, nous ne l\u2019avons pas encore publi\u00e9 pour la raison suivante\u00a0:\n\n%s\n\nPour effectuer les modifications n\u00e9cessaires, connectez-vous \u00e0 votre compte \u00e0 la rubrique \"Mes documents en attente\" (http:\/\/www.discis.fr\/mes-documents-en-attente).\n\nCordialement,"},"pubNo":{"subject":"[Discis] Publication de votre document","body":"Bonjour,\n\nNous sommes d\u00e9sol\u00e9 de vous informer que votre document %s soumis le %s ne sera pas publi\u00e9 sur Discis. Le motif est le suivant\u00a0: %s.\n\nNous vous encourageons \u00e0 modifier ce document pour le soumettre \u00e0 nouveau \u00e0 notre \u00e9quipe.\n\nCordialement,"}}} \ No newline at end of file diff --git a/onyx/lang/fr/register.json b/onyx/lang/fr/register.json new file mode 100644 index 00000000..bfa03627 --- /dev/null +++ b/onyx/lang/fr/register.json @@ -0,0 +1 @@ +{"title":"Inscription","helpCaptcha":"Si vous ne parvennez pas \u00e0 voir cette image, contactez un administrateur.","msgOk":"Votre inscription a \u00e9t\u00e9 r\u00e9alis\u00e9e avec succ\u00e8s.
Bienvenue sur Discis !","chPswd":"Votre mot de passe a \u00e9t\u00e9 r\u00e9initialis\u00e9 avec succ\u00e8s.","button":"S'inscrire","err0":"Le nom d'utilisateur comporte des catact\u00e8res invalides ou est trop court ou trop long !","err1":"Veuillez compl\u00e9ter tous les champs","err2":"Le texte que vous avez recopi\u00e9 ne correspond pas au contenu de l'image !","err3":"Le mot de passe et sa conformation sont diff\u00e9rents !","err4":"Le mot de passe est trop court ! Il doit contenir au moins 8 caract\u00e8res.","err5":"L'adresse \u00e9lectronique indiqu\u00e9e ne semble pas valide.","err6":"Le nom d'utilisateur que vous avez choisit existe d\u00e9j\u00e0 ou votre adresse \u00e9lectronique est d\u00e9j\u00e0 associ\u00e9e avec un autre compte.","mail":{"subject":"[Discis] Validation de votre inscription","body":"Soyez le bienvenu sur Discis !\n\nNous vous souhaitons beaucoup de succ\u00e8s avec la vente de vos documents ou la gestion de vos achats. Nous tenons \u00e0 vous informer que nous sommes \u00e0 disposition si vous avez besoin d'aide. Ainsi, vous pouvez nous contacter \u00e0 tout moment via la page contact du site.\n\nMerci de vous \u00eatre enregistr\u00e9,"},"tip":[{"title":"Bienvenue sur Discis !","content":"Votre compte Discis vous permettra de :\n @@ -31,5 +35,8 @@ {$ERRmessage} {/if} + +
{block name=content}{/block} +
{/block} diff --git a/onyx/tpl/bootstrap/public/score.tpl b/onyx/tpl/bootstrap/public/score.tpl index 8c6ef25c..2fea7aee 100644 --- a/onyx/tpl/bootstrap/public/score.tpl +++ b/onyx/tpl/bootstrap/public/score.tpl @@ -1,11 +1,22 @@ {extends file="layout.tpl"} {block name=head} - + {/block} {block name=content} +
+
+
    +
  • 00
  • +
  • :
  • +
  • 00
  • +
  • :
  • +
  • 00
  • +
+
+

TOP #10

@@ -56,7 +67,7 @@

Example

-

This is a example

+

This is a example

This is a example

This is a example

This is a example

@@ -103,8 +114,21 @@ {block name=end} + {/block} From bed471d75a086c7b621a11175286b510e537c7d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Tue, 22 Oct 2013 08:16:02 +0200 Subject: [PATCH 0038/2686] New router and associated pages --- htdocs/index.php | 145 +++++++++--------- nginx.conf | 2 +- onyx/config/sample.root.xml | 12 -- onyx/include/common.php | 15 +- .../common/{User.class.php => Team.class.php} | 0 onyx/include/public/home.php | 17 +- onyx/include/public/team.php | 16 ++ onyx/include/team/change.php | 6 + onyx/include/team/exercice.php | 6 + onyx/include/team/home.php | 8 + onyx/include/team/summary.php | 6 + onyx/include/team/team.php | 16 ++ 12 files changed, 134 insertions(+), 115 deletions(-) rename onyx/include/common/{User.class.php => Team.class.php} (100%) create mode 100644 onyx/include/public/team.php create mode 100644 onyx/include/team/change.php create mode 100644 onyx/include/team/exercice.php create mode 100644 onyx/include/team/home.php create mode 100644 onyx/include/team/summary.php create mode 100644 onyx/include/team/team.php diff --git a/htdocs/index.php b/htdocs/index.php index ad2248b4..fcd65efe 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -2,112 +2,107 @@ //Inclusion de l'API Onyx require_once(trim(file_get_contents('./.onyx'))); +define("SALT_USER", "connected"); +define("SALT_ADMIN", "admin"); + //On active le débogage si l'on est sur le domaine de debug if ($_SERVER["SERVER_NAME"] == "localhost" || $_SERVER["SERVER_NAME"] == "fic" || $_SERVER["SERVER_NAME"] == "atlantis.chen.li") define("DEBUG", true); //Chargement de tout le nécessaire pour le site -require_once("common.php"); +//require_once("common.php"); -$p = strtolower(gpc("p")); +$n = preg_match_all("#[^/]+#", strtolower(gpc("p")), $out); +$p = $out[0]; -if (empty($page) && $SESS->level > 0) +// Admin part +if ($p[0] == SALT_ADMIN) { - if ($SESS->level > 1) + if ($n <= 1) + $page = require("admin/home.php"); + else { - switch($p) + switch($p[1]) { - case "exercices/import/": - case "exercices/import": - include("admin/import_exercices.php"); + case "exercices/import/": + case "exercices/import": + $page = require("admin/import_exercices.php"); break; - case "users": - case "users/": - include("admin/list_users.php"); + case "users": + case "users/": + $page = require("admin/list_users.php"); break; - case "users/import": - case "users/import/": - include("admin/import_users.php"); + case "users/import": + case "users/import/": + $page = require("admin/import_users.php"); break; } } - - switch($p) - { - case "": - $_GET["p"] = ""; - case "accueil": - include("users/accueil.php"); - break; - - case "disconnect": - include("public/login.php"); - break; - } } -if (empty($page)) // Public pages +// Known users +else if ($p[0] == SALT_USER) { - switch($p) + $connected = true; + + if ($n <= 1) + $page = require("team/home.php"); + else { - case "": - $_GET["p"] = ""; - case "home": - include("public/home.php"); - break; + $TEAM = $p[1]; - case "login": - include("public/login.php"); - break; + if ($n <= 2) + $page = require("team/team.php"); + else + { + switch($p[2]) + { + case "change/": + case "change": + $page = require("team/change.php"); + break; - case "score": - include("public/score.php"); - break; + case "summary": + case "summary/": + $page = require("team/summary.php"); + break; + } - case "403": - $template->assign("err", 403); - $page = "404"; - break; - case "404": - $template->assign("err", 404); - $page = "404"; - break; - case "5mail": - include("mail.php"); - exit; - case "500": - $template->assign("err", 500); - $page = "404"; - break; + // SALT/$team/$theme + if (empty($page)) + { + $THEME = $p[2]; + + if ($n == 4) + { + $EXERCICE = $p[3]; + $page = require("team/exercice.php"); + } + } + } } } +// Public part +else +{ + if ($n == 0) + $page = require("public/home.php"); + else if ($n == 1) + { + $TEAM = $p[0]; + + $page = require("public/team.php"); + } +} + +// No page here...? if (empty($page)) { $template->assign("err", 404); $template->display("404.tpl"); } else -{ - $ALERTS = array(); - $nbAlert = @count($SESS->values["alerts"]); - if ($nbAlert > 0) - { - for ($i = 0; $i < $nbAlert; $i++) - { - if ($SESS->values["alerts"][$i]->page == $page) - { - $ALERTS[] = $SESS->values["alerts"][$i]; - unset($SESS->values["alerts"][$i]); - $i--; $nbAlert--; - $SESS->values["alerts"] = array_values($SESS->values["alerts"]); - } - } - $SESS->put(); - } - $template->assign("ALERTS", $ALERTS); - $template->display($page.".tpl"); -} diff --git a/nginx.conf b/nginx.conf index e85f1569..02cc969c 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,6 +1,6 @@ server { listen 80; - listen [::]:80; + listen [::]:80 ipv6only=on; server_name fic fic.p0m.fr fic.nemunai.re; access_log /var/log/nginx/fic.access_log; diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml index 5f3a4696..e6291018 100644 --- a/onyx/config/sample.root.xml +++ b/onyx/config/sample.root.xml @@ -38,16 +38,6 @@ - - - - - - - - - @@ -55,7 +45,5 @@ - - diff --git a/onyx/include/common.php b/onyx/include/common.php index b1397253..6754e327 100644 --- a/onyx/include/common.php +++ b/onyx/include/common.php @@ -7,26 +7,13 @@ if (empty($sess->values["connected"]) && !defined("xCSRF")) require_once("functions.php"); //Inclusion des principales fonctions require_once("common/Exercice.class.php"); +require_once("common/Team.class.php"); require_once("common/Theme.class.php"); -require_once("common/User.class.php"); - -//On charge la session -$SESS = new Session(); $template = new Template(); $template->assign("ERRmessage", false); -$template->assign("auth_lvl", $SESS->level); -$template->assign("SESS", $SESS->values); $template->assign("END", $VAR['end_challenge'] - time()); if (!empty($LANG)) $template->assign("LANG", $LANG); - -//Evite les attaques CSRF -if ($SESS->level > 2 && !empty($_SERVER["HTTP_REFERER"]) && !(preg_match('#^http://'.$_SERVER['HTTP_HOST'].'#', $_SERVER["HTTP_REFERER"]) && defined("xCSRF"))) -{ - elog("Possibilité d'attaque CSRF\n".var_export($_REQUEST, TRUE), 2); - unset($_POST, $_GET); - $_GET = $_POST = array(); -} diff --git a/onyx/include/common/User.class.php b/onyx/include/common/Team.class.php similarity index 100% rename from onyx/include/common/User.class.php rename to onyx/include/common/Team.class.php diff --git a/onyx/include/public/home.php b/onyx/include/public/home.php index 3e8231ad..a1542da3 100644 --- a/onyx/include/public/home.php +++ b/onyx/include/public/home.php @@ -2,16 +2,7 @@ if(!defined('ONYX')) exit; -$t = Team::get_teams(); -foreach ($t as $tt){ - var_dump ($tt->get_username()); -} - -if ($SESS->level < 1) -{ - $page = "public/home"; -} -else -{ - $page = "users/home"; -} +$template->assign("teams", Team::get_teams()); +$template->assign("top", Team::get_top()); + +return "public/home"; diff --git a/onyx/include/public/team.php b/onyx/include/public/team.php new file mode 100644 index 00000000..dfd91661 --- /dev/null +++ b/onyx/include/public/team.php @@ -0,0 +1,16 @@ +assign("team", $team); + + return "public/team"; +} +catch($e) +{ + return "404"; +} diff --git a/onyx/include/team/change.php b/onyx/include/team/change.php new file mode 100644 index 00000000..8a234331 --- /dev/null +++ b/onyx/include/team/change.php @@ -0,0 +1,6 @@ +assign("teams", Team::get_teams()); +$template->assign("top", Team::get_top()); + +return "users/home"; diff --git a/onyx/include/team/summary.php b/onyx/include/team/summary.php new file mode 100644 index 00000000..3ab8aeca --- /dev/null +++ b/onyx/include/team/summary.php @@ -0,0 +1,6 @@ +assign("team", $team); + + return "team/team"; +} +catch($e) +{ + return "404"; +} From 39d5e64ee286c815375754db206eb7f89869d9e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Tue, 22 Oct 2013 08:19:51 +0200 Subject: [PATCH 0039/2686] Hotfix: notice in router --- htdocs/index.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index fcd65efe..57e1f8f3 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -10,13 +10,13 @@ if ($_SERVER["SERVER_NAME"] == "localhost" || $_SERVER["SERVER_NAME"] == "fic" | define("DEBUG", true); //Chargement de tout le nécessaire pour le site -//require_once("common.php"); +require_once("common.php"); $n = preg_match_all("#[^/]+#", strtolower(gpc("p")), $out); $p = $out[0]; // Admin part -if ($p[0] == SALT_ADMIN) +if ($n && $p[0] == SALT_ADMIN) { if ($n <= 1) $page = require("admin/home.php"); @@ -43,7 +43,7 @@ if ($p[0] == SALT_ADMIN) } // Known users -else if ($p[0] == SALT_USER) +else if ($n && $p[0] == SALT_USER) { $connected = true; From 0035b984ff7f4cba56aa7b002704fcc86838c3ce Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Tue, 22 Oct 2013 08:31:12 +0200 Subject: [PATCH 0040/2686] Modify feedfortests.sql to match with new DB --- db/feedfortests.sql | 289 +++++++++++++++++--------------------------- 1 file changed, 112 insertions(+), 177 deletions(-) diff --git a/db/feedfortests.sql b/db/feedfortests.sql index d3d24598..36fbafe2 100644 --- a/db/feedfortests.sql +++ b/db/feedfortests.sql @@ -1,4 +1,69 @@ -INSERT INTO `fic2014`.`themes` ( +INSERT INTO `fic`.`users` ( +`id` , +`username` , +`password` , +`auth_level` , +`firstname` , +`lastname` , +`company` +) +VALUES ( +'1', 'Alpha', '2134s65df423sdf132sdg431dsg', '1', 'Alph', 'A', 'Epitra' +), ( +'2', 'Beta', '2134s65df423sef132sdg431dsg', '1', 'Bet', 'A', 'Epitra' +), ( +'3', 'Charli', '2134s45df423sdf132sdg431dsg', '1', 'Charl', 'I', 'Epitra' +), ( +'4', 'Delta', '2134s65df423sdf131sdg431dsg', '1', 'Delt', 'A', 'Epitra' +), ( +'5', 'Echo', '2134s65df423sdf132sdg431dfg', '1', 'Ech', 'O', 'Epitra' +), ( +'6', 'Foxtrot', '2134s65df423shf132sdg431dsg', '1', 'Fox', 'Trot', 'Epitra' +), ( +'7', 'Golf', '2134s65df423sdf1f2sdg431dsg', '1', 'Gol', 'F', 'Epitra' +), ( +'8', 'Hotel', '2134s65df423sdf13zsdg431dsg', '1', 'Hot', 'El', 'Epitra' +), ( +'9', 'India', '2134s65df423sdf13csdg431dsg', '1', 'Ind', 'Ia', 'Epitra' +), ( +'10', 'Juliet', '2134s65df4q3sdf132sdg431dsg', '1', 'Jule', 'Yer', 'Epitra' +), ( +'11', 'Kevlar', '2134s65df423sdf132s2g431dsg', '1', 'Krev', 'Lard', 'Epitra' +), ( +'12', 'Lambda', '2134s65df423sdf132sdg401dsg', '1', 'Lamb', 'Ada', 'Epitra' +), ( +'13' , 'Mike', '2134s65df423sdf132sdg401dsg', '1', 'Mi', 'Ke', 'Epitra' +), ( +'14' , 'November', '2134s65df423sdf132sdg401dsg', '1', 'Nov', 'Ember', 'Epitra' +), ( +'15' , 'Oscar', '2134s65df423sdf132sdg401dsg', '1', 'Os', 'Car', 'Epitra' +), ( +'16' , 'Papa', '2134s65df423sdf132sdg401dsg', '1', 'Pa', 'Pa', 'Epitra' +), ( +'17' , 'Quebec', '2134s65df423sdf132sdg401dsg', '1', 'Que', 'Bec', 'Epitra' +), ( +'18' , 'Romeo', '2134s65df423sdf132sdg401dsg', '1', 'Rom', 'Eo', 'Epitra' +), ( +'19' , 'Sierra', '2134s65df423sdf132sdg401dsg', '1', 'Sier', 'Ra', 'Epitra' +), ( +'20' , 'Tango', '2134s65df423sdf132sdg401dsg', '1', 'Tan', 'Go', 'Epitra' +), ( +'21' , 'Uniform', '2134s65df423sdf132sdg401dsg', '1', 'Uni', 'Form', 'Epitra' +), ( +'22' , 'Victor', '2134s65df423sdf132sdg401dsg', '1', 'Vic', 'Tor', 'Epitra' +), ( +'23' , 'Whiskey', '2134s65df423sdf132sdg401dsg', '1', 'Whis', 'Key', 'Epitra' +), ( +'24' , 'X-ray', '2134s65df423sdf132sdg401dsg', '1', 'X', 'Rey', 'Epitra' +), ( +'25' , 'Yankee', '2134s65df423sdf132sdg401dsg', '1', 'Yan', 'Kee', 'Epitra' +), ( +'26' , 'Zulu', '2134s65df423sdf132sdg401dsg', '1', 'Zul', 'Lu', 'Epitra' +), ( +'27' , 'Zero', '2134s65df423sdf132sdg401dsg', '1', 'Ze', 'Ro', 'Epitra' +); + +INSERT INTO `fic`.`themes` ( `id` , `filename` ) @@ -20,187 +85,57 @@ VALUES ( '8' , 'pcap.xml' ); -INSERT INTO `fic2014`.`users` ( -`id` , -`username` , -`password` , -`auth_level` -) -VALUES ( -'1' , 'Alpha', UNHEX( '' ) , '1' -), ( -'2' , 'Bravo', UNHEX( '' ) , '1' -), ( -'3' , 'Charlie', UNHEX( '' ) , '1' -), ( -'4' , 'Delta', UNHEX( '' ) , '1' -), ( -'5' , 'Echo', UNHEX( '' ) , '1' -), ( -'6' , 'Foxtrot', UNHEX( '' ) , '1' -), ( -'7' , 'Golf', UNHEX( '' ) , '1' -), ( -'8' , 'Hotel', UNHEX( '' ) , '1' -), ( -'9' , 'India', UNHEX( '' ) , '1' -), ( -'10' , 'Juliet', UNHEX( '' ) , '1' -), ( -'11' , 'Kilo', UNHEX( '' ) , '1' -), ( -'12' , 'Lima', UNHEX( '' ) , '1' -), ( -'13' , 'Mike', UNHEX( '' ) , '1' -), ( -'14' , 'November', UNHEX( '' ) , '1' -), ( -'15' , 'Oscar', UNHEX( '' ) , '1' -), ( -'16' , 'Papa', UNHEX( '' ) , '1' -), ( -'17' , 'Quebec', UNHEX( '' ) , '1' -), ( -'18' , 'Romeo', UNHEX( '' ) , '1' -), ( -'19' , 'Sierra', UNHEX( '' ) , '1' -), ( -'20' , 'Tango', UNHEX( '' ) , '1' -), ( -'21' , 'Uniform', UNHEX( '' ) , '1' -), ( -'22' , 'Victor', UNHEX( '' ) , '1' -), ( -'23' , 'Whiskey', UNHEX( '' ) , '1' -), ( -'24' , 'X-ray', UNHEX( '' ) , '1' -), ( -'25' , 'Yankee', UNHEX( '' ) , '1' -), ( -'26' , 'Zulu', UNHEX( '' ) , '1' -), ( -'27' , 'Zero', UNHEX( '' ) , '1' -); - -INSERT INTO `fic2014`.`exercices` ( +INSERT INTO `fic`.`exercices` ( `id` , `id_theme` , -`points` +`require` , +`level` , +`points` , +`statement` ) VALUES -('1', '1', '1'), -('2', '1', '5'), -('3', '1', '10'), -('4', '1', '20'), -('5', '1', '40'), -('6', '2', '1'), -('7', '2', '5'), -('8', '2', '10'), -('9', '2', '20'), -('10', '2', '40'), -('11', '3', '1'), -('12', '3', '5'), -('13', '3', '10'), -('14', '3', '20'), -('15', '3', '40'), -('16', '4', '1'), -('17', '4', '5'), -('18', '4', '10'), -('19', '4', '20'), -('20', '4', '40'), -('21', '5', '1'), -('22', '5', '5'), -('23', '5', '10'), -('24', '5', '20'), -('25', '5', '40'), -('26', '6', '1'), -('27', '6', '5'), -('28', '6', '10'), -('29', '6', '20'), -('30', '6', '40'), -('31', '7', '1'), -('32', '7', '5'), -('33', '7', '10'), -('34', '7', '20'), -('35', '7', '40'), -('36', '8', '1'), -('37', '8', '5'), -('38', '8', '10'), -('39', '8', '20'), -('40', '8', '40'); +('1', '1', '', '1', '1', 'Description 1'), +('2', '1', '1', '2', '5', 'Description 2'), +('3', '1', '2', '3', '10', 'Description 3'), +('4', '1', '3', '4', '20', 'Description 4'), +('5', '1', '4', '5', '40', 'Description 5'), +('6', '2', '', '1', '1', 'Description 6'), +('7', '2', '6', '2', '5', 'Description 7'), +('8', '2', '7', '3', '10', 'Description 8'), +('9', '2', '8', '4', '20', 'Description 9'), +('10', '2', '9', '5', '40', 'Description 10'), +('11', '3', '', '1', '1', 'Description 11'), +('12', '3', '11', '2', '5', 'Description 12'), +('13', '3', '12', '3', '10', 'Description 13'), +('14', '3', '13', '4', '20', 'Description 14'), +('15', '3', '14', '5', '40', 'Description 15'), +('16', '4', '', '1', '1', 'Description 16'), +('17', '4', '16', '2', '5', 'Description 17'), +('18', '4', '17', '3', '10', 'Description 18'), +('19', '4', '18', '4', '20', 'Description 19'), +('20', '4', '19', '5', '40', 'Description 20'), +('21', '5', '', '1', '1', 'Description 21'), +('22', '5', '21', '2', '5', 'Description 22'), +('23', '5', '22', '3', '10', 'Description 23'), +('24', '5', '23', '4', '20', 'Description 24'), +('25', '5', '24', '5', '40', 'Description 25'), +('26', '6', '', '1', '1', 'Description 26'), +('27', '6', '26', '2', '5', 'Description 27'), +('28', '6', '27', '3', '10', 'Description 28'), +('29', '6', '28', '4', '20', 'Description 29'), +('30', '6', '29', '5', '40', 'Description 30'), +('31', '7', '', '1', '1', 'Description 31'), +('32', '7', '30', '2', '5', 'Description 32'), +('33', '7', '31', '3', '10', 'Description 33'), +('34', '7', '32', '4', '20', 'Description 34'), +('35', '7', '33', '5', '40', 'Description 35'), +('36', '8', '', '1', '1', 'Description 36'), +('37', '8', '35', '2', '5', 'Description 37'), +('38', '8', '36', '3', '10', 'Description 38'), +('39', '8', '37', '4', '20', 'Description 39'), +('40', '8', '38', '5', '40', 'Description 40'); -INSERT INTO `fic2014`.`exercice_dependancies` ( -`id` , -`id_exercice` , -`id_dependence` -) -VALUES ( -'1', '2', '1' -), ( -'2', '3', '2' -), ( -'3', '4', '3' -), ( -'4', '5', '4' -), ( -'5', '7', '6' -), ( -'6', '8', '7' -), ( -'7', '9', '8' -), ( -'8', '10', '9' -), ( -'9', '12', '11' -), ( -'10', '13', '12' -), ( -'11', '14', '13' -), ( -'12', '15', '14' -), ( -'13', '17', '16' -), ( -'14', '18', '17' -), ( -'15', '19', '18' -), ( -'16', '20', '19' -), ( -'17', '22', '21' -), ( -'18', '23', '22' -), ( -'19', '24', '23' -), ( -'20', '25', '24' -), ( -'21', '27', '26' -), ( -'22', '28', '27' -), ( -'23', '29', '28' -), ( -'24', '30', '29' -), ( -'25', '32', '31' -), ( -'26', '33', '32' -), ( -'27', '34', '33' -), ( -'28', '35', '34' -), ( -'29', '37', '36' -), ( -'30', '38', '37' -), ( -'31', '39', '38' -), ( -'32', '40', '39' -); - -INSERT INTO `fic2014`.`solved` ( +INSERT INTO `fic`.`solved` ( `id` , `id_user` , `id_exercice` , From a767c4d900b1d5366d29ed05b7b921990e68a5e1 Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Tue, 22 Oct 2013 08:56:38 +0200 Subject: [PATCH 0041/2686] Correct some bugs in Team class. --- onyx/include/common/Team.class.php | 34 +++++++++++++++++------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 8ad7e448..1bf78e85 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -2,6 +2,16 @@ if(!defined('ONYX')) exit; +function cmp_team_pts($i1, $i2) +{ + if ($i1->get_pts() == $i2->get_pts()){ + return 0; + } + else{ + return ($i1->get_pts() < $i2->get_pts()) ? 1 : -1; + } +} + class Team { var $id = null; @@ -24,6 +34,7 @@ class Team if (!empty($res)) { + $this->id = $res['id']; $this->firstname = $res['firstname']; $this->lastname = $res['lastname']; $this->username = $res['username']; @@ -94,15 +105,16 @@ class Team function get_pts() { - if(isset($this->points)) + if(!isset($this->points)) { $db = new BDD(); - $res = $db->query("SELECT e.id, s.id_user, SUM(e.points) as sum_points + $res = $db->unique_query("SELECT e.id, s.id_user, SUM(e.points) as sum_points FROM exercices e LEFT OUTER JOIN solved s ON e.id = s.id_exercice - WHERE s.id_user = " . intval($this->id) . " + WHERE s.id_user = " . $this->id . " GROUP BY s.id_user"); + $db->deconnexion(); if (!empty($res)) @@ -110,6 +122,8 @@ class Team $this->points = $res['sum_points']; } } + + return $this->points; } function get_groupIds() @@ -145,19 +159,9 @@ class Team // TODO: Not tested, need feeding BDD public static function get_top() { - function cmp($i1, $i2) - { - if ($i1->get_pts() == $i2->get_pts()){ - return 0; - } - else{ - return ($i1->get_pts() < $i2->get_pts) ? -1 : 1; - } - } - - $teams = $this->get_teams(); + $teams = Team::get_teams(); - usort($teams, "cmp"); + usort($teams, "cmp_team_pts"); return $teams; } From 9c3173c6823786183de31027c3c495df837ea1a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Wed, 23 Oct 2013 21:32:17 +0200 Subject: [PATCH 0042/2686] Fix User -> Team --- onyx/include/common/Team.class.php | 67 +++++++++++++++--------------- 1 file changed, 33 insertions(+), 34 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 1bf78e85..4debbf23 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -15,13 +15,11 @@ function cmp_team_pts($i1, $i2) class Team { var $id = null; - var $firstname; - var $lastname; - var $username; - var $company; + var $key_hash; var $auth_level; + var $company; + var $members = null; var $points = null; - var $nb_themes = null; // Constructor function Team ($id=null) @@ -29,15 +27,13 @@ class Team if (!empty($id)) { $db = new BDD(); - $res = $db->unique_query("SELECT id, firstname, lastname, username, company, auth_level - FROM users WHERE id=" . intval($id)); + $res = $db->unique_query("SELECT id, key_hash, company, auth_level + FROM teams WHERE id=" . intval($id)) or die($db->erreur()); if (!empty($res)) { $this->id = $res['id']; - $this->firstname = $res['firstname']; - $this->lastname = $res['lastname']; - $this->username = $res['username']; + $this->key_hash = $res['key_hash']; $this->company = $res['company']; $this->auth_level = $res['auth_level']; } @@ -48,29 +44,25 @@ class Team // Class methods function update() { - $username = $this->username; + $key_hash = $this->key_hash; $auth_level = intval($this->auth_level); - $firstname = $this->firstname; - $lastname = $this->lastname; $company = $this->company; $db = new BDD(); - $db->escape($username); - $db->escape($firstname); - $db->escape($lastname); + $db->escape($key_hash); $db->escape($company); if (empty($this->id)) { - $db->query("INSERT INTO users - VALUES (NULL, '".$username."', 0x0, ".$auth_level.", '".$firstname."', '".$lastname."', '".$company."')"); + $db->query("INSERT INTO teams + VALUES (NULL, '".$key_hash."', ".$auth_level.", '".$company."')"); $this->id = $db->insert_id(); $aff = ($this->id > 0); } else { $db->query("UPDATE users - SET username = '".$username."', auth_level = '".$auth_level."', firstname = '".$firstname."', lastname = '".$lastname."', company = '".$company."' + SET auth_level = ".$auth_level.", key_hash = '".$key_hash."', company = '".$company."' WHERE id = ".intval($this->id)); $aff = $db->affected(); } @@ -83,18 +75,6 @@ class Team return $this->id; } - function get_firstname() { - return $this->firstname; - } - - function get_lastname() { - return $this->lastname; - } - - function get_username() { - return $this->username; - } - function get_company() { return $this->company; } @@ -103,6 +83,25 @@ class Team return $this->auth_level; } + function get_members() + { + if(!isset($this->members)) + { + $db = new BDD(); + + $res = $db->query("SELECT id, firstname, lastname, nickname + FROM team_members + WHERE id_team = " . intval($this->id)); + + $db->deconnexion(); + + if (!empty($res)) + $this->members = $res; + } + + return $this->members; + } + function get_pts() { if(!isset($this->points)) @@ -145,7 +144,7 @@ class Team public static function get_teams() { $db = new BDD(); - $ids = $db->query("SELECT `id` FROM `users`"); + $ids = $db->query("SELECT `id` FROM `teams`"); $db->deconnexion(); $array = array(); @@ -160,9 +159,9 @@ class Team public static function get_top() { $teams = Team::get_teams(); - + usort($teams, "cmp_team_pts"); return $teams; } -} \ No newline at end of file +} From 8a39c734fb11af87469355d333f9b7124613f055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Wed, 23 Oct 2013 21:36:06 +0200 Subject: [PATCH 0043/2686] New db schema --- db/fic2014.sql | 91 +++++++++++++++++++++++++++----------------------- 1 file changed, 49 insertions(+), 42 deletions(-) diff --git a/db/fic2014.sql b/db/fic2014.sql index 63dda3bd..0dfd2dd5 100644 --- a/db/fic2014.sql +++ b/db/fic2014.sql @@ -1,39 +1,39 @@ -- phpMyAdmin SQL Dump --- version 3.5.1 +-- version 4.0.5 -- http://www.phpmyadmin.net -- --- Client: localhost --- Généré le: Mer 09 Octobre 2013 à 23:52 --- Version du serveur: 5.5.32-log --- Version de PHP: 5.5.0-pl0-gentoo +-- Host: localhost +-- Generation Time: Oct 23, 2013 at 07:34 PM +-- Server version: 5.1.70-log +-- PHP Version: 5.5.4-pl0-gentoo -SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET time_zone = "+00:00"; -- --- Base de données: `fic2014` +-- Database: `fic2014` -- -- -------------------------------------------------------- -- --- Structure de la table `exercices` +-- Table structure for table `exercices` -- CREATE TABLE IF NOT EXISTS `exercices` ( - `id` varchar(100) COLLATE utf16_unicode_ci NOT NULL, + `id` varchar(100) COLLATE utf8_unicode_ci NOT NULL, `id_theme` int(10) unsigned NOT NULL, - `require` varchar(100) COLLATE utf16_unicode_ci NOT NULL, + `require` varchar(100) COLLATE utf8_unicode_ci NOT NULL, `level` tinyint(4) NOT NULL, `points` smallint(6) NOT NULL, - `statement` text COLLATE utf16_unicode_ci NOT NULL, + `statement` text COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- -------------------------------------------------------- -- --- Structure de la table `exercice_files` +-- Table structure for table `exercice_files` -- CREATE TABLE IF NOT EXISTS `exercice_files` ( @@ -48,7 +48,7 @@ CREATE TABLE IF NOT EXISTS `exercice_files` ( -- -------------------------------------------------------- -- --- Structure de la table `exercice_keys` +-- Table structure for table `exercice_keys` -- CREATE TABLE IF NOT EXISTS `exercice_keys` ( @@ -62,7 +62,7 @@ CREATE TABLE IF NOT EXISTS `exercice_keys` ( -- -------------------------------------------------------- -- --- Structure de la table `sessions` +-- Table structure for table `sessions` -- CREATE TABLE IF NOT EXISTS `sessions` ( @@ -79,7 +79,7 @@ CREATE TABLE IF NOT EXISTS `sessions` ( -- -------------------------------------------------------- -- --- Structure de la table `solved` +-- Table structure for table `solved` -- CREATE TABLE IF NOT EXISTS `solved` ( @@ -88,38 +88,45 @@ CREATE TABLE IF NOT EXISTS `solved` ( `id_exercice` int(10) unsigned NOT NULL, `time` datetime NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=1 ; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; -- -------------------------------------------------------- -- --- Structure de la table `themes` +-- Table structure for table `teams` +-- + +CREATE TABLE IF NOT EXISTS `teams` ( + `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `key_hash` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `auth_level` tinyint(1) NOT NULL, + `company` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `team_members` +-- + +CREATE TABLE IF NOT EXISTS `team_members` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `id_team` int(10) unsigned NOT NULL, + `firstname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `lastname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `nickname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; + +-- -------------------------------------------------------- + +-- +-- Table structure for table `themes` -- CREATE TABLE IF NOT EXISTS `themes` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `filename` varchar(255) COLLATE utf16_unicode_ci NOT NULL, + `filename` varchar(255) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=1 ; - --- -------------------------------------------------------- - --- --- Structure de la table `users` --- - -CREATE TABLE IF NOT EXISTS `users` ( - `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, - `username` varchar(255) COLLATE utf16_unicode_ci NOT NULL, - `password` binary(64) NOT NULL, - `auth_level` tinyint(1) NOT NULL, - `firstname` varchar(255) COLLATE utf16_unicode_ci NOT NULL, - `lastname` varchar(255) COLLATE utf16_unicode_ci NOT NULL, - `company` varchar(255) COLLATE utf16_unicode_ci NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf16 COLLATE=utf16_unicode_ci AUTO_INCREMENT=2 ; - - -INSERT INTO users (username, password, auth_level) -VALUES -("nemunaire", UNHEX('c1d050d16d8c90dae6fef376460299aa8d1cce7c5b299720a8e38952a77212f1019e2cd44ba58e0433c01cb4c81ab9a789c07df218b0b9f05af8d1198a3bd239'), 2); +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; From 5abb9d8713d10f2f96da3eef5733f02114b92045 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Thu, 24 Oct 2013 17:40:12 +0200 Subject: [PATCH 0044/2686] Deleted login.php, login.tpl, login.css --- htdocs/css/login.css | 37 ----------------------------- onyx/include/public/login.php | 29 ---------------------- onyx/tpl/bootstrap/public/login.tpl | 18 -------------- 3 files changed, 84 deletions(-) delete mode 100644 htdocs/css/login.css delete mode 100644 onyx/include/public/login.php delete mode 100644 onyx/tpl/bootstrap/public/login.tpl diff --git a/htdocs/css/login.css b/htdocs/css/login.css deleted file mode 100644 index f7bf2623..00000000 --- a/htdocs/css/login.css +++ /dev/null @@ -1,37 +0,0 @@ -body { - padding-top: 40px; - background-color: #eee; -} - -.form-signin { - max-width: 330px; - padding: 15px; - margin: 0 auto; -} -.form-signin .form-signin-heading, - -.form-signin .checkbox { - font-weight: normal; -} -.form-signin .form-control { - position: relative; - font-size: 16px; - height: auto; - padding: 10px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; -} -.form-signin .form-control:focus { - z-index: 2; -} -.form-signin input[type="text"] { - margin-bottom: -1px; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} -.form-signin input[type="password"] { - margin-bottom: 10px; - border-top-left-radius: 0; - border-top-right-radius: 0; -} diff --git a/onyx/include/public/login.php b/onyx/include/public/login.php deleted file mode 100644 index 1b22cbac..00000000 --- a/onyx/include/public/login.php +++ /dev/null @@ -1,29 +0,0 @@ -escape($username); - $bdd->escape($password); - $hash = mdp($username, $password); - $result = $bdd->unique_query("SELECT id, username, auth_level FROM users - WHERE username='$username' - AND password=unhex('$hash')"); - - if (!empty($result) && $result['auth_level'] != 0) - { - $SESS->level = $result["auth_level"]; - $SESS->values = $result; - $SESS->put($result["id"]); - header("Location: /home"); - exit; - } -} - -$page = "public/login"; diff --git a/onyx/tpl/bootstrap/public/login.tpl b/onyx/tpl/bootstrap/public/login.tpl deleted file mode 100644 index 59a794ee..00000000 --- a/onyx/tpl/bootstrap/public/login.tpl +++ /dev/null @@ -1,18 +0,0 @@ -{extends file="layout-nav.tpl"} - -{block name=head} - -{/block} - -{block name=content} - -
- -
- -{/block} From 026660aa2ffb4a6581565457278c7a05bfb77c8d Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sat, 26 Oct 2013 02:49:38 +0200 Subject: [PATCH 0045/2686] Add script for certs --- misc/certs/CA.sh | 49 ++++++ misc/certs/openssl.cnf | 352 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 401 insertions(+) create mode 100755 misc/certs/CA.sh create mode 100644 misc/certs/openssl.cnf diff --git a/misc/certs/CA.sh b/misc/certs/CA.sh new file mode 100755 index 00000000..f8378fc1 --- /dev/null +++ b/misc/certs/CA.sh @@ -0,0 +1,49 @@ +# Create CA for client +#openssl genrsa -des3 -out ca.key 4096 +#openssl req -new -x509 -days 365 -key ca.key -out ca.crt +# +## Server cert +#openssl genrsa -des3 -out server.key 2028 +#openssl req -new -key server.key -out server.csr +# +## Self sign ?? +#openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt + +# TODO serial +# TODO common name + +OPENSSL_CONF=openssl.cnf + +[ $# -ne 1 ] && echo "Usage: $0 init + client NAME" + +case $1 in + "init" ) + echo "Create CA for signing client certs" + openssl genrsa -des3 -out ca.key 4096 + sed -i 's/=.*#CommonName/= FIC2014 CA#CommonNameEnd/' $OPENSSL_CONF + openssl req -batch -new -x509 -days 365 -key ca.key -out ca.crt + + echo "Create server cert" + openssl genrsa -des3 -out server.key 2048 + sed -i 's/=.*#CommonNameEnd/= FIC2014 Server#CommonNameEnd/' $OPENSSL_CONF + openssl req -batch -new -key server.key -out server.csr + openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt + rm server.csr + ;; + "client" ) + [ $# -ne 2 ] && "client Usage" + openssl genrsa -des3 -out client.key 2048 + sed -i "s/=.*#CommonNameEnd/= $2#CommonNameEnd/" $OPENSSL_CONF + openssl req -batch -new -key client.key -out client.csr + openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt + openssl pkcs12 -export -inkey client.key -in client.crt -name $2 -out ${2}.p12 + + rm client.key + rm client.csr + rm client.crt + ;; + "*" ) + echo "*" + ;; +esac diff --git a/misc/certs/openssl.cnf b/misc/certs/openssl.cnf new file mode 100644 index 00000000..d7afe95d --- /dev/null +++ b/misc/certs/openssl.cnf @@ -0,0 +1,352 @@ +# +# OpenSSL example configuration file. +# This is mostly being used for generation of certificate requests. +# + +# This definition stops the following lines choking if HOME isn't +# defined. +HOME = . +RANDFILE = $ENV::HOME/.rnd + +# Extra OBJECT IDENTIFIER info: +#oid_file = $ENV::HOME/.oid +oid_section = new_oids + +# To use this configuration file with the "-extfile" option of the +# "openssl x509" utility, name here the section containing the +# X.509v3 extensions to use: +# extensions = +# (Alternatively, use a configuration file that has only +# X.509v3 extensions in its main [= default] section.) + +[ new_oids ] + +# We can add new OIDs in here for use by 'ca', 'req' and 'ts'. +# Add a simple OID like this: +# testoid1=1.2.3.4 +# Or use config file substitution like this: +# testoid2=${testoid1}.5.6 + +# Policies used by the TSA examples. +tsa_policy1 = 1.2.3.4.1 +tsa_policy2 = 1.2.3.4.5.6 +tsa_policy3 = 1.2.3.4.5.7 + +#################################################################### +[ ca ] +default_ca = CA_default # The default ca section + +#################################################################### +[ CA_default ] + +dir = /etc/ssl # Where everything is kept +certs = $dir/certs # Where the issued certs are kept +crl_dir = $dir/crl # Where the issued crl are kept +database = $dir/index.txt # database index file. +#unique_subject = no # Set to 'no' to allow creation of + # several ctificates with same subject. +new_certs_dir = $dir/newcerts # default place for new certs. + +certificate = $dir/cacert.pem # The CA certificate +serial = $dir/serial # The current serial number +crlnumber = $dir/crlnumber # the current crl number + # must be commented out to leave a V1 CRL +crl = $dir/crl.pem # The current CRL +private_key = $dir/private/cakey.pem# The private key +RANDFILE = $dir/private/.rand # private random number file + +x509_extensions = usr_cert # The extentions to add to the cert + +# Comment out the following two lines for the "traditional" +# (and highly broken) format. +name_opt = ca_default # Subject Name options +cert_opt = ca_default # Certificate field options + +# Extension copying option: use with caution. +# copy_extensions = copy + +# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs +# so this is commented out by default to leave a V1 CRL. +# crlnumber must also be commented out to leave a V1 CRL. +# crl_extensions = crl_ext + +default_days = 365 # how long to certify for +default_crl_days= 30 # how long before next CRL +default_md = default # use public key default MD +preserve = no # keep passed DN ordering + +# A few difference way of specifying how similar the request should look +# For type CA, the listed attributes must be the same, and the optional +# and supplied fields are just that :-) +policy = policy_match + +# For the CA policy +[ policy_match ] +countryName = match +stateOrProvinceName = match +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +# For the 'anything' policy +# At this point in time, you must list all acceptable 'object' +# types. +[ policy_anything ] +countryName = optional +stateOrProvinceName = optional +localityName = optional +organizationName = optional +organizationalUnitName = optional +commonName = supplied +emailAddress = optional + +#################################################################### +[ req ] +default_bits = 2048 +default_keyfile = privkey.pem +distinguished_name = req_distinguished_name +attributes = req_attributes +x509_extensions = v3_ca # The extentions to add to the self signed cert + +# Passwords for private keys if not present they will be prompted for +# input_password = secret +# output_password = secret + +# This sets a mask for permitted string types. There are several options. +# default: PrintableString, T61String, BMPString. +# pkix : PrintableString, BMPString (PKIX recommendation before 2004) +# utf8only: only UTF8Strings (PKIX recommendation after 2004). +# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). +# MASK:XXXX a literal mask value. +# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. +string_mask = utf8only + +# req_extensions = v3_req # The extensions to add to a certificate request + +[ req_distinguished_name ] +countryName = Country Name (2 letter code) +countryName_default = FR +countryName_min = 2 +countryName_max = 2 + +stateOrProvinceName = State or Province Name (full name) +stateOrProvinceName_default = France + +localityName = Locality Name (eg, city) +localityName_default = Paris + +0.organizationName = Organization Name (eg, company) +0.organizationName_default = Epita + +# we can do this but it is not needed normally :-) +#1.organizationName = Second Organization Name (eg, company) +#1.organizationName_default = World Wide Web Pty Ltd + +organizationalUnitName = Organizational Unit Name (eg, section) +organizationalUnitName_default = SRS + +commonName = Common Name (e.g. server FQDN or YOUR name) +commonName_default = tata#CommonNameEndEndEndEndEnd +commonName_max = 64 + +emailAddress = Email Address +emailAddress_max = 64 + +# SET-ex3 = SET extension number 3 + +[ req_attributes ] +challengePassword = A challenge password +challengePassword_min = 4 +challengePassword_max = 20 + +unstructuredName = An optional company name + +[ usr_cert ] + +# These extensions are added when 'ca' signs a request. + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This is required for TSA certificates. +# extendedKeyUsage = critical,timeStamping + +[ v3_req ] + +# Extensions to add to a certificate request + +basicConstraints = CA:FALSE +keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +[ v3_ca ] + + +# Extensions for a typical CA + + +# PKIX recommendation. + +subjectKeyIdentifier=hash + +authorityKeyIdentifier=keyid:always,issuer + +# This is what PKIX recommends but some broken software chokes on critical +# extensions. +#basicConstraints = critical,CA:true +# So we do this instead. +basicConstraints = CA:true + +# Key usage: this is typical for a CA certificate. However since it will +# prevent it being used as an test self-signed certificate it is best +# left out by default. +# keyUsage = cRLSign, keyCertSign + +# Some might want this also +# nsCertType = sslCA, emailCA + +# Include email address in subject alt name: another PKIX recommendation +# subjectAltName=email:copy +# Copy issuer details +# issuerAltName=issuer:copy + +# DER hex encoding of an extension: beware experts only! +# obj=DER:02:03 +# Where 'obj' is a standard or added object +# You can even override a supported extension: +# basicConstraints= critical, DER:30:03:01:01:FF + +[ crl_ext ] + +# CRL extensions. +# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. + +# issuerAltName=issuer:copy +authorityKeyIdentifier=keyid:always + +[ proxy_cert_ext ] +# These extensions should be added when creating a proxy certificate + +# This goes against PKIX guidelines but some CAs do it and some software +# requires this to avoid interpreting an end user certificate as a CA. + +basicConstraints=CA:FALSE + +# Here are some examples of the usage of nsCertType. If it is omitted +# the certificate can be used for anything *except* object signing. + +# This is OK for an SSL server. +# nsCertType = server + +# For an object signing certificate this would be used. +# nsCertType = objsign + +# For normal client use this is typical +# nsCertType = client, email + +# and for everything including object signing: +# nsCertType = client, email, objsign + +# This is typical in keyUsage for a client certificate. +# keyUsage = nonRepudiation, digitalSignature, keyEncipherment + +# This will be displayed in Netscape's comment listbox. +nsComment = "OpenSSL Generated Certificate" + +# PKIX recommendations harmless if included in all certificates. +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer + +# This stuff is for subjectAltName and issuerAltname. +# Import the email address. +# subjectAltName=email:copy +# An alternative to produce certificates that aren't +# deprecated according to PKIX. +# subjectAltName=email:move + +# Copy subject details +# issuerAltName=issuer:copy + +#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem +#nsBaseUrl +#nsRevocationUrl +#nsRenewalUrl +#nsCaPolicyUrl +#nsSslServerName + +# This really needs to be in place for it to be a proxy certificate. +proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo + +#################################################################### +[ tsa ] + +default_tsa = tsa_config1 # the default TSA section + +[ tsa_config1 ] + +# These are used by the TSA reply generation only. +dir = ./demoCA # TSA root directory +serial = $dir/tsaserial # The current serial number (mandatory) +crypto_device = builtin # OpenSSL engine to use for signing +signer_cert = $dir/tsacert.pem # The TSA signing certificate + # (optional) +certs = $dir/cacert.pem # Certificate chain to include in reply + # (optional) +signer_key = $dir/private/tsakey.pem # The TSA private key (optional) + +default_policy = tsa_policy1 # Policy if request did not specify it + # (optional) +other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) +digests = md5, sha1 # Acceptable message digests (mandatory) +accuracy = secs:1, millisecs:500, microsecs:100 # (optional) +clock_precision_digits = 0 # number of digits after dot. (optional) +ordering = yes # Is ordering defined for timestamps? + # (optional, default: no) +tsa_name = yes # Must the TSA name be included in the reply? + # (optional, default: no) +ess_cert_id_chain = no # Must the ESS cert id chain be included? + # (optional, default: no) From 30135b4c6e1617e64b27141e56c5beafd649e2fb Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sat, 26 Oct 2013 02:49:59 +0200 Subject: [PATCH 0046/2686] Add install script --- misc/init_db.sql | 2 ++ misc/install.sh | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ misc/server.conf | 5 ++++ 3 files changed, 75 insertions(+) create mode 100644 misc/init_db.sql create mode 100755 misc/install.sh create mode 100644 misc/server.conf diff --git a/misc/init_db.sql b/misc/init_db.sql new file mode 100644 index 00000000..e2ca05e8 --- /dev/null +++ b/misc/init_db.sql @@ -0,0 +1,2 @@ +DROP DATABASE IF EXISTS fic2014; +CREATE DATABASE fic2014; diff --git a/misc/install.sh b/misc/install.sh new file mode 100755 index 00000000..ede53942 --- /dev/null +++ b/misc/install.sh @@ -0,0 +1,68 @@ +#! /bin/sh + +# Install FIC 2014 server + +# Depends: +# +# nginx 1.4.3 +# openssh 6.3p1-1 +# iptables 1.4.19.1-1 +# mariadb 5.5.33.a-1 + +# Exit values +# 0 Everything is good +# 1 +# 2 File not found +# 3 Service not running + +# By default the config dir is .. +DIR=${PWD%/*} +CONF="server.conf" +BASENAME=`basename $0` +FULL_INSTALL=false + +display_help() +{ + # By default install only config files + # --full: install package, enable services, install config + echo "Usage: $BASENAME [--full] (alpha|beta)" + exit 1 +} + +HTTP_DIR="" +DB_TYPE="" +DB_NAME="" +DB_USER="" +DB_PASS="" + +parse_conf() +{ + if ! [ -f $CONF ]; then + echo "The configuration file: " $CONF " not found" + exit 2 + fi + HTTP_DIR=$(sed -n 's/[ \t]*http_root[ \t]*=[ \t]*\(.*\)[ \t]*/\1/p' $CONF) + DB_TYPE=$(sed -n 's/[ \t]*db_type[ \t]*=[ \t]*\(.*\)[ \t]*/\1/p' $CONF) + DB_NAME=$(sed -n 's/[ \t]*db_name[ \t]*=[ \t]*\(.*\)[ \t]*/\1/p' $CONF) + DB_USER=$(sed -n 's/[ \t]*db_user[ \t]*=[ \t]*\(.*\)[ \t]*/\1/p' $CONF) + DB_PASS=$(sed -n 's/[ \t]*db_pass[ \t]*=[ \t]*\(.*\)[ \t]*/\1/p' $CONF) +} + +INIT_DB="init_db.sql" + +init_db() +{ + if ! [ -f $INIT_DB ]; then + echo "The configuration file " $INIT_DB " not found" + exit 2 + fi + + if ! [ -S /var/run/mysqld/mysqld.sock ]; then + echo "The mysqld service is not running" + exit 3 + fi +} + +[ $# -ne 1 ] && display_help + +parse_conf diff --git a/misc/server.conf b/misc/server.conf new file mode 100644 index 00000000..c9ec3d86 --- /dev/null +++ b/misc/server.conf @@ -0,0 +1,5 @@ +http_root=/srv/http/fic2014-server +db_type=mysql +db_name=fic +db_user=toto +db_pass=toto42 From 7571c8c1b12655650dc1edae3271a381ec9b50b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sat, 26 Oct 2013 08:56:06 +0200 Subject: [PATCH 0047/2686] Move directory tpl users to teams --- onyx/include/team/exercice.php | 2 +- onyx/include/team/home.php | 2 +- onyx/include/team/{change.php => me.php} | 2 +- onyx/include/team/summary.php | 2 +- onyx/include/team/team.php | 2 +- onyx/tpl/bootstrap/{users => teams}/home.tpl | 0 6 files changed, 5 insertions(+), 5 deletions(-) rename onyx/include/team/{change.php => me.php} (61%) rename onyx/tpl/bootstrap/{users => teams}/home.tpl (100%) diff --git a/onyx/include/team/exercice.php b/onyx/include/team/exercice.php index d8ace4ea..84856f02 100644 --- a/onyx/include/team/exercice.php +++ b/onyx/include/team/exercice.php @@ -3,4 +3,4 @@ if(!defined('ONYX')) exit; -return "team/exercice"; +return "teams/exercice"; diff --git a/onyx/include/team/home.php b/onyx/include/team/home.php index 7521d39f..eaa60a72 100644 --- a/onyx/include/team/home.php +++ b/onyx/include/team/home.php @@ -5,4 +5,4 @@ if(!defined('ONYX')) exit; $template->assign("teams", Team::get_teams()); $template->assign("top", Team::get_top()); -return "users/home"; +return "teams/home"; diff --git a/onyx/include/team/change.php b/onyx/include/team/me.php similarity index 61% rename from onyx/include/team/change.php rename to onyx/include/team/me.php index 8a234331..bf209f06 100644 --- a/onyx/include/team/change.php +++ b/onyx/include/team/me.php @@ -3,4 +3,4 @@ if(!defined('ONYX')) exit; -return "team/change"; +return "teams/change"; diff --git a/onyx/include/team/summary.php b/onyx/include/team/summary.php index 3ab8aeca..62a22790 100644 --- a/onyx/include/team/summary.php +++ b/onyx/include/team/summary.php @@ -3,4 +3,4 @@ if(!defined('ONYX')) exit; -return "team/summary"; +return "teams/summary"; diff --git a/onyx/include/team/team.php b/onyx/include/team/team.php index dcc68e71..98333fdc 100644 --- a/onyx/include/team/team.php +++ b/onyx/include/team/team.php @@ -8,7 +8,7 @@ try $template->assign("team", $team); - return "team/team"; + return "teams/team"; } catch($e) { diff --git a/onyx/tpl/bootstrap/users/home.tpl b/onyx/tpl/bootstrap/teams/home.tpl similarity index 100% rename from onyx/tpl/bootstrap/users/home.tpl rename to onyx/tpl/bootstrap/teams/home.tpl From f8eff22c225c88dc88f24198c002d404fc275b46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sat, 26 Oct 2013 08:59:59 +0200 Subject: [PATCH 0048/2686] Public part: home and team part --- htdocs/index.php | 12 +++++++----- onyx/include/public/team.php | 2 +- onyx/tpl/bootstrap/public/home.tpl | 5 +++++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index 57e1f8f3..50a4aeb4 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -12,6 +12,9 @@ if ($_SERVER["SERVER_NAME"] == "localhost" || $_SERVER["SERVER_NAME"] == "fic" | //Chargement de tout le nécessaire pour le site require_once("common.php"); +$template->assign("SALT_USER",SALT_USER); +$template->assign("SALT_ADMIN",SALT_ADMIN); + $n = preg_match_all("#[^/]+#", strtolower(gpc("p")), $out); $p = $out[0]; @@ -46,7 +49,6 @@ if ($n && $p[0] == SALT_ADMIN) else if ($n && $p[0] == SALT_USER) { $connected = true; - if ($n <= 1) $page = require("team/home.php"); else @@ -59,9 +61,9 @@ else if ($n && $p[0] == SALT_USER) { switch($p[2]) { - case "change/": - case "change": - $page = require("team/change.php"); + case "me/": + case "me": + $page = require("team/me.php"); break; case "summary": @@ -92,7 +94,7 @@ else $page = require("public/home.php"); else if ($n == 1) { - $TEAM = $p[0]; + $TEAM = intval(substr($p[0], 0, strpos($p[0], "-"))); $page = require("public/team.php"); } diff --git a/onyx/include/public/team.php b/onyx/include/public/team.php index dfd91661..71ccb620 100644 --- a/onyx/include/public/team.php +++ b/onyx/include/public/team.php @@ -10,7 +10,7 @@ try return "public/team"; } -catch($e) +catch(Exception $e) { return "404"; } diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index 68369382..fb80872d 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -3,4 +3,9 @@

Hello World!

+{foreach from=$teams item=i} + +{/foreach} {/block} From 867d1d6f74944dc42598af49fe56956cf5dc4a27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sat, 26 Oct 2013 09:00:21 +0200 Subject: [PATCH 0049/2686] Connected: fix top bar menu --- onyx/tpl/bootstrap/layout-nav.tpl | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/onyx/tpl/bootstrap/layout-nav.tpl b/onyx/tpl/bootstrap/layout-nav.tpl index 15f488ba..446e46f3 100644 --- a/onyx/tpl/bootstrap/layout-nav.tpl +++ b/onyx/tpl/bootstrap/layout-nav.tpl @@ -9,21 +9,13 @@ - FIC + FIC
From 73e1e8f127d0173c55f63d618ba5e0efc6add04f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sat, 26 Oct 2013 09:04:22 +0200 Subject: [PATCH 0050/2686] DB: theme require a name, not filename --- db/fic2014.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/fic2014.sql b/db/fic2014.sql index 0dfd2dd5..ec666486 100644 --- a/db/fic2014.sql +++ b/db/fic2014.sql @@ -127,6 +127,6 @@ CREATE TABLE IF NOT EXISTS `team_members` ( CREATE TABLE IF NOT EXISTS `themes` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `filename` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; From c27a97ce6e1e0bcd5e513706df9a97c9ff004262 Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Sat, 26 Oct 2013 15:38:43 +0200 Subject: [PATCH 0051/2686] BDD: add 'teamname' and change feedfortest.sql --- db/feedfortests.sql | 103 ++++++++++++++++++++++++++++++-------------- db/fic2014.sql | 1 + 2 files changed, 71 insertions(+), 33 deletions(-) diff --git a/db/feedfortests.sql b/db/feedfortests.sql index 36fbafe2..b370d694 100644 --- a/db/feedfortests.sql +++ b/db/feedfortests.sql @@ -1,71 +1,108 @@ -INSERT INTO `fic`.`users` ( +INSERT INTO `fic`.`teams` ( `id` , -`username` , -`password` , +`team_name` , +`key_hash` , `auth_level` , -`firstname` , -`lastname` , `company` ) VALUES ( -'1', 'Alpha', '2134s65df423sdf132sdg431dsg', '1', 'Alph', 'A', 'Epitra' +'1', 'Team1', '2134s65df423sdf132sdg431dsg', '1', 'Epita' ), ( -'2', 'Beta', '2134s65df423sef132sdg431dsg', '1', 'Bet', 'A', 'Epitra' +'2', 'Team2', '2134s65df423sef132sdg431dsg', '1', 'Epita' ), ( -'3', 'Charli', '2134s45df423sdf132sdg431dsg', '1', 'Charl', 'I', 'Epitra' +'3', 'Team3', '2134s45df423sdf132sdg431dsg', '1', 'Epita' ), ( -'4', 'Delta', '2134s65df423sdf131sdg431dsg', '1', 'Delt', 'A', 'Epitra' +'4', 'Team4', '2134s65df423sdf131sdg431dsg', '1', 'Epita' ), ( -'5', 'Echo', '2134s65df423sdf132sdg431dfg', '1', 'Ech', 'O', 'Epitra' +'5', 'Team5', '2134s65df423sdf132sdg431dfg', '1', 'Epita' ), ( -'6', 'Foxtrot', '2134s65df423shf132sdg431dsg', '1', 'Fox', 'Trot', 'Epitra' +'6', 'Team6', '2134s65df423shf132sdg431dsg', '1', 'Epita' ), ( -'7', 'Golf', '2134s65df423sdf1f2sdg431dsg', '1', 'Gol', 'F', 'Epitra' +'7', 'Team7', '2134s65df423sdf1f2sdg431dsg', '1', 'Epita' ), ( -'8', 'Hotel', '2134s65df423sdf13zsdg431dsg', '1', 'Hot', 'El', 'Epitra' +'8', 'Team8', '2134s65df423sdf13zsdg431dsg', '1', 'Epita' ), ( -'9', 'India', '2134s65df423sdf13csdg431dsg', '1', 'Ind', 'Ia', 'Epitra' +'9', 'Team9', '2134s65df423sdf13csdg431dsg', '1', 'Epita' ), ( -'10', 'Juliet', '2134s65df4q3sdf132sdg431dsg', '1', 'Jule', 'Yer', 'Epitra' +'10', 'Team10', '2134s65df4q3sdf132sdg431dsg', '1', 'Epita' ), ( -'11', 'Kevlar', '2134s65df423sdf132s2g431dsg', '1', 'Krev', 'Lard', 'Epitra' +'11', 'Team11', '2134s65df423sdf132s2g431dsg', '1', 'Epita' ), ( -'12', 'Lambda', '2134s65df423sdf132sdg401dsg', '1', 'Lamb', 'Ada', 'Epitra' +'12', 'Team12', '2134s65df423sdf132sdg401dsg', '1', 'Epita' ), ( -'13' , 'Mike', '2134s65df423sdf132sdg401dsg', '1', 'Mi', 'Ke', 'Epitra' +'13' , 'Team13', '2134s65df423sdf132sdg401dsg', '1', 'Epita' ), ( -'14' , 'November', '2134s65df423sdf132sdg401dsg', '1', 'Nov', 'Ember', 'Epitra' +'14' , 'Team14', '2134s65df423sdf132sdg401dsg', '1', 'Epita' ), ( -'15' , 'Oscar', '2134s65df423sdf132sdg401dsg', '1', 'Os', 'Car', 'Epitra' +'15' , 'Team15', '2134s65df423sdf132sdg401dsg', '1', 'Epita' +); + +INSERT INTO `fic`.`team_members` ( +`id` , +`id_team` , +`firstname` , +`lastname` , +`nickname` +) +VALUES ( +'1', '1', 'Alph', 'A', 'Alominia' ), ( -'16' , 'Papa', '2134s65df423sdf132sdg401dsg', '1', 'Pa', 'Pa', 'Epitra' +'2', '1', 'Bet', 'A', 'CaptainSandwich' ), ( -'17' , 'Quebec', '2134s65df423sdf132sdg401dsg', '1', 'Que', 'Bec', 'Epitra' +'3', '2', 'Charl', 'I', 'Tintin' ), ( -'18' , 'Romeo', '2134s65df423sdf132sdg401dsg', '1', 'Rom', 'Eo', 'Epitra' +'4', '2', 'Delt', 'A', 'Wolwerin' ), ( -'19' , 'Sierra', '2134s65df423sdf132sdg401dsg', '1', 'Sier', 'Ra', 'Epitra' +'5', '3', 'Ech', 'O', 'Homer' ), ( -'20' , 'Tango', '2134s65df423sdf132sdg401dsg', '1', 'Tan', 'Go', 'Epitra' +'6', '3', 'Fox', 'Trot', 'KevBG91' ), ( -'21' , 'Uniform', '2134s65df423sdf132sdg401dsg', '1', 'Uni', 'Form', 'Epitra' +'7', '4', 'Gol', 'F', 'R2D2' ), ( -'22' , 'Victor', '2134s65df423sdf132sdg401dsg', '1', 'Vic', 'Tor', 'Epitra' +'8', '4', 'Hot', 'El', 'Corbaine' ), ( -'23' , 'Whiskey', '2134s65df423sdf132sdg401dsg', '1', 'Whis', 'Key', 'Epitra' +'9', '5', 'Ind', 'Ia', 'Lelama' ), ( -'24' , 'X-ray', '2134s65df423sdf132sdg401dsg', '1', 'X', 'Rey', 'Epitra' +'10', '5', 'Jule', 'Yer', 'Betrave' ), ( -'25' , 'Yankee', '2134s65df423sdf132sdg401dsg', '1', 'Yan', 'Kee', 'Epitra' +'11', '6', 'Krev', 'Lard', 'BlueSunday' ), ( -'26' , 'Zulu', '2134s65df423sdf132sdg401dsg', '1', 'Zul', 'Lu', 'Epitra' +'12', '6', 'Lamb', 'Ada', 'Chatpitre' ), ( -'27' , 'Zero', '2134s65df423sdf132sdg401dsg', '1', 'Ze', 'Ro', 'Epitra' +'13' , '7', 'Mi', 'Ke', 'Tournewsol' +), ( +'14' , '7', 'Nov', 'Ember', 'Dasilva' +), ( +'15' , '8', 'Os', 'Car', 'Laurie' +), ( +'16' , '8', 'Pa', 'Pa', 'Nowel' +), ( +'17' , '9', 'Que', 'Bec', 'Polyr' +), ( +'18' , '9', 'Rom', 'Eo', 'Granola' +), ( +'19' , '10', 'Sier', 'Ra', 'Petilus75' +), ( +'20' , '11', 'Tan', 'Go', 'Lolilol42' +), ( +'21' , '12', 'Uni', 'Form', 'JmLayfrite' +), ( +'22' , '13', 'Vic', 'Tor', 'Minerva' +), ( +'23' , '13', 'Whis', 'Key', 'Moly' +), ( +'24' , '14', 'X', 'Rey', 'Mistigri' +), ( +'25' , '14', 'Yan', 'Kee', 'Astroboy' +), ( +'26' , '15', 'Zul', 'Lu', 'Salameche' +), ( +'27' , '15', 'Ze', 'Ro', 'Mandy' ); INSERT INTO `fic`.`themes` ( `id` , -`filename` +`name` ) VALUES ( '1' , 'pdf.xml' diff --git a/db/fic2014.sql b/db/fic2014.sql index ec666486..1a5405ec 100644 --- a/db/fic2014.sql +++ b/db/fic2014.sql @@ -98,6 +98,7 @@ CREATE TABLE IF NOT EXISTS `solved` ( CREATE TABLE IF NOT EXISTS `teams` ( `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, + `team_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `key_hash` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `auth_level` tinyint(1) NOT NULL, `company` varchar(255) COLLATE utf8_unicode_ci NOT NULL, From 30a7f656165c15a6228824f79ce1454649084070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sat, 26 Oct 2013 17:42:18 +0200 Subject: [PATCH 0052/2686] Add missing team.tpl page --- onyx/tpl/bootstrap/public/team.tpl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 onyx/tpl/bootstrap/public/team.tpl diff --git a/onyx/tpl/bootstrap/public/team.tpl b/onyx/tpl/bootstrap/public/team.tpl new file mode 100644 index 00000000..f9a9f87f --- /dev/null +++ b/onyx/tpl/bootstrap/public/team.tpl @@ -0,0 +1,16 @@ +{extends file="layout.tpl"} +{block name=content} +

+ {$team->company} +

+
    +
  • Score : {$team->get_pts()}
  • +
  • Membre{if count($team->get_members()) > 1}s{/if} : +
      + {foreach from=$team->get_members() item=m} +
    • {$m.lastname} {$m.firstname}
    • + {/foreach} +
    +
  • +
+{/block} From b069d8f4ed8280f3bf95417a59e64318a360650f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sat, 26 Oct 2013 18:17:25 +0200 Subject: [PATCH 0053/2686] New class Member, use it in Team ; update DB schema --- db/fic2014.sql | 11 ++-- onyx/include/common.php | 1 + onyx/include/common/Member.class.php | 84 ++++++++++++++++++++++++++++ onyx/include/common/Team.class.php | 35 ++++++------ onyx/tpl/bootstrap/public/team.tpl | 4 +- 5 files changed, 110 insertions(+), 25 deletions(-) create mode 100644 onyx/include/common/Member.class.php diff --git a/db/fic2014.sql b/db/fic2014.sql index ec666486..01945b2e 100644 --- a/db/fic2014.sql +++ b/db/fic2014.sql @@ -100,7 +100,7 @@ CREATE TABLE IF NOT EXISTS `teams` ( `id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, `key_hash` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `auth_level` tinyint(1) NOT NULL, - `company` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `slogan` varchar(64) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; @@ -113,9 +113,10 @@ CREATE TABLE IF NOT EXISTS `teams` ( CREATE TABLE IF NOT EXISTS `team_members` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id_team` int(10) unsigned NOT NULL, - `firstname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, - `lastname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, - `nickname` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `firstname` varchar(32) COLLATE utf8_unicode_ci NOT NULL, + `lastname` varchar(32) COLLATE utf8_unicode_ci NOT NULL, + `nickname` varchar(32) COLLATE utf8_unicode_ci NOT NULL, + `company` varchar(32) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; @@ -127,6 +128,6 @@ CREATE TABLE IF NOT EXISTS `team_members` ( CREATE TABLE IF NOT EXISTS `themes` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `name` varchar(32) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; diff --git a/onyx/include/common.php b/onyx/include/common.php index 6754e327..6e0f0067 100644 --- a/onyx/include/common.php +++ b/onyx/include/common.php @@ -7,6 +7,7 @@ if (empty($sess->values["connected"]) && !defined("xCSRF")) require_once("functions.php"); //Inclusion des principales fonctions require_once("common/Exercice.class.php"); +require_once("common/Member.class.php"); require_once("common/Team.class.php"); require_once("common/Theme.class.php"); diff --git a/onyx/include/common/Member.class.php b/onyx/include/common/Member.class.php new file mode 100644 index 00000000..677b9c37 --- /dev/null +++ b/onyx/include/common/Member.class.php @@ -0,0 +1,84 @@ +unique_query("SELECT id, id_team, firstname, lastname, nickname, company + FROM team_members WHERE id=" . intval($id)) or die($db->erreur()); + $db->deconnexion(); + + if (!empty($res)) + { + $this->id = $res['id']; + if (empty($team)) + $this->team = $res['id_team']; + else + $this->team = $team; + $this->firstname = $res['firstname']; + $this->lastname = $res['lastname']; + $this->nickname = $res['nickname']; + $this->company = $res['company']; + } + } + } + + function update() + { + $firstname = $this->firstname; + $lastname = $this->lastname; + $nickname = $this->nickname; + $company = $this->company; + + if (gettype($this->team) != "object") + $id_team = intval($this->team); + else + $id_team = $this->team->id; + + $db = new BDD(); + $db->escape($firstname); + $db->escape($lastname); + $db->escape($nickname); + $db->escape($company); + + if (empty($this->id)) + { + $db->query("INSERT INTO team_members + VALUES (NULL, ".intval($id_team).", '".$firstname."', '".$lastname."', '".$nickname."', '".$company."')"); + $this->id = $db->insert_id(); + $aff = ($this->id > 0); + } + else + { + $db->query("UPDATE team_members + SET id_team = ".intval($id_team).", firstname = '$firstname', lastname = '$lastname', nickname = '$lastname', company = '$company' + WHERE id = ".intval($this->id)); + $aff = $db->affected(); + } + $db->deconnexion(); + + return ($aff == 1); + } + + function get_team() + { + if (gettype($this->team) != "object") + $this->team = new Team(intval($this->team)); + + return $this->team; + } +} + +?> \ No newline at end of file diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 4debbf23..aeeb6799 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -17,8 +17,8 @@ class Team var $id = null; var $key_hash; var $auth_level; - var $company; - var $members = null; + var $slogan; + var $members = array(); var $points = null; // Constructor @@ -27,14 +27,14 @@ class Team if (!empty($id)) { $db = new BDD(); - $res = $db->unique_query("SELECT id, key_hash, company, auth_level + $res = $db->unique_query("SELECT id, key_hash, slogan, auth_level FROM teams WHERE id=" . intval($id)) or die($db->erreur()); if (!empty($res)) { $this->id = $res['id']; $this->key_hash = $res['key_hash']; - $this->company = $res['company']; + $this->slogan = $res['slogan']; $this->auth_level = $res['auth_level']; } $db->deconnexion(); @@ -46,23 +46,23 @@ class Team { $key_hash = $this->key_hash; $auth_level = intval($this->auth_level); - $company = $this->company; + $slogan = $this->slogan; $db = new BDD(); $db->escape($key_hash); - $db->escape($company); + $db->escape($slogan); if (empty($this->id)) { $db->query("INSERT INTO teams - VALUES (NULL, '".$key_hash."', ".$auth_level.", '".$company."')"); + VALUES (NULL, '".$key_hash."', ".$auth_level.", '".$slogan."')"); $this->id = $db->insert_id(); $aff = ($this->id > 0); } else { - $db->query("UPDATE users - SET auth_level = ".$auth_level.", key_hash = '".$key_hash."', company = '".$company."' + $db->query("UPDATE teams + SET auth_level = ".$auth_level.", key_hash = '".$key_hash."', slogan = '".$slogan."' WHERE id = ".intval($this->id)); $aff = $db->affected(); } @@ -75,8 +75,8 @@ class Team return $this->id; } - function get_company() { - return $this->company; + function get_slogan() { + return $this->slogan; } function get_auth_level() { @@ -85,18 +85,17 @@ class Team function get_members() { - if(!isset($this->members)) + if(count($this->members) == 0) { $db = new BDD(); - $res = $db->query("SELECT id, firstname, lastname, nickname - FROM team_members + $res = $db->query("SELECT id FROM team_members WHERE id_team = " . intval($this->id)); $db->deconnexion(); - if (!empty($res)) - $this->members = $res; + foreach($res as $member) + $this->members[] = new Member($member["id"], $this); } return $this->members; @@ -117,9 +116,9 @@ class Team $db->deconnexion(); if (!empty($res)) - { $this->points = $res['sum_points']; - } + else + $this->points = 0; } return $this->points; diff --git a/onyx/tpl/bootstrap/public/team.tpl b/onyx/tpl/bootstrap/public/team.tpl index f9a9f87f..39094e42 100644 --- a/onyx/tpl/bootstrap/public/team.tpl +++ b/onyx/tpl/bootstrap/public/team.tpl @@ -1,14 +1,14 @@ {extends file="layout.tpl"} {block name=content}

- {$team->company} + {$team->slogan}

- -
+ +
From fd855c0f0d43063f2600e878d9f3350f166eed6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Mon, 25 Nov 2013 15:38:42 +0100 Subject: [PATCH 0108/2686] Add clock.tpl --- onyx/tpl/bootstrap/clock.tpl | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 onyx/tpl/bootstrap/clock.tpl diff --git a/onyx/tpl/bootstrap/clock.tpl b/onyx/tpl/bootstrap/clock.tpl new file mode 100644 index 00000000..05c184c2 --- /dev/null +++ b/onyx/tpl/bootstrap/clock.tpl @@ -0,0 +1,20 @@ +
+ + +
+
    +
  • +
  • :
  • +
  • +
  • :
  • +
  • +
+
From c5f96c8bb99db867fe6b2ae5f2fabc2c652fb479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Mon, 25 Nov 2013 15:55:12 +0100 Subject: [PATCH 0109/2686] Ignore submissions --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 571d5f74..cb02566c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ onyx/log/* onyx/config/root.xml onyx/db/*.profile.php onyx/tpl/*/*.html +submission/* From e137e755c07ce7947f74bef171c8d079dbd417e2 Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Mon, 25 Nov 2013 21:12:01 +0100 Subject: [PATCH 0110/2686] Add public array --- onyx/include/common/Team.class.php | 17 +++++++++++++ onyx/tpl/bootstrap/public/home.tpl | 40 ++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 7494898a..3a2cd470 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -232,4 +232,21 @@ class Team return $res['count_teams']; } + + public static function first_to_solve_exercice($id_exercice) + { + $db = new BDD(); + $res = $db->unique_query("SELECT t3.team_name as result + FROM solved AS t1 + INNER JOIN ( + SELECT MIN(s.time) AS minTime + FROM solved AS s + WHERE s.id_exercice = ".$id_exercice." + ) AS t2 + INNER JOIN teams AS t3 ON t1.id_team = t3.id + WHERE t1.time = t2.minTime"); + $db->deconnexion(); + + return $res['result']; + } } diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index 2fe5783b..6f0d757e 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -2,12 +2,38 @@ {block name=main}
-

Example

-

This is a example

-

This is a example

-

This is a example

-

This is a example

-

This is a example

-

This is a example

+ + + + + +{for $i=1 to $nbExoMax} + +{/for} + + + +{$total=0} +{foreach from=$themes item=theme} + + + {$themeID=$theme->get_id()} + {foreach from=$theme->get_exercices_ordered() item=exo} + {$teamName=""} + {for $i=0 to $nbExoMax} + {$teamName=Team::first_to_solve_exercice($exo->get_id())} + {/for} + {if $teamName != ""} + + {else} + + {/if} + {/foreach} + +{/foreach} + +
Exercice {$i}
{$theme->get_name()}{$teamName}
+ +
{/block} From a9fdcaf9f260b8634bc7c808725d10dee75ef23d Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 18:24:46 +0100 Subject: [PATCH 0111/2686] Use a variable to handle the misc_dir --- onyx/include/admin/certificate.php | 46 +++++++++++++++++++---------- onyx/include/admin/home.php | 27 ++++++++++++----- onyx/include/admin/import_users.php | 11 +++++-- 3 files changed, 58 insertions(+), 26 deletions(-) diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index ce7b4016..89e9ca61 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -24,39 +24,53 @@ function remove_directory($dir) function new_client($name) { - //TODO handle if already exist - putenv("OPENSSL_CONF=".ONYX. '../misc/openssl.cnf'); - putenv("TOP_DIR=".ONYX. '../misc/pki'); - $output = shell_exec(ONYX . "../misc/CA.sh -newclient $name"); + if (isset($VAR['misc_dir'])) + $misc_dir = $VAR['misc_dir']; + else + { + erreur("Merci d'ajouter la variable misc_dir dans root.xml"); + return "admin/home"; + } + + //TODO handle if already exist + putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); + putenv("TOP_DIR=$misc_dir/pki"); + $output = shell_exec("$misc_dir/CA.sh -newclient $name"); } if (!empty($p[2])) { + if (isset($VAR['misc_dir'])) + $misc_dir = $VAR['misc_dir']; + else + { + erreur("Merci d'ajouter la variable misc_dir dans root.xml"); + return "admin/home"; + } + + $misc_dir = $VAR['misc_dir']; + if ($p[2] == "newca") { - //TODO handle if already exist - putenv("OPENSSL_CONF=".ONYX. '../misc/openssl.cnf'); - putenv("TOP_DIR=".ONYX. '../misc/pki'); - $output = shell_exec(ONYX . '../misc/CA.sh -newca'); + putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); + putenv("TOP_DIR=$misc_dir/pki"); + $output = shell_exec("$misc_dir/CA.sh -newca"); - //TODO handle the path ? - $ca_file = ONYX . '../misc/pki/cacert.crt'; + $ca_file = "$misc_dir/pki/cacert.crt"; //TODO check permission ? if (file_exists($ca_file)) { - $data = openssl_x509_parse(file_get_contents(ONYX . '../misc/pki/cacert.crt')); + $data = openssl_x509_parse(file_get_contents("$misc_dir/pki/cacert.crt")); $template->assign("cert", $data); } } elseif ($p[2] == "deleteca") { - //TODO handle var path - $dir = ONYX . '../misc/pki'; - + $dir = "$misc_dir/pki"; remove_directory($dir); } } -//header("Location: /admin/"); -//exit; \ No newline at end of file +header("Location: /admin/"); +exit; diff --git a/onyx/include/admin/home.php b/onyx/include/admin/home.php index 2e333fa1..79bcbfcc 100644 --- a/onyx/include/admin/home.php +++ b/onyx/include/admin/home.php @@ -2,20 +2,31 @@ if(!defined('ONYX')) exit; -if (is_writable(ONYX."../misc/") && !is_dir(ONYX."../misc/pki/")) - mkdir(ONYX."../misc/pki/"); +if (isset($VAR['misc_dir'])) + $misc_dir = $VAR['misc_dir']; +else +{ + erreur("Merci d'ajouter la variable misc_dir dans root.xml"); + return "admin/home"; +} -$wright = is_writable(ONYX."../misc/pki/"); +if (is_writable($misc_dir) && !is_dir("$misc_dir/pki/")) + mkdir("$misc_dir/pki/"); + +$wright = is_writable("$misc_dir/pki/"); $template->assign("cert_writable", $wright); -//TODO handle the path ? -$ca_file = ONYX . '../misc/pki/cacert.crt'; +$ca_file = "$misc_dir/pki/cacert.crt"; -//TODO check permission ? if (file_exists($ca_file)) { - $data = openssl_x509_parse(file_get_contents(ONYX . '../misc/pki/cacert.crt')); - $template->assign("cert", $data); + if (!is_readable($ca_file)) + erreur("Impossible de lire le fichier"); + else + { + $data = openssl_x509_parse(file_get_contents(ONYX . '../misc/pki/cacert.crt')); + $template->assign("cert", $data); + } } return "admin/home"; diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index a8b328e5..aa28124d 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -6,8 +6,15 @@ include 'certificate.php'; if (!empty($_FILES["inputFile"]['tmp_name'])) { - //TODO use a variable to define the path - if (!file_exists(ONYX . "../misc/fic_pki/cacert.crt")) + if (isset($VAR['misc_dir'])) + $misc_dir = $VAR['misc_dir']; + else + { + erreur("Please add the misc_dir variable into root.xml"); + return "admin/import_users"; + } + + if (!file_exists("$misc_dir/pki/cacert.crt")) { erreur("The root certificate file not found, please create this first"); return "admin/import_users"; From 30802be380e3540af4c8ecd713f1ecbca0690515 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 19:02:49 +0100 Subject: [PATCH 0112/2686] Fixed create or delete ca redirection page --- onyx/include/admin/certificate.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index 89e9ca61..1fe836d7 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -70,7 +70,11 @@ if (!empty($p[2])) $dir = "$misc_dir/pki"; remove_directory($dir); } + + if ($p[2] == "deleteca" || $p[2] == "newca") + { + header("Location: /admin/"); + exit; + } } -header("Location: /admin/"); -exit; From e3f51487ab4d1c7e1d15642e8b31e30a76828475 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 19:18:51 +0100 Subject: [PATCH 0113/2686] Fixed client certificate generation --- onyx/include/admin/certificate.php | 10 +--------- onyx/include/admin/import_users.php | 2 +- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index 1fe836d7..c80b2a66 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -22,16 +22,8 @@ function remove_directory($dir) } } -function new_client($name) +function new_client($name, $misc_dir) { - if (isset($VAR['misc_dir'])) - $misc_dir = $VAR['misc_dir']; - else - { - erreur("Merci d'ajouter la variable misc_dir dans root.xml"); - return "admin/home"; - } - //TODO handle if already exist putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); putenv("TOP_DIR=$misc_dir/pki"); diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index aa28124d..76c4f292 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -72,7 +72,7 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) if (!empty($team->team_name)) { //TODO save the certificate subject - new_client($team->team_name); + new_client($team->team_name, $misc_dir); } } } From 7cf991d537f2df8bf02587e653632477103316ad Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 19:36:28 +0100 Subject: [PATCH 0114/2686] Add a textarea to show the output of the CA.sh --- misc/CA.sh | 20 +++++++++++++++----- onyx/include/admin/certificate.php | 1 + onyx/include/admin/import_users.php | 4 +++- onyx/tpl/bootstrap/admin/import_users.tpl | 5 +++++ 4 files changed, 24 insertions(+), 6 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index 1feb3e8c..6805446f 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -25,6 +25,8 @@ usage() [ $# -lt 1 ] && usage +OUTPUT=`mktemp` + case $1 in "-newca" ) # echo -e -n "${GREEN}Create the directories, take care this will delete" @@ -45,7 +47,11 @@ case $1 in sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= server #CERTTYPE/" $OPENSSL_CONF - pass=`pwgen 10 1` + pass=`pwgen 10 1` 2> $OUTPUT + if [ $? -ne 0 ]; then + cat $OUTPUT + exit 5 + fi openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ -out ${TOP_DIR}/${CAREQ} -passout pass:$pass \ @@ -72,7 +78,7 @@ case $1 in echo -e "${GREEN}Signing the Server crt${COLOR_RST}" openssl ca -policy policy_match -out server.crt -infiles server.csr if [ $? -ne 0 ]; then - echo -e "${RED}Signing failed${COLOR_RST}" + echo -e "${RED}Signing failed for new server${COLOR_RST}" rm -rf server.key server.crt server.csr exit 3 else @@ -94,7 +100,11 @@ case $1 in sed -i "s/=.*#COMMONNAME/= $2#COMMONNAME/" $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= client #CERTTYPE/" $OPENSSL_CONF - pass=`pwgen 10 1` + pass=`pwgen 10 1` 2> $OUTPUT + if [ $? -ne 0 ]; then + cat $OUTPUT + exit 5 + fi openssl req -batch -new -keyout ${2}.key -out ${2}.csr \ -config ${OPENSSL_CONF} -passout pass:$pass -days ${DAYS} @@ -103,14 +113,14 @@ case $1 in openssl ca -batch -policy policy_match -out ${2}.crt \ -config ${OPENSSL_CONF} -infiles ${2}.csr if [ $? -ne 0 ]; then - echo -e "${RED}Signing failed${COLOR_RST}" + echo -e "${RED}Signing failed for $2 ${COLOR_RST}" exit 3 fi # echo -e "${GREEN}Export the Client files to pkcs12${COLOR_RST}" openssl pkcs12 -export -inkey ${2}.key -in ${2}.crt -name ${2} \ -passin pass:$pass -out ${2}.p12 -passout pass:$pass if [ $? -ne 0 ]; then - echo -e "${RED}pkcs12 export failed${COLOR_RST}" + echo -e "${RED}pkcs12 export failed${COLOR_RST} for $2" exit 4 else echo -e "Exported pkcs12 file is ${2}.p12" diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index c80b2a66..24a8ddb7 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -28,6 +28,7 @@ function new_client($name, $misc_dir) putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); putenv("TOP_DIR=$misc_dir/pki"); $output = shell_exec("$misc_dir/CA.sh -newclient $name"); + return $output; } if (!empty($p[2])) diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index 76c4f292..b9b07dfc 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -31,6 +31,7 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) $elements = $xpath->query("//teams/team"); if (!is_null($elements)) { + $output = ""; foreach ($elements as $element) { $team = new Team(); @@ -72,9 +73,10 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) if (!empty($team->team_name)) { //TODO save the certificate subject - new_client($team->team_name, $misc_dir); + $output .= new_client($team->team_name, $misc_dir); } } + $template->assign("output", $output); } erreur("Fichier XML importé avec succès.", "success"); } diff --git a/onyx/tpl/bootstrap/admin/import_users.tpl b/onyx/tpl/bootstrap/admin/import_users.tpl index 73775932..72ed401c 100644 --- a/onyx/tpl/bootstrap/admin/import_users.tpl +++ b/onyx/tpl/bootstrap/admin/import_users.tpl @@ -10,4 +10,9 @@
+ +{if isset($output)} +

Output

+
{$output}
+{/if} {/block} From 04d96014092645071ffd26eda4b5c39c0fdb0ebb Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 20:59:22 +0100 Subject: [PATCH 0115/2686] Deleted heads bloc in layout and team.tpl --- onyx/tpl/bootstrap/admin/layout.tpl | 2 +- onyx/tpl/bootstrap/teams/team.tpl | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/onyx/tpl/bootstrap/admin/layout.tpl b/onyx/tpl/bootstrap/admin/layout.tpl index 393320ce..cf6b9d4a 100644 --- a/onyx/tpl/bootstrap/admin/layout.tpl +++ b/onyx/tpl/bootstrap/admin/layout.tpl @@ -3,7 +3,7 @@ {block name=head} {literal} {/literal} {/block} diff --git a/onyx/tpl/bootstrap/teams/team.tpl b/onyx/tpl/bootstrap/teams/team.tpl index 478e971e..eb92a925 100644 --- a/onyx/tpl/bootstrap/teams/team.tpl +++ b/onyx/tpl/bootstrap/teams/team.tpl @@ -1,9 +1,5 @@ {extends file="teams/layout.tpl"} -{block name=head} - -{/block} - {block name=content}

THIS IS TEAM From 3bd7654e81bd20eae821d4fdec13bea83f7e5d17 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 21:06:38 +0100 Subject: [PATCH 0116/2686] Delete href in logos and add Epita in the footer --- onyx/tpl/bootstrap/clock.tpl | 4 ---- onyx/tpl/bootstrap/layout.tpl | 3 ++- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/onyx/tpl/bootstrap/clock.tpl b/onyx/tpl/bootstrap/clock.tpl index 05c184c2..2b63efcb 100644 --- a/onyx/tpl/bootstrap/clock.tpl +++ b/onyx/tpl/bootstrap/clock.tpl @@ -1,13 +1,9 @@
    diff --git a/onyx/tpl/bootstrap/layout.tpl b/onyx/tpl/bootstrap/layout.tpl index 910a3a13..38523569 100644 --- a/onyx/tpl/bootstrap/layout.tpl +++ b/onyx/tpl/bootstrap/layout.tpl @@ -33,7 +33,8 @@
    From 124a7c2a32a017381357e5663e4a675a170d9be8 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Mon, 25 Nov 2013 21:30:53 +0100 Subject: [PATCH 0117/2686] Fixed error ouput when pwgen was not found --- misc/CA.sh | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index 6805446f..a0133311 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -25,8 +25,6 @@ usage() [ $# -lt 1 ] && usage -OUTPUT=`mktemp` - case $1 in "-newca" ) # echo -e -n "${GREEN}Create the directories, take care this will delete" @@ -47,12 +45,14 @@ case $1 in sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= server #CERTTYPE/" $OPENSSL_CONF - pass=`pwgen 10 1` 2> $OUTPUT + type pwgen > /dev/null if [ $? -ne 0 ]; then - cat $OUTPUT + echo "command not found: pwgen" exit 5 fi + pass=`pwgen 10 1` + openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ -out ${TOP_DIR}/${CAREQ} -passout pass:$pass \ -config $OPENSSL_CONF @@ -100,12 +100,14 @@ case $1 in sed -i "s/=.*#COMMONNAME/= $2#COMMONNAME/" $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= client #CERTTYPE/" $OPENSSL_CONF - pass=`pwgen 10 1` 2> $OUTPUT + type pwgen > /dev/null if [ $? -ne 0 ]; then - cat $OUTPUT + echo "command not found: pwgen" exit 5 fi + pass=`pwgen 10 1` + openssl req -batch -new -keyout ${2}.key -out ${2}.csr \ -config ${OPENSSL_CONF} -passout pass:$pass -days ${DAYS} From 62fca492ad7c2eaff2d5927c3390bc8d40b7775a Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Mon, 25 Nov 2013 23:06:26 +0100 Subject: [PATCH 0118/2686] Add timestamp comparison in ranking system --- onyx/include/common/Team.class.php | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 3a2cd470..30b9f343 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -5,7 +5,21 @@ if(!defined('ONYX')) exit; function cmp_team_pts($i1, $i2) { if ($i1->get_pts() == $i2->get_pts()){ - return 0; + $db = new BDD(); + + $timestampi1 = $db->unique_query("SELECT MAX( s.time ) AS maxTime + FROM solved AS s + WHERE s.id_team =".$i1); + $timestampi2 = $db->unique_query("SELECT MAX( s.time ) AS maxTime + FROM solved AS s + WHERE s.id_team =".$i12); + + $db->deconnexion(); + + if ($timestampi1 < $timestampi2){ + return 1 + else + return -1 } else{ return ($i1->get_pts() < $i2->get_pts()) ? 1 : -1; From 11dc0c153a6c73db3e12422970e37db846606b5c Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Tue, 26 Nov 2013 20:25:25 +0100 Subject: [PATCH 0119/2686] Fix some code errors that should not be commited yesterday... (sry) --- onyx/include/common/Team.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 30b9f343..0e3c9ffe 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -9,17 +9,17 @@ function cmp_team_pts($i1, $i2) $timestampi1 = $db->unique_query("SELECT MAX( s.time ) AS maxTime FROM solved AS s - WHERE s.id_team =".$i1); + WHERE s.id_team =".$i1->get_id()); $timestampi2 = $db->unique_query("SELECT MAX( s.time ) AS maxTime FROM solved AS s - WHERE s.id_team =".$i12); + WHERE s.id_team =".$i2->get_id()); $db->deconnexion(); - if ($timestampi1 < $timestampi2){ - return 1 + if ($timestampi1['maxTime'] > $timestampi2['maxTime']) + return 1; else - return -1 + return -1; } else{ return ($i1->get_pts() < $i2->get_pts()) ? 1 : -1; From 67b5422c28b1970849803fb8a8b86c68f698f166 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Thu, 28 Nov 2013 16:03:36 +0100 Subject: [PATCH 0120/2686] Deleted team/home Change the default page of team to summary page --- htdocs/index.php | 2 +- onyx/include/team/home.php | 8 -------- onyx/tpl/bootstrap/teams/home.tpl | 11 ----------- 3 files changed, 1 insertion(+), 20 deletions(-) delete mode 100644 onyx/include/team/home.php delete mode 100644 onyx/tpl/bootstrap/teams/home.tpl diff --git a/htdocs/index.php b/htdocs/index.php index 372a9adb..e451421d 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -108,7 +108,7 @@ else if ($n && $p[0] == SALT_USER) $template->assign("themes", Theme::get_themes()); if ($n <= 2) - $page = require("team/team.php"); + $page = require("team/summary.php"); else { switch($p[2]) diff --git a/onyx/include/team/home.php b/onyx/include/team/home.php deleted file mode 100644 index eaa60a72..00000000 --- a/onyx/include/team/home.php +++ /dev/null @@ -1,8 +0,0 @@ -assign("teams", Team::get_teams()); -$template->assign("top", Team::get_top()); - -return "teams/home"; diff --git a/onyx/tpl/bootstrap/teams/home.tpl b/onyx/tpl/bootstrap/teams/home.tpl deleted file mode 100644 index 5bcb3d87..00000000 --- a/onyx/tpl/bootstrap/teams/home.tpl +++ /dev/null @@ -1,11 +0,0 @@ -{extends file="teams/layout.tpl"} - -{block name=head} - -{/block} - -{block name=content} -

    - YOUPIII !!! -

    -{/block} From b406ae93e3b54721d6dacdc533efdae481fb788e Mon Sep 17 00:00:00 2001 From: Li Chen Date: Thu, 28 Nov 2013 16:28:43 +0100 Subject: [PATCH 0121/2686] Add team informations in the me page --- onyx/include/team/me.php | 2 ++ onyx/tpl/bootstrap/teams/me.tpl | 32 +++++++++++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/onyx/include/team/me.php b/onyx/include/team/me.php index 053de859..b6a81f13 100644 --- a/onyx/include/team/me.php +++ b/onyx/include/team/me.php @@ -2,4 +2,6 @@ if(!defined('ONYX')) exit; +$template->assign("members", $TEAM->get_members()); + return "teams/me"; diff --git a/onyx/tpl/bootstrap/teams/me.tpl b/onyx/tpl/bootstrap/teams/me.tpl index eafc7f2c..bd05fbd7 100644 --- a/onyx/tpl/bootstrap/teams/me.tpl +++ b/onyx/tpl/bootstrap/teams/me.tpl @@ -1,7 +1,33 @@ {extends file="teams/layout.tpl"} {block name=content} -

    - THIS IS ME -

    +
    +
    +

    Information sur l'équipe

    +
    +
    + {if not empty($members)} + + + + + + + + + + {foreach from=$members item=member} + + + + + + + {/foreach} + +
    #PrénomNomPseudonymeEntreprise
    {$member->firstname}{$member->lastname}{$member->nickname}{$member->company}
    + {/if} +
    +
    + {/block} From 4f2dbf54703e7897cd725afc93dee5c12e18e8df Mon Sep 17 00:00:00 2001 From: Li Chen Date: Thu, 28 Nov 2013 17:01:31 +0100 Subject: [PATCH 0122/2686] Add progress bar in the me page Fixed class panel-body name in the me.tpl --- onyx/include/team/summary.php | 15 +++++++++++++++ onyx/tpl/bootstrap/teams/me.tpl | 2 +- onyx/tpl/bootstrap/teams/summary.tpl | 15 +++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/onyx/include/team/summary.php b/onyx/include/team/summary.php index 4403c9ca..556a9298 100644 --- a/onyx/include/team/summary.php +++ b/onyx/include/team/summary.php @@ -2,7 +2,22 @@ if(!defined('ONYX')) exit; +$themes = Theme::get_themes(); +if (!empty($themes)) +{ + $max_exo = 0; + $res_exo = 0; + foreach($themes as $th) + { + $max_exo += $th->get_nb_exercices(); + //$res_exo += $TEAM->get_nb_res_exercices_by_theme($th->get_id()); + $res_exo += count($TEAM->get_solved_exercices($th->get_id())); + } + $percent = $res_exo * 100 / $max_exo; +} + $template->assign("themes", Theme::get_themes()); $template->assign("nbExoMax", Exercice::get_nb_exo_max()); +$template->assign("percent", $percent); return "teams/summary"; diff --git a/onyx/tpl/bootstrap/teams/me.tpl b/onyx/tpl/bootstrap/teams/me.tpl index bd05fbd7..7b73a58a 100644 --- a/onyx/tpl/bootstrap/teams/me.tpl +++ b/onyx/tpl/bootstrap/teams/me.tpl @@ -5,7 +5,7 @@

    Information sur l'équipe

    -
    +
    {if not empty($members)} diff --git a/onyx/tpl/bootstrap/teams/summary.tpl b/onyx/tpl/bootstrap/teams/summary.tpl index 944f6e13..cf025cba 100644 --- a/onyx/tpl/bootstrap/teams/summary.tpl +++ b/onyx/tpl/bootstrap/teams/summary.tpl @@ -1,5 +1,20 @@ {extends file="teams/layout.tpl"} {block name=content} +{if isset($percent)} +
    +
    +

    Progression

    +
    +
    +
    +
    + {$percent}% Complete +
    +
    +
    +
    +{/if} {include file="summary.tpl"} {/block} From dd766cf774e0c1a30df28a8757195cfd28dc70cb Mon Sep 17 00:00:00 2001 From: Li Chen Date: Thu, 28 Nov 2013 17:13:03 +0100 Subject: [PATCH 0123/2686] Team layout: change 'modifier' to 'info' --- onyx/tpl/bootstrap/teams/layout.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onyx/tpl/bootstrap/teams/layout.tpl b/onyx/tpl/bootstrap/teams/layout.tpl index 15921f1b..6be3e306 100644 --- a/onyx/tpl/bootstrap/teams/layout.tpl +++ b/onyx/tpl/bootstrap/teams/layout.tpl @@ -39,7 +39,7 @@ $(document).ready(function() { + {if $teams} @@ -19,6 +20,9 @@ @@ -29,6 +33,7 @@ + {/foreach} From c067f6dbbe754471e5008a01df9f4b1876cda9a3 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 00:24:53 +0100 Subject: [PATCH 0141/2686] Fixed undefined var in admin/home.tpl --- onyx/tpl/bootstrap/admin/home.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onyx/tpl/bootstrap/admin/home.tpl b/onyx/tpl/bootstrap/admin/home.tpl index 35c6d854..b9c60a39 100644 --- a/onyx/tpl/bootstrap/admin/home.tpl +++ b/onyx/tpl/bootstrap/admin/home.tpl @@ -16,7 +16,7 @@
  • [emailAddress] : {$cert['subject']['emailAddress']}
  • Supprimer - {elseif ! $cert_writable} + {elseif isset($cert_writable) && ! $cert_writable}
    Répertoire non accessible en écriture.
    Nouveau {else} From 745d8a8bd5e3196629c272b2728da1cb40408b9b Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 01:08:40 +0100 Subject: [PATCH 0142/2686] Fixed multiple team->update in import_users Show the pass at the end of import --- misc/CA.sh | 3 +-- onyx/include/admin/import_users.php | 13 +++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index 45911707..1f23c18e 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -181,8 +181,7 @@ case $1 in echo -e "Exported pkcs12 file is ${2}.p12" fi mv ${2}.crt ${TOP_DIR}/certs -# TODO handle this file - echo "$2:$pass" >> teams.pass + echo "$2:$pass" >> ${TOP_DIR}/../teams.pass clean "client" $2 ;; "-revoke" ) diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index c143971c..dece7040 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -48,15 +48,15 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) else if ($child->nodeName == "member") { - if (!$team->update()) + // Slogan rly needed ? + if (empty($team->id) && !$team->update()) { - $error .= "Unable to add team $team->team_name
    "; - continue; + $error .= "Unable to add team $team->team_name
    "; + continue; } $user = new Member(); $user->team = $team; - foreach ($child->childNodes as $child_member) { if ($child_member->nodeName == "firstname") @@ -87,6 +87,11 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) $output .= new_client($team->team_name, $misc_dir); } } + if (file_exists("$misc_dir/teams.pass")) + { + $output .= file_get_contents("$misc_dir/teams.pass"); + unlink("$misc_dir/teams.pass"); + } $template->assign("output", $output); } From 3f0a403fd4c08869bdd7e3f80dcd41395057e593 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 01:17:30 +0100 Subject: [PATCH 0143/2686] Add some confirmation before delete user or revoke certificate --- onyx/tpl/bootstrap/admin/users.tpl | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/onyx/tpl/bootstrap/admin/users.tpl b/onyx/tpl/bootstrap/admin/users.tpl index 201c04a4..6c9f0aa0 100644 --- a/onyx/tpl/bootstrap/admin/users.tpl +++ b/onyx/tpl/bootstrap/admin/users.tpl @@ -19,10 +19,15 @@
    @@ -41,10 +46,13 @@ From 964d3b067f663e36fd2b6cd3dc20ff1fae5d3a48 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 19:21:32 +0100 Subject: [PATCH 0144/2686] Dont show generate certificate and revoke together --- onyx/tpl/bootstrap/admin/users.tpl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/onyx/tpl/bootstrap/admin/users.tpl b/onyx/tpl/bootstrap/admin/users.tpl index 6c9f0aa0..5cb1d126 100644 --- a/onyx/tpl/bootstrap/admin/users.tpl +++ b/onyx/tpl/bootstrap/admin/users.tpl @@ -21,13 +21,16 @@ {$t->id}
    + + + {if not $t->revoked} - - + {else} + {/if}
    From 31eabf84b468305cd3fe4aeeb50a5a30c988f773 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 19:40:47 +0100 Subject: [PATCH 0145/2686] Move the function remove_team from list_users.php to Team.class Revoke certificates after drop all teams --- onyx/include/admin/certificate.php | 15 ++++++++----- onyx/include/admin/list_users.php | 35 ++++++++++++++++++++---------- onyx/include/common/Team.class.php | 9 ++++++++ onyx/tpl/bootstrap/admin/users.tpl | 2 +- 4 files changed, 43 insertions(+), 18 deletions(-) diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index 23a35290..580d6b62 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -31,6 +31,13 @@ function new_client($name, $misc_dir) return $output; } +function revoke_client($name, $misc_dir) +{ + putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); + putenv("TOP_DIR=$misc_dir/pki"); + $output = shell_exec("$misc_dir/CA.sh -revoke $name"); +} + if (!empty($p[2])) { if (isset($VAR['misc_dir'])) @@ -60,11 +67,9 @@ if (!empty($p[2])) $name = $_GET['name']; if (isset($name)) { - putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); - putenv("TOP_DIR=$misc_dir/pki"); - $output = shell_exec("$misc_dir/CA.sh -revoke $name"); - //TODO Check revocation failed - Team::set_revoked(TRUE, $name); + $output = revoke_client($name, $misc_dir); + //TODO Check revocation failed + Team::set_revoked(TRUE, $name); } } // Is new team diff --git a/onyx/include/admin/list_users.php b/onyx/include/admin/list_users.php index 3968bc16..3ac2871f 100644 --- a/onyx/include/admin/list_users.php +++ b/onyx/include/admin/list_users.php @@ -2,29 +2,40 @@ if(!defined('ONYX')) exit; -function remove_team($id) -{ - $db = new BDD(); - $db->query("DELETE FROM team_members WHERE id_team = ".$id); - $db->query("DELETE FROM solved WHERE id_team = ".$id); - $db->query("DELETE FROM teams WHERE id = ".$id); - $db->deconnexion(); -} +include 'certificate.php'; if (!empty($_GET["delete"])) { - $id_team = intval($_GET["delete"]); + if (isset($VAR['misc_dir'])) + $misc_dir = $VAR['misc_dir']; + else + { + erreur("Merci d'ajouter la variable misc_dir dans root.xml"); + return SALT_ADMIN."/users"; + } - remove_team($id_team); + $id_team = intval($_GET["delete"]); + revoke_client($_GET['name'], $misc_dir); + Team::remove_team($id_team); header("Location: /".SALT_ADMIN."/teams"); exit; } else if (isset($_GET["drop"])) { + if (isset($VAR['misc_dir'])) + $misc_dir = $VAR['misc_dir']; + else + { + erreur("Merci d'ajouter la variable misc_dir dans root.xml"); + return SALT_ADMIN."/users"; + } + foreach(Team::get_teams() as $team) { - remove_team($team->get_id()); + //TODO check output + revoke_client($team->team_name, $misc_dir); + Team::remove_team($team->get_id()); } header("Location: /".SALT_ADMIN."/teams"); @@ -33,4 +44,4 @@ else if (isset($_GET["drop"])) $template->assign("teams", Team::get_teams()); -return "admin/users"; \ No newline at end of file +return SALT_ADMIN."/users"; diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index d9b3a966..f2ba89e9 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -246,6 +246,15 @@ class Team return ($aff == 1); } + public static function remove_team($id) + { + $db = new BDD(); + $db->query("DELETE FROM team_members WHERE id_team = ".$id); + $db->query("DELETE FROM solved WHERE id_team = ".$id); + $db->query("DELETE FROM teams WHERE id = ".$id); + $db->deconnexion(); + } + public static function get_teams() { $db = new BDD(); diff --git a/onyx/tpl/bootstrap/admin/users.tpl b/onyx/tpl/bootstrap/admin/users.tpl index 5cb1d126..3745aa70 100644 --- a/onyx/tpl/bootstrap/admin/users.tpl +++ b/onyx/tpl/bootstrap/admin/users.tpl @@ -19,7 +19,7 @@ - + From 854da4a12a08f4e5807e3ea0b9e09d35d08d085b Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 20:04:49 +0100 Subject: [PATCH 0147/2686] Change the icone download to floppy-save in the list_users page --- onyx/tpl/bootstrap/admin/users.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onyx/tpl/bootstrap/admin/users.tpl b/onyx/tpl/bootstrap/admin/users.tpl index 3745aa70..387013bb 100644 --- a/onyx/tpl/bootstrap/admin/users.tpl +++ b/onyx/tpl/bootstrap/admin/users.tpl @@ -22,7 +22,7 @@ - + {if not $t->revoked} From ad5052bb992aaa94885cb354f5d35a240b990dfa Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 20:24:59 +0100 Subject: [PATCH 0148/2686] Add confimation to delete the root certificat --- onyx/tpl/bootstrap/admin/home.tpl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/onyx/tpl/bootstrap/admin/home.tpl b/onyx/tpl/bootstrap/admin/home.tpl index b9c60a39..33a7366d 100644 --- a/onyx/tpl/bootstrap/admin/home.tpl +++ b/onyx/tpl/bootstrap/admin/home.tpl @@ -15,7 +15,8 @@
  • [CN] : {$cert['subject']['CN']}
  • [emailAddress] : {$cert['subject']['emailAddress']}
  • -
    Supprimer + Supprimer {elseif isset($cert_writable) && ! $cert_writable}
    Répertoire non accessible en écriture.
    Nouveau From 8f2edb704872c9d7cf8e472c87d3db628f2a11dd Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 20:29:59 +0100 Subject: [PATCH 0149/2686] Add catch NotFoundException in admin/exercice.php --- onyx/include/admin/exercice.php | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/onyx/include/admin/exercice.php b/onyx/include/admin/exercice.php index fa6858cd..415e1901 100644 --- a/onyx/include/admin/exercice.php +++ b/onyx/include/admin/exercice.php @@ -4,17 +4,33 @@ if(!defined('ONYX')) exit; $p = $out[0]; -if (isset($p[2])) +//TODO maybe move the try catch to index.html ? +try { + if (isset($p[2])) + { $tmp = explode("-", $p[2]); $id = intval($tmp[0]); if ($id == 0) return "404"; $theme = new Theme($id); $template->assign("theme", $theme); + } + + if (isset($p[3])) + $template->assign("ex", new Exercice($p[3], $theme)); +} +catch (ThemeNotFoundException $e) +{ + return "404"; +} +catch(ExerciceNotFoundException $e) +{ + return "404"; +} +catch(ExerciceNotFoundException $e) +{ + return "404"; } -if (isset($p[3])) - $template->assign("ex", new Exercice($p[3], $theme)); - return SALT_ADMIN."/exercice"; From 4d1918a530e7837eab4db4da72c7089178d95cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Mon, 9 Dec 2013 11:54:06 +0100 Subject: [PATCH 0150/2686] Add a script for generating static site --- gen_site.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100755 gen_site.sh diff --git a/gen_site.sh b/gen_site.sh new file mode 100755 index 00000000..52544b99 --- /dev/null +++ b/gen_site.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +BASEURL="localhost" + +cd `dirname "$0"` + +mkdir -p out +cd out + +wget -c -m http://$BASEURL/ http://$BASEURL/connected/ From e2173a7d4474e7d26033a397992e1a1bd63cde78 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 11 Dec 2013 12:58:17 +0100 Subject: [PATCH 0151/2686] Modification for production --- htdocs/index.php | 7 +++++-- misc/openssl.cnf | 6 +++--- nginx.conf | 26 ++++++++++++++++++++------ onyx/config/sample.root.xml | 7 ++++++- onyx/tpl/bootstrap/clock.tpl | 6 +++--- onyx/tpl/bootstrap/layout.tpl | 6 +++--- 6 files changed, 40 insertions(+), 18 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index b14b78ba..0be26241 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -2,8 +2,9 @@ //Inclusion de l'API Onyx require_once(trim(file_get_contents('./.onyx'))); -define("SALT_USER", "connected"); -define("SALT_ADMIN", "admin"); +define("SALT_PUBLIC", $VAR["prefix_public"]); +define("SALT_USER", $VAR["prefix_teams"]); +define("SALT_ADMIN", $VAR["prefix_admin"]); //On active le débogage si l'on est sur le domaine de debug @@ -13,6 +14,8 @@ if ($_SERVER["SERVER_NAME"] == "localhost" || $_SERVER["SERVER_NAME"] == "fic" | //Chargement de tout le nécessaire pour le site require_once("common.php"); +$template->assign("SALT_CDN",SALT_PUBLIC); +$template->assign("SALT_PUBLIC",SALT_PUBLIC); $template->assign("SALT_USER",SALT_USER); $template->assign("SALT_ADMIN",SALT_ADMIN); diff --git a/misc/openssl.cnf b/misc/openssl.cnf index 95fa5f76..a8c067f9 100644 --- a/misc/openssl.cnf +++ b/misc/openssl.cnf @@ -39,7 +39,7 @@ default_ca = CA_default # The default ca section #################################################################### [ CA_default ] -dir = fic_pki #DIR # Where everything is kept +dir = /srv/fic2014-server/misc//pki #DIR # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. @@ -147,7 +147,7 @@ organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = SRS commonName = Common Name (e.g. server FQDN or YOUR name) -commonName_default = toto#COMMONNAME +commonName_default = FIC2014 Server #COMMONNAME commonName_max = 64 emailAddress = Email Address @@ -176,7 +176,7 @@ basicConstraints=CA:FALSE # the certificate can be used for anything *except* object signing. # This is OK for an SSL server. -nsCertType = client #CERTTYPE +nsCertType = server #CERTTYPE # For an object signing certificate this would be used. # nsCertType = objsign diff --git a/nginx.conf b/nginx.conf index 1a4f42e1..b7fc7845 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,12 +1,26 @@ server { - listen 80; - listen [::]:80; - server_name fic fic.p0m.fr fic.nemunai.re; + listen 443 ssl; + listen [::]:443 ipv6only=on; access_log /var/log/nginx/fic.access_log; - error_log /var/log/nginx/fic.error_log debug; + error_log /var/log/nginx/fic.error_log; - root /var/www/fic2014-server/htdocs; + root /srv/fic2014-server/htdocs; + index index.php; + + ssl_certificate /srv/fic2014-server/misc/server.crt; + ssl_certificate_key /srv/fic2014-server/misc/server.key; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; + ssl_client_certificate /srv/fic2014-server/misc/pki/cacert.crt; + ssl_verify_client on; + add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; + + if ($ssl_client_s_dn !~ "/C=FR/ST=France/O=Epita/OU=SRS/") + { + return 401; + } location / { if (-f $request_filename) { @@ -39,7 +53,7 @@ server { { if (!-e $document_root$document_uri) { return 404; } include /etc/nginx/fastcgi.conf; - fastcgi_pass 127.0.0.1:9000; + fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; break; } diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml index e6291018..0491002f 100644 --- a/onyx/config/sample.root.xml +++ b/onyx/config/sample.root.xml @@ -1,8 +1,13 @@ - + 1381441316 + /srv/fic2014-server/misc/ + /srv/fic2014-server/submission/ ]]> + challenge-public + challenge + challenge-admin 0 diff --git a/onyx/tpl/bootstrap/clock.tpl b/onyx/tpl/bootstrap/clock.tpl index 10b4febb..7cbddfeb 100644 --- a/onyx/tpl/bootstrap/clock.tpl +++ b/onyx/tpl/bootstrap/clock.tpl @@ -1,11 +1,11 @@
      diff --git a/onyx/tpl/bootstrap/layout.tpl b/onyx/tpl/bootstrap/layout.tpl index 38523569..12be4bb4 100644 --- a/onyx/tpl/bootstrap/layout.tpl +++ b/onyx/tpl/bootstrap/layout.tpl @@ -5,7 +5,7 @@ {block name=title}Challenge FIC2014{/block} - + - + @@ -38,7 +38,7 @@ - + {block name=end}{/block} From 49554c01c8d9bfc3991c5fa109d584e228a74689 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 11 Dec 2013 12:58:20 +0100 Subject: [PATCH 0152/2686] Modification for production --- gen_site.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gen_site.sh b/gen_site.sh index 52544b99..442b3511 100755 --- a/gen_site.sh +++ b/gen_site.sh @@ -7,4 +7,4 @@ cd `dirname "$0"` mkdir -p out cd out -wget -c -m http://$BASEURL/ http://$BASEURL/connected/ +wget -c -m https://$BASEURL/ https://$BASEURL/connected/ From c7d0f7d1e126f5085a5f671c47c96d3204aabb47 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 11 Dec 2013 17:20:26 +0100 Subject: [PATCH 0153/2686] Modification for two servers --- nginx-server-common.conf | 43 ++++++++++++++++++++++++ nginx-server.conf | 18 ++++++++++ nginx.conf | 66 ++++++++++++++++++------------------- onyx/config/sample.root.xml | 10 +++--- 4 files changed, 98 insertions(+), 39 deletions(-) create mode 100644 nginx-server-common.conf create mode 100644 nginx-server.conf diff --git a/nginx-server-common.conf b/nginx-server-common.conf new file mode 100644 index 00000000..c5d27bc7 --- /dev/null +++ b/nginx-server-common.conf @@ -0,0 +1,43 @@ + access_log /var/log/nginx/fic.access_log; + error_log /var/log/nginx/fic.error_log; + + root /var/www/fic2014-server/htdocs; + index index.php; + + add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; + + location / { + if (-f $request_filename) { + break; + } + if (-d $request_filename) { + break; + } + + rewrite ^/(.*)$ /index.php?p=$1 last; + } + + location ~* \favicon.ico$ { + access_log off; + expires 1d; + add_header Cache-Control public; + } + + location ~ ^/(img|js|css)/ { + access_log off; + expires 7d; + add_header Cache-Control public; + } + + location ~ /(\.ht|\.git|\.svn|\.onyx) { + return 403; + } + + location ~ .*.php$ + { + if (!-e $document_root$document_uri) { return 404; } + include /etc/nginx/fastcgi.conf; + fastcgi_pass unix:/var/run/fastcgi/php-fpm.sock; + fastcgi_index index.php; + break; + } diff --git a/nginx-server.conf b/nginx-server.conf new file mode 100644 index 00000000..ba338775 --- /dev/null +++ b/nginx-server.conf @@ -0,0 +1,18 @@ +server { + listen 443 ssl; + listen [::]:443 ipv6only=on ssl; + + ssl_certificate /var/www/fic2014-server/misc/server.crt; + ssl_certificate_key /var/www/fic2014-server/misc/server.key; +# ssl_protocols TLSv1 TLSv1.1 TLSv1.2; +# ssl_prefer_server_ciphers on; +# ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; + + include /var/www/fic2014-server/nginx-server-common.conf; +} + +server { + listen [::1]:80 ipv6only=on; + + include /var/www/fic2014-server/nginx-server-common.conf; +} diff --git a/nginx.conf b/nginx.conf index b7fc7845..796a8d48 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,60 +1,58 @@ server { listen 443 ssl; - listen [::]:443 ipv6only=on; + listen [::]:443 ipv6only=on ssl; + + root /var/www/fic2014-server/htdocs/; access_log /var/log/nginx/fic.access_log; error_log /var/log/nginx/fic.error_log; - root /srv/fic2014-server/htdocs; - index index.php; - - ssl_certificate /srv/fic2014-server/misc/server.crt; - ssl_certificate_key /srv/fic2014-server/misc/server.key; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_prefer_server_ciphers on; - ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; - ssl_client_certificate /srv/fic2014-server/misc/pki/cacert.crt; - ssl_verify_client on; + ssl_certificate /var/www/fic2014-server/misc/server.crt; + ssl_certificate_key /var/www/fic2014-server/misc/server.key; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; + ssl_client_certificate /var/www/fic2014-server/misc/pki/cacert.crt; + ssl_verify_client on; add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; - if ($ssl_client_s_dn !~ "/C=FR/ST=France/O=Epita/OU=SRS/") + location / { - return 401; - } + default_type text/html; + if ($ssl_client_s_dn !~ "/C=FR/ST=France/O=Epita/OU=SRS/") + { + return 401; + } - location / { - if (-f $request_filename) { - break; - } - if (-d $request_filename) { - break; - } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Team1/") { + root /var/www/fic2014-server/htdocs/connected/166$1; - rewrite ^/(.*)$ /index.php?p=$1 last; + rewrite ^/submission-([0-9]+)-([0-9]+).html$ /submission.php?team=166&theme=$1&exercice=$2 last; + } } location ~* \favicon.ico$ { - access_log off; - expires 1d; - add_header Cache-Control public; + access_log off; + expires 1d; + add_header Cache-Control public; } location ~ ^/(img|js|css)/ { - access_log off; - expires 7d; - add_header Cache-Control public; + access_log off; + expires 7d; + add_header Cache-Control public; } location ~ /(\.ht|\.git|\.svn|\.onyx) { - deny all; + return 403; } - location ~ .*.php$ + location /submission.php { - if (!-e $document_root$document_uri) { return 404; } - include /etc/nginx/fastcgi.conf; - fastcgi_pass unix:/var/run/php5-fpm.sock; - fastcgi_index index.php; + root /var/www/fic2014-server/; + include /etc/nginx/fastcgi.conf; + fastcgi_pass unix:/var/run/fastcgi/php-fpm.sock; break; } + } diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml index 0491002f..d94fd659 100644 --- a/onyx/config/sample.root.xml +++ b/onyx/config/sample.root.xml @@ -1,13 +1,13 @@ - + - 1381441316 - /srv/fic2014-server/misc/ - /srv/fic2014-server/submission/ - ]]> + 1386827772 + /var/www/fic2014-server/misc/ + /var/www/fic2014-server/submission/ challenge-public challenge challenge-admin + ]]> 0 From bc877802cc0aa47468a6a00bf3fec3df60cbc867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Wed, 11 Dec 2013 18:10:39 +0100 Subject: [PATCH 0154/2686] Start check submission script --- check.pl | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100755 check.pl diff --git a/check.pl b/check.pl new file mode 100755 index 00000000..2c12913a --- /dev/null +++ b/check.pl @@ -0,0 +1,80 @@ +#!/usr/bin/env perl + +use v5.10.1; +use strict; +use warnings; +use DBI; + +use Data::Dumper; + +# First, read PHP configuration to extract some settings +my $profile; +my $submission_dir; + +open my $conf, "<", "onyx/config/root.xml"; +for my $p (<$conf>) +{ + if ($p =~ /<(?:option|var) name="(.*)">(.*)<\/(?:option|var)>/) + { + $profile = $2 if ($1 eq "profile"); + $submission_dir = $2 if ($1 eq "submission_dir"); + } +} +close $conf; + +die("No DB profile found") if ! $profile; +die("submission_dir is not a directory") if ! $submission_dir || ! -d $submission_dir; + +# Read db settings +my %db_settings; +open my $dbprof, "<", "onyx/db/$profile.profile.php"; +while (<$dbprof>) +{ + if (/\$___profile\[['"](.+)['"]\] = ['"](.+)['"]/) + { + $db_settings{$1} = $2; + } +} +close $dbprof; + +my $dbh; +# List all files to treat +opendir(my $dh, $submission_dir) || die "Can't opendir submission_dir: $!"; +for my $f (readdir $dh) +{ + if ($f =~ /^([0-9]+)-([0-9]+)-([0-9]+)$/) + { + my $team = $1; + my $theme = $2; + my $exercice = $3; + + open my $fh, "<", "$submission_dir/$f"; + my $solution = <$fh>; + close $fh; + + $dbh = DBI->connect("DBI:mysql:database=$db_settings{db};host=$db_settings{host};port=3306", + $db_settings{user}, $db_settings{pass}, + {'RaiseError' => 1, 'PrintError' => 1}) + or die $DBI::errstr if !$dbh; + + my $sth = query($dbh, "SELECT format, value FROM exercice_keys WHERE id_exercice = ".int($exercice)); + + while (my $row = get_row($sth)) + { + say Dumper($row); + } + } +} +closedir $dh; + +$dbh->disconnect() if $dbh; + +sub query +{ + my $sth = $_[0]->prepare($_[1]); + $sth->execute(); + + die($_[0]->errstr) if (!$sth); + + return $sth; +} From 9109c3e3e019da5f89ce957ba2d6a2c5c75d6fd6 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 11 Dec 2013 18:11:32 +0100 Subject: [PATCH 0155/2686] Add gencrl into CA.sh --- misc/CA.sh | 34 ++++++++++++++++++++++++------ onyx/include/admin/certificate.php | 4 +++- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index 1f23c18e..aa0f6212 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -25,7 +25,7 @@ END_BOLD="" usage() { - echo "Usage: $0 (-newca|-newserver|-newclient NAME|-revoke NAME)" + echo "Usage: $0 (-newca|-newserver|-newclient NAME|-revoke NAME|-gencrl)" exit 1 } @@ -38,8 +38,9 @@ clean() mkdir -p ${TOP_DIR}/newcerts mkdir -p ${TOP_DIR}/private mkdir -p ${TOP_DIR}/pkcs + echo "01" > ${TOP_DIR}/crlnumber elif [ "$1" = "client" ]; then - rm -rf ${2}.key ${2}.csr + rm -rf ${TOP_DIR}/${2}.key ${TOP_DIR}/${2}.csr fi rm -rf $OUTPUT } @@ -151,7 +152,7 @@ case $1 in pass=`pwgen -n -B -y 12 1` - openssl req -batch -new -keyout ${2}.key -out ${2}.csr \ + openssl req -batch -new -keyout ${TOP_DIR}/${2}.key -out ${TOP_DIR}/${2}.csr \ -config ${OPENSSL_CONF} -passout pass:$pass -days ${DAYS} > $OUTPUT 2>&1 if [ $? -ne 0 ]; then cat $OUTPUT @@ -160,8 +161,8 @@ case $1 in fi echo -e "${GREEN}Signing the Client crt${COLOR_RST}" - openssl ca -batch -policy policy_match -out ${2}.crt \ - -config ${OPENSSL_CONF} -infiles ${2}.csr > $OUTPUT 2>&1 + openssl ca -batch -policy policy_match -out ${TOP_DIR}/${2}.crt \ + -config ${OPENSSL_CONF} -infiles ${TOP_DIR}/${2}.csr > $OUTPUT 2>&1 if [ $? -ne 0 ]; then echo -e "${RED}Signing failed for $2 ${COLOR_RST}" cat $OUTPUT @@ -169,7 +170,7 @@ case $1 in exit 3 fi echo -e "${GREEN}Export the Client files to pkcs12${COLOR_RST}" - openssl pkcs12 -export -inkey ${2}.key -in ${2}.crt -name ${2} \ + openssl pkcs12 -export -inkey ${TOP_DIR}/${2}.key -in ${TOP_DIR}/${2}.crt -name ${2} \ -passin pass:$pass -out ${TOP_DIR}/pkcs/${2}.p12 \ -passout pass:$pass > $OUTPUT 2>&1 if [ $? -ne 0 ]; then @@ -180,8 +181,9 @@ case $1 in else echo -e "Exported pkcs12 file is ${2}.p12" fi - mv ${2}.crt ${TOP_DIR}/certs + mv ${TOP_DIR}/${2}.crt ${TOP_DIR}/certs echo "$2:$pass" >> ${TOP_DIR}/../teams.pass + echo "$pass" clean "client" $2 ;; "-revoke" ) @@ -200,7 +202,25 @@ case $1 in fi rm ${TOP_DIR}/certs/${2}.crt rm ${TOP_DIR}/pkcs/${2}.p12 + + echo -e "${GREEN}Generate crl.pem${COLOR_RST}" + openssl ca -config ${OPENSSL_CONF} -gencrl -out ${TOP_DIR}/crl.pem > $OUTPUT 2>&1 + if [ $? -ne 0 ]; then + echo -e "${RED}Generate crl.pem failed" + cat $OUTPUT + exit 5 + fi + ;; + "-gencrl" ) + echo -e "${GREEN}Generate crl.pem${COLOR_RST}" + openssl ca -config ${OPENSSL_CONF} -gencrl -out ${TOP_DIR}/crl.pem > $OUTPUT 2>&1 + if [ $? -ne 0 ]; then + echo -e "${RED}Generate crl.pem failed" + cat $OUTPUT + exit 5 + fi + ;; * ) usage ;; diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index 580d6b62..5698f903 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -80,8 +80,10 @@ if (!empty($p[2])) //TODO check revoked attribute if (isset($name)) { - new_client($name, $misc_dir); + $output = new_client($name, $misc_dir); Team::set_revoked(FALSE, $name); + erreur($output, "sucess"); + return "admin/import_users"; } } elseif ($p[2] == "get") From 2b88c05dd77297235add38da2b700b3eeb3211ec Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 11 Dec 2013 18:12:12 +0100 Subject: [PATCH 0156/2686] Add ssl_crl in nginx.conf --- nginx.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nginx.conf b/nginx.conf index 796a8d48..5bcfbb8e 100644 --- a/nginx.conf +++ b/nginx.conf @@ -15,7 +15,8 @@ server { ssl_client_certificate /var/www/fic2014-server/misc/pki/cacert.crt; ssl_verify_client on; add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; - + ssl_crl /var/www/fic2014-server/misc/pki/crl.pem; + location / { default_type text/html; From 812f87c22e57266fe1358ddb190142f06e33bae6 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Wed, 11 Dec 2013 19:16:51 +0100 Subject: [PATCH 0157/2686] Exercice.class.php: Fixed intval in exercice id --- onyx/include/common/Exercice.class.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/onyx/include/common/Exercice.class.php b/onyx/include/common/Exercice.class.php index 8d8bf053..48010ae2 100644 --- a/onyx/include/common/Exercice.class.php +++ b/onyx/include/common/Exercice.class.php @@ -135,12 +135,14 @@ class Exercice do { array_push($checked, $exo); - $res = $db->unique_query("SELECT `require` FROM exercices WHERE id = ".intval($exo)); + $res = $db->unique_query("SELECT `require` FROM exercices WHERE id = ".$exo); $exo = $res['require']; $ret++; } while ($exo != "" && !in_array($exo, $checked)); $this->number = $ret; + + $db->deconnexion(); } function update($create) From b3beb516b05463d1d05c1766b737661067f94a4c Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Wed, 11 Dec 2013 19:18:45 +0100 Subject: [PATCH 0158/2686] Modify get_top for TOP3 themes --- onyx/include/common/Team.class.php | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index f2ba89e9..42f928ed 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -2,7 +2,7 @@ if(!defined('ONYX')) exit; -function cmp_team_pts($i1, $i2) +function cmp_team_pts($i1, $i2, $idTheme) { if ($i1->get_pts() == $i2->get_pts()){ $db = new BDD(); @@ -22,7 +22,7 @@ function cmp_team_pts($i1, $i2) return -1; } else{ - return ($i1->get_pts() < $i2->get_pts()) ? 1 : -1; + return ($i1->get_pts($idTheme) < $i2->get_pts($idTheme)) ? 1 : -1; } } @@ -147,17 +147,29 @@ class Team return $this->members; } - function get_pts() + function get_pts($themeID=-1) { if(!isset($this->points)) { $db = new BDD(); + $res = null; - $res = $db->unique_query("SELECT E.id, S.id_team, SUM(E.points) as sum_points + if ($themeID != -1) + { + $res = $db->unique_query("SELECT E.id, S.id_team, SUM(E.points) as sum_points FROM exercices E LEFT OUTER JOIN solved S ON E.id = S.id_exercice WHERE S.id_team = ".$this->id." GROUP BY S.id_team"); + } + else + { + $res = $db->unique_query("SELECT E.id, S.id_team, SUM(E.points) as sum_points + FROM exercices E + LEFT OUTER JOIN solved S ON E.id = S.id_exercice + WHERE S.id_team = ".$this->id." AND E.id_theme = ".$themeID." + GROUP BY S.id_team"); + } $db->deconnexion(); @@ -269,11 +281,11 @@ class Team return $array; } - public static function get_top($nb=0) + public static function get_top($nb=0, $idTheme=-1) { $teams = Team::get_teams(); - usort($teams, "cmp_team_pts"); + usort($teams, "cmp_team_pts", $idTheme); if ($nb != 0) $teams = array_slice($teams, 0, $nb); From 60ec66ee2d9646b04b4e68ec78cc44f4e665d8a2 Mon Sep 17 00:00:00 2001 From: Quentin Grosyeux Date: Thu, 12 Dec 2013 17:40:49 +0100 Subject: [PATCH 0159/2686] Summary display correction --- onyx/tpl/bootstrap/summary.tpl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/onyx/tpl/bootstrap/summary.tpl b/onyx/tpl/bootstrap/summary.tpl index d0350e49..6c2572de 100644 --- a/onyx/tpl/bootstrap/summary.tpl +++ b/onyx/tpl/bootstrap/summary.tpl @@ -14,6 +14,7 @@
    {$sum=0} + {$cpt=0} {$themeID=$theme->get_id()} {$solved_exercices=$my_team->get_solved_exercices($themeID)} {foreach from=$theme->get_exercices_ordered() item=exo} @@ -30,8 +31,12 @@ {else} {/if} + {$cpt=$cpt+1} {/foreach} - + {for $i=$cpt to $nbExoMax-1} + + {/for} + {$total=$total+$sum} {/foreach} @@ -42,4 +47,4 @@ -
    Membres Points PlaceRévoqué
    {$t->id}
    + + +
    {$t->team_name} {$t->slogan}{$t->get_pts()} {$t->get_rank()}{if $t->revoked}Oui{else}Non{/if}
    {$t->id}
    - - - - + + + + + + + +
    {$t->team_name} {$t->slogan}
    - Importer + + Importer {if $teams} - Exporter - Vider + + Exporter + + Vider {/if}
    {$t->team_name} {$t->slogan}
    {$t->id}
    - + From 5656d116afe5c354f7e0ecd436ab69b34b0b7c9b Mon Sep 17 00:00:00 2001 From: Li Chen Date: Sun, 1 Dec 2013 20:03:20 +0100 Subject: [PATCH 0146/2686] Fixed bad url in theme page --- onyx/include/admin/exercice.php | 13 ++++++++++--- onyx/tpl/bootstrap/admin/exercice.tpl | 12 ++++++++++-- onyx/tpl/bootstrap/admin/themes.tpl | 4 ++-- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/onyx/include/admin/exercice.php b/onyx/include/admin/exercice.php index 3a925efb..fa6858cd 100644 --- a/onyx/include/admin/exercice.php +++ b/onyx/include/admin/exercice.php @@ -5,9 +5,16 @@ if(!defined('ONYX')) exit; $p = $out[0]; if (isset($p[2])) - $template->assign("theme", $p[2]); +{ + $tmp = explode("-", $p[2]); + $id = intval($tmp[0]); + if ($id == 0) + return "404"; + $theme = new Theme($id); + $template->assign("theme", $theme); +} if (isset($p[3])) - $template->assign("ex", $p[3]); + $template->assign("ex", new Exercice($p[3], $theme)); -return "admin/exercice"; +return SALT_ADMIN."/exercice"; diff --git a/onyx/tpl/bootstrap/admin/exercice.tpl b/onyx/tpl/bootstrap/admin/exercice.tpl index 1537536f..605034b2 100644 --- a/onyx/tpl/bootstrap/admin/exercice.tpl +++ b/onyx/tpl/bootstrap/admin/exercice.tpl @@ -1,7 +1,15 @@ {extends file="admin/layout.tpl"} {block name=content}

    - Theme: {$theme}
    - Exercice: {$ex} + Theme: {$theme->name}
    + {if isset($ex)} + Exercice: {$ex->id} + {else} +

      + {foreach $theme->get_exercices_ordered() as $ex} +
    • {$ex->get_name()}
    • + {/foreach} +
    + {/if}

    {/block} diff --git a/onyx/tpl/bootstrap/admin/themes.tpl b/onyx/tpl/bootstrap/admin/themes.tpl index 150ded87..86c9bf2b 100644 --- a/onyx/tpl/bootstrap/admin/themes.tpl +++ b/onyx/tpl/bootstrap/admin/themes.tpl @@ -19,10 +19,10 @@ Exporter
    {$t->name}{$t->name} FIXME
    {$theme->get_name()}{$pts}{$sum}{$sum}
    {$total}
    + \ No newline at end of file From 0f7c1bc7e9381838be0c4ba002e90d9762f9981c Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 12 Dec 2013 16:43:01 +0100 Subject: [PATCH 0160/2686] Fixed sha1 Exercice.class --- onyx/include/common/Exercice.class.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/onyx/include/common/Exercice.class.php b/onyx/include/common/Exercice.class.php index 48010ae2..df3cde50 100644 --- a/onyx/include/common/Exercice.class.php +++ b/onyx/include/common/Exercice.class.php @@ -16,6 +16,8 @@ class Exercice function Exercice($id=null, $theme=null) { + global $VAR; + if (!empty($id)) { $db = new BDD(); @@ -33,7 +35,13 @@ class Exercice // Decode sha1 if ($this->files) foreach($this->files as &$f) + { + $f["path_orig"] = $f["path"]; + if (isset($VAR["files_dir"])) + $f["path"] = $VAR["files_dir"].$f["path"]; + $f["basename"] = basename($f["path"]); $f["sha1"] = strhex($f["sha1"]); + } $this->keys = $db->query("SELECT `id`, `format`, `value` FROM exercice_keys @@ -135,7 +143,7 @@ class Exercice do { array_push($checked, $exo); - $res = $db->unique_query("SELECT `require` FROM exercices WHERE id = ".$exo); + $res = $db->unique_query("SELECT `require` FROM exercices WHERE id = '".$exo."'"); $exo = $res['require']; $ret++; } while ($exo != "" && !in_array($exo, $checked)); @@ -181,7 +189,7 @@ class Exercice $format = $key['format']; $value = $key['value']; if (isset($key['id'])) - $kid = intval($key['id']); + $kid = $key['id']; else $kid = 0; @@ -219,14 +227,14 @@ class Exercice if (!isset($file['id'])) { $db->query("INSERT INTO exercice_files - VALUES (NULL, '".$id."', '".$path."', '".$name."', '".$sha1."');"); + VALUES (NULL, '".$id."', '".$path."', '".$name."', UNHEX('".$sha1."'));"); $this->files[$k]['id'] = $db->insert_id(); } else { $db->query("UPDATE exercice_files - SET `path` = '".$path."', `name` = '".$name."', `sha1` = '".$sha1."' + SET `path` = '".$path."', `name` = '".$name."', `sha1` = UNHEX('".$sha1."') WHERE id = ".$fid); } } From 01624d389c56a069de6ec9678607e4eb5d027aa1 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 12 Dec 2013 17:00:35 +0100 Subject: [PATCH 0161/2686] Fixed themes drop --- onyx/include/admin/list_themes.php | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/onyx/include/admin/list_themes.php b/onyx/include/admin/list_themes.php index b8e40b76..5b74f0b9 100644 --- a/onyx/include/admin/list_themes.php +++ b/onyx/include/admin/list_themes.php @@ -8,9 +8,11 @@ function remove_themes($id) $res = $db->query("SELECT id FROM exercices WHERE id_theme = ".$id); foreach($res as $r) { - $db->query("DELETE FROM exercice_files WHERE id_exercice = ".$id); - $db->query("DELETE FROM exercice_keys WHERE id_exercice = ".$id); - $db->query("DELETE FROM solved WHERE id_exercice = ".$id); + $id_ex = $r['id']; + $db->escape($id_ex); + $db->query("DELETE FROM exercice_files WHERE id_exercice = '".$id_ex."'"); + $db->query("DELETE FROM exercice_keys WHERE id_exercice = '".$id_ex."'"); + $db->query("DELETE FROM solved WHERE id_exercice = '".$id_ex."'"); } $db->query("DELETE FROM exercices WHERE id_theme = ".$id); @@ -29,10 +31,13 @@ if (!empty($_GET["delete"])) } else if (isset($_GET["drop"])) { - foreach(Theme::get_themes() as $thm) - { - remove_themes($thm->get_id()); - } + $db = new BDD(); + $db->query("TRUNCATE exercice_files"); + $db->query("TRUNCATE exercice_keys"); + $db->query("TRUNCATE exercices"); + $db->query("TRUNCATE themes"); + $db->query("TRUNCATE solved"); + $db->deconnexion(); header("Location: /".SALT_ADMIN."/themes"); exit; @@ -40,4 +45,4 @@ else if (isset($_GET["drop"])) $template->assign("themes", Theme::get_themes()); -return "admin/themes"; \ No newline at end of file +return "admin/themes"; From 60f950dd6c1055b61b2bb94e8381db5594b42f70 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 12 Dec 2013 18:02:16 +0100 Subject: [PATCH 0162/2686] Add file_dir into sample.root.xml --- onyx/config/sample.root.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml index d94fd659..4d05ed20 100644 --- a/onyx/config/sample.root.xml +++ b/onyx/config/sample.root.xml @@ -2,6 +2,7 @@ 1386827772 + /var/www/fic2014-server/files/ /var/www/fic2014-server/misc/ /var/www/fic2014-server/submission/ challenge-public From 4b101ef4b2f0e39865ee10b2fbae0808764c8cc6 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 12 Dec 2013 19:33:18 +0100 Subject: [PATCH 0163/2686] Modify public theme --- onyx/tpl/bootstrap/public/home.tpl | 5 ++--- onyx/tpl/bootstrap/public/layout.tpl | 1 - onyx/tpl/bootstrap/summary.tpl | 6 +++--- onyx/tpl/bootstrap/teams/exercice.tpl | 4 ++-- onyx/tpl/bootstrap/teams/theme.tpl | 4 ++-- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index 6f0d757e..73af278d 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -1,9 +1,9 @@ {extends file="public/layout.tpl"} {block name=main} -
    +
    - +
    @@ -33,7 +33,6 @@ {/foreach}
    -
    {/block} diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index 1ce60ca4..d6022bdc 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -36,7 +36,6 @@ {foreach from=$teams item=my_team key=k}
    -

    {$my_team->get_name()}

    {include file="summary.tpl"}
    diff --git a/onyx/tpl/bootstrap/summary.tpl b/onyx/tpl/bootstrap/summary.tpl index 6c2572de..71b33b7c 100644 --- a/onyx/tpl/bootstrap/summary.tpl +++ b/onyx/tpl/bootstrap/summary.tpl @@ -1,7 +1,7 @@ - +
    - + {for $i=1 to $nbExoMax} {/for} @@ -47,4 +47,4 @@ -
    {$my_team->get_name()}Exercice {$i}{$total}
    \ No newline at end of file + diff --git a/onyx/tpl/bootstrap/teams/exercice.tpl b/onyx/tpl/bootstrap/teams/exercice.tpl index 387c43f8..f9151160 100644 --- a/onyx/tpl/bootstrap/teams/exercice.tpl +++ b/onyx/tpl/bootstrap/teams/exercice.tpl @@ -33,7 +33,7 @@ {if file_exists($file['path'])} - + @@ -56,7 +56,7 @@ {if $cur_exercice->has_solved($my_team)} Déjà résolu à {$cur_exercice->has_solved($my_team)|date_format:"%H:%M:%S"} :) {else} -
    +
    diff --git a/onyx/tpl/bootstrap/teams/theme.tpl b/onyx/tpl/bootstrap/teams/theme.tpl index 4b043282..14b4052f 100644 --- a/onyx/tpl/bootstrap/teams/theme.tpl +++ b/onyx/tpl/bootstrap/teams/theme.tpl @@ -6,9 +6,9 @@

    {foreach from=$cur_theme->get_exercices_ordered() item=exercice} {if $exercice->has_solved($my_team)} - {link class="btn btn-success" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name()}/{$exercice->get_id()}" label="{$exercice->get_name()}"} + {link class="btn btn-success" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}" label="{$exercice->get_name()}"} {elseif $exercice->is_unlocked($my_team)} - {link class="btn btn-primary" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name()}/{$exercice->get_id()}" label="{$exercice->get_name()}"} + {link class="btn btn-primary" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}" label="{$exercice->get_name()}"} {else} {$exercice->get_name()} {/if} From bbec08ac4ff80565fbe565f7167b0e5cb78b2b9f Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 13 Dec 2013 18:45:25 +0100 Subject: [PATCH 0164/2686] Server synchronisation --- check.pl | 58 +++++++++++++++++++++++++--- gen_site.sh | 83 +++++++++++++++++++++++++++++++++++++++- nginx-server-common.conf | 7 +++- nginx.conf | 41 +++++++++++++++----- submission.php | 24 ++++++++++++ synchro.sh | 23 +++++++++++ 6 files changed, 218 insertions(+), 18 deletions(-) create mode 100644 submission.php create mode 100755 synchro.sh diff --git a/check.pl b/check.pl index 2c12913a..9d88f259 100755 --- a/check.pl +++ b/check.pl @@ -4,14 +4,20 @@ use v5.10.1; use strict; use warnings; use DBI; +use File::Basename; -use Data::Dumper; +#Return number of good solutions +my $exit = 0; + +my $root = dirname(__FILE__); + +chdir($root); # First, read PHP configuration to extract some settings my $profile; my $submission_dir; -open my $conf, "<", "onyx/config/root.xml"; +open my $conf, "<", "$root/onyx/config/root.xml"; for my $p (<$conf>) { if ($p =~ /<(?:option|var) name="(.*)">(.*)<\/(?:option|var)>/) @@ -27,7 +33,7 @@ die("submission_dir is not a directory") if ! $submission_dir || ! -d $submissio # Read db settings my %db_settings; -open my $dbprof, "<", "onyx/db/$profile.profile.php"; +open my $dbprof, "<", "$root/onyx/db/$profile.profile.php"; while (<$dbprof>) { if (/\$___profile\[['"](.+)['"]\] = ['"](.+)['"]/) @@ -42,8 +48,10 @@ my $dbh; opendir(my $dh, $submission_dir) || die "Can't opendir submission_dir: $!"; for my $f (readdir $dh) { - if ($f =~ /^([0-9]+)-([0-9]+)-([0-9]+)$/) + if ($f =~ /^([0-9]+)-([0-9]+)-([a-zA-Z0-9_]+)$/) { + my $good = -1; + my $team = $1; my $theme = $2; my $exercice = $3; @@ -57,18 +65,51 @@ for my $f (readdir $dh) {'RaiseError' => 1, 'PrintError' => 1}) or die $DBI::errstr if !$dbh; - my $sth = query($dbh, "SELECT format, value FROM exercice_keys WHERE id_exercice = ".int($exercice)); + my $sth = query($dbh, "SELECT format, value FROM exercice_keys WHERE id_exercice = '$exercice';"); + # Check solutions while (my $row = get_row($sth)) { - say Dumper($row); + $good = 1 if ($good == -1); + + my $type = @$row[0]; + my $sol = @$row[1]; + + if ($type eq "raw" && $sol ne $solution) { + $good = 0; + last; + } + elsif ($type ne "raw") { + $good = 0; + warn "$type not implemented"; + last; + } } + + # Register solve + if ($good == -1) { + say "Exercice $exercice doesn't exist ; given by team $team in theme $theme."; + } + elsif ($good == 1) + { + say "Team $team solve exercice $exercice in $theme at ".localtime(); + query($dbh, "INSERT INTO solved (id_team, id_exercice, time) VALUES ($team, '$exercice', CURRENT_TIMESTAMP);"); + $exit++; + } + else { + say "Team $team didn't give the correct answer for exercice $exercice."; + } + + # Remove the file + unlink("$submission_dir/$f"); } } closedir $dh; $dbh->disconnect() if $dbh; +exit( $exit > 126 ? 126 : $exit ); + sub query { my $sth = $_[0]->prepare($_[1]); @@ -78,3 +119,8 @@ sub query return $sth; } + +sub get_row +{ + return $_[0]->fetchrow_arrayref(); +} diff --git a/gen_site.sh b/gen_site.sh index 442b3511..974eeb67 100755 --- a/gen_site.sh +++ b/gen_site.sh @@ -1,10 +1,91 @@ #!/bin/sh BASEURL="localhost" +SALT_TEAM="connected" +OUT_TEAM="./teams" + +MAX_PARAL=9 + +DEBUG=0 + cd `dirname "$0"` +if [ "$UID" = "0" ] +then + SCRIPT=`pwd`/`basename "$0"` + su -c "sh -c '$SCRIPT $@'" synchro + exit $? +fi + +if [ -f "/tmp/generate_site" ] +then + echo "This script is already running" 1>&2 + echo "Remove the file /tmp/generate_site if you are sure this is not true" 1>&2 + exit 1 +fi + +touch /tmp/generate_site + +WGET_OPT="--no-check-certificate -c" + +if [ $DEBUG -ne 1 ] +then + WGET_OPT="-q" +fi + mkdir -p out cd out -wget -c -m https://$BASEURL/ https://$BASEURL/connected/ +# First, remove existing version if any +rm -rf "$BASEURL" "$OUT_TEAM" + +wget $WGET_OPT -m -b "http://$BASEURL/" -o /dev/null + +mkdir -p "$BASEURL" +ln -sf "`pwd`/../files/" "$BASEURL/files" + +NB=0 +PIDLIST= +# Get list of teams and fetch them in parallel +for l in $(curl -k "http://$BASEURL/$SALT_TEAM/" 2> /dev/null | grep -oE "/[^/]+/[0-9]+/") +do + ( + wget $WGET_OPT -m "http://$BASEURL/$l" + + for m in $(grep -R " Date: Fri, 13 Dec 2013 18:48:13 +0100 Subject: [PATCH 0165/2686] Thursday release --- .gitignore | 1 + misc/openssl.cnf | 6 +++--- onyx/include/common/Team.class.php | 15 +++++++++------ onyx/include/common/Theme.class.php | 5 +++++ onyx/tpl/bootstrap/public/layout.tpl | 2 +- onyx/tpl/bootstrap/summary.tpl | 2 +- onyx/tpl/bootstrap/teams/me.tpl | 1 - 7 files changed, 20 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index cb02566c..b1d213ad 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ onyx/config/root.xml onyx/db/*.profile.php onyx/tpl/*/*.html submission/* +misc/openssl.cnf diff --git a/misc/openssl.cnf b/misc/openssl.cnf index a8c067f9..a0183194 100644 --- a/misc/openssl.cnf +++ b/misc/openssl.cnf @@ -39,7 +39,7 @@ default_ca = CA_default # The default ca section #################################################################### [ CA_default ] -dir = /srv/fic2014-server/misc//pki #DIR # Where everything is kept +dir = /var/www/fic2014-server/misc//pki #DIR # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. @@ -147,7 +147,7 @@ organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = SRS commonName = Common Name (e.g. server FQDN or YOUR name) -commonName_default = FIC2014 Server #COMMONNAME +commonName_default = Groupe_8#COMMONNAME commonName_max = 64 emailAddress = Email Address @@ -176,7 +176,7 @@ basicConstraints=CA:FALSE # the certificate can be used for anything *except* object signing. # This is OK for an SSL server. -nsCertType = server #CERTTYPE +nsCertType = client #CERTTYPE # For an object signing certificate this would be used. # nsCertType = objsign diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 42f928ed..83aae4e7 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -121,6 +121,10 @@ class Team return $this->team_name; } + function get_name_url() { + return urlencode($this->team_name); + } + function get_auth_level() { return $this->auth_level; } @@ -195,10 +199,10 @@ class Team function get_rank() { $teams = Team::get_top(); - for ($i = 0; $i < 10; $i++){ - $tid = $teams[$i]->get_id(); - if ($tid == $this->id) - return $i; + foreach($teams as $k => $t) + { + if ($t->get_id() == $this->id) + return $k + 1; } return 0; @@ -232,9 +236,8 @@ class Team $i = 0; if ($ids) { - foreach ($ids as $id){ + foreach ($ids as $id) $array[] = new Exercice($id['id_exercice']); - } } return $array; diff --git a/onyx/include/common/Theme.class.php b/onyx/include/common/Theme.class.php index 15f81d41..9ff832c4 100644 --- a/onyx/include/common/Theme.class.php +++ b/onyx/include/common/Theme.class.php @@ -60,6 +60,11 @@ class Theme return $this->name; } + function get_name_url() + { + return urlencode($this->name); + } + function get_id() { return $this->id; diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index d6022bdc..a71a787b 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -54,7 +54,7 @@ $(document).ready(function() { update_end(); $('#carousel-team').carousel({ - interval: 2000 }); + interval: 5000 }); setInterval( function() { update_end(); diff --git a/onyx/tpl/bootstrap/summary.tpl b/onyx/tpl/bootstrap/summary.tpl index 71b33b7c..e65c6d12 100644 --- a/onyx/tpl/bootstrap/summary.tpl +++ b/onyx/tpl/bootstrap/summary.tpl @@ -12,7 +12,7 @@ {$total=0} {foreach from=$themes item=theme} - {$theme->get_name()} + {$theme->get_name()} {$sum=0} {$cpt=0} {$themeID=$theme->get_id()} diff --git a/onyx/tpl/bootstrap/teams/me.tpl b/onyx/tpl/bootstrap/teams/me.tpl index 7b73a58a..ca4ec59d 100644 --- a/onyx/tpl/bootstrap/teams/me.tpl +++ b/onyx/tpl/bootstrap/teams/me.tpl @@ -9,7 +9,6 @@ {if not empty($members)} - From 134f6be772fb13ef6e97a2b3afa9c826c3177cc5 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 13 Dec 2013 19:02:44 +0100 Subject: [PATCH 0166/2686] Disable the print of difficulty (always 0) --- onyx/tpl/bootstrap/teams/exercice.tpl | 1 - 1 file changed, 1 deletion(-) diff --git a/onyx/tpl/bootstrap/teams/exercice.tpl b/onyx/tpl/bootstrap/teams/exercice.tpl index f9151160..d07770c8 100644 --- a/onyx/tpl/bootstrap/teams/exercice.tpl +++ b/onyx/tpl/bootstrap/teams/exercice.tpl @@ -7,7 +7,6 @@
      -
    • Difficulté : {$cur_exercice->level}
    • Gain : {$cur_exercice->points}
    • Description : {$cur_exercice->statement}
    From 6cabc4003f2b9a4b38587f82b09bce3a11ac6b91 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 13 Dec 2013 20:03:04 +0100 Subject: [PATCH 0167/2686] Revert "Modify get_top for TOP3 themes" This reverts commit b3beb516b05463d1d05c1766b737661067f94a4c. --- onyx/include/common/Team.class.php | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 83aae4e7..35a48d45 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -2,7 +2,7 @@ if(!defined('ONYX')) exit; -function cmp_team_pts($i1, $i2, $idTheme) +function cmp_team_pts($i1, $i2) { if ($i1->get_pts() == $i2->get_pts()){ $db = new BDD(); @@ -22,7 +22,7 @@ function cmp_team_pts($i1, $i2, $idTheme) return -1; } else{ - return ($i1->get_pts($idTheme) < $i2->get_pts($idTheme)) ? 1 : -1; + return ($i1->get_pts() < $i2->get_pts()) ? 1 : -1; } } @@ -151,29 +151,17 @@ class Team return $this->members; } - function get_pts($themeID=-1) + function get_pts() { if(!isset($this->points)) { $db = new BDD(); - $res = null; - if ($themeID != -1) - { - $res = $db->unique_query("SELECT E.id, S.id_team, SUM(E.points) as sum_points + $res = $db->unique_query("SELECT E.id, S.id_team, SUM(E.points) as sum_points FROM exercices E LEFT OUTER JOIN solved S ON E.id = S.id_exercice WHERE S.id_team = ".$this->id." GROUP BY S.id_team"); - } - else - { - $res = $db->unique_query("SELECT E.id, S.id_team, SUM(E.points) as sum_points - FROM exercices E - LEFT OUTER JOIN solved S ON E.id = S.id_exercice - WHERE S.id_team = ".$this->id." AND E.id_theme = ".$themeID." - GROUP BY S.id_team"); - } $db->deconnexion(); @@ -284,11 +272,11 @@ class Team return $array; } - public static function get_top($nb=0, $idTheme=-1) + public static function get_top($nb=0) { $teams = Team::get_teams(); - usort($teams, "cmp_team_pts", $idTheme); + usort($teams, "cmp_team_pts"); if ($nb != 0) $teams = array_slice($teams, 0, $nb); From 10eb72688fce178e42ee60f0c7a75eefdc7a78c7 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Fri, 13 Dec 2013 20:11:26 +0100 Subject: [PATCH 0168/2686] Add some check before solving exercice --- check.pl | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/check.pl b/check.pl index 9d88f259..4c87106b 100755 --- a/check.pl +++ b/check.pl @@ -65,7 +65,7 @@ for my $f (readdir $dh) {'RaiseError' => 1, 'PrintError' => 1}) or die $DBI::errstr if !$dbh; - my $sth = query($dbh, "SELECT format, value FROM exercice_keys WHERE id_exercice = '$exercice';"); + my $sth = query($dbh, "SELECT format, value FROM exercice_keys WHERE id_exercice = ".$dbh->quote($exercice)); # Check solutions while (my $row = get_row($sth)) @@ -88,16 +88,40 @@ for my $f (readdir $dh) # Register solve if ($good == -1) { - say "Exercice $exercice doesn't exist ; given by team $team in theme $theme."; + say localtime().": Exercice $exercice doesn't exist ; given by team $team in theme $theme."; } elsif ($good == 1) { - say "Team $team solve exercice $exercice in $theme at ".localtime(); - query($dbh, "INSERT INTO solved (id_team, id_exercice, time) VALUES ($team, '$exercice', CURRENT_TIMESTAMP);"); - $exit++; + # Check if the exercice exists + $sth = query($dbh, "SELECT `require` FROM exercices E WHERE E.id_theme = $theme AND E.id = ".$dbh->quote($exercice)); + if ($sth->rows && (my $row = get_row($sth))) + { + # Check if the team has solved dependancies + $sth = query($dbh, "SELECT COUNT(S.id) FROM solved S WHERE S.id_exercice = ".$dbh->quote(@$row[0])) if @$row[0]; + if (! (@$row[0] && $sth->rows)) + { + # Check if the team has not already solved this exercice + $sth = query($dbh, "SELECT COUNT(S.id) FROM solved S WHERE S.id_exercice = ".$dbh->quote($exercice)); + if (! $sth->rows) + { + say localtime().": Team $team solve exercice $exercice in $theme"; + query($dbh, "INSERT INTO solved (id_team, id_exercice, time) VALUES ($team, ".$dbh->quote($exercice).", CURRENT_TIMESTAMP);"); + $exit++; + } + else { + warn localtime().": Team $team try to solve exercice $exercice in $theme but ALREADY solved it"; + } + } + else { + warn localtime().": Team $team try to solve exercice $exercice in $theme but has NOT SOLVED required exercice ".@$row[0]; + } + } + else { + warn localtime().": Team $team try to solve exercice $exercice in $theme but does not exist"; + } } else { - say "Team $team didn't give the correct answer for exercice $exercice."; + say localtime().": Team $team didn't give the correct answer for exercice $exercice."; } # Remove the file From c349769425ada01d6755bec979393763e7695473 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 14 Dec 2013 06:11:14 +0100 Subject: [PATCH 0169/2686] Friday release --- check.pl | 17 +++--- clear_cache.sh | 15 +++++ gen_site.sh | 83 ++++++++++++++++++++++---- launch.sh | 53 ++++++++++++++++ nginx.conf | 1 + onyx/include/admin/list_themes.php | 2 + onyx/include/common/Exercice.class.php | 58 ++++++++++++++++-- onyx/include/common/Team.class.php | 47 ++++++++------- onyx/include/common/Theme.class.php | 19 +++++- onyx/require/cache.php | 31 ++++++---- onyx/tpl/bootstrap/public/home.tpl | 26 ++++++-- onyx/tpl/bootstrap/public/layout.tpl | 25 +++----- onyx/tpl/bootstrap/public/score.tpl | 1 - onyx/tpl/bootstrap/summary.tpl | 10 ++-- onyx/tpl/bootstrap/teams/exercice.tpl | 2 +- synchro.sh | 18 ++++-- 16 files changed, 319 insertions(+), 89 deletions(-) create mode 100755 clear_cache.sh create mode 100755 launch.sh diff --git a/check.pl b/check.pl index 4c87106b..147e5ca0 100755 --- a/check.pl +++ b/check.pl @@ -88,23 +88,26 @@ for my $f (readdir $dh) # Register solve if ($good == -1) { - say localtime().": Exercice $exercice doesn't exist ; given by team $team in theme $theme."; + say STDERR localtime().": Exercice $exercice doesn't exist ; given by team $team in theme $theme."; } elsif ($good == 1) { # Check if the exercice exists $sth = query($dbh, "SELECT `require` FROM exercices E WHERE E.id_theme = $theme AND E.id = ".$dbh->quote($exercice)); - if ($sth->rows && (my $row = get_row($sth))) + if ($sth->rows) { + my $row = get_row($sth); + # Check if the team has solved dependancies - $sth = query($dbh, "SELECT COUNT(S.id) FROM solved S WHERE S.id_exercice = ".$dbh->quote(@$row[0])) if @$row[0]; - if (! (@$row[0] && $sth->rows)) + $sth = query($dbh, "SELECT S.id FROM solved S WHERE S.id_exercice = ".$dbh->quote(@$row[0])) if @$row[0]; + if (! @$row[0] || $sth->rows) { # Check if the team has not already solved this exercice - $sth = query($dbh, "SELECT COUNT(S.id) FROM solved S WHERE S.id_exercice = ".$dbh->quote($exercice)); + $sth = query($dbh, "SELECT S.id FROM solved S WHERE S.id_exercice = ".$dbh->quote($exercice)); if (! $sth->rows) { - say localtime().": Team $team solve exercice $exercice in $theme"; + say $team; + say STDERR localtime().": Team $team solve exercice $exercice in $theme"; query($dbh, "INSERT INTO solved (id_team, id_exercice, time) VALUES ($team, ".$dbh->quote($exercice).", CURRENT_TIMESTAMP);"); $exit++; } @@ -121,7 +124,7 @@ for my $f (readdir $dh) } } else { - say localtime().": Team $team didn't give the correct answer for exercice $exercice."; + say STDERR localtime().": Team $team didn't give the correct answer for exercice $exercice."; } # Remove the file diff --git a/clear_cache.sh b/clear_cache.sh new file mode 100755 index 00000000..cb528dd4 --- /dev/null +++ b/clear_cache.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +cd `dirname "$0"` + +for n in "$@" +do + MD5=`echo -n $n | md5sum | cut -d " " -f 1` + if [ -f "onyx/cache/$MD5.cache.php" ] + then + rm -f "onyx/cache/$MD5.cache.php" + echo "--- $n deleted" + else + echo "/!\\ $n not found ($MD5)" + fi +done diff --git a/gen_site.sh b/gen_site.sh index 974eeb67..4667aea2 100755 --- a/gen_site.sh +++ b/gen_site.sh @@ -4,7 +4,7 @@ BASEURL="localhost" SALT_TEAM="connected" OUT_TEAM="./teams" -MAX_PARAL=9 +MAX_PARAL=10 DEBUG=0 @@ -34,8 +34,13 @@ then WGET_OPT="-q" fi +./clear_cache.sh top + mkdir -p out -cd out + +ORIG_DIR=`pwd` +MYTMPDIR=`mktemp -d` +cd "$MYTMPDIR" # First, remove existing version if any rm -rf "$BASEURL" "$OUT_TEAM" @@ -43,15 +48,38 @@ rm -rf "$BASEURL" "$OUT_TEAM" wget $WGET_OPT -m -b "http://$BASEURL/" -o /dev/null mkdir -p "$BASEURL" -ln -sf "`pwd`/../files/" "$BASEURL/files" +ln -sf "$ORIG_DIR/files/" "$BASEURL/files" + +# Get list of teams +TEAMS= +if [ $# -gt 0 ] +then + while [ $# -gt 0 ] + do + TEAMS="$TEAMS /$SALT_TEAM/$1/" + shift + done + FULLSYNC=0 +else + for l in $(curl -k "http://$BASEURL/$SALT_TEAM/" 2> /dev/null | grep -oE "/[^/]+/[0-9]+/") + do + TEAMS="$TEAMS $l" + done + FULLSYNC=1 +fi + +echo "Team list to generate: $TEAMS" NB=0 PIDLIST= -# Get list of teams and fetch them in parallel -for l in $(curl -k "http://$BASEURL/$SALT_TEAM/" 2> /dev/null | grep -oE "/[^/]+/[0-9]+/") +# Fetch them in parallel +for l in $TEAMS do ( - wget $WGET_OPT -m "http://$BASEURL/$l" + if ! wget $WGET_OPT -m "http://$BASEURL/$l" + then + exit 1 + fi for m in $(grep -R "&2 + exit $ERR + +else + MOREOPT= + if [ "$FULL" -eq "1" ] + then + MOREOPT="--delete" + fi + # Ok, now, sync files with prod + rsync -av $MOREOPT * "$ORIG_DIR/out" + + cd "$ORIG_DIR" + rm -rf "$MYTMPDIR" +fi diff --git a/launch.sh b/launch.sh new file mode 100755 index 00000000..5847e65c --- /dev/null +++ b/launch.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +cd `dirname "$0"` + +if [ "$UID" = "0" ] +then + SCRIPT=`pwd`/`basename "$0"` + su -c "sh $SCRIPT" synchro + exit $? +fi + +touch ./logs/checks.log +tail -f ./logs/checks.log & + +FULLREGEN=0 + +while true; +do + if [ "$FULLREGEN" != "0" ] + then + ./synchro.sh + else + ./synchro.sh delete + fi + + if [ `ls submission | wc -l` -gt 1 ] + then + TMPF=`mktemp` + if ! ./check.pl 2>> ./logs/checks.log > "$TMPF" + then + FULLREGEN=1 + fi + + if [ `cat "$TMPF" | wc -l` -gt 0 ] + then + while ! cat "$TMPF" | xargs ./gen_site.sh + do + echo "FAIL regeneration, retry..." 1>&2 + done + fi + rm "$TMPF" + + elif [ "$FULLREGEN" != "0" ] + then + while ! ./gen_site.sh; do + echo "FAIL regeneration, retry..." 1>&2 + done + FULLREGEN=0 + + else + sleep 1 + fi +done diff --git a/nginx.conf b/nginx.conf index 1ed8be7d..04144ca7 100644 --- a/nginx.conf +++ b/nginx.conf @@ -21,6 +21,7 @@ server { location / { default_type text/html; + expires epoch; set $team 0; diff --git a/onyx/include/admin/list_themes.php b/onyx/include/admin/list_themes.php index 5b74f0b9..a52a60f1 100644 --- a/onyx/include/admin/list_themes.php +++ b/onyx/include/admin/list_themes.php @@ -18,6 +18,8 @@ function remove_themes($id) $db->query("DELETE FROM exercices WHERE id_theme = ".$id); $db->query("DELETE FROM themes WHERE id = ".$id); $db->deconnexion(); + + Cache::del("ordered_th".$id); } if (!empty($_GET["delete"])) diff --git a/onyx/include/common/Exercice.class.php b/onyx/include/common/Exercice.class.php index df3cde50..d74111f9 100644 --- a/onyx/include/common/Exercice.class.php +++ b/onyx/include/common/Exercice.class.php @@ -75,6 +75,23 @@ class Exercice } } + static function __set_state(array $array) + { + $tmp = new Exercice(); + + $tmp->id = $array["id"]; + $tmp->number = $array["number"]; + $tmp->theme = $array["theme"]; + $tmp->require = $array["require"]; + $tmp->level = $array["level"]; + $tmp->points = $array["points"]; + $tmp->statement = $array["statement"]; + $tmp->files = $array["files"]; + $tmp->keys = $array["keys"]; + + return $tmp; + } + function get_id() { return $this->id; @@ -89,10 +106,12 @@ class Exercice // trié par date function get_solved() { - $db = new BDD(); + $id = $this->id; + $db = new BDD(); + $db->escape($id); $res = $db->query("SELECT `id_team`, `time` FROM solved - WHERE id_exercice = '$this->id' + WHERE id_exercice = '$id' ORDER BY time"); $db->deconnexion(); @@ -105,11 +124,13 @@ class Exercice if ($this->require == "") return 1; - $db = new BDD(); + $req = $this->require; + $db = new BDD(); + $db->escape($req); $res = $db->unique_query("SELECT `id` FROM solved WHERE id_team = '".intval($team->id)."' - AND id_exercice = '$this->require'"); + AND id_exercice = '$req'"); $db->deconnexion(); if (empty($res)) return 0; @@ -118,9 +139,11 @@ class Exercice function has_solved($team) { - $db = new BDD(); + $id = $this->id; - $res = $db->unique_query("SELECT `time` FROM solved WHERE id_exercice = '$this->id' + $db = new BDD(); + $db->escape($id); + $res = $db->unique_query("SELECT `time` FROM solved WHERE id_exercice = '$id' AND id_team = ".intval($team->get_id())); $db->deconnexion(); @@ -143,6 +166,7 @@ class Exercice do { array_push($checked, $exo); + $db->escape($exo); $res = $db->unique_query("SELECT `require` FROM exercices WHERE id = '".$exo."'"); $exo = $res['require']; $ret++; @@ -278,6 +302,28 @@ class Exercice return $res['max']; } + + public function first_to_solve_exercice() + { + $db = new BDD(); + + $id = $this->id; + $db->escape($id); + + $res = $db->unique_query("SELECT t3.team_name as result + FROM solved AS t1 + INNER JOIN ( + SELECT MIN(s.time) AS minTime + FROM solved AS s + WHERE s.id_exercice = '".$id."' + ) AS t2 + INNER JOIN teams AS t3 ON t1.id_team = t3.id + WHERE t1.time = t2.minTime"); + $db->deconnexion(); + + return $res['result']; + } + } class ExerciceNotFoundException extends Exception diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 35a48d45..88b4c8ec 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -60,6 +60,22 @@ class Team } } + static function __set_state(array $array) + { + $tmp = new Team(); + + $tmp->id = $array["id"]; + $tmp->team_name = $array["team_name"]; + $tmp->key_hash = $array["key_hash"]; + $tmp->auth_level = $array["auth_level"]; + $tmp->slogan = $array["slogan"]; + $tmp->members = $array["members"]; + $tmp->points = $array["points"]; + $tmp->revoked = $array["revoked"]; + + return $tmp; + } + // Class methods function update() { @@ -274,14 +290,20 @@ class Team public static function get_top($nb=0) { - $teams = Team::get_teams(); + $top = Cache::read("top"); + if (empty($top)) + { + $top = Team::get_teams(); - usort($teams, "cmp_team_pts"); + usort($top, "cmp_team_pts"); + + Cache::set("top", $top); + } if ($nb != 0) - $teams = array_slice($teams, 0, $nb); + $top = array_slice($top, 0, $nb); - return $teams; + return $top; } public static function get_nb_teams() @@ -292,21 +314,4 @@ class Team return $res['count_teams']; } - - public static function first_to_solve_exercice($id_exercice) - { - $db = new BDD(); - $res = $db->unique_query("SELECT t3.team_name as result - FROM solved AS t1 - INNER JOIN ( - SELECT MIN(s.time) AS minTime - FROM solved AS s - WHERE s.id_exercice = ".$id_exercice." - ) AS t2 - INNER JOIN teams AS t3 ON t1.id_team = t3.id - WHERE t1.time = t2.minTime"); - $db->deconnexion(); - - return $res['result']; - } } diff --git a/onyx/include/common/Theme.class.php b/onyx/include/common/Theme.class.php index 9ff832c4..c155fcb7 100644 --- a/onyx/include/common/Theme.class.php +++ b/onyx/include/common/Theme.class.php @@ -29,6 +29,16 @@ class Theme } } + static function __set_state(array $array) + { + $tmp = new Theme(); + + $tmp->id = $array["id"]; + $tmp->name = $array["name"]; + + return $tmp; + } + function update() { $name = $this->name; @@ -52,6 +62,8 @@ class Theme } $db->deconnexion(); + Cache::del("ordered_th".$this->id); + return ($aff == 1); } @@ -93,6 +105,10 @@ class Theme function get_exercices_ordered() { + $res = Cache::read("ordered_th".$this->id); + if (!empty($res)) + return $res; + $db = new BDD(); $res = $db->query("SELECT E.id, E.require FROM exercices E INNER JOIN themes T ON T.id = E.id_theme @@ -130,13 +146,14 @@ class Theme foreach($res as &$r) $r = new Exercice($r["id"]); + Cache::set("ordered_th".$this->id, $res); return $res; } public static function get_themes() { $db = new BDD(); - $ids = $db->query("SELECT `id` FROM `themes`"); + $ids = $db->query("SELECT `id` FROM `themes` ORDER BY `name`"); $db->deconnexion(); $array = array(); diff --git a/onyx/require/cache.php b/onyx/require/cache.php index 70564154..0971f736 100644 --- a/onyx/require/cache.php +++ b/onyx/require/cache.php @@ -2,34 +2,45 @@ class Cache { - + static function set($id,$var) { $file = ''; - - file_put_contents(ONYX.'cache/'.md5($id).'.cache.php',$file) or trigger_error('dossier cache inaccessible en écriture.',E_USER_ERROR); + + $tmpfname = tempnam("/tmp", "cache"); + + if(file_put_contents($tmpfname, $file, LOCK_EX) !== FALSE) + rename($tmpfname, ONYX.'cache/'.md5($id).'.cache.php') or trigger_error('dossier cache inaccessible en écriture.',E_USER_ERROR); + else + trigger_error('impossible d\'?crire dans '.$tmpfname,E_USER_ERROR); } - + static function read($id) { if(!is_readable(ONYX.'cache/'.md5($id).'.cache.php')) return FALSE; - - include(ONYX.'cache/'.md5($id).'.cache.php'); - if(!$cache) return FALSE; + + $tmpfname = tempnam("/tmp", "cache"); + copy(ONYX.'cache/'.md5($id).'.cache.php', $tmpfname); + + include($tmpfname); + + unlink($tmpfname); + + if(empty($cache)) return FALSE; return $cache; } - + static function del($id) { if(!is_file(ONYX.'cache/'.md5($id).'.cache.php')) return FALSE; return unlink(ONYX.'cache/'.md5($id).'.cache.php'); } - + static function flush() { foreach(glob(ONYX.'cache/*.cache.php') as $file) unlink($file); } - + } ?> \ No newline at end of file diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index 73af278d..e97c2cef 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -1,9 +1,13 @@ {extends file="public/layout.tpl"} {block name=main} -
    - -
    # Prénom Nom Pseudonyme
    + {if isset($teams)} +
    @@ -21,7 +25,7 @@ {foreach from=$theme->get_exercices_ordered() item=exo} {$teamName=""} {for $i=0 to $nbExoMax} - {$teamName=Team::first_to_solve_exercice($exo->get_id())} + {$teamName=$exo->first_to_solve_exercice()} {/for} {if $teamName != ""} @@ -33,6 +37,20 @@ {/foreach}
    {$teamName}
    +

    +
    + {foreach from=$teams item=my_team key=k} +
    +
    + {include file="summary.tpl"} +
    + {/foreach} +
    +
    +{/if} + + + {/block} diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index a71a787b..da0bfa40 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -17,32 +17,23 @@ {/if}
    -
    +

    Top 10

    {foreach from=$top item=t key=k} -
    {$k+1}. {link href="{$t->id}-{$t->get_name()}" href_prefix="/" label=$t->get_name()}
    +
    {$k+1}. {link href="{$t->id}-{$t->get_name()}" href_prefix="/" label=$t->get_name()} + +{$t->get_pts()} + +
    {/foreach}
    -
    +
    {block name=main}{/block}
    -{if isset($teams)} - -{/if}
    {/block} @@ -54,7 +45,7 @@ $(document).ready(function() { update_end(); $('#carousel-team').carousel({ - interval: 5000 }); + interval: 10000 }); setInterval( function() { update_end(); diff --git a/onyx/tpl/bootstrap/public/score.tpl b/onyx/tpl/bootstrap/public/score.tpl index 5b113b44..1bfec7c4 100644 --- a/onyx/tpl/bootstrap/public/score.tpl +++ b/onyx/tpl/bootstrap/public/score.tpl @@ -2,7 +2,6 @@ {block name=main}
    -

    {$my_team->get_name()}

    {include file="summary.tpl"}
    {/block} diff --git a/onyx/tpl/bootstrap/summary.tpl b/onyx/tpl/bootstrap/summary.tpl index e65c6d12..1eed15df 100644 --- a/onyx/tpl/bootstrap/summary.tpl +++ b/onyx/tpl/bootstrap/summary.tpl @@ -1,7 +1,7 @@ - +
    - + {for $i=1 to $nbExoMax} {/for} @@ -12,7 +12,7 @@ {$total=0} {foreach from=$themes item=theme} - + {$sum=0} {$cpt=0} {$themeID=$theme->get_id()} @@ -43,8 +43,8 @@ - - + +
    {$my_team->get_name()}{$my_team->get_name()}Exercice {$i}
    {$theme->get_name()}{$theme->get_name()}
    Total :{$total}Total :{$total}
    diff --git a/onyx/tpl/bootstrap/teams/exercice.tpl b/onyx/tpl/bootstrap/teams/exercice.tpl index d07770c8..a487174c 100644 --- a/onyx/tpl/bootstrap/teams/exercice.tpl +++ b/onyx/tpl/bootstrap/teams/exercice.tpl @@ -8,7 +8,7 @@
    • Gain : {$cur_exercice->points}
    • -
    • Description : {$cur_exercice->statement}
    • +
    • Description : {$cur_exercice->statement|escape|nl2br}
    diff --git a/synchro.sh b/synchro.sh index 4ffc1ef3..9ea8a4b9 100755 --- a/synchro.sh +++ b/synchro.sh @@ -5,17 +5,23 @@ cd `dirname "$0"` if [ "$UID" = "0" ] then SCRIPT=`pwd`/`basename "$0"` - su -c "sh $SCRIPT" synchro + su -c "sh $SCRIPT $@" synchro exit $? fi -rsync -e ssh -av --delete out/localhost/* phobos:~/htdocs/ -rsync -e ssh -av --delete out/teams phobos:~/ -rsync -e ssh -av --delete files phobos:~/ -rsync -e ssh -av --delete misc phobos:~/ +OPTS= +if [ "$1" = "delete" ] +then + OPTS="$OPTS --delete" +fi + +rsync -e ssh -av $OPTS out/localhost/* phobos:~/htdocs/ +rsync -e ssh -av $OPTS out/teams phobos:~/ +rsync -e ssh -av $OPTS files phobos:~/ +rsync -e ssh -av $OPTS misc phobos:~/ scp nginx.conf submission.php phobos:~/ -rsync -e ssh -av --delete out/localhost/* phobos:~/htdocs/ +rsync -e ssh -av $OPTS out/localhost/* phobos:~/htdocs/ rsync -e ssh -av phobos:~/submission/ submission/ ssh phobos "rm ~/submission/*" From 7a42ea56b06d9a171a9ecc4e96d82ac1021f9abe Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 11 Jan 2014 17:02:46 +0100 Subject: [PATCH 0170/2686] Add refresh in public/home.tpl --- onyx/tpl/bootstrap/public/home.tpl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index e97c2cef..6751cbcf 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -1,5 +1,9 @@ {extends file="public/layout.tpl"} +{block name=head2} + +{/block} + {block name=main} {if isset($teams)} +{/block} From 147bb5be5567ca444037a7b8e87cc5ff940def82 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 10:43:16 +0100 Subject: [PATCH 0196/2686] Check localtime before check an answer --- check.pl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/check.pl b/check.pl index 2840f349..095af269 100755 --- a/check.pl +++ b/check.pl @@ -30,6 +30,17 @@ for my $p (<$conf>) } close $conf; +my $end_time = 1999999999; +if (-f "$root/misc/challenge_started") +{ + open my $conf, "<", "$root/misc/challenge_started"; + $end_time = <$conf>; + close $conf; + chomp($end_time); + $end_time += 14400; +} + +die("TIME expired!") if time() > $end_time; die("No DB profile found") if ! $profile; die("submission_dir is not a directory") if ! $submission_dir || ! -d $submission_dir; From 5b2b4265a4ca06736cc541f992fdfb655f6e3a21 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 10:58:59 +0100 Subject: [PATCH 0197/2686] Can use comm-socket with argument --- comm-socket.pl | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/comm-socket.pl b/comm-socket.pl index e9c1b0f3..3748db21 100644 --- a/comm-socket.pl +++ b/comm-socket.pl @@ -7,12 +7,22 @@ use threads; die("Give at least the socket file as argument") if (! @ARGV); +my $sock_path = shift @ARGV; + my $socket = IO::Socket::UNIX->new( Type => SOCK_STREAM, - Peer => $ARGV[0], + Peer => $sock_path, ); -die "Can't create socket: $!" unless $socket; +die "Can't read socket ($sock_path): $!" unless $socket; + +if (@ARGV) +{ + while (my $arg = shift @ARGV) + { + say $socket $arg; + } +} my $s = IO::Select->new(); From 0774eb7009d5ffa0e61d0546043712cfb0cb41de Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 11:11:11 +0100 Subject: [PATCH 0198/2686] Fix obscur deletion in admin panel; add Whirlpool hash --- onyx/include/admin/exercice.php | 2 +- onyx/include/common/Exercice.class.php | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/onyx/include/admin/exercice.php b/onyx/include/admin/exercice.php index c1d2b9ab..e4507cc8 100644 --- a/onyx/include/admin/exercice.php +++ b/onyx/include/admin/exercice.php @@ -2,7 +2,7 @@ if(!defined('ONYX')) exit; -$template->assign("fortyp", array("raw" => "RAW", "sha1" => "SHA-1", "md5" => "MD5", "sha224" => "SHA-224", "sha256" => "SHA-256", "sha384" => "SHA-384", "sha512" => "SHA-512")); +$template->assign("fortyp", array("raw" => "RAW", "sha1" => "SHA-1", "md5" => "MD5", "sha224" => "SHA-224", "sha256" => "SHA-256", "sha384" => "SHA-384", "sha512" => "SHA-512", "whirlpool" => "Whirlpool")); $p = $out[0]; diff --git a/onyx/include/common/Exercice.class.php b/onyx/include/common/Exercice.class.php index d01e8e93..7fade8d4 100644 --- a/onyx/include/common/Exercice.class.php +++ b/onyx/include/common/Exercice.class.php @@ -301,8 +301,11 @@ class Exercice function flush_keys() { + $id = $this->id; + $db = new BDD(); - $db->query("DELETE FROM exercice_keys WHERE id_exercice = ".intval($this->id)); + $db->escape($id); + $db->query("DELETE FROM exercice_keys WHERE id_exercice = '$id'"); $db->deconnexion(); $this->keys = array(); @@ -312,9 +315,9 @@ class Exercice { if ($format == "raw") { - $this->add_key("sha1", hash("sha1", $value)); + $this->add_key("sha256", hash("sha256", $value)); $this->add_key("sha512", hash("sha512", $value)); - $this->add_key("md5", hash("md5", $value)); + $this->add_key("whirlpool", hash("whirlpool", $value)); } else $this->keys[] = array( From b145741db0253e096e60d26dbb02859a613c30f7 Mon Sep 17 00:00:00 2001 From: Thibaut Le Page <`echo dGhpbHAuaXMK | base64 -d`@gmail.com> Date: Mon, 20 Jan 2014 11:16:55 +0100 Subject: [PATCH 0199/2686] final version --- epita.pdf | Bin 0 -> 4982 bytes guide.pdf | Bin 33294 -> 33134 bytes guide.tex | 108 +++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 79 insertions(+), 29 deletions(-) create mode 100644 epita.pdf diff --git a/epita.pdf b/epita.pdf new file mode 100644 index 0000000000000000000000000000000000000000..061a6f765afd1721b7ef81586efec02fd6435619 GIT binary patch literal 4982 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 S5kX)%D3no1NXJ;0@qYl*G+pul literal 0 HcmV?d00001 diff --git a/guide.pdf b/guide.pdf index 0e5f6ef285a597708b64b4dc7bad09d815a43735..207d669de3368b271a2d5c5fef5292f58f72632b 100644 GIT binary patch literal 33134 zcma%?W3VVao35A5y=>dIZQI(*wr$(CZQHhO+iRcwPR*P;bLOk5?@y{b>7+aTq*M2m z+)W}cEK0*b%K}Amba(v*#eq+cZ)<1)#mx;xCv9S5>STt`#Kgt{MJH-*^e|%Vh*;>cK~B3fWd{QrM>_)t6B{FUC^`vzCkN-htqUp937fc>8<{AI z2}1GmLeVLjINCZp7@0WYv;BQa#eeb~og7RItfAbpoHey-j@n?qUnwns?W9(;-B7;sJVl|I`%7-Ow% zPVYH)%65-1uFNgx^Al1%rfnxS__pL+b+5?@lI*tWXmw0}_rSx-a5EvH2GCeR9zLOl z|G;6ys55~wI)>p{-JN$=R?qKsm^dX@G0Q>>s)#G1{yF;kspJPAK#2+55#{!p@R|9_-z2A&iD59xcBL{NGN2(1RLmYdbz+Lo0(Kz{t)Oz;RFzt%>q17xjbXp!QqT(@vech|$)-tZ;2q9kU%b?j^~3bR8E~Pg z?V*M0URS$7bTor5akcCfIwpV%OU|51$D-&k7>gKH%T!KC&xYP_p0B8OfqWD_&~(#& zNPmXtg}`1OkX`=#1%c2+dl;;AxY=^e#6F&-4YD{?u79mjRnep!LM+Y(m1xm@`X&ps zzv#1}?q;l^>Lz?pyBwDm-j-YSK}q@Iy5db~$3(;8m{zoJ{vtb&Uuca%tBV~u3s%8aXt6a#rps)P|LlS1@BGP4K_Jx=s8H3IZ3 zF`Q-RjF+xafJV!EV&DdHW|$6Z6gqN?h^X3(G;8whtfa87GVC_#&mh z61o8~gS*>v-1KsJFhK5mlah@U(Q+xg33Kj>$aL{;PoaC0gc0xM>HyCNy$TFHP4sfq z-&>KAgkD2MsI8GWELd9?Q5t2HoQ2vy>()NvZYM|S_b`s#=MgOtwwBF8+HJ*qK8XzQ zUT$@w<4l$?Z`y7Ub!e=LXtN)&sYVcvEhW zxjt?USoo;n2&cQjbZqNf{32XDBu3rXsNUx<--pZNPd&d`qgW|@@PkSV@-V~akYM!r z$hQS)AH=f$f@@5h!&!Kqv}x4G`kT%HzQ_NN6y^hP#19tVt(r0zc6FogIyyhqFgJ`K zccxx_i4N1USZu!7^%Wo+X!-c!{=2^B`~wG%jGa1zZZqi?%1}$#*3L z%N?CdiPq(&w>+ze4~Rq*W*is`@ilWq@^4SJO3J%}l>HZ{I*q3e!s(cdikmFTjJ}r) zdx>Q#PgXd_DB`F6H?No|Q zg=~Mi9$^s5vh-uO-A#_V7+g+=Pn%4eG&xAdm0EYG^uk@qxp&X*#QU8vv6fc#X zkwgD0=JArQse3fP(`o(iu5^0jYYFE2ZMzNlwVO=WKnFI~q0LPGJ#ZJ6T0%lOD4>)h_5min_IWrvbQqIQ&aVQ%c5X?jehpRt3<$~n`{JSq#u@<$0ne&&$ai_7bIVSQdz*?cr~*lUojqWHsTo$WjRS`0H*na&{+FoH)9@w_+f9ZA=BU@f@#DBZWEx z%LQrM7o>@qcRYb5W+8}eX`vNb?$JsIrG?Z|QpqBxgc8!ZM{t76-E11%OyO!pwlZp^ z_{DXW#yEq@6@e6}x*b#sFrP)a^-=mtl0)l>tC^0LC_^%)3Y4~|B%UBWoCGJ=U0S5n zdxY(UiI%rqtBF05T5>ND0MSGgc^C;ckTtBB8x>MNXB0+a>n8nZELVb2XtNE+_3suq zaujVj>L-mCPphhmI1_*sFA^{&HqFUNA%7$j=Bq995UCC^&nz#(jWNPhaE$DGqzegx z#y6e{L?0HKn|bS?e*(2!&f8Y8^U+O1%k@2K z)Cu!C5-+6Meu3~F02UheS}Hf<)TLmHf-BvtzCgDX!!#_pSCX|scC%5!f!o+B+ec-i zOAm^!b1@g_~u#B!DBY)j>;4SvjQDil?B^k!PJzq@-y+lVT*=o>-J~t zDC!gq@v>+NX%Wf6!|7YUtXI(%TKSO6YwMbD;Ev0btn~Q(10uNNvE8eU?K*TzaahBjR>KM2xnW!zlYn(Shqx)Vt}Db& zR$UCU;iPmUuZ_xQ6Ea@4lhFF!8|3dC4hLwFaT-yEQsIWcRmSOg?M5&uCTiMp9~g^J zag=gS1VV85Ia6=0Hf)YVz}^~-;PsqF@OBa^gQ(3aX-Vj2Mm;X_^e*8!fYUloGLnFbbIy}k^T#&>PgT=F^CStCoQ7Tt! zmEAC~B3@}3z09_lY->WZJM$_&#`b2-Ua=N;gSBR2J*^b65{3nL)duLP-Mj@D#&sC2 zxgIk`ZW+B}Vhxb-Ox3_tiA`l`FHe>+qNOqUS{%?7s<2ex!Jc0Q_?4z7Os$Ox$NuIC z^xhQtmEfFEz)U9d#oEY$+hc^s|ZOEsx zu2_UieYHBcs?iG>hL9&SQNcFHuum6_Csq2X*Z*4Ti<3y>9lG5*y6M$i3;c$nDnBLl z;my``f(AAgE8_^_NR>u~C8(I$`(-VT`zo==r$FZ8eLg|^FqYG%N@M!8zstUgr4jTq zB*Nt!M0Es2)*}VFj~4~2u^2;-`yuYu+I@mJQo~;g*F2{0%$@Ic!wv@HiL}{dA1#;E zR*lB^8V#IppieRace?{XX|iathqBf9TPtB7dc0^5u6!==h3-(cljlk(665kP>CR&Fv9izgx7_J%Kvex4d_gyuX(Di&Oc>6ZRuchmB-tK8oyt4VU(vN~ z(=yWaQq=tk6LQ9jv);?tV4d5?L-%$0#^*u*R03sUWBi}=^!Ml=N_gY+X zeLLb*8@9oxpxu`RX-FVY5K1Ui7QdLG@ysg5{5AQ22s>B8qvE2UQJyLH7&+(? zGS@5N?e!crh%-BcO7~O<+d#MYY6TNX6XI+b*UQ-Y9Ce%tby)<=a)WV%%_HOrWcbQZ z_PjSgn8%btMq*y9c37}c5TKl;)%F)6bwWqsm)V~&3y^AQH*Nxrmk2q1oWVo*CKQeE z3B5xvL7Ny|?-XL>X0GIq&Upi-(6sSmSU79=Qx}`BPNc^zd5kk*nA%d8ZG<%+t}EWn zo&#|Da>vd88FZ$9Lh@h0|G&LS1~#Vu_A0Nnq++p0VS7&1p77EXyYc$;;RL9Gdmwi* z;|FhII8!0~W#2zZHH>*YI$YJjepLt6Z@I|Hu|&q!s*B8&9$y-w!un1nTqPJPv{TRO z?e*8%eOtbN4nFJ`YDg=t1RWdbL@1C@m+C9CP7XfDHmU;hw{uX0u}cXz&d-4|FFhoRmk0wgO8AxO$UZ5YhOkiBerly{J>u>6&DODl3_!=bS*faml3 z!eoi~q_h>-B&0Qy0_*9Se> zcfn^Dm+X;KoTCWfJVfI|uBZvARau^it3{Fd=8I|vt22%|BuL#&9N8#Uvh`2cIfoh- z=VTiWRyg*K=0H{E3Sww=vP_i3gyDG8Wu9{{jnz8Y(xQX_IsyBD;Ot!S|5y(Y*r0OV z{ZTTLUwc$?EV}l8V!mh}4s#Mblta}HodZ{fZo3X7u8A3c z=m>fonh_?;lJcktgS4fPV0KZ8LP-y|os(i;87dy2E0Us9dOXmF!3V1$`a3Npwv|m& znk$?e7Q90Nq;}BCa#H!oL-VT(@5RKV%Yk>ILsB$&sK+4=+VY??t}!bQuVjVANaYo> ztf~bF(NjWbiQW8^_a(Skrz^riRg;0A^VB}QHX)4FbA!7WK!o`ixr*bO0e?OI1I#VT zC4T)#9PG?8N@>DhV28|Pp<3nej^LA@{to2G>B_)Q3Fa%*d!O8XeKu8zcuUb~aFO*5 zHtAfDoFKN%hQ+wHL*+th+iEgjbffS7_X>o-t<*l(-RAdAXip>O5nKO)G0GK;6lWGz z=C=I09c2m0*l0^1_%H6vO>H$a6P@YOxl83YY>0?ZsE{JBH8Z!+^Ve=B5{-(Hn1YjE zs`_N7O%Ly2szNJ~NmW^?Rctw=G^c~Qryr2)O=@Pmb?1+60nX`EU8B0T0-{Apxt715 zL&Kyns4_L)xej(aqIJ%SpR`6!V7L+_~>N=5RJYGKP;6Z z<;XU7^#Dy7F=Vq0Fp;5-i`fwY)?d1VTYQD1;#KmzOtxpM!)(~mifF!F0zgmhCA#_6 zpAad2rQrbv}tzT_fJot9?;NTN0xXz^#48VHP z&YVf_qM8VeL)f)Jl*{juZ5`Q0LIRjwBPde#cX_(3$A z?+(t5-T0v;^X*_8vv5%bsx3-lI_n071~WES65L2ds>e-oVsp(IDm_?yh`Hj$XoA{8b;XyTN2U@+a;wZC8ZQN-|lDb4zkU)Pu%%2 zfjq>RKu=|HS*cmSbqtR&VomExPX^LK#^91^4mzZ~S+NRE`f8lB4<@&@WVLY&hz@Nd zoYAF#F-hNy$xi$&)Ael_P z@jq?474=51$zpsZ@Llb#6EV2up?;PVPXK164zYZ2)(@XODN%O!P{=dvNkjsDwSu+{ zZR`3=OH;ak+f?QH7^hbWMcCpFO6_QG*QK&ZZ6;)$SNQI~7VyO4_cPh>0EOQAH8lZ{ zJz_namiB%_0t#vk{0kMs@^7jbW`_Sy#b}PlFtz_xF%(}wHDMc|=+5Z+zwlcDyrCWJ zI<+~D<6e7%G|3fIDCxdmrAhl@L-t)Xpj~~4y+39lWr6Zlu4??)~VinX5lK0@%^6IS?JOkB3)q8_M z=4EaZ)w{=WJ!|f=^MB8p{dGiQGrk#|tK(Hm<;^vd_MVI9E7V|2L`B>oLMlPdW~t$V z)uj#9M$CwxkTxTKPeEi(<8;x+KU3os-1(>@4T4H~c&Rhyp?!Zjs;g|%@Zyy6+abre zxV@@~R$3%p+-tp>J!(cSehX)k^xSVOPHhXxy!X%|Z8l;pHcIf|_e!+8<()6u%M?ah zQF$q<{UM}$*?WO*bSAKZ@h?yj6erdklQx?rSvCo}cl*sHkTeKQbN>xX(Hwvhed!~` zteFvMN@UhmmKxD#2xD>Nzw0zv1oMaE$hW}?nSWvyVI?hS>E5II|-UE zfGM0gH#Soio?>#ThUXu#$JY|}OFeJb%M;R^I=X0=f+0dr&3@Tz6n{}))|AO7x=C3) zF%jQlyMdokoGoGufDr4pPmN2bwXB|))M)Q7777NEXyJQ~fth70D38uN*~Q?Qp5)R=l2*@~T+b(`2cEbA)M3w2f0l-C8)r1g8uMY;$w>ghUuS+$)hU=vk0M zSswxdYIcmT<@jY2Io<+5CgOU6zn+fno@v4uCTGnC%cuRkI2wr9_-{y+Ebu*UTNL?+DvK*vD06>;>?$gQq0Ot6dFg7WFzZ% zX-x?AuO^W(T~<=2QEJutW-9uc3I$)VbMcxk~C=0hP;bps%O z8PA>ejY|N9!*bTAyU;v-lFW~Qyy8>c7N1Wc8z+)V%B2ILBHt(=c;lb8z2WMikGon~ zEO9W?rlKbMh%cXM!Ojh1TV^JAPCCl?qHR2ST=ePM7kbN5ogj7K4=xdo-!`DBWqa9bF@{=IecLQWLi&O-@u4Z-l?>65S$@Rp0W#S20Q}s0cbh?!?U)d7NuBb z=3AJdfI2CTjabzAax>UA>AF~&+BL%`gs4amQ71+Zr0b8E#!6zN+>!(eJ?I1qOA6y@JE3Qewi(uPm_!8lmXNNYSjEnYyhM!_qwaL<+08xH)@OY zE~TxI-?6fQpGkDL#6Q03GS7cMhm~HkKt)v+?n9W1{xL18azUgVJJ?##1q3)3IeIt3i1{^i> z(92s}pCkjKk=Ra=dZ#ZGjYsKH8CzZaDXuc5+W=xfD@&xS#Es6&LW^w!A}$dIHbt(} zWRHFCdMH8Oj8U|+&LFb?eF)ZBLJvhO+BfD_jGZWl-uFIR5L1P%6KfH}=46^q@YclY zeK3@VqD2&)PZB($4?M3!%<|b~-lz#1ymMyE6YySkpe=ldtBh^8B~IHGSs5sd?Y=H} zz-A7Fj@=$W?oeqjxU|F*^y??O=G3KTMq&DiE9nc}oxfB0h}hctfSRH;O{F=d;g<}Xl+mw#jli_rWgV~v`9UqX zRYT+hcPbj_ThU|9SZrscNi=|7kCoU(f~AC~>vtBnKd1-bx4ME~CIntF8>A3QR;$PP z{>`M8nv+%RYp1xt{Vbrj0XT+SlNQ6>Zd3f+Aw@<)39_K07vj|J`|8vu4%jaIZIF3# z8dS##BUsH~b-&wA>MfNuUe3@&r%fgs1sruxxFL0YTWA?jRmMe`X^eE>%9c^4j**8`K&St)ou$@jWBtqv^eV#=9bW?YdLQ|xqGm_ zXh^@F#Xbw^0nGk8(Ko93i*Z8>d+vNpX^VhzhFLL&gf64IrA%gvvX2qXMW;<< ze+(eJl8t^!ZU49Vo*PH-RZ711?e=h~0sKugjCZhNlG z$5s_(1eu4ieL~M(j%aHh#E&@B6Y$oj(rPzAO6P0DRw#;Sy&7Gmt0Rb+5s@3m(-GsR!tG(2E1I)<1#=Gyf4QI@<1`U?B6`Pd@KbBzXue7Gh zy>5o@%L(&h=RjRvbEE^#rff>av&NtEHLdJEka*gE6n zrxe@(lfGfMS9setpaR0qyE?@A;pqjrreQ zdt#ygk9ENRGJ9+^Yj(z5vj3WXrTPM%-p@qFCr8(J@gD~}v#Jw#P41ot`}{MW@Qfds zP}TD3?-|@;(jdNaxKy4%`=>K4lJ?IO$+}cT;>6aHGL@AslEDT|1! zdv~%Y-SgwI^S9^9#ty314~R}pUC_h)=<%?q9&h^V@ouee%6iGHi^8zF@tjrXlK)RO zv2ffk0m=8Xh@vFZum0VO*7Bbda{|nRi!jFBUUTnCBJcLAfY!?*WwBH_mAaWo|63Pz z_!PQSza7(!wFDraPJVCnd0n@|*OBbsq zm|$-;Aq@@l&!dJ=->fhL=@0t$PW&zCaA;y}&LYabKulcP;M8H55__=t=GTG26Gh?n zNRV&=20JD%6bR5R67(s?zuS&a70g2;0#U|0>?SIo$l#K0hT2N5?ZpuldBh7JL0oWM zknAo|lS7uoH3z>JONjPUF56JL7s~fl8|~vQ9U3vb8m}CYF2Ha5U{sy{dR=&UNo%b} zM}MO>vIsgG8j&Xu43)x>xk2E9PBxma+3c|r7Yx(wu8sbJm`BbZ;XE#35YE=9${nR= zN#qj&XKHu9UG2dt{s4yrgg7VUipvPk{$sJhmR~kDnALWeZRdUN^7Wl9QV(jjpWF+o zh&0CLBtfxCn@+sWT47_;>|j*5*Plc6htj&!FI%3^hIwE265bdz!zp1v-2XKnSOjFi z(VZLTX{&&dMldO+=k_zpjms^3HXs1K5%bzjt{@@)1i=f+|`w1^F z7v!+HqayB`ni|MBugZRHURC8@!v-kK1p_zJu#(A?V3s~#$Xat7Xww+xhz>?PBjb%x zo=bDZ-v@DouR!K!^H-UyK^oM!zX+x(M4+JUak=4?4+uU0m<1!3VvgBMH{~VcA<@;e zkJC)uA!IOt6%4tv;vJY1f`xC~sXFWfd4fqNca%ZNa8&eF8pP^0&n;&wRXXYo8^d_L z#x|?p2eU!5Stza5mTa%X)F5qST#*l^<+}a&=xAUWS44G{klS(l^sSqKx+U$L3%j8t z7Oas@U@@pl!A0~K^t+=ctlv{D-}{){pFHteT7(g6i%VlRSY;o>Q0sD z`KjZ~f@}BK64>PQna#n-}4q~|~#&E3KFcL;N| zW?cjJr3t1=uBn+w+(u`VMw0{U%6F96d{X!ZD$=*G)20QqFC>a%fKJQjgsY=)5)Ixr z6Z7@xF_eCKfI7V=e!;Ve z63Q~jDh`7E@;Rev*I4q7cH5eK2v#Lln@&Y3Or%*i%s4(0x{uESZ!x}X4R6|AkWd@a z(LJMaRZ0v*9{AK6w^MkG{fC|Owx?huO!Y!s_d%xGQk z^NIuJo83h`2$9hOp`e&5)u4o)H?j-iD`oUXf>CRHP>-Sp2jcQ#mtuY88PwZ@q>m7+ z#~*k3QDH-@s__&MM*eMwW))K=D!R0n2ys?s+LB5>gVMG2g@au&ne>J`90;7iGjYnvGYx~XnG|K?F4nSsM0BWlF-tXcBmVPmXoiN{c#EeQLK_sTGqXL$7CN6a z){YqM-0tofd@WD%`~7X+z<^vGM?bC}5bKp+VX%o4C`g8iGxf05O$Nc8BgQ%7`Bqo6 zE#VQQvz@|1NaR^=O>B&&Ih;=RUudb>jMc9fJt*K&XI?6#{1BYT=P_Lxs4F(%&q3#T zGFTyt&cAJYmMZTC9ZQ(Mv5&>?td^611%xNe`;zuL+yH)(JCTO)23q`_8d?3l<1}T}SY?{^~9$4E;_6{Hz*+ zRbz*8tD%11G7&9i#Tj&O1g&BDO2P3~n$r-x?_R>Udk$EnVe;6Q_r(NLF_#zcVYAo| zp*QK6S(={aZ7jpoHNuL_B;az2H?{n^L27JL5QS~y?}I+8oxKy{>N-=Ts+THUY7QjAwxz14L8K#h@pxwV{NPVWL*hw!lK1Y8ZxN4~neD&rMCv4N+7!|wgxtDA>A4g)tc4^9 zN5uVtQ>5+Cv0k`D@h1?mfMK+YZ`EVsWhkwMOTV z@1Hpn54!7F8!O!6q@T-j`TDYQftbZ=vV1gNP38{dYY|7H{%Pg z&JFylE#(?wm(`i=Zk2&1m!jegKi0Zx0WJh9i&^9wehRbMqJ4~hCa`OLt?KlbJY)?A zNJ{>&Nn!{xq-PuR8VpI&Xk@ZJe`jV zixG2V=5u7{i`XB#cC-8tQwSMEZlN>S{dW*^!~vowd{MWcyHXP-9bep#;^%-KmFG&WOPL<~>Arzp zSde*HdEd_lU?Q9DX{RM0e-I1f$(j;Kp& z4VMt~Z+&iYC2F!UdlQx?9Swh~X~=-!*FL2d@~>1d{inf>Jz}nvWIp(kS+9;G!<-mm z)f{#;sUpbvBs0!Y>2!RPrk9a$D8h;asR9hed{H5)ny_EmQos1fJJFkml_8nE98zb{m~yeR^Ev<{nwug+L`y#VcMY*jNMiSJKLohmqMsfczgFzzJC=@ z=6^Gu%&hY$NJ@EF>Xm;bSYA4kd%1BZ)0~Gj3!!i-L5hI{XR!dHzpVTVFrfp z&lkOc=ZgvJLl%tj{aE}Y*Lah;Li$rPmC3wKRlL-zI}sO;$_dju1ts3(ptAI6re7vZ zCXwM01ftinVfG}=I;y&}XR^+9iRwgmW9&F>*{UQb`8@zIfN)`wE`?U0N2`UdGAO`y z0H*5RX@HDwlKs7=@uwtfSeacKF<2Vvf`tD4fmNeIzX3 z6rvIvO`t0j29JR)yn3${Z;T2)Z=wfi0?)0g1ZLfXW$!N*N< zV&%=rXiFB9sI=L-M>`HVW&UeVEgy$k8RWlM)B*mx?+3rV&6%djL9UvDXf)mm|2wBo|;}T06A4jUNV&IffQmqWP>I4WTRV_?1S4gwI;l470 z|K-n(cR6_{%m5nF)}!lf4Cx%F&;u9+*+hIxt@sW;i!iLBKu3VnaE_UrGSadza&4Yl zC-OKJaYSpOTPN&17_iSo~_~-AI|FY!#*H1M<62hXkHctQ8uIPpSSI-j*BlCYZJvFOCsw1za z)U=da$Xg{hK)CQ!hL!mRKvC+0xSCv&`}=7zH;Bj^?}7x4MB{7?#E|0?Q04{rK^^=m zAmnNT5lL}@CnY7#AxxD%VV!4lXRt;J{9W<=F#cF4)TG)^MAgo|y|F8_66lQxhD`3{Cin+7`Y{Xoas7xU!Y>to@-_4NnzEk{x&x!i^&hfG7 z`R)n!1#ZWj({d(@WAgj!UPh}sz*z>Bnw~`w=QJ97I@(F*{%g!W=O!$#W^pD@e-=le zqowD@$N$I2zotJ2x6vu}&nP_r)=+T6*bv@H+u2a_-XNTuO=6^IsiWh9k6gfipZM?$~KG?LJq zEHs6h+q1=XId-5@VFG#%2u?2GvsJ=O|SNPov z3Z<<$qgU?=wfYmZ(Q63Ob0kh+!jYc$C>~8Dp&_RxgXgYY;GownSI+fDrNUXl(ZC`l z55U|%5BLWfR;L^j};(_lMhAd&wA23GF$dg~rLfCaEBz2twS9hcEivpNFBRBQL3qQ{H!xYa52V!;P8Y7W4#EyV zL4!fA3wMenx+A#~FueQ26$qk&fj%mqri1F(x`yjm^qODWo|e#`zrVIOazSR}*>m5S zW^RilV}b+JsG4@=pcW~A*(|(*O5GW9#-oL=vKx*?WeMhI_h!b+mATvzK5C}_R+n0s zWujW7>aCKO%kO!5Tj2S8{C!kFwQG4SWZ6)Mp$>Zx_v~)k)B2XX-(z9+f(}u(DQ^}z+4j+ z`hje5eoGj4U1n9Nvb&Y6G}vx|LqZ2(6>>)hU7cDTk`rbE%=WFrGVN_!8htg`0w1n{ z;#|551U4Ii+hLdI8qmydF#C)iL`VYdBQSyW<{G5eg}ul@Y3>RM`ui?Lz@N&1aYJ}G z#Qn%=LZC}nq@xzm@>7|OYKy%o*da;9M4+vs5B{)nce>3WXCUet@IVT zVP@YLn;VtW7?riaZ7k}2+e&{-no#7Rh<1NDw{T-1jaHeWD??0z03Vk5Nho*+usS3k zrRh&xz6;)Qgc3+NMNxQ%#K#m|V_q@h%Ei61u;(34ub4Q{Hm6(4%O9B1IU-8<89Xm< zfU%?<35uop;NeGEjPgZO{-B$@Z#Ct3!1Z>BuSDCJmDiiBj@vNV(n|e;7wb5 zpPftpRGueO{R-IRUmM^{zi@AE4;2%oQkSVa+Khi$3DHR$$E^b?i_W(zDWYPt?*IDL z+Uo99b(<69wFhec)QLgztujxbeS?t9hnB*JG$y6@2fYwZsi7N}AO!W(3d z0GgZ6a7U2vXitTnwi06-PhdnPeCQ|J0t8kPAV4M^P~PQ)qdTzWLauO(aP{ek0$uj~ z9vn`#*3&7{jP|zB&?UuY!X{|Z%Rc;fhx_rgk&17-bu}3;j>&wTq}+7<7OORFra_Nw zn2r3HpPh~+{2H0oIiiNjVASaTeNkH8UCa#$+VPgp{c(_N6+vZsmeQ4LoxD@t<$C?E z4>9df+W<64jf2)*?cok|^q7FV`d4HhHpY)#rD|2t)5&VB!oPDkaPgVn1pz zdW#uVuz+1B6Lu@IHpRI$cG~WMuxqlN7)4LyqQRRGPUeHWSxAlK!udWbl2gx2(5;Gcc`h#CFK@ir zK;E1q$Zv;Uae}f7m%;ghm$PoxjiEM+mwT4ixBIXXo+z-!Y^F_n4-P||lP_yuyicO1 z6ri%`t4WL^vl5(4OWa=LHO1(xEk>t-ci_-_#WUCwAUyCnXdUtfOceeR<{Rr+E1d|s zXHzBm^^)68B8x5Z;vJ9+q}7ZhZ7=f*13=f_rAU;shqMG3TOXJhRX@apec6+Lg1B`( z7%D@)3B236@TdeV6P~Z)L!xSQG+HlIw7k#P4QZ1L3gN0r3;VP3EnUfmMs82GT-rM) z*Qaxace?--ZeAg~oKg$6nUw1+Laz-pb%5n-iVF2JSamXA{G^MoCTl-i8~Odp@KPS~ za;;v77L2R2y0X0AK;C}u*uksTlNbmMu-;H4F=~`!Q0O_(xUW*#*3n&1|Gsmg`Q_VT z-16P=$VSu_M2EDnXreeY(gH2qd3I$~pSL?n4%8}AYides3*5ZQ=E3iE-b8qUp1Ujg z8^n4-dy;U`Jd8hNY_Awl+O{JrQK3(25CsP}f1rRhdE69FC_JGC&@jNPFy~ zp_m%8+Sc!c>{0wrIG~x6uasrEw9^#mwBQRX>NshjN(`kw4qji1L6~=h^Z$54jLO9gh@hdk@4|3ZYNNz z^nB=JJcx|gA|6)2{x=ne23dQVsKY9&TyR!)XB+AW@!fdz)U?p42W}%D@{FV8kV-Ws z+4~pjTba-j6FwM~wE?eL6Mi&O0+(3kE$Z?0ZtA#6Q$i@=7yNsjO|F>j?ntM*u(uTr zbW4jlP7Yl>7{M%S+5(V}bwoTqGVB~YC=x+dKKNluJfyP7S&7A#^iW4*9B9I`9Po7K z^D)b?R|HdVQA=)ml}2uAZ#Hy20r1TB&T`+5)pSMAm>#!p7s?PLdGZ{5uM9`3;>ffB zS$bJe*tbHK(i@nqDR$mXDmM>=1skV_ty+7{u#TiW`LNE0 zWLdsLA``r^U8;ixWsd<~@|x!TSvQS~x4gVt#>R!YCeSSZMKl(HOv)e}XZ#Qfk*dUKB$p?U_V zF&E()OJQ0!st04*of!_-nA(b&o_9ggwOJh2q`72q?^e?|JT%O!V!K$i(m{juIp^P4 zqR%|2ZXH+Z3gZwLE>RyuHe6WBJ7wA!8-CS+%vRe2ve>sZK5O&vyx&iQwAVgYzg;9> z{H1F+D+@j_Hx)0M!o*a*<>|&HrX?o#DjH_9%Z<1svwz>0wc*W3_AQ)seV1G_5cFuP zE4!H`@zEmg2G!KonV{M1G>qrQmY!|2-HwSUS9msTe!S+Zl&grO^wdIGH%ppoa;jzO zD6RVmS%wOENBN|;X&dBfJOgb0c#56wiHj_b_qMjat7ATctUEYu;YTo07F41db-lAjsrNbUoH zRY~#YDvoQ&Kk0W-Zqk8O^EC!#hcKfOY8CyNLKwTP$?0|qkjv+sJz+uS=I zn^{}>1o!F;&*<8vczf zAx^~G@ZobnP{W|j>guBz#CH_b)Z+VV&V7zCKlC1+9H8+MAeOdiIhvFKOkvY zSX+m0-ZQ`2e%$p=p{skAsYXCW_ukP{Ld|$W?)t@=e%MQ530z6m+WJxCaOelWi>!=% zMd`R(zy0$lp{L*izP#s?>p0kn9kJ7%DcTttccsBzhHd#ErMH zfx8my)tYr~d3e;hfpV2@G^8q^BCL$g6BmOTk?6j=hTf8V49PlUa;Ka> zSAPP0#u1Kl(z5Y((Gdlz;evK%@fZCN1p00dn{8Sr(Iz1*v^4XJfIM{u9@V* zO6l{-E>0qmjL^nvSIx)V)j`u~y{zCNz7UT;5hp>!L0t)RRQ8~jr~W^ky;E=|QQtip zJ+W=uwvCBxJDJ!vpV*$*6WewswvCC+Gv{2rZ~ede>YQ`ceX*-|S9NvOZ>_zc6Pz?A z@{vG1K{qats2U7oQ0ox)t=x-9KL46H5D%=#NR~>LOnF=!3mof{HjKs5##e7@^jyM& zuP6oMC$&Q-QU=vQ;!CoQPU(I(e?NF0`FlLTd3}Qjiv)eUh0*Z*qLO=Ht-hvi>9DBz z$T1*Q0RG$6LYZwY6Z`inll%Mrc5fN^arORUgd-yOtb$F%HJ`ZGfSFTX3v)X`YMIh# z%pKf)Oh1&YThi~u!9&1j<(;9d)_bT>$Hcrn57`!}e|RX+Ube-WQZV z>Sx}+tKkdGIt4c?v4r;_gAL(n;`b7;9^pFx!K>aVur-8mEfQ{|R}qf2&nC7m%c63R zB2$zDJCR{=DxjzbqS}Gn6S%0Cn&pAeLPXaO{Chpk;WC!SGUCDUxmCR^H0^E3S=ZM& zq5S?^J+8c04e>$E>IKS{_*@ayY`&#*kjk*i5=7PCQDeSFY(}gK`^~_h?`>*U`=NCh z(~6WRumwN$&+H6QEhB&bk=aSWD~7I8osS}?Vk;(R;zJ`DUpHGz{Y)*N->0W$t8~Ot zLoS(`H3(Z3!{B}D%dGYzR@?+E#Y6YIA&0i9LcoaEY9I1KRgXS*p03fwqZIEv?( z>^#j}U>xrVMstE!5TkZ>y}X>HowwA89y&v?cT9O9lEQNoiDG|WD3M_>%~bXmK2YkQ zY*w7o>g!^SInO~kyR+r}@5bBDl7?*+O^@6Xn&V*5RS?sq4TQR@;n^&nb}0Tlksko@8OH%&QKTG_Z4aZWhqtpfBM_ma5`99 z3Itp70GRAoLB+FgN#?vGrM5cv7w0#362?vmlOI_}mGkX{>7@euU%kqBT8ONekH27)o$7HjT)*GKd)g)Xr$xP;D0 zqPp66lAb|xScxFfC(v6N|2a_;rH#_wfnRlOIy^ngQB9sl9rw&HCfIPa%?)1E6@m*p zrp%bD08Gc9-8hSd*G4f^uBlE3@693^>#3U^#i4E=HE4%R46HDVLAfiP<&swxEEmFJ zyS4Eh=ZqE??coIVu)0i6Tjc$OLISv`v=;(;Y#=@<=Oifb36bIGLi2H&xNzmg*b+P8 z&xAMwWgNC$L*Pd;+~jqepJHl)^!U|57Gu(ll569t!#!Au+M5LU{o3lvBWGv%RFwwZ zmuhv59&RlWyIe~Ol~-NFs#L6Zp!mG)^8Uo{`J9@Zz7v#~FCjE+moP+%@4vRN9WB-F zKseo^zTM8-Uo0~wPh)EVbP8T85h4-O>0)Ad-oC&hjcS)2()sMy&hf{Y#&`6*)t8k# zjwz*twz;|@>eoH%&vd54jt@Q-3MOlvae5p8Pe>J9{VBRio3xcG1HV9>kW?&!K)&VrdE+Rx$2-riJ{yJnAIL*GOS<2RP3ULH9>^y1#_rx0lE%DY{0p{- zdEC^oJkT*nvR@n3Z$eWxjztyL0aiBT)^XN2HTVmK6%{`g@ZmHmVUaSvAsBcT&i^NZ z^FKp|{uj?78_$1{&AK;TA_M-fuaNK8-$KmP%>|YJMfF3U?43lux$Us zb{zjHGyDI}r?Rtiv;Nn6G;4Wjp^vs)8=n#)TZLIbD~w*T5YuKy2EGU5>Y<=xD5EEW zim&y9N*F;xHy}s?Ao~I0!fU~ik+6(yL*-V5l0Z4%l?*+TANxScGAi?*29H)rKHqKE z|5(-TQQrsGrHV$i+#PKj^3Vzzl0@lCFs#?tS3vuVgF+mPCV-NvZTd%~dQ{5UK<7Z6 ziJZbNbWl39EShnfS{;YPf$~{rDR?hs;vlrB3NyBlyxDTNPule!*TzpdDW^A&NtDp3 z&;;ZV7~Oq+6YkrpA-#c*PDDfXfsQe+%CVQljK%4^D?&oTMpV?>=+noFiF!0D?~Z6i zrURF*s(G{ppdwRAqB2es4+RG+qXZ9=ASnqC3keTDhssgy0}!Z=D^X0HOr}bjytIFa z*FBMeZf^GD{B6w4oSRZ|)adI_I+c}!M-KxBE3ZpAlUU`;9Q#qITxDd4uAcs=;RV|X zJtdk-HD&L%l0{24SXoYdp!8+&Fk=k;xfOCZmu@)sn}hr&AIDhY&r3l#GW{*#o-j8m z88np%IZHIQJU80UP(GIM8{!dEgHWzLu~;ffWVR^nA-jFQf%puuDT-s1`zS!DP<~2bb3ivR|81@>&w8b6jMRw_5oF$J=h7q}qfu{U``aTIH2NtPg;v`v!YnzafMOd`gB(MT1Cg+&}>(r-k_PA^PO-O43m?6C(Is+cZA% zH7q@Y?4hG6j*^T$Bu?T*0l2;ki@%&>*fYorqFmT%qgB*$9 z@H?7KJ$^i${It&6b<|*692^SybUFdzIT{RH3JWzHHa7s+^B`J<#x*kHjV@= zP6TY5xcLkUi+&3M0i5YrJ)nZW_tE!@024jlhR^%Ov<6tlNS8<7&Rr9}FpjRsf<3tFOfS*JtfIsKVQM z`7fQF@iJn~K#A4#>-;_MV@2*jyESXJdzWC(F7v3ariPZL)G!aiS5kA7_^wd}DLt6< zT1Lj{{WGUwBLo9x2%i}pH4=#cxJTfIpeO<&_ezC^z$2&=hm3_ zzjexP2}oi}f_aOkh)B_2+(?iI;H`lb4hkS~1JV`!dUeS~f5-MIa25O#a_j5`Vye3d zjSIN_Jm4~B70t|>?x%&5m++3SZcUU?XF6M`ngx_SiQmT|Q1*2M%|TWDQ0=4w>xka57r$*6A@iHKID7RiZ~E`& zP3kZ@woxxbql{u~LKzPw=Mr>^FtdWvb2#l%anaqGv!YR1+M=_?#SfG>lX6C=dQ-pOIGs)Y-GN_HUOGT*TU2NdbKeL7JVIAqTyyzr-nafL zSv;MeD@o>l8zFM1`2~}rqGbtX%*ssT+wzx2Q)iy_sBL9VTdW^NJ!vQMYTez zok~-9cnj!>?}SG4YnAZz^H^+dmfeV=8iLOEaNCintK_D$Uo%dFgvVLLmbrQ=5iV2| zn)-$c29pGJqyX9!qihy?DY3ft}x{@j|^Vsqa?Po83RF-@A~U#hkjRk4i8&O5`uM zYN-Qy6Wo$H%~K*XvdaOs#w_7VNF%Xip3?E0<4aOkrCX-`-{T&_f^csT+W05kI;78T zH0xPN&(Ha?vo^ar#?0+pq~+ecF(d7 z7ht+D)qM(K7}$lLZOC?pnk2dz5qlM&IxpPv&IqO@(BLPykVCd|IO{J(cr(q7hMyp` z3I&N5wmvuw&~RD&9G9pWPQl%=+xqZD$YkDArBlSls9}lj36#MD5qFZgZ5}QUIF-z_h&N6nUI}DyPdW+C5yGq@=s3z4`Hr)v9%LB0aJx zi2;q3(%Ql#>sazQxdur?I9UK!F(|!!Q~rJup2Lj){jy}5#4-HY2)$8Vx@ppZ`ckkW z(3&*?5D+oqGb1k(zlST8{GL5~b!L8j87I4cZ#LEnp&Wx;WaM3Hko7n?yqy(iQJZ4Y zl2${WnK!*lHA^!=Gj(LrTtA*@_hY^%PA>n_M`>t*2Dc8s3=v#@+8>Pec#>Q3?a`McLM^|N|i2v*ZU&kR6!+t#m=ZE+81V|gYXRH*Yt zEG;sh>JwS3$co$kTmo#+@*Hm?GLM$HMethtz~i;>)A1%D#jNrRDJAxRWE%L{Qxp{` zk!Kidlmjx4r{`V{ioB?)!+!AG^9QhKOB2W=3bCh4q>)J$)?2;oNQNxECPVQe-F5&M zS4%3j<-E|2;1Pl|FHIO*r^wbLcz#kY!$Ck|1&p&fH;zu6zOusTOm>XU07L+~FeXYw$$LNI}OyCT4E|K`2p#rKMr94({049(dqR zzr6-Bv37`Mpb1e=-VHN?ePx6KmS6jFKm@j^p>1^mxsTtRpCuMA1`-ZKK%D?7% zrmy{CqpLmZ&2V07R2^cFacpl=3a~Ih`N7oKvzbl>(sv<<+PU4@zvRf+Z>CNo*mPmZ zqCxmTH^+gDX9zSd$3Txjuh2o0!?FAXwpydmj|It{%mY$z@RQ%YcP|=)xf|T?1&5B9&jcCVBbGk108af26C8H&F3Ox1y?$=*SrTnIbUv&_rC~2I5`qgtmBFOM+p-7mIdG0O;msL{?uBX;uB5t9 zO~&I3&R$i}(^v2IiWzRulDE*dEXpS+rM1*I{s*DsTDj~a^K6&BPgsm z_AaYXDcbfXc%=f4YA$weBwE#|wz8+eY~~-K(4lNA*W(E$$7+vo4HDIz=xEdH#%wC{ zp$wbaOwVGl8{y8>*T$m{A7YnmF|T)$`{u0DF+G4wMzmfKMJ4f}y^|5MQl%?OtG zR;K*vdMoWE5r5xK2ld}yNfQ#ovTDN4F3+dJ<@mee3CyC&3sUB25#XPYi{_6}Yqw0) zO5old8~Q(S7l3h-4KWR^M~*b>DKC!hUN$T8gq4YSytHDBt)Bre=i=9UekNP8J7-eC z0_v;Up2wBJgsSj}k({s$XcHMjtn^4929`yt(jP;^r2_>P>vZBz&*JV-l~5MD|FSR(yE-o$Jb7TK;TC@L23f3{ z;&R6nN~!KywNpxWvNKsx*Pfj;zBRmQh}H=-6bH|pU#e${=p-ii82Bjo=m35_H5IYY z$;gJWo+&7&B29=TC&Y!0FGl@-a7%T2^WM}yPktQlRP`QN8-#}iMzC%oo7kgOG^;kK zG$c1B)lF4{YeTUi)p}bglC_%D1*6ubEW)amG`kO|)rqe0R@Uzssfw}9(0o1Zbh(SC z)zvGdA-B>{7=t@YOfIW`CT|)dl3nMfjTPns*dO2(^d#0PKGT zX|0fSXa#47>O%~`!*@Pr@vu$cmo1y)i~Lalz=Au8es~_~z_HYEh~%MUFVHxs%Uew8 zl@_y|`-c?$Z%G5z;|PIb-w4urKQ(b3}3p81il5XwBfpYjS5q)8{><4 za4b4@2OY3YE8TwXf8LE=0^q?9SDg{xb}9GT`g;*e-MG@YBGWG$QSw59xV8eEPGqte zI*T*E#xFG~cMSp$=(3P*r>{37yGfG9)-Sk*e*1!xStBS5POSnul|C&Cqx>TNccuK& z{9&ck0K^cY>FZ3Lpb|EwTFv~wowYCC172o=3z`H(GfVNLRfx}50{wZmvN7;*o9txy ziq!PVNgb7+!|&P_yH^#VOOt6M(^?okjr@sahKdElhLjP|)g=qe!Nj7&`S`!rtZ0ok z5XY)OPNHS~^Z{X{bR8a-Yb2{zfoFVX4&`eY%p=kqY$_KX(3qr4Ie6m0m#z7()p@WV zP(fA0LKAch4E@bh^RP4PxIYfR5fD+%!v80V=l`u__`j8LwpI?vbpif8{a^3jaPaW( zi15tB&sh0fzPAIXmvHv%rFm^*?NJ|vVOt)quW^r ze{Wa}7L!40vfM|7HE)T7QNa$_N!t(yB)!rbO0TV6p{u>x$g#ECIeiT)DIbMYa(0o- za)mlvYJX;?tR{4gO3`v9hxf_;VD*G+jY@8M$w7#>2 z_e1~|^<88|`(opw=tMef0ayhxZ3=9WhU%Ug1cr=+s%?3*8hmqHbjh+RUO7+=|FJRh zMwSpz;>e0GZ?2rX2tpvO`3GyOYx8bX5P2HoFNWXoSM0lmNA7#?++;cK=Tx;BBCCf$ znva@~ZxPKkTF-USICrO_+7)940gI{yB<*bkD?S7i@}_wms$o*lLPq6dh6$>^3-rK{ zMQ9A`2|OPIO`anJ-YH$30t6E;m|2Iqu7%|Y{NhCC&ijkyMyOUtk1za0t>`hfJqD|U zXa=)txLjr{37QD_0(bb$GyK!r5)r7oHdV%R0lWwe*>E>z_u!6jeyAGC3(tpnZSR&v z-{f9=v10)&|M5kb!%r_xZrC-wQMv78GXhn34aI5EY6d<|pBh00JBx|8C-^IZRqCk} zq2aoAPYjqlo_miV8{CFXp^x$E&mT+Y>qil3G1|IBUkC^+3B;bOlJ*D7iQ4K@S7RSu z63Ql=&&@QjGWYb}+^k^BC^}jKBn{p>CXB*(th(#68|@b>@p+wN`HgF}dYXFcUX%yL zit)T1G)cO>^=;DA@wKVy1V4ZCPj6w5X>}M$P+K&Od@ku2tZVs8y$lHNVDd^RogfI$ z)J67hl!3K|;qJRr&XT^&rsk}%;WC9zd}hLc8R*<4q|-w&ptg9KBKAZ;wgHb>w8BH0 zi-$by^3^BMwdI%fEsKb?zQDlg^ZMjp2;YK&&g!}@K3KAk(0RP{b&B4k_mK@~)3fBs zD!fTN+ctNtb3;Gy?1GUG_16vg*4S?a)h5>#+%~v~JaY#tUYxpcnRFM4zK%{EXL}iM z-*Gq_xqt3ltVJVolb9-+W^(@V;J`BPTAU3j+!ve*#o4?iqd4|9;4O0$M+PRLZzW$+ z^S`KQ6eypJx=gkhyx?bK-*9_Axng28-&FryWj2vQI&`p?K6Hdm+XrwvJ{f^b)je~p zwBFAOQPO*Tq+@w4suXGN zSyt!d;E(-*RQjKSFqZ5e(C7$?ABXTBn#`!z12km8!vhJIYPuU|uwTXX9CUI;(_=Pk zP6MOO<0uXVioz`}Q2cw5-(}Rd(z!+sAo9d%1w^{FKqTi7w{cxy$q1@| zh?UsElvla1Fabg58_UX0gI{BRHO=?|7s`zx@{OgEo8?gj=Wwg7w~3$VL}4pMSQM1p z{0x+fvhBQq!r?Uh#>Nc;tnpLHr9AZ}a@6&BK-p-f!CAFH;xiAmFtK$m_Io6rl?;$8 z!;M1H|KR$;wdg#Kwo1ZD=aU3ArEhQm+c3>AOlbtmbgA)PqH%{0>J0J- z6P%CPDpt%5{|8v9l&?(Lt5Bc>^Y^Hm&~B!$a_D7MoOwMqz;yQYmkczS-^hr z5%&)y+rPo9VGeubKF_N7Onl%rP5CU%u9=L^H>A?zOsCll$%<0q6$WbqX#8Bby%Ka8 z-M3+hVHbJ1m8pZM{fZ;ofZESx4nB`&`)P}*w|#9{^^so|0u^oOqCwXTNno4b$A!D} z#bm;1zkYvB5b!H$XiRf$iDC?gVfeI<$vdHBDiGQ)wN%ztGP3NkIw`94)3K~FQf+B* zlS^MdShkK*N?5IKlOcn**ix zCtusvPS%fT;f@d9q5v$ZFEr2eqb{4X>PFs_aqh8jdBC)@1_tSHo{Lbnzd`xUofjgLPlGc_2!7Qe<;;@2sXep4&}mgTHcKcSBJOLG3FG3-Bm693CFBI|!g ze%V?X85yZKyZ%w^J?RSs%>YsP3$FJ+J^nvWDgS>=d7NDTZBLWe^io@tLcPMt05uoq z4-CXFf+nO6hEn!CMN&h?q%epwStOoSIxd4}% z%Y^3uut3=o+r1K@52`<>P1P{rFYF<6ImR;x2ncX62ylP%O{H1z<{!|U9|u($79OL* zD{vr-{G(|Gxs~(tjOQ)=%onp88(8Jv&`q-hIVY{+rYAD3py!@vCuXL{GctZIdmteo zd^fs9`e%?VB$$9*{#!>P<)FZI8ZkN;1JJ-vpq)sd;-YoS_YThJ!W$H| zK-e8(GgkwX#({q51b8M2dkrzck52P&B5ebDKmav!L8I|$sr3Ou$geK#whXt&c(j&F zYB(|L0P6X!V%3HN;?c|oZ_yHBU4WE^cNH6cALNnh3#>v9@z5$>UxGHB>qfLlZ)Cuw zVW0hXC?CU&+Y{Q*LKJC1j+}$m*Nz!{Uk-tl0ovX2EIdF(_o^~fob(hewOE!OoGO(= zUl4XB+|ogumK;TVk{HwVfi;Gx2lhJ4;G0%U){3RK=9_R$KcGDUcU`0M*!mtVphrcs zGZkd&236gAPYPoeh_qK-k0q23y5BwgCPFDxM!%7DO^>%TQ*TppYAiN3ZX3vA#U;H6 zp1_DC!s`?0x)sLGn=Vqa1LsRi_{02xm(D60>gK5{#Px!6UGd8(%A}q0RH%;Z*}uI1nYq%x2GqJ-X6G#gTGBG@W|4b!?{L+6Z3i4c^~I3 zI~_vvx8c5zG2y&*AvhO#JYVKR1*!Tc<*v`C;;v{q453M<7l_xPQBdc;81i+CFo{jU z5{&Km1%pbnXb1-i2%neWNHjQN4m=Q1f44LO1*bEG`PtDEdGAx1Y~USiplb(BWy{`7 z&jZx*PZyV&hx+Ea{I1RNUEp=zzKDP}c!?#Mr=&#KX4>bYFh)6=wsXjn5Hav`*2w#v zC_$eHeyxH-jh<+*DS8`BNHpkS1)Le*!34hBuU!tM2F2{+hxA}=plg>+Q19KzAEG}P z6)jGU+#+<$5$bgSSkQyr$}7S4r`Y+#w8vf9+yo$&Dfj94Sj^~Lz&J>`&?T6&6ZKda zZ(r4>ZQm1?#^uR0>;9w<8A;+1b1hB;wL^HI-Zk7JRlxAT0n09JQlCB_#FZ8m>G#Um z6zvM>JaO2oYuAwPy1STQUQ`#5|46VLcg~KgO`)-mqdms4h_^9(DZwo}{7ypP9~UUS zG==|wq+Jo#bz=O&WB_ILZ8Oxw6tB+cvL?c57k0azxLdkSsT|1rMQUbiQt;*GFiZsS z555(DZG`ayZ`(DuQ~X`i*VY7Pcj~wp*>z?rKN|ND8B3_8&9mpul)V$oWP?-}xqK+(47*G{aBXJ^*GGKtFz>Su@WbKG3C&KR12KXtCL_zbfOUhE+J~ZzM z{_&1>%`KAXs4(qA7hUd-U&Cy=XE46`FwkXdU)RHFWD zSE%9>l^CHJNnllV$4y*~y%$34vZ&lw>6=|p@#lR|aY-X6 zejZNV8|qG;s2wDb=L6DPDYShqOhC69Bj{EIO|!PKtc(x$+vOhUjDj5wc%o7_Fu^rb{G_5#>P3(r9I%U z;~&~%#Z7eXRYkao4?OYGJ@&%JOxhMA`PFZHo2fHqz?Hb+`EEJ#cww98{*EV*K7Kxu z4j=qSLA-*$jb|Z0JX;Q_bR&>PPrG3uF4yoUnhmMB$yrPQc@R6(B%apLO+B164SPDe zRiL<4Ibs;O@s3>Eq0VWcCf03M-B|>3wm^9!;kW5yu_G|3V#3Xu z;a$PJ;ZD+#!kMAaen)~jA@gynKe?C0cYBx9&zE*3zG}*Mme=I-lZd|C$h%!so$&l)JD9|r z&wu}PWx_EQAUnoaw&!nLUekhGGl9Crlhq-<1+{X;u|0pG`ab&)L;RKmt4NzooH!cW z46F&gQfd#vZ+u6qJbl6l8dG) zY<{A37XsZaX|o|XPeos$`Ic=3Cq1FbC|KG6v~T5hqYkVmA-;}IN`$Wvn%)A4tI(Ia zYh&{qU@t!(dbhXlFs-F)S#i_ycLVTK)9>_7U#{sor9|PiqqHn5Ppf(%wKIibnd4n3 zjLM_nf0$=E|FhoVe;Joq{#$itYXkyT3W2F z>%R^_1>%399{;yl+1bUFn1zLl`+qeq|En4N?*M>doi*nTNld>L%?I638HlHzAMJW2 z!_I2Ag<1+ZIN?a_FylE&q0ynJUOoOZ_8_FfU=1l5IJzoDb6Xw)&riYbv24Z}8b7o? z3LJkxqUTvhkusZtCFiUeWuQ;d^%tA<{|n}PPLi1pMW;qUlP!WE`OBY-2oYv7A5xC^ zLq=)Xr$i(kuaq8oKVDR`0$+8vi2lVn0X|4V1vWSm>Z@WhDX0kn4?MAW|b}guMUu1J&_) zfCK$o#~mT_D`+o#h}kpnCOG*@8J?O+npwnQ%rbb}C^V2DHdM(Go{*haOplDf4N_zn zqkWxv6|D;%z8`Fa7Msi{6mtlffP)+km4X}`H#YqF*0iwp)GU_drxi=wR3If>J$q^b zd@QiJm_>FBaE&LW70eumE7C7QE%vl0PDEiA%oiK+15$rXi@6?#xkcg|gea&O#0D z_W{)*Y2gr2aAQzx6ZFdycpG#)#DiN99{ycwWC})XTtE~l?=I4B4g@66z;Pw6JW}L8 z4Sx(#7NG@k#qa@81=rFL5(VJ&D7c{EP^4`|{x@xbS%C#XGJt(XCErMB$v7jBBqJfP zP7*B}VJ&3Pt8%$1*dPOCMbTRFP-^+85i||xs8DUu+G6bB?xIxgo1(G6q3^ZE?*5q0 z{UZq$M%Kz$o=*WmGZP19oP+E8lO?3?fbUmIJbXq>uX?Vwwofgk$0fVljqP1(Lxskp z1l3Z!pgyJDsDrbF5q)@r?U64FeIGCw2)YeLBaYm#C+s`1Ro>ei_cPmMe!EZUnWqSLalJX zqPR+$3NQ{6*$>K7l**dryI1&9#oWh9+;FLLAyT9Xb$+FEHbxGa5MEnlf(6UFz|c%r&)WFH|N} z-Lz;UI$AoD3drbFSt?S#1nKK@Wa?p8ap27rwP-_&ild5Q<;;~dEy|o-!zeU3Dn!F; z2UV;g;&v*q^_8QREGwB?my|2W&*v{;u?dtb+T=KD(5uST21+Kj;2g7m#H<-n=F5X+ZJIhV_V+@(`1fP?FO>%FFK!S?!7pO6cLX*n6Ob*wR+u#3RWC-=co z+tKH}Pnd0u3?ONlX5)o+J?>ThVKR8NZn{K6fQH#hMkea%qlIs7Gj2Twcx$CxpDwTg8)T4=CQ)>dR_3rdhh@~4Ll*5669NR4MU63_8I5HuYWLR4&iwz9E$?StWZQ$q9E*OdJHynhwn|F*-0#+aFkyr2>yXuOM+h)(Otq7@e&YbzD7LA9W~P zQ(A9zBuT&IMCV}JTw2#@a5y5Jhg*1x7TS$IyueRqD<|tMWoqn$7b#(o3jg*_WqTSL7IVm4~OSmb&bBTrlH0 z-c0s>$)6-Q0YfiiHeP+3*385!J9Sg~|NS2@oyca(9TiK*^bABk>va|4kY{#{tGl;^ zSsEs6>tYKgmWx!BE%c>|Kde>%c5JXO`>(pL*w;?SmFao3;#|rDFMlqqGLk5CTAL`Y zO)5q&J~j<^JGP$V8Cc1kW#Kkug$~0OY*4cj%Dck_+l!q0LCFMBZi7eEa6Y#=8I8J~ zdk-~@n946~S-AEMRFnbTc?7grW=eiR(Mgi9J>R00rW$Ub8CSC9F`I@=A*Lb^f zj&91#F4k<4pq%_I;zG5A-;c-D>(>Lt7p^dFLyO+gcyIYc(fB8(oe%Lc+*XgB`UUee z0{xu2kF@UYaZJx2gaKVUWJ4_!Pw_$w_ZMq_IjoK~?_-C()A-LHAh@+KY_|-6nzmbz zqpu9)+)5kJ<)JL{G1W*vmJ4$kqV3wpV4wD{Eb^Ed&F{+5x(MA{V)`qw!T+%5$vdo( z>tZ%eu9@l8jr&59j;9M=Enzat!!4Hi6JRPab~|gqhHkx*x$;lrN%64>v&o65pmCedA9r1o8n1tylWMeT^!ZnX zhz!jUv|e=t`&@!*+-R5y&K95o)w@bmXn52*k~{ps+!{sn?>Qdl!6<}Ey|9=*A>Y==W=b1xmHn}L{WFZLZZA08tu7Q#Mknp`4kte~51!YU zF5|Utqx`_qDUPw++44RhEo44qS-OWmS_8N~{oL8QyLwD}ukO*ae;FnhlY)ij#m3lu zALb_wN`eIdkVbqbhq-bBk{9u5(g`JnHR;Y4v{}|;Y`SO4)^^L(pPpJWW-*J+`8%Ul z3JQOnheKA5P)j1Q zh>_`-q3bS4h$+k#kiAOl@UXk`Ay3_O3l>;mbTCK|Jq~!mM-^|Gkmg$ zsrqcBDYVq^Rfyc0p62f?z1cT!fxxoUp`2Vpa3o~Pk|@sc4P;C>6zhsjgA!Rqq-gW_HMreoN5*45}$gqnBhp*#!=``v^MI1Ftoy9(}yA=!(G^Eqbc#5VHteSmZCcL|2h{W;`Y@n-0)u z;RF`!VlH$tS2!flKt@;jq$^$6Xp|5&>n0{2wDs;XY?d)aN)RiMR+7S`T0iKHn(@<) zU#^jf#3r%agQo*@-JCPS#^f=gV>TGq(|^nrJ7QryAUfK3VNJ>z!u~liFb1*ljFd+p zQ_->1RPaNUMnK7vA^RCm4`)3nR z%DzJV+SXs@+`{Or8O&F5x@L@XlFkT+(wX|ml$jY2TBRH|{MfirP5;dL32V=#{RQ9> za5r~W(*4?f@9u|l%pV{KIi8&VxxivJeo)z?6W2Q%pfmMHXwZxaK@Xh!2_d025^1Wz%twlNT#Y@Fvrs?^YXQm7~8*?kPl&xyG zrMuMKP7-R=}{%5_oMT8VOE-Ly|tXiX6OV`O&BOAuf(US%B%55h+tXYQ}B^ zTWW%fdyCL(Qkx|>vByz5`mw{F9YiuUL_ZZbEoRLJ<)hT6JT=UMKMIp0PFUuMYsrjc z>4bRUM0j5hg5`*kUWc6S1kh9-A$8ry)%lk-(-!q}bHJXyU*(|y3$G5|el?PGeJ)o1 zv`?gI7x~GA=*g5vV;7|M0P^49)M7;EZi3-%%!POWtx*(ezZ&;1UZ7bkg3mKnquY+#OTZFG`?S6*#i(`=s{W8!Jl@`kmmxpZf1i?#mGhsIk%B@( IQ4;q50`*GycmMzZ literal 33294 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 diff --git a/guide.tex b/guide.tex index a095ccd4..601df144 100644 --- a/guide.tex +++ b/guide.tex @@ -10,12 +10,12 @@ \setmonofont{Inconsolata} \title{Challenge FIC 2014 : Guide introductif} -\author{EPITA} +\author{\includegraphics[width=80pt]{epita}} \date{22 janvier 2014} \newcommand{\certClient}[1]{\texttt{client\_#1.p12}} -\newcommand{\certServeurWin}[0]{\texttt{serveur.der}} -\newcommand{\certServeurLinux}[0]{\texttt{serveur.pem}} +\newcommand{\certServeurWin}[0]{\texttt{ca.der}} +\newcommand{\certServeurLinux}[0]{\texttt{ca.pem}} \newcommand{\WindowsLogo}{\raisebox{-0.1em}{\includegraphics[height=0.75em]{windows_key}}} \newcommand{\WinKey}{\keystroke{\WindowsLogo}} @@ -24,9 +24,9 @@ \maketitle{} -\textbf{\textsc{Bienvenue}} à cette seconde épreuve du challenge +\textbf{\textsc{Bienvenue}} dans cette seconde épreuve du challenge \emph{forensics} ! Votre première activité consiste à accéder au site dédié à -cet événement ; ce guide est là pour vous aider à y parvenir. +cet événement ; ce guide est là pour vous y aider. \paragraph{Important :} La clef USB qui vous a été donnée contient des fichiers permettant votre authentification auprès de nos serveurs. Ne la @@ -38,12 +38,14 @@ laissez pas sans surveillance ! \vspace{\baselineskip} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\section{Installation du certificat \emph{client}} +\section{Installation du certificat client} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Le certificat \emph{client} est envoyé à notre serveur pour vous identifier et -authentifier. Si votre numéro d'équipe était \emph{X}, il s'agirait du -fichier nommé \certClient{X} sur votre clef USB. +vous authentifier. +Si votre numéro d'équipe était \emph{X}, il s'agirait du fichier nommé +\certClient{X} sur votre clef USB. +Il est protégé avec le mot de passe qui vous a été fourni sur papier. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Mozilla Firefox} @@ -94,52 +96,100 @@ concernant \nameref{sec:clIE}. \subsection{Internet Explorer} \label{sec:clIE} -Sous Windows, un \textbf{double-clic} sur le fichier \certClient{X} devrait -suffire à faire surgir les instruction d'installation pour ce certificat. - -Vous pouvez \textbf{aussi} l'importer \emph{via} la console de gestion des -certificats : \begin{enumerate} - \item Pressez les touches \WinKey{} + \keystroke{R}. - \item Écrivez \texttt{\textbf{certmgr.msc}} et appuyez sur la touche - \emph{Entrée} \Return{}. - \item Cliquez sur le dossier \textbf{Personnel}. - \item Dans le menu \textbf{Action}, sous-menu \textbf{Toutes les tâches}, - choisissez \textbf{Importer…} - \item Cliquez sur \textbf{Suivant} et suivez les instructions. - \item Lorsqu'on vous le demande, placez le certificat dans le magasin - \textbf{Personnel}. + \item \textbf{Double-cliquez} sur le fichier \certClient{X}. + L'\emph{assistant d'importation du certificat} apparaît. + \item Cliquez sur \textbf{Suivant}. + \item Cliquez sur \textbf{Suivant}. + \item Entrez le mot de passe fourni sur papier puis cliquez sur \textbf{Suivant}. + \item Cliquez sur \textbf{Suivant} (le certificat sera automatiquement + placé dans le magasin \emph{Personnel}). + \item Cliquez sur \textbf{Terminer}. \end{enumerate} +Selon votre version de Windows, votre système peut ensuite vous demander de +définir un mot de passe pour protéger ce certificat. + \paragraph{Microsoft Internet Explorer :} Aucune version de \emph{Microsoft Internet Explorer} (nom d'« Internet Explorer » jusqu'à sa version 6 comprise) n'est supportée par notre serveur. La fin du support officiel étant prévue le 8 avril prochain, vous devriez déjà y être préparé ! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -\section{Installation du certificat \emph{serveur}} +\section{Installation du certificat de l'autorité de certification du serveur} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Pour ne pas rencontrer d'avertissement lors de vos connexions au serveur, -c'est-à-dire être en mesure de vérifier la validité du certificat du serveur, -nous vous recommandons d'ajouter également à votre navigateur le certificat de -notre autorité de certification. +c'est-à-dire être en mesure de \textbf{vérifier la validité} du certificat du +serveur, nous vous \textbf{recommandons} d'ajouter également à votre +navigateur le certificat de notre autorité de certification. -Sur votre clef USB, ce certificat est nommé \certServeurWin{} (pour les -utilisateurs de Microsoft Windows) ou \certServeurLinux{} (pour les -utilisateurs de Linux). +Sur votre clef USB, ce certificat est nommé \certServeurWin{}. + +\paragraph{Note :} Ajouter un certificat d'autorité racine n'est pas anodin : +si un certificat était forgé par cette autorité pour un site tiers (comme +Twitter, Gmail, etc.), il serait considéré valide par votre navigateur, +permettant ainsi un espionnage \emph{man in the middle} de vos échanges avec +ce site. + +Pour cette raison, au cas où vous oublieriez de le supprimer après le +challenge, ce certificat n'est valide que jusqu'à 23 h 59 ce soir. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Mozilla Firefox} \label{sec:servFFox} +Suivez la même procédure que pour le certificat client +(cf. \autoref{sec:clFFox}) mais choisissez l'onglet \textbf{Autorités} (au +lieu de \emph{Vos certificats}) et, lorsqu'on vous demande pour quelles +actions faire confiance au certificat, sélectionnez \textbf{Confirmer cette AC +pour identifier des sites web}. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Chromium/Google Chrome} \label{sec:servChrome} +\subsubsection{Sous Microsoft Windows} + +Le navigateur utilise les paramètres du système ; suivez les instructions +concernant \nameref{sec:servIE}. + +\subsubsection{Sous Mac OS} + +\begin{enumerate} + \item Suivez la même procédure que pour le certificat client + (cf. \autoref{sec:clChrome}) mais sélectionnez cette fois-ci le + fichier \certServeurWin{}. + \item Cliquez sur \textbf{Toujours approuver}. +\end{enumerate} + +\subsubsection{Sous GNU/Linux, FreeBSD ou OpenBSD} + +\begin{enumerate} + \item Ouvrez le menu des préférences du navigateur. + \item Cliquez sur \textbf{Afficher les paramètres avancés}. + \item Dans la section \textbf{HTTPS/SSL}, cliquez sur \textbf{Gérer les + certificats}. + \item Sélectionnez l'onglet \textbf{Autorités}. + \item Cliquez sur \textbf{Importer…} et sélectionnez \certServeurWin{}. + \item Choisissez \textbf{Faire confiance à ce certificat pour identifier les sites web}. +\end{enumerate} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Internet Explorer} \label{sec:servIE} +\begin{enumerate} + \item \textbf{Double-cliquez} sur le fichier \certServeurWin{}. + \item Cliquez sur \textbf{Installer un certificat…} + \item Cliquez sur \textbf{Suivant}. + \item Sélectionnez \textbf{Placer tous les certificats dans le magasin + suivant} et choisissez le magasin \textbf{Autorités de certification + racines de confiance}. Cliquez enfin sur \textbf{Suivant}. + \item Cliquez sur \textbf{Terminer}. + \item Un avertissement de sécurité apparaît, reprenant notamment notre + avertissement de début de section. Cliquez sur \textbf{Oui}. +\end{enumerate} + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \end{document} From 9461aea9fcdb100c840a1260ee96bb9d5eadaf9e Mon Sep 17 00:00:00 2001 From: Thibaut Le Page <`echo dGhpbHAuaXMK | base64 -d`@gmail.com> Date: Mon, 20 Jan 2014 11:28:05 +0100 Subject: [PATCH 0200/2686] nicer links: no more red borders --- guide.pdf | Bin 33134 -> 33351 bytes guide.tex | 8 ++++++++ 2 files changed, 8 insertions(+) diff --git a/guide.pdf b/guide.pdf index 207d669de3368b271a2d5c5fef5292f58f72632b..eb1b32f8a003e8cf7b797ca86c628c101b8a8054 100644 GIT binary patch delta 26407 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෗gAF~tkLPMQc8%VU_(wO6_dMWqrkOwd9hV(3yN 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 Date: Mon, 20 Jan 2014 15:50:00 +0100 Subject: [PATCH 0201/2686] Truncate exercice_tries --- onyx/include/admin/list_themes.php | 1 + 1 file changed, 1 insertion(+) diff --git a/onyx/include/admin/list_themes.php b/onyx/include/admin/list_themes.php index a52a60f1..54800012 100644 --- a/onyx/include/admin/list_themes.php +++ b/onyx/include/admin/list_themes.php @@ -36,6 +36,7 @@ else if (isset($_GET["drop"])) $db = new BDD(); $db->query("TRUNCATE exercice_files"); $db->query("TRUNCATE exercice_keys"); + $db->query("TRUNCATE exercice_tries"); $db->query("TRUNCATE exercices"); $db->query("TRUNCATE themes"); $db->query("TRUNCATE solved"); From ebb0cabf9aa8acafbd23c3b10272f43142ea2cb8 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 16:52:44 +0100 Subject: [PATCH 0202/2686] Change file path --- onyx/include/common/Exercice.class.php | 3 ++- onyx/tpl/bootstrap/teams/exercice.tpl | 2 +- synchro.sh | 10 +++++----- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/onyx/include/common/Exercice.class.php b/onyx/include/common/Exercice.class.php index 7fade8d4..ad6a8b24 100644 --- a/onyx/include/common/Exercice.class.php +++ b/onyx/include/common/Exercice.class.php @@ -37,8 +37,9 @@ class Exercice foreach($this->files as &$f) { $f["path_orig"] = $f["path"]; + $f["path_hash"] = hash("sha384", $f["path"])."/".basename($f["path"]); if (isset($VAR["files_dir"])) - $f["path"] = $VAR["files_dir"].$f["path"]; + $f["path"] = $VAR["files_dir"].$f["path_hash"]; $f["basename"] = basename($f["path"]); $f["sha1"] = strhex($f["sha1"]); } diff --git a/onyx/tpl/bootstrap/teams/exercice.tpl b/onyx/tpl/bootstrap/teams/exercice.tpl index 3574f047..48ae7f99 100644 --- a/onyx/tpl/bootstrap/teams/exercice.tpl +++ b/onyx/tpl/bootstrap/teams/exercice.tpl @@ -32,7 +32,7 @@ {if file_exists($file['path'])} - + diff --git a/synchro.sh b/synchro.sh index 989d2bca..7bff0c25 100755 --- a/synchro.sh +++ b/synchro.sh @@ -15,11 +15,11 @@ then OPTS="$OPTS --delete" fi -rsync -e ssh -av $OPTS out/errors phobos:~/ -rsync -e ssh -av $OPTS out/htdocs phobos:~/ -rsync -e ssh -av $OPTS out/teams phobos:~/ -rsync -e ssh -av $OPTS files phobos:~/ -rsync -e ssh -av $OPTS misc phobos:~/ +rsync -e ssh -av $OPTS out/errors phobos:~/ +rsync -e ssh -av $OPTS out/htdocs phobos:~/ +rsync -e ssh -av $OPTS out/teams phobos:~/ +rsync -e ssh -avL $OPTS files phobos:~/ +rsync -e ssh -av $OPTS misc phobos:~/ scp nginx.conf submission.php phobos:~/ rsync -e ssh -av phobos:~/submission/ submission/ From 6f260045fa10f16104bae1a9aa067288096b3722 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 18:23:02 +0100 Subject: [PATCH 0203/2686] CA.sh: Add a Master CA --- misc/CA.sh | 75 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index aa0f6212..16d07dfd 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -11,17 +11,21 @@ fi CAKEY=./cakey.key CAREQ=./careq.csr CACERT=./cacert.crt +MASTERKEY=./master.key +MASTEREQ=./master.csr +MASTERCERT=./master.crt + DAYS=365 -#GREEN="\033[1;32m" -#RED="\033[1;31m" -#COLOR_RST="\033[0m" +GREEN="\033[1;32m" +RED="\033[1;31m" +COLOR_RST="\033[0m" -GREEN="" -RED="" -COLOR_RST="" -BOLD="" -END_BOLD="" +#GREEN="" +#RED="" +#COLOR_RST="" +#BOLD="" +#END_BOLD="" usage() { @@ -61,7 +65,7 @@ case $1 in ESCAPED=$(echo "${TOP_DIR}" | sed 's/[\/\.]/\\&/g') echo -e "${GREEN}Making CA key and csr${COLOR_RST}" - sed -i 's/=.*#COMMONNAME/= FIC2014 CA #COMMONNAME/' $OPENSSL_CONF + sed -i 's/=.*#COMMONNAME/= FIC2014 MASTER #COMMONNAME/' $OPENSSL_CONF sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= objsign #CERTTYPE/" $OPENSSL_CONF @@ -71,9 +75,37 @@ case $1 in exit 5 fi + # MASTER CA + sed -i 's/cacert\.crt/master\.crt/' $OPENSSL_CONF + sed -i 's/cakey\.key/master\.key/' $OPENSSL_CONF pass=`pwgen -n -B -y 12 1` + echo "Master pass: " $pass + openssl req -batch -new -keyout ${TOP_DIR}/private/${MASTERKEY} \ + -out ${TOP_DIR}/${MASTEREQ} -passout pass:$pass \ + -config $OPENSSL_CONF > $OUTPUT 2>&1 + if [ $? -ne 0 ]; then + cat $OUTPUT + clean "ca" + exit 4 + fi - openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ + echo -e "${GREEN}Self signes the MASTER certificate${COLOR_RST}" + openssl ca -batch -create_serial -out ${TOP_DIR}/${MASTERCERT} \ + -days ${DAYS} -keyfile ${TOP_DIR}/private/${MASTERKEY} \ + -selfsign -extensions v3_ca -config ${OPENSSL_CONF} \ + -infiles ${TOP_DIR}/${MASTEREQ} > $OUTPUT 2>&1 + if [ $? -ne 0 ]; then + cat $OUTPUT + clean "ca" + exit 4 + fi + + sed -i 's/=.*#COMMONNAME/= FIC2014 CA #COMMONNAME/' $OPENSSL_CONF + echo -e "${GREEN}Generate CA certificate${COLOR_RST}" + + pass=`pwgen -n -B -y 12 1` + echo "CA pass: " $pass + openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ -out ${TOP_DIR}/${CAREQ} -passout pass:$pass \ -config $OPENSSL_CONF > $OUTPUT 2>&1 if [ $? -ne 0 ]; then @@ -90,17 +122,20 @@ case $1 in clean "ca" exit 4 fi - - echo -e "${GREEN}Self signes the CA certificate${COLOR_RST}" - openssl ca -batch -create_serial -out ${TOP_DIR}/${CACERT} \ - -days ${DAYS} -keyfile ${TOP_DIR}/private/${CAKEY} \ - -selfsign -extensions v3_ca -config ${OPENSSL_CONF} \ - -infiles ${TOP_DIR}/${CAREQ} > $OUTPUT 2>&1 + echo -e "${GREEN}Signing CA crt by Master${COLOR_RST}" + openssl ca -policy policy_match -config ${OPENSSL_CONF} \ + -out ${TOP_DIR}/${CACERT} -infiles ${TOP_DIR}/${CAREQ} if [ $? -ne 0 ]; then + echo -e "${RED}Signing failed for CA${COLOR_RST}" + rm -rf ${TOP_DIR}/${CACERT} ${TOP_DIR}/${CAKEY} ${TOP_DIR}/${CAREQ} cat $OUTPUT - clean "ca" + sed -i 's/master\.crt/cacert\.crt/' $OPENSSL_CONF + sed -i 's/master\.key/cakey\.key/' $OPENSSL_CONF exit 4 - fi + fi + + sed -i 's/master\.crt/cacert\.crt/' $OPENSSL_CONF + sed -i 's/master\.key/cakey\.key/' $OPENSSL_CONF ;; "-newserver" ) echo -e "${GREEN}Making the Server key and cert${COLOR_RST}" @@ -108,7 +143,7 @@ case $1 in echo -e "${RED}Can not found the CA's key${COLOR_RST}" exit 2 fi - sed -i 's/=.*#COMMONNAME/= FIC2014 Server #COMMONNAME/' $OPENSSL_CONF + sed -i 's/=.*#COMMONNAME/= srs.epita.fr #COMMONNAME/' $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= server #CERTTYPE/" $OPENSSL_CONF openssl req -batch -new -keyout server.key -out server.csr \ -days ${DAYS} -config ${OPENSSL_CONF} > $OUTPUT 2>&1 @@ -118,7 +153,7 @@ case $1 in fi echo -e "${GREEN}Signing the Server crt${COLOR_RST}" openssl ca -policy policy_match -config ${OPENSSL_CONF} \ - -out server.crt -infiles server.csr > $OUTPUT 2>&1 + -out server.crt -infiles server.csr if [ $? -ne 0 ]; then echo -e "${RED}Signing failed for new server${COLOR_RST}" rm -rf server.key server.crt server.csr From 63d73bc601e4177236292fb2a7e444dbe4edd8d8 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 18:34:18 +0100 Subject: [PATCH 0204/2686] Fixed CA.sh path var --- misc/CA.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/misc/CA.sh b/misc/CA.sh index 16d07dfd..9ba3878a 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -172,6 +172,9 @@ case $1 in echo "==============================================================" echo -e "${GREEN}Making the client key and csr of ${BOLD}${2}${END_BOLD}${COLOR_RST}" + ESCAPED=$(echo "${TOP_DIR}" | sed 's/[\/\.]/\\&/g') + sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF + if ! [ -f ${TOP_DIR}/private/${CAKEY} ]; then echo -e "${RED}Can not found the CA's key${COLOR_RST}" exit 2 From 83c61f6fe447ac8d0ea3372c95c23885f7516de7 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 18:44:46 +0100 Subject: [PATCH 0205/2686] misc/ --- synchro.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/synchro.sh b/synchro.sh index 7bff0c25..07dea5ba 100755 --- a/synchro.sh +++ b/synchro.sh @@ -19,7 +19,7 @@ rsync -e ssh -av $OPTS out/errors phobos:~/ rsync -e ssh -av $OPTS out/htdocs phobos:~/ rsync -e ssh -av $OPTS out/teams phobos:~/ rsync -e ssh -avL $OPTS files phobos:~/ -rsync -e ssh -av $OPTS misc phobos:~/ +rsync -e ssh -av $OPTS misc/server.* misc/pki/cacert.crt misc/pki/crl.pem phobos:~/ scp nginx.conf submission.php phobos:~/ rsync -e ssh -av phobos:~/submission/ submission/ From 363ba3325a94f27473bc6a790062f47c07f4e16f Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 18:59:15 +0100 Subject: [PATCH 0206/2686] Make some changes on chrono --- htdocs/index.php | 2 +- onyx/include/admin/chrono.php | 2 +- onyx/tpl/bootstrap/admin/exercice.tpl | 2 +- onyx/tpl/bootstrap/admin/home.tpl | 26 +++++++++++++++++++------- onyx/tpl/bootstrap/public/home.tpl | 2 +- 5 files changed, 23 insertions(+), 11 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index 1ae3750c..ac03ea5d 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -131,7 +131,7 @@ else if ($n && $p[0] == SALT_USER) $page = "teams/list"; } - else if (empty($VAR["start_challenge"]) || $VAR["start_challenge"] < time()) + else if (empty($VAR["start_challenge"])) { $TEAM = new Team($p[1]); $template->assign("my_team", $TEAM); diff --git a/onyx/include/admin/chrono.php b/onyx/include/admin/chrono.php index d62bc9c3..99350ee0 100644 --- a/onyx/include/admin/chrono.php +++ b/onyx/include/admin/chrono.php @@ -9,7 +9,7 @@ if (count($p) > 2) switch($p[2]) { case "start": - file_put_contents($VAR["misc_dir"]."/challenge_started", time() + 42); + file_put_contents($VAR["misc_dir"]."/challenge_started", time() + (intval($_POST["time"]) - 240) * 60); break; case "init": diff --git a/onyx/tpl/bootstrap/admin/exercice.tpl b/onyx/tpl/bootstrap/admin/exercice.tpl index 01de1461..affd82af 100644 --- a/onyx/tpl/bootstrap/admin/exercice.tpl +++ b/onyx/tpl/bootstrap/admin/exercice.tpl @@ -70,7 +70,7 @@
- {if is_file($file.path)} Calculated from {$file.path}: {sha1_file($file.path)}{/if} + {if is_file($file.path)} Calculated from {$file.path}: {sha1_file($file.path)} pas bon{else}label-success">ok{/if}{/if}
diff --git a/onyx/tpl/bootstrap/admin/home.tpl b/onyx/tpl/bootstrap/admin/home.tpl index 25101ae8..885c26fe 100644 --- a/onyx/tpl/bootstrap/admin/home.tpl +++ b/onyx/tpl/bootstrap/admin/home.tpl @@ -15,24 +15,36 @@
  • [CN] : {$cert['subject']['CN']}
  • [emailAddress] : {$cert['subject']['emailAddress']}
  • - Supprimer + {elseif isset($cert_writable) && ! $cert_writable}
    Répertoire non accessible en écriture.
    - Nouveau + {else} - Nouveau + Pas de certificat + {/if}
    -

    Chrono

    +

    Chrono Lancé{else}danger">Arrêté{/if}

    - Start - Réinitialiser + +
    + +
    + + minutes +
    +
    +
    + + Réinitialiser +
    +
    {/block} diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index 6751cbcf..72f6efbe 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -1,7 +1,7 @@ {extends file="public/layout.tpl"} {block name=head2} - + {/block} {block name=main} From 9108124ca4ad3994dc762de4d4c6506e0c092973 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 18:59:49 +0100 Subject: [PATCH 0207/2686] Generate a directory for files --- gen_hash_link_files.sh | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100755 gen_hash_link_files.sh diff --git a/gen_hash_link_files.sh b/gen_hash_link_files.sh new file mode 100755 index 00000000..2cb4873a --- /dev/null +++ b/gen_hash_link_files.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +FROM=`realpath $1`; shift +TO=`realpath $1`; shift + +if [ -z "$FROM" ] || [ -z "$TO" ] +then + echo "Usage: $0 from to" + exit 1 +elif ! [ -d "$FROM" ] +then + echo "$FROM not found" + exit 2 +fi + +mkdir -p "$TO" || exit 3 +rm -rf "$TO" || exit 3 + +for i in `find "$FROM" -mindepth 1 -type f` +do + FILE=`echo $i | sed "s!^$FROM/!!"` + HASH=`echo -n $FILE | sha384sum | cut -d " " -f 1` + + mkdir -p "$TO/$HASH/" + ln -s "$i" "$TO/$HASH/" +done From ac5aa1099e05c567ef8621d4ee4e4c013b8c24d8 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Mon, 20 Jan 2014 20:53:20 +0100 Subject: [PATCH 0208/2686] Revert "CA.sh: Add a Master CA" This reverts commit 6f260045fa10f16104bae1a9aa067288096b3722. --- misc/CA.sh | 79 +++++++++++++++--------------------------------------- 1 file changed, 22 insertions(+), 57 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index 9ba3878a..3e7cc1cc 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -11,21 +11,17 @@ fi CAKEY=./cakey.key CAREQ=./careq.csr CACERT=./cacert.crt -MASTERKEY=./master.key -MASTEREQ=./master.csr -MASTERCERT=./master.crt - DAYS=365 -GREEN="\033[1;32m" -RED="\033[1;31m" -COLOR_RST="\033[0m" +#GREEN="\033[1;32m" +#RED="\033[1;31m" +#COLOR_RST="\033[0m" -#GREEN="" -#RED="" -#COLOR_RST="" -#BOLD="" -#END_BOLD="" +GREEN="" +RED="" +COLOR_RST="" +BOLD="" +END_BOLD="" usage() { @@ -65,7 +61,7 @@ case $1 in ESCAPED=$(echo "${TOP_DIR}" | sed 's/[\/\.]/\\&/g') echo -e "${GREEN}Making CA key and csr${COLOR_RST}" - sed -i 's/=.*#COMMONNAME/= FIC2014 MASTER #COMMONNAME/' $OPENSSL_CONF + sed -i 's/=.*#COMMONNAME/= FIC2014 CA #COMMONNAME/' $OPENSSL_CONF sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= objsign #CERTTYPE/" $OPENSSL_CONF @@ -75,37 +71,9 @@ case $1 in exit 5 fi - # MASTER CA - sed -i 's/cacert\.crt/master\.crt/' $OPENSSL_CONF - sed -i 's/cakey\.key/master\.key/' $OPENSSL_CONF pass=`pwgen -n -B -y 12 1` - echo "Master pass: " $pass - openssl req -batch -new -keyout ${TOP_DIR}/private/${MASTERKEY} \ - -out ${TOP_DIR}/${MASTEREQ} -passout pass:$pass \ - -config $OPENSSL_CONF > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then - cat $OUTPUT - clean "ca" - exit 4 - fi - echo -e "${GREEN}Self signes the MASTER certificate${COLOR_RST}" - openssl ca -batch -create_serial -out ${TOP_DIR}/${MASTERCERT} \ - -days ${DAYS} -keyfile ${TOP_DIR}/private/${MASTERKEY} \ - -selfsign -extensions v3_ca -config ${OPENSSL_CONF} \ - -infiles ${TOP_DIR}/${MASTEREQ} > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then - cat $OUTPUT - clean "ca" - exit 4 - fi - - sed -i 's/=.*#COMMONNAME/= FIC2014 CA #COMMONNAME/' $OPENSSL_CONF - echo -e "${GREEN}Generate CA certificate${COLOR_RST}" - - pass=`pwgen -n -B -y 12 1` - echo "CA pass: " $pass - openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ + openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ -out ${TOP_DIR}/${CAREQ} -passout pass:$pass \ -config $OPENSSL_CONF > $OUTPUT 2>&1 if [ $? -ne 0 ]; then @@ -122,20 +90,17 @@ case $1 in clean "ca" exit 4 fi - echo -e "${GREEN}Signing CA crt by Master${COLOR_RST}" - openssl ca -policy policy_match -config ${OPENSSL_CONF} \ - -out ${TOP_DIR}/${CACERT} -infiles ${TOP_DIR}/${CAREQ} - if [ $? -ne 0 ]; then - echo -e "${RED}Signing failed for CA${COLOR_RST}" - rm -rf ${TOP_DIR}/${CACERT} ${TOP_DIR}/${CAKEY} ${TOP_DIR}/${CAREQ} - cat $OUTPUT - sed -i 's/master\.crt/cacert\.crt/' $OPENSSL_CONF - sed -i 's/master\.key/cakey\.key/' $OPENSSL_CONF - exit 4 - fi - sed -i 's/master\.crt/cacert\.crt/' $OPENSSL_CONF - sed -i 's/master\.key/cakey\.key/' $OPENSSL_CONF + echo -e "${GREEN}Self signes the CA certificate${COLOR_RST}" + openssl ca -batch -create_serial -out ${TOP_DIR}/${CACERT} \ + -days ${DAYS} -keyfile ${TOP_DIR}/private/${CAKEY} \ + -selfsign -extensions v3_ca -config ${OPENSSL_CONF} \ + -infiles ${TOP_DIR}/${CAREQ} > $OUTPUT 2>&1 + if [ $? -ne 0 ]; then + cat $OUTPUT + clean "ca" + exit 4 + fi ;; "-newserver" ) echo -e "${GREEN}Making the Server key and cert${COLOR_RST}" @@ -143,7 +108,7 @@ case $1 in echo -e "${RED}Can not found the CA's key${COLOR_RST}" exit 2 fi - sed -i 's/=.*#COMMONNAME/= srs.epita.fr #COMMONNAME/' $OPENSSL_CONF + sed -i 's/=.*#COMMONNAME/= FIC2014 Server #COMMONNAME/' $OPENSSL_CONF sed -i "s/=.*#CERTTYPE/= server #CERTTYPE/" $OPENSSL_CONF openssl req -batch -new -keyout server.key -out server.csr \ -days ${DAYS} -config ${OPENSSL_CONF} > $OUTPUT 2>&1 @@ -153,7 +118,7 @@ case $1 in fi echo -e "${GREEN}Signing the Server crt${COLOR_RST}" openssl ca -policy policy_match -config ${OPENSSL_CONF} \ - -out server.crt -infiles server.csr + -out server.crt -infiles server.csr > $OUTPUT 2>&1 if [ $? -ne 0 ]; then echo -e "${RED}Signing failed for new server${COLOR_RST}" rm -rf server.key server.crt server.csr From cc588d51f9103f9890c0821b2b091d01ae3ab91c Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 21 Jan 2014 03:07:52 +0100 Subject: [PATCH 0209/2686] Ready to generate new certificates --- check.pl | 5 + misc/CA.sh | 21 ++- misc/openssl.cnf | 218 ++++----------------------- nginx.conf | 15 +- onyx/tpl/bootstrap/public/layout.tpl | 4 +- submission.php | 10 +- synchro.sh | 3 +- 7 files changed, 67 insertions(+), 209 deletions(-) diff --git a/check.pl b/check.pl index 095af269..5b2863f9 100755 --- a/check.pl +++ b/check.pl @@ -110,6 +110,11 @@ for my $f (readdir $dh) elsif ($type eq "sha512") { $tmp_solution = sha512_hex($solution); } + elsif ($type eq "whirlpool") { + my $hash = Digest->new( 'Whirlpool' ); + $hash->add( $solution ); + $tmp_solution = $hash->hexdigest; + } elsif ($type ne "raw") { warn "$type not implemented"; } diff --git a/misc/CA.sh b/misc/CA.sh index 3e7cc1cc..db4ba6c4 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -11,7 +11,8 @@ fi CAKEY=./cakey.key CAREQ=./careq.csr CACERT=./cacert.crt -DAYS=365 + +DAYS=2 #GREEN="\033[1;32m" #RED="\033[1;31m" @@ -63,7 +64,6 @@ case $1 in echo -e "${GREEN}Making CA key and csr${COLOR_RST}" sed -i 's/=.*#COMMONNAME/= FIC2014 CA #COMMONNAME/' $OPENSSL_CONF sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF - sed -i "s/=.*#CERTTYPE/= objsign #CERTTYPE/" $OPENSSL_CONF type pwgen > /dev/null if [ $? -ne 0 ]; then @@ -72,10 +72,9 @@ case $1 in fi pass=`pwgen -n -B -y 12 1` - openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ -out ${TOP_DIR}/${CAREQ} -passout pass:$pass \ - -config $OPENSSL_CONF > $OUTPUT 2>&1 + -config $OPENSSL_CONF -extensions CORE_CA > $OUTPUT 2>&1 if [ $? -ne 0 ]; then cat $OUTPUT clean "ca" @@ -94,7 +93,7 @@ case $1 in echo -e "${GREEN}Self signes the CA certificate${COLOR_RST}" openssl ca -batch -create_serial -out ${TOP_DIR}/${CACERT} \ -days ${DAYS} -keyfile ${TOP_DIR}/private/${CAKEY} \ - -selfsign -extensions v3_ca -config ${OPENSSL_CONF} \ + -selfsign -extensions CORE_CA -config ${OPENSSL_CONF} \ -infiles ${TOP_DIR}/${CAREQ} > $OUTPUT 2>&1 if [ $? -ne 0 ]; then cat $OUTPUT @@ -108,17 +107,16 @@ case $1 in echo -e "${RED}Can not found the CA's key${COLOR_RST}" exit 2 fi - sed -i 's/=.*#COMMONNAME/= FIC2014 Server #COMMONNAME/' $OPENSSL_CONF - sed -i "s/=.*#CERTTYPE/= server #CERTTYPE/" $OPENSSL_CONF + sed -i 's/=.*#COMMONNAME/=10.226.3.70#COMMONNAME/' $OPENSSL_CONF openssl req -batch -new -keyout server.key -out server.csr \ - -days ${DAYS} -config ${OPENSSL_CONF} > $OUTPUT 2>&1 + -days ${DAYS} -config ${OPENSSL_CONF} -extensions SERVER_SSL > $OUTPUT 2>&1 if [ $? -ne 0 ]; then cat $OUTPUT exit 4 fi echo -e "${GREEN}Signing the Server crt${COLOR_RST}" openssl ca -policy policy_match -config ${OPENSSL_CONF} \ - -out server.crt -infiles server.csr > $OUTPUT 2>&1 + -out server.crt -extensions SERVER_SSL -infiles server.csr if [ $? -ne 0 ]; then echo -e "${RED}Signing failed for new server${COLOR_RST}" rm -rf server.key server.crt server.csr @@ -145,7 +143,6 @@ case $1 in exit 2 fi sed -i "s/=.*#COMMONNAME/= $2#COMMONNAME/" $OPENSSL_CONF - sed -i "s/=.*#CERTTYPE/= client #CERTTYPE/" $OPENSSL_CONF type pwgen > /dev/null if [ $? -ne 0 ]; then @@ -156,7 +153,7 @@ case $1 in pass=`pwgen -n -B -y 12 1` openssl req -batch -new -keyout ${TOP_DIR}/${2}.key -out ${TOP_DIR}/${2}.csr \ - -config ${OPENSSL_CONF} -passout pass:$pass -days ${DAYS} > $OUTPUT 2>&1 + -config ${OPENSSL_CONF} -passout pass:$pass -days ${DAYS} -extensions CLIENT_SSL > $OUTPUT 2>&1 if [ $? -ne 0 ]; then cat $OUTPUT clean "client" $2 @@ -165,7 +162,7 @@ case $1 in echo -e "${GREEN}Signing the Client crt${COLOR_RST}" openssl ca -batch -policy policy_match -out ${TOP_DIR}/${2}.crt \ - -config ${OPENSSL_CONF} -infiles ${TOP_DIR}/${2}.csr > $OUTPUT 2>&1 + -config ${OPENSSL_CONF} -extensions CLIENT_SSL -infiles ${TOP_DIR}/${2}.csr > $OUTPUT 2>&1 if [ $? -ne 0 ]; then echo -e "${RED}Signing failed for $2 ${COLOR_RST}" cat $OUTPUT diff --git a/misc/openssl.cnf b/misc/openssl.cnf index a0183194..2cb594f2 100644 --- a/misc/openssl.cnf +++ b/misc/openssl.cnf @@ -55,8 +55,6 @@ crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.key # The private key RANDFILE = $dir/private/.rand # private random number file -x509_extensions = usr_cert # The extentions to add to the cert - # Comment out the following two lines for the "traditional" # (and highly broken) format. name_opt = ca_default # Subject Name options @@ -70,7 +68,7 @@ cert_opt = ca_default # Certificate field options # crlnumber must also be commented out to leave a V1 CRL. # crl_extensions = crl_ext -default_days = 365 # how long to certify for +default_days = 2 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = default # use public key default MD preserve = no # keep passed DN ordering @@ -147,7 +145,7 @@ organizationalUnitName = Organizational Unit Name (eg, section) organizationalUnitName_default = SRS commonName = Common Name (e.g. server FQDN or YOUR name) -commonName_default = Groupe_8#COMMONNAME +commonName_default =10.226.3.70#COMMONNAME commonName_max = 64 emailAddress = Email Address @@ -163,191 +161,37 @@ challengePassword_max = 20 unstructuredName = An optional company name -[ usr_cert ] - -# These extensions are added when 'ca' signs a request. - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -nsCertType = client #CERTTYPE - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "FIC 2014 generated certificates" - -# PKIX recommendations harmless if included in all certificates. +[CORE_CA] +nsComment = "FIC2014 CA" +basicConstraints = critical,CA:TRUE,pathlen:1 +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +issuerAltName = issuer:copy +keyUsage = keyCertSign, cRLSign +nsCertType = sslCA subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer - -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy -# An alternative to produce certificates that aren't -# deprecated according to PKIX. -# subjectAltName=email:move - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -# This is required for TSA certificates. -# extendedKeyUsage = critical,timeStamping - -[ v3_req ] - -# Extensions to add to a certificate request - -basicConstraints = CA:FALSE -keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -[ v3_ca ] - - -# Extensions for a typical CA - - -# PKIX recommendation. - -subjectKeyIdentifier=hash - authorityKeyIdentifier=keyid:always,issuer -# This is what PKIX recommends but some broken software chokes on critical -# extensions. -#basicConstraints = critical,CA:true -# So we do this instead. -basicConstraints = CA:true - -# Key usage: this is typical for a CA certificate. However since it will -# prevent it being used as an test self-signed certificate it is best -# left out by default. -# keyUsage = cRLSign, keyCertSign - -# Some might want this also -# nsCertType = sslCA, emailCA - -# Include email address in subject alt name: another PKIX recommendation -# subjectAltName=email:copy -# Copy issuer details -# issuerAltName=issuer:copy - -# DER hex encoding of an extension: beware experts only! -# obj=DER:02:03 -# Where 'obj' is a standard or added object -# You can even override a supported extension: -# basicConstraints= critical, DER:30:03:01:01:FF - -[ crl_ext ] - -# CRL extensions. -# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. - -# issuerAltName=issuer:copy -authorityKeyIdentifier=keyid:always - -[ proxy_cert_ext ] -# These extensions should be added when creating a proxy certificate - -# This goes against PKIX guidelines but some CAs do it and some software -# requires this to avoid interpreting an end user certificate as a CA. - -basicConstraints=CA:FALSE - -# Here are some examples of the usage of nsCertType. If it is omitted -# the certificate can be used for anything *except* object signing. - -# This is OK for an SSL server. -# nsCertType = server - -# For an object signing certificate this would be used. -# nsCertType = objsign - -# For normal client use this is typical -# nsCertType = client, email - -# and for everything including object signing: -# nsCertType = client, email, objsign - -# This is typical in keyUsage for a client certificate. -# keyUsage = nonRepudiation, digitalSignature, keyEncipherment - -# This will be displayed in Netscape's comment listbox. -nsComment = "OpenSSL Generated Certificate" - -# PKIX recommendations harmless if included in all certificates. +[SERVER_SSL] +nsComment = "FIC2014 Server" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +issuerAltName = issuer:copy +basicConstraints = critical,CA:FALSE +keyUsage = digitalSignature, keyEncipherment +nsCertType = server +extendedKeyUsage = serverAuth subjectKeyIdentifier=hash -authorityKeyIdentifier=keyid,issuer +authorityKeyIdentifier=keyid:always,issuer -# This stuff is for subjectAltName and issuerAltname. -# Import the email address. -# subjectAltName=email:copy -# An alternative to produce certificates that aren't -# deprecated according to PKIX. -# subjectAltName=email:move - -# Copy subject details -# issuerAltName=issuer:copy - -#nsCaRevocationUrl = http://www.domain.dom/ca-crl.pem -#nsBaseUrl -#nsRevocationUrl -#nsRenewalUrl -#nsCaPolicyUrl -#nsSslServerName - -# This really needs to be in place for it to be a proxy certificate. -proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo - -#################################################################### -[ tsa ] - -default_tsa = tsa_config1 # the default TSA section - -[ tsa_config1 ] - -# These are used by the TSA reply generation only. -dir = ./demoCA # TSA root directory -serial = $dir/tsaserial # The current serial number (mandatory) -crypto_device = builtin # OpenSSL engine to use for signing -signer_cert = $dir/tsacert.pem # The TSA signing certificate - # (optional) -certs = $dir/cacert.pem # Certificate chain to include in reply - # (optional) -signer_key = $dir/private/tsakey.pem # The TSA private key (optional) - -default_policy = tsa_policy1 # Policy if request did not specify it - # (optional) -other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) -digests = md5, sha1 # Acceptable message digests (mandatory) -accuracy = secs:1, millisecs:500, microsecs:100 # (optional) -clock_precision_digits = 0 # number of digits after dot. (optional) -ordering = yes # Is ordering defined for timestamps? - # (optional, default: no) -tsa_name = yes # Must the TSA name be included in the reply? - # (optional, default: no) -ess_cert_id_chain = no # Must the ESS cert id chain be included? - # (optional, default: no) +[CLIENT_SSL] +nsComment = "FIC2014 Client" +subjectKeyIdentifier = hash +authorityKeyIdentifier = keyid,issuer:always +issuerAltName = issuer:copy +basicConstraints = critical,CA:FALSE +keyUsage = digitalSignature, nonRepudiation +nsCertType = client +extendedKeyUsage = clientAuth +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer diff --git a/nginx.conf b/nginx.conf index e7440406..6959d22b 100644 --- a/nginx.conf +++ b/nginx.conf @@ -2,6 +2,13 @@ server_tokens off; client_header_buffer_size 512; client_max_body_size 512; +server { + listen 80 default; + listen [::]:80 ipv6only=on default; + + rewrite ^ https://$host$uri; +} + server { listen 443 ssl; listen [::]:443 ipv6only=on ssl; @@ -13,14 +20,14 @@ server { access_log /var/log/nginx/fic.access_log; error_log /var/log/nginx/fic.error_log; - ssl_certificate /var/www/fic2014-server/misc/server.crt; - ssl_certificate_key /var/www/fic2014-server/misc/server.key; + ssl_certificate /var/www/fic2014-server/server.crt; + ssl_certificate_key /var/www/fic2014-server/server.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; - ssl_client_certificate /var/www/fic2014-server/misc/pki/cacert.crt; + ssl_client_certificate /var/www/fic2014-server/cacert.crt; ssl_verify_client optional; - ssl_crl /var/www/fic2014-server/misc/pki/crl.pem; + ssl_crl /var/www/fic2014-server/crl.pem; add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index 6056acc6..8538e0ca 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -22,13 +22,13 @@

    Top 10

    {foreach from=$top item=t key=k} -
    {$k+1}. {link href="{$t->id}-{$t->get_name_url()}" href_prefix="/" label=$t->get_name()} +
    {$k+1}. {link href="{$t->id}-{$t->get_name_url()}" href_prefix="/" label={$t->get_name()|replace:"_":" et "}} {$t->get_pts()}
    {/foreach} -
        {link href="classement" href_prefix="/" label="Classement general"}
    +
        {link href="classement" href_prefix="/" label="Classement général"}
    diff --git a/submission.php b/submission.php index 85bffa3f..02f65569 100644 --- a/submission.php +++ b/submission.php @@ -8,7 +8,8 @@ function show($file) header("HTTP/1.1 403 Forbidden"); } -$file = __DIR__."/submission/".intval($_GET["team"])."-".intval($_GET["theme"])."-".urlencode($_GET["exercice"]); +$filename = intval($_GET["team"])."-".intval($_GET["theme"])."-".urlencode($_GET["exercice"]); +$file = __DIR__."/submission/".$filename; if (file_exists($file)) @@ -16,7 +17,12 @@ if (file_exists($file)) else if (!empty($_POST["solution"]) && !empty($_GET["team"]) && !empty($_GET["theme"]) && !empty($_GET["exercice"])) { - file_put_contents($file, $_POST['solution'], LOCK_EX); + $algos = array("md5", "sha1", "sha256", "sha384", "sha512", "whirlpool"); + $content = ""; + foreach($algos as $algo) + $content .= mcrypt_encrypt(MCRYPT_SERPENT_256, hash($algo, $_POST["solution"]), hash($algo, $filename), MCRYPT_MODE_ECB)."\n"; + + file_put_contents($file, $content, LOCK_EX); show(__DIR__."/teams/".intval($_GET["team"])."/".urlencode($_GET["theme"])."/".urlencode($_GET["exercice"])."/submission/index.html"); } diff --git a/synchro.sh b/synchro.sh index 07dea5ba..5f69615a 100755 --- a/synchro.sh +++ b/synchro.sh @@ -19,8 +19,7 @@ rsync -e ssh -av $OPTS out/errors phobos:~/ rsync -e ssh -av $OPTS out/htdocs phobos:~/ rsync -e ssh -av $OPTS out/teams phobos:~/ rsync -e ssh -avL $OPTS files phobos:~/ -rsync -e ssh -av $OPTS misc/server.* misc/pki/cacert.crt misc/pki/crl.pem phobos:~/ -scp nginx.conf submission.php phobos:~/ +rsync -e ssh -av $OPTS nginx.conf submission.php misc/server.* misc/pki/cacert.crt misc/pki/crl.pem phobos:~/ rsync -e ssh -av phobos:~/submission/ submission/ ssh phobos "rm -fv ~/submission/*" From 8d7394b833e0442c638d15f4aa83bf5b49b584cb Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 21 Jan 2014 03:08:08 +0100 Subject: [PATCH 0210/2686] New script to generate nginx.conf part --- check.pl | 74 ++++++++++++++++++----- launch.sh | 5 ++ nginx.conf | 34 ++++++++--- nginx_gen_team.sh | 3 + onyx/tpl/bootstrap/admin/export_teams.tpl | 2 +- submission.php | 17 +++++- synchro.sh | 2 +- 7 files changed, 108 insertions(+), 29 deletions(-) create mode 100644 nginx_gen_team.sh diff --git a/check.pl b/check.pl index 5b2863f9..92fd49ab 100755 --- a/check.pl +++ b/check.pl @@ -5,8 +5,40 @@ use strict; use warnings; use DBI; use File::Basename; -use Digest::MD5 qw(md5_hex); -use Digest::SHA qw(sha1_hex sha224_hex sha256_hex sha384_hex sha512_hex); +use Digest; +use Digest::MD5 qw(md5); +use Digest::SHA qw(sha1 sha224 sha256 sha384 sha512); +use Mcrypt qw(:ALGORITHMS :MODES :FUNCS); + +sub encrypt +{ + my ($algo, $key, $data, $mode) = @_; + + my $td = mcrypt_load( $algo, "", $mode, '' ); + mcrypt_init($td, $key, ""); + + my $encrypted = mcrypt_encrypt($td, $data); + + mcrypt_end($td); + + return $encrypted; +} + +sub my_crypt +{ + my ($key, $content) = @_; + + my $kfirst = pack('H*', substr($key, 0, 64)); + $content = encrypt(SERPENT, $kfirst, $content, ECB); + + if (length $key > 64) + { + my $ksec = pack('H*', substr($key, 64, 64)); + $content = encrypt(SERPENT, $ksec, $content, ECB); + } + + return unpack('H*', $content); +} #Return number of good solutions my $exit = 0; @@ -70,9 +102,18 @@ for my $f (readdir $dh) my $exercice = $3; open my $fh, "<", "$submission_dir/$f"; - my $solution = <$fh>; + my %solution; + $solution{md5} = <$fh>; chomp( $solution{md5} ); + $solution{sha1} = <$fh>; chomp( $solution{sha1} ); + $solution{sha256} = <$fh>; chomp( $solution{sha256} ); + $solution{sha384} = <$fh>; chomp( $solution{sha384} ); + $solution{sha512} = <$fh>; chomp( $solution{sha512} ); + $solution{whirlpool} = <$fh>; chomp( $solution{whirlpool} ); close $fh; + use Data::Dumper; + print STDERR Dumper(\%solution); + $dbh = DBI->connect("DBI:mysql:database=$db_settings{db};host=$db_settings{host};port=3306", $db_settings{user}, $db_settings{pass}, {'RaiseError' => 1, 'PrintError' => 1}) @@ -89,39 +130,40 @@ for my $f (readdir $dh) my $type = @$row[0]; my $sol = @$row[1]; - - my $tmp_solution = $solution; + my $filh; my $tmp_solution; if ($type eq "md5") { - $tmp_solution = md5_hex($solution); + $filh = md5($f); } elsif ($type eq "sha1") { - $tmp_solution = sha1_hex($solution); + $filh = sha1($f); } elsif ($type eq "sha224") { - $tmp_solution = sha224_hex($solution); + $filh = sha224($f); } elsif ($type eq "sha256") { - $tmp_solution = sha256_hex($solution); + $filh = sha256($f); } elsif ($type eq "sha384") { - $tmp_solution = sha384_hex($solution); + $filh = sha384($f); } elsif ($type eq "sha512") { - $tmp_solution = sha512_hex($solution); + $filh = sha512($f); } elsif ($type eq "whirlpool") { my $hash = Digest->new( 'Whirlpool' ); - $hash->add( $solution ); - $tmp_solution = $hash->hexdigest; + $hash->add( $f ); + $filh = $hash->digest; } - elsif ($type ne "raw") { + else { warn "$type not implemented"; } - say STDERR "check: $sol vs $tmp_solution"; + $tmp_solution = my_crypt($sol, $filh) if ($filh); - if ($sol ne $tmp_solution) + say STDERR "check $type: $solution{$type} vs $tmp_solution"; + + if ($solution{$type} ne $tmp_solution) { $good = 0; last; diff --git a/launch.sh b/launch.sh index eb2ee30a..eee62513 100755 --- a/launch.sh +++ b/launch.sh @@ -12,10 +12,12 @@ fi touch ./logs/checks.log tail -f ./logs/checks.log & +KP1=$! TMPF=`mktemp` tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/test.sock -o ./out & +KP2=$! while ! [ -f /tmp/stop ]; do @@ -23,6 +25,7 @@ do if [ `ls submission | wc -l` -gt 1 ] then + ./clear_cache.sh top ./check.pl 2>> ./logs/checks.log >> "$TMPF" else @@ -30,4 +33,6 @@ do fi done +kill -9 $KP1 $KP2 + rm -rf "$TMPF" diff --git a/nginx.conf b/nginx.conf index 6959d22b..da0b2a10 100644 --- a/nginx.conf +++ b/nginx.conf @@ -45,15 +45,29 @@ server { set $team 0; - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=bombal_s/") { set $team 161; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_1/") { set $team 166; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_2/") { set $team 167; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_3/") { set $team 168; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_4/") { set $team 169; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_5/") { set $team 170; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_6/") { set $team 171; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_7/") { set $team 172; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Groupe_8/") { set $team 173; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Amin_Martin/") { set $team 343; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Bernard_Angoustures/") { set $team 344; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Cacace_Diallo/") { set $team 345; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Delaporte_Notebaert/") { set $team 346; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Dibe/") { set $team 347; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Dubief_Roccia/") { set $team 348; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Ezzahoui/") { set $team 349; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Fall/") { set $team 350; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Guerin_Chapiron/") { set $team 351; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Hugot_Hincelin/") { set $team 352; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Jawor_Giraud/") { set $team 353; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Konan/") { set $team 354; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Le_Mignan_Yadaba/") { set $team 355; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Michel-villaz_Gzenayi/") { set $team 356; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Muller_Perrin/") { set $team 357; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Pourcelot/") { set $team 358; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Quint_Kaczmarek/") { set $team 359; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Ruff_Czarny/") { set $team 360; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Sinet_Girault/") { set $team 361; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Therrode/") { set $team 362; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Sabono_Calmeji/") { set $team 363; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Renaud_Vandemeulebroucke/") { set $team 364; } + if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=De_Priest_Tjonck/") { set $team 365; } if ($team) { root /var/www/fic2014-server/teams/$team$1; @@ -105,7 +119,7 @@ server { { root /var/www/fic2014-server/; - limit_rate 1k; + limit_rate 4k; include /etc/nginx/fastcgi.conf; fastcgi_pass unix:/var/run/php-fpm.sock; diff --git a/nginx_gen_team.sh b/nginx_gen_team.sh new file mode 100644 index 00000000..ebf28572 --- /dev/null +++ b/nginx_gen_team.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +curl http://localhost/admin/teams/export 2> /dev/null | grep "(.*)<.*$@ if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=\2/") { set $team \1; }@' diff --git a/onyx/tpl/bootstrap/admin/export_teams.tpl b/onyx/tpl/bootstrap/admin/export_teams.tpl index f9b47af1..7dc7767d 100644 --- a/onyx/tpl/bootstrap/admin/export_teams.tpl +++ b/onyx/tpl/bootstrap/admin/export_teams.tpl @@ -2,7 +2,7 @@ {foreach from=$teams item=t} - {$t->team_name} + {$t->team_name} {if $t->slogan}{$t->slogan}{/if} {if $t->get_members()} {foreach from=$t->get_members() item=m} diff --git a/submission.php b/submission.php index 02f65569..e9cf71fe 100644 --- a/submission.php +++ b/submission.php @@ -20,7 +20,22 @@ else if (!empty($_POST["solution"]) && !empty($_GET["team"]) && !empty($_GET["th $algos = array("md5", "sha1", "sha256", "sha384", "sha512", "whirlpool"); $content = ""; foreach($algos as $algo) - $content .= mcrypt_encrypt(MCRYPT_SERPENT_256, hash($algo, $_POST["solution"]), hash($algo, $filename), MCRYPT_MODE_ECB)."\n"; + { + $cnt = hash($algo, $filename, true); + // Encrypt twice on long key + $key = hash($algo, $_POST["solution"]); + + $kfirst = pack('H*', substr($key, 0, 64)); + $cnt = mcrypt_encrypt(MCRYPT_SERPENT, $kfirst, $cnt, MCRYPT_MODE_ECB); + + if (strlen($key) > 64) + { + $ksec = pack('H*', substr($key, 64, 64)); + $cnt = mcrypt_encrypt(MCRYPT_SERPENT, $ksec, $cnt, MCRYPT_MODE_ECB); + } + + $content .= bin2hex($cnt)."\n"; + } file_put_contents($file, $content, LOCK_EX); diff --git a/synchro.sh b/synchro.sh index 5f69615a..9406d1cd 100755 --- a/synchro.sh +++ b/synchro.sh @@ -19,7 +19,7 @@ rsync -e ssh -av $OPTS out/errors phobos:~/ rsync -e ssh -av $OPTS out/htdocs phobos:~/ rsync -e ssh -av $OPTS out/teams phobos:~/ rsync -e ssh -avL $OPTS files phobos:~/ -rsync -e ssh -av $OPTS nginx.conf submission.php misc/server.* misc/pki/cacert.crt misc/pki/crl.pem phobos:~/ +rsync -e ssh -av $OPTS nginx.conf submission.php misc/server.crt misc/server.key misc/pki/cacert.crt misc/pki/crl.pem phobos:~/ rsync -e ssh -av phobos:~/submission/ submission/ ssh phobos "rm -fv ~/submission/*" From 15a0c26b912ef5767e245b522b858333f7c1474c Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 21 Jan 2014 03:42:01 +0100 Subject: [PATCH 0211/2686] Add backup script --- backup.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100755 backup.sh diff --git a/backup.sh b/backup.sh new file mode 100755 index 00000000..120f5424 --- /dev/null +++ b/backup.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +cd `dirname "$0"` +TO_BCKP="/mnt/backup" + +chown synchro "$TO_BCKP" + +if [ "$UID" = "0" ] +then + SCRIPT=`pwd`/`basename "$0"` + su -c "sh $SCRIPT $@" synchro + exit $? +fi + +if mount | grep "$TO_BCKP" > /dev/null +then + + mysqldump -u backup --password="Riuy6of sae^W0Sh" fic2014 > "$TO_BCKP"/db-`date +%Y%m%d-%H%M`.sql + + rsync -avL true_files/ "$TO_BCKP" + rsync -avL logs/ "$TO_BCKP" + rsync -avL misc/ "$TO_BCKP" + rsync -avL .git "$TO_BCKP" + +else + echo No volume mount on $TO_BCKP +fi From d26e7826bd0f538d419e5ac13e52dfa982d95797 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 21 Jan 2014 03:56:17 +0100 Subject: [PATCH 0212/2686] Better backups --- backup.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/backup.sh b/backup.sh index 120f5424..84852fca 100755 --- a/backup.sh +++ b/backup.sh @@ -15,12 +15,13 @@ fi if mount | grep "$TO_BCKP" > /dev/null then - mysqldump -u backup --password="Riuy6of sae^W0Sh" fic2014 > "$TO_BCKP"/db-`date +%Y%m%d-%H%M`.sql + mysqldump -u backup --password="Riuy6of sae^W0Sh" fic2014 > "$TO_BCKP"/db/`date +%Y%m%d-%H%M`.sql - rsync -avL true_files/ "$TO_BCKP" - rsync -avL logs/ "$TO_BCKP" - rsync -avL misc/ "$TO_BCKP" + rsync -avL misc "$TO_BCKP" rsync -avL .git "$TO_BCKP" + rsync -avL logs "$TO_BCKP" + rsync -avL /var/log "$TO_BCKP" + rsync -avL true_files "$TO_BCKP" else echo No volume mount on $TO_BCKP From 0c33d83131dfba13f167f20e6ef2d385f082bf9c Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 21 Jan 2014 17:45:46 +0100 Subject: [PATCH 0213/2686] Fixed carousel --- onyx/tpl/bootstrap/public/home.tpl | 79 +++++++++++++--------------- onyx/tpl/bootstrap/public/layout.tpl | 6 ++- onyx/tpl/bootstrap/summary.tpl | 2 +- 3 files changed, 43 insertions(+), 44 deletions(-) diff --git a/onyx/tpl/bootstrap/public/home.tpl b/onyx/tpl/bootstrap/public/home.tpl index 72f6efbe..395aebdd 100644 --- a/onyx/tpl/bootstrap/public/home.tpl +++ b/onyx/tpl/bootstrap/public/home.tpl @@ -5,56 +5,51 @@ {/block} {block name=main} - {if isset($teams)} +{if isset($teams)} {/if} - - - {/block} diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index 8538e0ca..e8aeb0e0 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -22,7 +22,7 @@

    Top 10

    {foreach from=$top item=t key=k} -
    {$k+1}. {link href="{$t->id}-{$t->get_name_url()}" href_prefix="/" label={$t->get_name()|replace:"_":" et "}} +
    {$k+1}. {link href="{$t->id}-{$t->get_name_url()}" href_prefix="/" label={$t->get_name()|replace:"_":" "}} {$t->get_pts()} @@ -46,5 +46,9 @@ var end_challenge = new Date({$END * 1000}); {/if} update_end(); + $(document).ready(function() { + $('#carousel-team').carousel({ + interval: 2000 }); + }); {/block} diff --git a/onyx/tpl/bootstrap/summary.tpl b/onyx/tpl/bootstrap/summary.tpl index 1eed15df..c7435bcf 100644 --- a/onyx/tpl/bootstrap/summary.tpl +++ b/onyx/tpl/bootstrap/summary.tpl @@ -1,7 +1,7 @@ - + {for $i=1 to $nbExoMax} {/for} From 939e6d994d323f6308bbcfb4e2346c0f5ad812f8 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Tue, 21 Jan 2014 17:49:17 +0100 Subject: [PATCH 0214/2686] Increase the time of each carousel item to 10000 --- onyx/tpl/bootstrap/public/layout.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index e8aeb0e0..98f98070 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -48,7 +48,7 @@ update_end(); $(document).ready(function() { $('#carousel-team').carousel({ - interval: 2000 }); + interval: 10000 }); }); {/block} From ad5185dbc1e5cdb1b62893199954524fe6f80246 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 27 Aug 2014 12:25:23 +0200 Subject: [PATCH 0215/2686] Fix default config --- nginx-server-common.conf | 2 +- onyx/config/sample.root.xml | 2 +- onyx/db/sample.profile.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nginx-server-common.conf b/nginx-server-common.conf index d93c6113..13e887a0 100644 --- a/nginx-server-common.conf +++ b/nginx-server-common.conf @@ -41,7 +41,7 @@ location ~ .*.php$ { if (!-e $document_root$document_uri) { return 404; } - include /etc/nginx/fastcgi.conf; + include /etc/nginx/fastcgi_params; fastcgi_pass unix:/var/run/php-fpm.sock; fastcgi_index index.php; break; diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml index 4d05ed20..86666818 100644 --- a/onyx/config/sample.root.xml +++ b/onyx/config/sample.root.xml @@ -38,7 +38,7 @@ - + diff --git a/onyx/db/sample.profile.php b/onyx/db/sample.profile.php index 1ad73643..f3c4e489 100644 --- a/onyx/db/sample.profile.php +++ b/onyx/db/sample.profile.php @@ -2,7 +2,7 @@ if(!defined('ONYX')) exit; -$___profile['db'] = 'kohler_palettes'; +$___profile['db'] = 'fic2014'; $___profile['host'] = 'localhost'; $___profile['user'] = 'root'; $___profile['pass'] = ''; From 30dc4612706c5503a127e292c9702d7eac96fd99 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 27 Aug 2014 12:26:13 +0200 Subject: [PATCH 0216/2686] Salt for CDN is not the same as PUBLIC --- htdocs/index.php | 2 +- onyx/tpl/bootstrap/layout.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/index.php b/htdocs/index.php index ac03ea5d..c0ed32bb 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -14,7 +14,7 @@ define("SALT_ADMIN", $VAR["prefix_admin"]); //Chargement de tout le nécessaire pour le site require_once("common.php"); -$template->assign("SALT_CDN",SALT_PUBLIC); +$template->assign("SALT_CDN",""); $template->assign("SALT_PUBLIC",SALT_PUBLIC); $template->assign("SALT_USER",SALT_USER); $template->assign("SALT_ADMIN",SALT_ADMIN); diff --git a/onyx/tpl/bootstrap/layout.tpl b/onyx/tpl/bootstrap/layout.tpl index 62f5cb44..ab292ff5 100644 --- a/onyx/tpl/bootstrap/layout.tpl +++ b/onyx/tpl/bootstrap/layout.tpl @@ -41,7 +41,7 @@ --> - + {block name=end}{/block} From 4ca3e568568a1a5f99266541b080d51417d48678 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 27 Aug 2014 12:26:49 +0200 Subject: [PATCH 0217/2686] Add a Dockerfile for development purpose --- Dockerfile | 45 +++++++++++++++++++++++++++++ php-fpm.conf | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 Dockerfile create mode 100644 php-fpm.conf diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..1b6e7725 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +# DOCKER-VERSION 1.1.0 + +# /!\ WARNING: the container generated through this Dockerfile is made only for development purpose; it is NOT SAFE or production ready. + +FROM debian:wheezy +MAINTAINER Pierre-Olivier Mercier + +# Install packages #################################################### + +RUN apt-get -y update +RUN apt-get install -y nginx-light php5-fpm mysql-server php5-mysql pwgen openssl + +# Copying files ####################################################### + +ADD . /var/www/fic2014-server/ + +# Configure softwares ################################################# + +RUN ln -sf /var/www/fic2014-server/nginx-server.conf /etc/nginx/sites-enabled/default +RUN ln -sf /var/www/fic2014-server/php-fpm.conf /etc/php5/fpm/pool.d/www.conf + +# Generate test certificates ########################################## + +RUN cd /var/www/fic2014-server/misc; bash ./CA.sh -newca + +# Import DB ########################################################### + +RUN service mysql start && echo "CREATE DATABASE fic2014;" | mysql -u root && cat /var/www/fic2014-server/db/fic2014.sql | mysql -u root fic2014 + +# Uncomment the following line to fill with random values +#RUN cat /var/www/fic2014-server/db/feed.sql | mysql -u root fic2014 + +# Configure site ###################################################### + +RUN ln -sf /var/www/fic2014-server/onyx/config/sample.root.xml /var/www/fic2014-server/onyx/config/root.xml +RUN sed -i "s/1386827772/`date -d 'now + 4 hours' +%s`/" /var/www/fic2014-server/onyx/config/root.xml +RUN sed -i "s/challenge-public//" /var/www/fic2014-server/onyx/config/root.xml + +RUN chmod 777 /var/www/fic2014-server/onyx/cache/ /var/www/fic2014-server/onyx/cache/templates/cache/ /var/www/fic2014-server/onyx/cache/templates/compile/ + +# ENVIRONNEMENT ####################################################### + +RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +EXPOSE 80/tcp 443/tcp +CMD ["sh", "-c", "cd /var/www/fic2014-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; service nginx start && service php5-fpm start && service mysql start && /bin/bash"] diff --git a/php-fpm.conf b/php-fpm.conf new file mode 100644 index 00000000..e972ebe8 --- /dev/null +++ b/php-fpm.conf @@ -0,0 +1,81 @@ +; Start a new pool named 'www'. +; the variable $pool can we used in any directive and will be replaced by the +; pool name ('www' here) +[www] + +; Unix user/group of processes +; Note: The user is mandatory. If the group is not set, the default user's group +; will be used. +user = www-data +group = www-data + +; The address on which to accept FastCGI requests. +; Valid syntaxes are: +; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on +; a specific port; +; 'port' - to listen on a TCP socket to all addresses on a +; specific port; +; '/path/to/unix/socket' - to listen on a unix socket. +; Note: This value is mandatory. +listen = /var/run/php-fpm.sock + +; Set permissions for unix socket, if one is used. In Linux, read/write +; permissions must be set in order to allow connections from a web server. Many +; BSD-derived systems allow connections regardless of permissions. +; Default Values: user and group are set as the running user +; mode is set to 0666 +listen.owner = www-data +listen.group = www-data +listen.mode = 0640 + +; Choose how the process manager will control the number of child processes. +; Possible Values: +; static - a fixed number (pm.max_children) of child processes; +; dynamic - the number of child processes are set dynamically based on the +; following directives. With this process management, there will be +; always at least 1 children. +; pm.max_children - the maximum number of children that can +; be alive at the same time. +; pm.start_servers - the number of children created on startup. +; pm.min_spare_servers - the minimum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is less than this +; number then some children will be created. +; pm.max_spare_servers - the maximum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is greater than this +; number then some children will be killed. +; ondemand - no children are created at startup. Children will be forked when +; new requests will connect. The following parameter are used: +; pm.max_children - the maximum number of children that +; can be alive at the same time. +; pm.process_idle_timeout - The number of seconds after which +; an idle process will be killed. +; Note: This value is mandatory. +pm = dynamic + +; The number of child processes to be created when pm is set to 'static' and the +; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. +; This value sets the limit on the number of simultaneous requests that will be +; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. +; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP +; CGI. The below defaults are based on a server without much resources. Don't +; forget to tweak pm.* to fit your needs. +; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' +; Note: This value is mandatory. +pm.max_children = 200 + +; The number of child processes created on startup. +; Note: Used only when pm is set to 'dynamic' +; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 +pm.start_servers = 10 + +; The desired minimum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.min_spare_servers = 5 + +; The desired maximum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.max_spare_servers = 10 From 05c51d8f68ce93285aeafa338caf9777afe1cec8 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 27 Aug 2014 12:42:06 +0200 Subject: [PATCH 0218/2686] Add TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 00000000..f2d42400 --- /dev/null +++ b/TODO @@ -0,0 +1,2 @@ +- Départager les ex-æquo dans le classement +- Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe From 99d0152c3234c384f1d486efdd06d3b82b93c34c Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 9 Sep 2014 10:05:08 +0200 Subject: [PATCH 0219/2686] Prepare merge with server code --- Makefile => docs/guide/Makefile | 0 epita.pdf => docs/guide/epita.pdf | Bin guide.pdf => docs/guide/guide.pdf | Bin guide.tex => docs/guide/guide.tex | 0 windows_key.pdf => docs/guide/windows_key.pdf | Bin 5 files changed, 0 insertions(+), 0 deletions(-) rename Makefile => docs/guide/Makefile (100%) rename epita.pdf => docs/guide/epita.pdf (100%) rename guide.pdf => docs/guide/guide.pdf (100%) rename guide.tex => docs/guide/guide.tex (100%) rename windows_key.pdf => docs/guide/windows_key.pdf (100%) diff --git a/Makefile b/docs/guide/Makefile similarity index 100% rename from Makefile rename to docs/guide/Makefile diff --git a/epita.pdf b/docs/guide/epita.pdf similarity index 100% rename from epita.pdf rename to docs/guide/epita.pdf diff --git a/guide.pdf b/docs/guide/guide.pdf similarity index 100% rename from guide.pdf rename to docs/guide/guide.pdf diff --git a/guide.tex b/docs/guide/guide.tex similarity index 100% rename from guide.tex rename to docs/guide/guide.tex diff --git a/windows_key.pdf b/docs/guide/windows_key.pdf similarity index 100% rename from windows_key.pdf rename to docs/guide/windows_key.pdf From 7e4711ba5cf1c6ad6faeeb911a3a59a2f06fe29e Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 9 Sep 2014 10:38:46 +0200 Subject: [PATCH 0220/2686] Add README file --- README.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..606e81bf --- /dev/null +++ b/README.md @@ -0,0 +1,61 @@ +# FIC forensic challenge validation server + +This is a CTF server for distributing and validating exercices. It is design to +be robust, so it uses some uncommon technologies like client certificate for +authentication, cryptographic functions and DMZ network architecture. + +## Development and testing + +The easiest way to have a working server is to build a Docker container. + +### Docker + +First, build the container with the following command: +``` +docker build -t fic2014 . +``` + +Then, run it with: +``` +docker run -t -i -P fic2014 +``` +It will ask you for a passphrase, you must provide one with at least 4 +characters. This key is used to generate the server certificate. + +When you see: +``` +root@xxxxxxxxxxxx:/var/www/fic2014-server/misc# +``` +congratulations, the container is running! + +Use `docker ps` to view to which local ports was assigned the contained +webserver. + + +## Production environnement + +### Setup + +#### Frontend + +FIXME + +#### Backend + +FIXME + + +### History + +#### FIC2014 + +Two machines were used : one for backend (Phobos) and one for frontend +(Deimos). They ran a GNU/Linux Gentoo Hardened with custom 3.2 kernel without +module loading, unused and unecessary components and with all GrSecurity +features activated. + +Each machine was two network interfaces: one was used to permit to the backend +machine to connect to the frontend (over IPv6). The second interface on the +backend was used for administration purpose (with a laptop not connected to +Internet). The second interface on the frontend was used to provide network +connectivity to participants. From 832e9cd221ebe540750d5219be0377d78422be5a Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 5 Nov 2014 16:38:47 +0100 Subject: [PATCH 0221/2686] Add forgotten dependency --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 1b6e7725..c52741bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,7 +8,7 @@ MAINTAINER Pierre-Olivier Mercier # Install packages #################################################### RUN apt-get -y update -RUN apt-get install -y nginx-light php5-fpm mysql-server php5-mysql pwgen openssl +RUN apt-get install -y nginx-light php5-fpm mysql-server php5-mysql php5-mcrypt pwgen openssl # Copying files ####################################################### From b135e7f6f687d7176d945b3e1ed7d14f9bb91221 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 5 Nov 2014 16:38:54 +0100 Subject: [PATCH 0222/2686] Update TODO --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index f2d42400..7ebe286b 100644 --- a/TODO +++ b/TODO @@ -1,2 +1,5 @@ - Départager les ex-æquo dans le classement - Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe +- Retrouver toutes les dépendances +- Vérifier la liste des ciphers dans la conf de nginx +- Dans la conf de nginx, vérifier que le contenu statique soit mis en cache côté navigateur From 27f9e7e37240bac7d70073fa749389cd61e6b041 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 5 Nov 2014 16:39:05 +0100 Subject: [PATCH 0223/2686] Add setup instructions --- README.md | 48 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 606e81bf..fe82b807 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ -# FIC forensic challenge validation server +FIC forensic challenge validation server +======================================== This is a CTF server for distributing and validating exercices. It is design to be robust, so it uses some uncommon technologies like client certificate for authentication, cryptographic functions and DMZ network architecture. -## Development and testing +Development and testing +----------------------- The easiest way to have a working server is to build a Docker container. @@ -32,17 +34,53 @@ Use `docker ps` to view to which local ports was assigned the contained webserver. -## Production environnement +Production environnement +------------------------ ### Setup +You should compile/install hardened kernel (with latest stable GrSec patch) on +each machine. + +Prefer GNU/Linux distributions where most packages are compiled with `-fPIC` +and `-fstack-protector`, like Ubuntu or +[Gentoo Hardened](http://www.gentoo.org/proj/en/hardened/). + #### Frontend -FIXME +Keep in mind that this is the machine exposed to participant. + +##### Requirements + +* `nginx` with those modules: `aio` (for fast delivery of huge + content), `fastcgi`, `rewrite`, `ssl`; +* `php-fpm` with `mcrypt` module (for submission encryption); + +##### Firewall rules + +Expose to participants only 80 and 443 ports. + +Expose on synchronization interface the 22 port, used for synchronization and +administration purpose from backend. + +DROP **has to be** the default rule for INPUT, FORWARD and OUTPUT chains; use +CONNTRACK states. + #### Backend -FIXME +##### Requirements + +* `mysql`; +* `nginx` with `fastcgi` module; +* `php-fpm` with `mysql` module; +* `openssl` and `pwgen` for client certificat generation; +* `Mcrypt` from CPAN (`cpan -i Mcrypt`) to decrypt submissions (see https://metacpan.org/pod/Mcrypt); + +##### Firewall rules + +This machine shouldn't have any network connection, except outgoing one to the +frontend for synchronization. ### History From 76269a821d82a13599af712962eb6c079dad8d64 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 5 Nov 2014 17:00:37 +0100 Subject: [PATCH 0224/2686] Don't forget to crypt disks --- README.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fe82b807..3511bdf4 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ This is a CTF server for distributing and validating exercices. It is design to be robust, so it uses some uncommon technologies like client certificate for authentication, cryptographic functions and DMZ network architecture. -Development and testing +Development And Testing ----------------------- The easiest way to have a working server is to build a Docker container. @@ -34,7 +34,7 @@ Use `docker ps` to view to which local ports was assigned the contained webserver. -Production environnement +Production Environnement ------------------------ ### Setup @@ -46,6 +46,11 @@ Prefer GNU/Linux distributions where most packages are compiled with `-fPIC` and `-fstack-protector`, like Ubuntu or [Gentoo Hardened](http://www.gentoo.org/proj/en/hardened/). +As machines aren't always in safe place (transportation, night before CTF, +...), disks should be encrypted. + +**Always set strong password when it is possible** eg. SSL certificats, ... + #### Frontend Keep in mind that this is the machine exposed to participant. @@ -75,6 +80,7 @@ CONNTRACK states. * `nginx` with `fastcgi` module; * `php-fpm` with `mysql` module; * `openssl` and `pwgen` for client certificat generation; +* `mcrypt`; * `Mcrypt` from CPAN (`cpan -i Mcrypt`) to decrypt submissions (see https://metacpan.org/pod/Mcrypt); ##### Firewall rules @@ -97,3 +103,9 @@ machine to connect to the frontend (over IPv6). The second interface on the backend was used for administration purpose (with a laptop not connected to Internet). The second interface on the frontend was used to provide network connectivity to participants. + + +The D Day +--------- + +TODO From ca7570d90850fa6c95002d8fb6499aee5d2fd023 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 5 Nov 2014 17:18:07 +0100 Subject: [PATCH 0225/2686] Fix template paths --- onyx/include/admin/exercice.php | 2 +- onyx/include/admin/list_users.php | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/onyx/include/admin/exercice.php b/onyx/include/admin/exercice.php index e4507cc8..b007d591 100644 --- a/onyx/include/admin/exercice.php +++ b/onyx/include/admin/exercice.php @@ -65,4 +65,4 @@ catch(ExerciceNotFoundException $e) return "404"; } -return SALT_ADMIN."/exercice"; +return "admin/exercice"; diff --git a/onyx/include/admin/list_users.php b/onyx/include/admin/list_users.php index 3ac2871f..8f57ccea 100644 --- a/onyx/include/admin/list_users.php +++ b/onyx/include/admin/list_users.php @@ -11,7 +11,7 @@ if (!empty($_GET["delete"])) else { erreur("Merci d'ajouter la variable misc_dir dans root.xml"); - return SALT_ADMIN."/users"; + return "admin/users"; } $id_team = intval($_GET["delete"]); @@ -28,7 +28,7 @@ else if (isset($_GET["drop"])) else { erreur("Merci d'ajouter la variable misc_dir dans root.xml"); - return SALT_ADMIN."/users"; + return "admin/users"; } foreach(Team::get_teams() as $team) @@ -44,4 +44,4 @@ else if (isset($_GET["drop"])) $template->assign("teams", Team::get_teams()); -return SALT_ADMIN."/users"; +return "admin/users"; From dbc97fda8a522cee370a197decb948b3c4ed9c66 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 5 Nov 2014 17:36:28 +0100 Subject: [PATCH 0226/2686] Update TODO --- TODO | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO b/TODO index 7ebe286b..2bcccf76 100644 --- a/TODO +++ b/TODO @@ -3,3 +3,4 @@ - Retrouver toutes les dépendances - Vérifier la liste des ciphers dans la conf de nginx - Dans la conf de nginx, vérifier que le contenu statique soit mis en cache côté navigateur +- Mettre à jour Smarty (et passer en « secure mode » ?) From 4a67552a298845bfa803c6603ea11e0941b1d6ae Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 5 Nov 2014 17:37:44 +0100 Subject: [PATCH 0227/2686] Can send solutions on the backend (using the same file as frontend) --- onyx/include/team/exercice.php | 22 +++++++++++++--------- submission.php | 20 ++++++++++++-------- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/onyx/include/team/exercice.php b/onyx/include/team/exercice.php index 7e2e5eb5..fa6af0d0 100644 --- a/onyx/include/team/exercice.php +++ b/onyx/include/team/exercice.php @@ -41,18 +41,22 @@ if (isset($VAR['submission_dir'])) { if (is_writable("$submission_dir/")) { - $file = $submission_dir.'/'.$p[1].'-'.$p[2].'-'.$p[3]; + function show_submission_result($path) + { + header("Location: /".SALT_USER."/".$path); + exit; + } - file_put_contents($file, $_POST['solution'], LOCK_EX); + $_GET["team"] = $p[1]; + $_GET["theme"] = $p[2]; + $_GET["exercice"] = $p[3]; - header("Location: /".implode("/", $p)); - exit; - } - else - { - header("Location: /".implode("/", $p)."/werr"); - exit; + require("../submission.php"); } + + // Fallback error + header("Location: /".implode("/", $p)."/werr"); + exit; } } } diff --git a/submission.php b/submission.php index e9cf71fe..f99d2386 100644 --- a/submission.php +++ b/submission.php @@ -1,11 +1,15 @@ Date: Wed, 5 Nov 2014 17:46:18 +0100 Subject: [PATCH 0228/2686] Change fic2014 to fic --- Dockerfile | 22 +++++++++++----------- README.md | 6 +++--- backup.sh | 2 +- misc/CA.sh | 2 +- misc/openssl.cnf | 12 ++++++------ nginx-server-common.conf | 4 ++-- nginx-server.conf | 8 ++++---- nginx.conf | 24 ++++++++++++------------ onyx/config/sample.root.xml | 8 ++++---- onyx/db/sample.profile.php | 2 +- onyx/tpl/bootstrap/layout.tpl | 4 ++-- 11 files changed, 47 insertions(+), 47 deletions(-) diff --git a/Dockerfile b/Dockerfile index c52741bf..75aba18f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,34 +12,34 @@ RUN apt-get install -y nginx-light php5-fpm mysql-server php5-mysql php5-mcrypt # Copying files ####################################################### -ADD . /var/www/fic2014-server/ +ADD . /var/www/fic-server/ # Configure softwares ################################################# -RUN ln -sf /var/www/fic2014-server/nginx-server.conf /etc/nginx/sites-enabled/default -RUN ln -sf /var/www/fic2014-server/php-fpm.conf /etc/php5/fpm/pool.d/www.conf +RUN ln -sf /var/www/fic-server/nginx-server.conf /etc/nginx/sites-enabled/default +RUN ln -sf /var/www/fic-server/php-fpm.conf /etc/php5/fpm/pool.d/www.conf # Generate test certificates ########################################## -RUN cd /var/www/fic2014-server/misc; bash ./CA.sh -newca +RUN cd /var/www/fic-server/misc; bash ./CA.sh -newca # Import DB ########################################################### -RUN service mysql start && echo "CREATE DATABASE fic2014;" | mysql -u root && cat /var/www/fic2014-server/db/fic2014.sql | mysql -u root fic2014 +RUN service mysql start && echo "CREATE DATABASE fic;" | mysql -u root && cat /var/www/fic-server/db/fic2014.sql | mysql -u root fic # Uncomment the following line to fill with random values -#RUN cat /var/www/fic2014-server/db/feed.sql | mysql -u root fic2014 +#RUN cat /var/www/fic-server/db/feed.sql | mysql -u root fic # Configure site ###################################################### -RUN ln -sf /var/www/fic2014-server/onyx/config/sample.root.xml /var/www/fic2014-server/onyx/config/root.xml -RUN sed -i "s/1386827772/`date -d 'now + 4 hours' +%s`/" /var/www/fic2014-server/onyx/config/root.xml -RUN sed -i "s/challenge-public//" /var/www/fic2014-server/onyx/config/root.xml +RUN ln -sf /var/www/fic-server/onyx/config/sample.root.xml /var/www/fic-server/onyx/config/root.xml +RUN sed -i "s/1386827772/`date -d 'now + 4 hours' +%s`/" /var/www/fic-server/onyx/config/root.xml +RUN sed -i "s/challenge-public//" /var/www/fic-server/onyx/config/root.xml -RUN chmod 777 /var/www/fic2014-server/onyx/cache/ /var/www/fic2014-server/onyx/cache/templates/cache/ /var/www/fic2014-server/onyx/cache/templates/compile/ +RUN chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/templates/cache/ /var/www/fic-server/onyx/cache/templates/compile/ # ENVIRONNEMENT ####################################################### RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* EXPOSE 80/tcp 443/tcp -CMD ["sh", "-c", "cd /var/www/fic2014-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; service nginx start && service php5-fpm start && service mysql start && /bin/bash"] +CMD ["sh", "-c", "cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; service nginx start && service php5-fpm start && service mysql start && /bin/bash"] diff --git a/README.md b/README.md index 3511bdf4..ea77dd1c 100644 --- a/README.md +++ b/README.md @@ -14,19 +14,19 @@ The easiest way to have a working server is to build a Docker container. First, build the container with the following command: ``` -docker build -t fic2014 . +docker build -t fic . ``` Then, run it with: ``` -docker run -t -i -P fic2014 +docker run -t -i -P fic ``` It will ask you for a passphrase, you must provide one with at least 4 characters. This key is used to generate the server certificate. When you see: ``` -root@xxxxxxxxxxxx:/var/www/fic2014-server/misc# +root@xxxxxxxxxxxx:/var/www/fic-server/misc# ``` congratulations, the container is running! diff --git a/backup.sh b/backup.sh index 84852fca..2a0f9d0e 100755 --- a/backup.sh +++ b/backup.sh @@ -15,7 +15,7 @@ fi if mount | grep "$TO_BCKP" > /dev/null then - mysqldump -u backup --password="Riuy6of sae^W0Sh" fic2014 > "$TO_BCKP"/db/`date +%Y%m%d-%H%M`.sql + mysqldump -u backup --password="Riuy6of sae^W0Sh" fic > "$TO_BCKP"/db/`date +%Y%m%d-%H%M`.sql rsync -avL misc "$TO_BCKP" rsync -avL .git "$TO_BCKP" diff --git a/misc/CA.sh b/misc/CA.sh index db4ba6c4..bfc99b5e 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -62,7 +62,7 @@ case $1 in ESCAPED=$(echo "${TOP_DIR}" | sed 's/[\/\.]/\\&/g') echo -e "${GREEN}Making CA key and csr${COLOR_RST}" - sed -i 's/=.*#COMMONNAME/= FIC2014 CA #COMMONNAME/' $OPENSSL_CONF + sed -i 's/=.*#COMMONNAME/= FIC CA #COMMONNAME/' $OPENSSL_CONF sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF type pwgen > /dev/null diff --git a/misc/openssl.cnf b/misc/openssl.cnf index 2cb594f2..1fc532fd 100644 --- a/misc/openssl.cnf +++ b/misc/openssl.cnf @@ -15,7 +15,7 @@ oid_section = new_oids # To use this configuration file with the "-extfile" option of the # "openssl x509" utility, name here the section containing the # X.509v3 extensions to use: -# extensions = +# extensions = # (Alternatively, use a configuration file that has only # X.509v3 extensions in its main [= default] section.) @@ -39,7 +39,7 @@ default_ca = CA_default # The default ca section #################################################################### [ CA_default ] -dir = /var/www/fic2014-server/misc//pki #DIR # Where everything is kept +dir = /var/www/fic-server/misc//pki #DIR # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. @@ -111,7 +111,7 @@ x509_extensions = v3_ca # The extentions to add to the self signed cert # input_password = secret # output_password = secret -# This sets a mask for permitted string types. There are several options. +# This sets a mask for permitted string types. There are several options. # default: PrintableString, T61String, BMPString. # pkix : PrintableString, BMPString (PKIX recommendation before 2004) # utf8only: only UTF8Strings (PKIX recommendation after 2004). @@ -162,7 +162,7 @@ challengePassword_max = 20 unstructuredName = An optional company name [CORE_CA] -nsComment = "FIC2014 CA" +nsComment = "FIC CA" basicConstraints = critical,CA:TRUE,pathlen:1 subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always @@ -173,7 +173,7 @@ subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer [SERVER_SSL] -nsComment = "FIC2014 Server" +nsComment = "FIC Server" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always issuerAltName = issuer:copy @@ -185,7 +185,7 @@ subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer [CLIENT_SSL] -nsComment = "FIC2014 Client" +nsComment = "FIC Client" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always issuerAltName = issuer:copy diff --git a/nginx-server-common.conf b/nginx-server-common.conf index 13e887a0..5df0e129 100644 --- a/nginx-server-common.conf +++ b/nginx-server-common.conf @@ -1,7 +1,7 @@ access_log /var/log/nginx/fic.access_log; error_log /var/log/nginx/fic.error_log; - root /var/www/fic2014-server/htdocs; + root /var/www/fic-server/htdocs; index index.php; add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; @@ -19,7 +19,7 @@ location /files { - root /var/www/fic2014-server/; + root /var/www/fic-server/; } location ~* \favicon.ico$ { diff --git a/nginx-server.conf b/nginx-server.conf index 64c4eed6..3e8e0cc3 100644 --- a/nginx-server.conf +++ b/nginx-server.conf @@ -2,17 +2,17 @@ server { listen 443 ssl; listen [::]:443 ipv6only=on ssl; - ssl_certificate /var/www/fic2014-server/misc/server.crt; - ssl_certificate_key /var/www/fic2014-server/misc/server.key; + ssl_certificate /var/www/fic-server/misc/server.crt; + ssl_certificate_key /var/www/fic-server/misc/server.key; # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # ssl_prefer_server_ciphers on; # ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; - include /var/www/fic2014-server/nginx-server-common.conf; + include /var/www/fic-server/nginx-server-common.conf; } server { listen 80; - include /var/www/fic2014-server/nginx-server-common.conf; + include /var/www/fic-server/nginx-server-common.conf; } diff --git a/nginx.conf b/nginx.conf index da0b2a10..a9d69b23 100644 --- a/nginx.conf +++ b/nginx.conf @@ -13,21 +13,21 @@ server { listen 443 ssl; listen [::]:443 ipv6only=on ssl; - root /var/www/fic2014-server/htdocs/; + root /var/www/fic-server/htdocs/; server_tokens off; access_log /var/log/nginx/fic.access_log; error_log /var/log/nginx/fic.error_log; - ssl_certificate /var/www/fic2014-server/server.crt; - ssl_certificate_key /var/www/fic2014-server/server.key; + ssl_certificate /var/www/fic-server/server.crt; + ssl_certificate_key /var/www/fic-server/server.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; - ssl_client_certificate /var/www/fic2014-server/cacert.crt; + ssl_client_certificate /var/www/fic-server/cacert.crt; ssl_verify_client optional; - ssl_crl /var/www/fic2014-server/crl.pem; + ssl_crl /var/www/fic-server/crl.pem; add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; @@ -70,17 +70,17 @@ server { if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=De_Priest_Tjonck/") { set $team 365; } if ($team) { - root /var/www/fic2014-server/teams/$team$1; + root /var/www/fic-server/teams/$team$1; rewrite ^/([0-9]+-?[a-zA-Z0-9_-]*)/([a-zA-Z0-9_]+)/submission$ /submission.php?team=$team&theme=$1&exercice=$2 last; } if ($team = 0) { - root /var/www/fic2014-server/htdocs/; + root /var/www/fic-server/htdocs/; } } location /errors { - root /var/www/fic2014-server/; + root /var/www/fic-server/; } location /connected @@ -90,7 +90,7 @@ server { location /files { - root /var/www/fic2014-server/; + root /var/www/fic-server/; aio on; directio 512; @@ -98,14 +98,14 @@ server { } location ~* \favicon.ico$ { - root /var/www/fic2014-server/htdocs/; + root /var/www/fic-server/htdocs/; access_log off; expires 1d; add_header Cache-Control public; } location ~ ^/(assets|img|js|css|fonts)/ { - root /var/www/fic2014-server/htdocs/; + root /var/www/fic-server/htdocs/; access_log off; expires 7d; add_header Cache-Control public; @@ -117,7 +117,7 @@ server { location /submission.php { - root /var/www/fic2014-server/; + root /var/www/fic-server/; limit_rate 4k; diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml index 86666818..748b5433 100644 --- a/onyx/config/sample.root.xml +++ b/onyx/config/sample.root.xml @@ -1,10 +1,10 @@ - + 1386827772 - /var/www/fic2014-server/files/ - /var/www/fic2014-server/misc/ - /var/www/fic2014-server/submission/ + /var/www/fic-server/files/ + /var/www/fic-server/misc/ + /var/www/fic-server/submission/ challenge-public challenge challenge-admin diff --git a/onyx/db/sample.profile.php b/onyx/db/sample.profile.php index f3c4e489..670c80b0 100644 --- a/onyx/db/sample.profile.php +++ b/onyx/db/sample.profile.php @@ -2,7 +2,7 @@ if(!defined('ONYX')) exit; -$___profile['db'] = 'fic2014'; +$___profile['db'] = 'fic'; $___profile['host'] = 'localhost'; $___profile['user'] = 'root'; $___profile['pass'] = ''; diff --git a/onyx/tpl/bootstrap/layout.tpl b/onyx/tpl/bootstrap/layout.tpl index ab292ff5..9f812352 100644 --- a/onyx/tpl/bootstrap/layout.tpl +++ b/onyx/tpl/bootstrap/layout.tpl @@ -2,7 +2,7 @@ - {block name=title}Challenge FIC2014{/block} + {block name=title}Challenge FIC2015{/block} @@ -35,7 +35,7 @@

    From 17a05b0d26634340f109457650bf53235e6ab16c Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 5 Nov 2014 18:02:55 +0100 Subject: [PATCH 0229/2686] Display an error on admin home page if misc/ is not writable --- TODO | 1 + onyx/include/admin/home.php | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/TODO b/TODO index 2bcccf76..f289df09 100644 --- a/TODO +++ b/TODO @@ -4,3 +4,4 @@ - Vérifier la liste des ciphers dans la conf de nginx - Dans la conf de nginx, vérifier que le contenu statique soit mis en cache côté navigateur - Mettre à jour Smarty (et passer en « secure mode » ?) +- Admin, exercice: pas normal qu'il y ait des réponses RAW dans les data de tests diff --git a/onyx/include/admin/home.php b/onyx/include/admin/home.php index 79bcbfcc..6268084f 100644 --- a/onyx/include/admin/home.php +++ b/onyx/include/admin/home.php @@ -3,7 +3,14 @@ if(!defined('ONYX')) exit; if (isset($VAR['misc_dir'])) +{ $misc_dir = $VAR['misc_dir']; + if (!is_writable($misc_dir)) + { + erreur("Dossier misc/ non accessible en écriture. ($misc_dir)"); + return "admin/home"; + } +} else { erreur("Merci d'ajouter la variable misc_dir dans root.xml"); From ec2604142f47b119b6e9ec8391b1e8a9c27c91ca Mon Sep 17 00:00:00 2001 From: nemunaire Date: Mon, 10 Nov 2014 17:21:29 +0100 Subject: [PATCH 0230/2686] Stronger SSL config --- TODO | 1 - nginx-server-common.conf | 2 ++ nginx.conf | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index f289df09..ba8dafcc 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ - Départager les ex-æquo dans le classement - Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe - Retrouver toutes les dépendances -- Vérifier la liste des ciphers dans la conf de nginx - Dans la conf de nginx, vérifier que le contenu statique soit mis en cache côté navigateur - Mettre à jour Smarty (et passer en « secure mode » ?) - Admin, exercice: pas normal qu'il y ait des réponses RAW dans les data de tests diff --git a/nginx-server-common.conf b/nginx-server-common.conf index 5df0e129..e33e72cf 100644 --- a/nginx-server-common.conf +++ b/nginx-server-common.conf @@ -5,6 +5,8 @@ index index.php; add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; location / { if (-f $request_filename) { diff --git a/nginx.conf b/nginx.conf index a9d69b23..170fd8f3 100644 --- a/nginx.conf +++ b/nginx.conf @@ -24,12 +24,15 @@ server { ssl_certificate_key /var/www/fic-server/server.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; - ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; +# ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; + ssl_ciphers AES256+EECDH:AES256+EDH; ssl_client_certificate /var/www/fic-server/cacert.crt; ssl_verify_client optional; ssl_crl /var/www/fic-server/crl.pem; add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; error_page 400 /errors/400/index.html; error_page 403 /errors/403/index.html; From 0c22173def65cdbcca8f0606c403432a9b7f1f93 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Mon, 10 Nov 2014 17:24:19 +0100 Subject: [PATCH 0231/2686] Remember to add ssl_dhparam --- TODO | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO b/TODO index ba8dafcc..1e48acdb 100644 --- a/TODO +++ b/TODO @@ -2,5 +2,6 @@ - Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe - Retrouver toutes les dépendances - Dans la conf de nginx, vérifier que le contenu statique soit mis en cache côté navigateur +- Ajouter dans la conf de nginx un ssl_dhparam + générer le fichier dans un script - Mettre à jour Smarty (et passer en « secure mode » ?) - Admin, exercice: pas normal qu'il y ait des réponses RAW dans les data de tests From 5196487b0c6d8802d6e6c9361b1b8d938494c348 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Mon, 10 Nov 2014 17:26:16 +0100 Subject: [PATCH 0232/2686] Update TODO --- TODO | 1 - 1 file changed, 1 deletion(-) diff --git a/TODO b/TODO index 1e48acdb..c19e8c63 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ - Départager les ex-æquo dans le classement - Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe - Retrouver toutes les dépendances -- Dans la conf de nginx, vérifier que le contenu statique soit mis en cache côté navigateur - Ajouter dans la conf de nginx un ssl_dhparam + générer le fichier dans un script - Mettre à jour Smarty (et passer en « secure mode » ?) - Admin, exercice: pas normal qu'il y ait des réponses RAW dans les data de tests From cf4f70e7a5c6cbd7f35a2adf318950e6824eddf6 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Mon, 10 Nov 2014 18:00:57 +0100 Subject: [PATCH 0233/2686] Update Dockerfile (best-practices, misc dir rights, ...) --- Dockerfile | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 75aba18f..16415623 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,8 +7,17 @@ MAINTAINER Pierre-Olivier Mercier # Install packages #################################################### -RUN apt-get -y update -RUN apt-get install -y nginx-light php5-fpm mysql-server php5-mysql php5-mcrypt pwgen openssl +RUN apt-get -y update && \ + apt-get install -y \ + nginx-light \ + php5-fpm \ + mysql-server \ + php5-mysql \ + php5-mcrypt \ + pwgen \ + openssl \ + && \ + apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # Copying files ####################################################### @@ -40,6 +49,5 @@ RUN chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/tem # ENVIRONNEMENT ####################################################### -RUN apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* EXPOSE 80/tcp 443/tcp -CMD ["sh", "-c", "cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; service nginx start && service php5-fpm start && service mysql start && /bin/bash"] +CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; service nginx start && service php5-fpm start && service mysql start && /bin/bash"] From e1e9050522ede1b6b7efad67d7b29255a7b083d1 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Mon, 10 Nov 2014 18:14:51 +0100 Subject: [PATCH 0234/2686] Fix DB schema by adding missing hash algorithms --- TODO | 1 - db/fic2014.sql | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/TODO b/TODO index c19e8c63..c755440e 100644 --- a/TODO +++ b/TODO @@ -3,4 +3,3 @@ - Retrouver toutes les dépendances - Ajouter dans la conf de nginx un ssl_dhparam + générer le fichier dans un script - Mettre à jour Smarty (et passer en « secure mode » ?) -- Admin, exercice: pas normal qu'il y ait des réponses RAW dans les data de tests diff --git a/db/fic2014.sql b/db/fic2014.sql index 0b8f5e2c..ea48d5c5 100644 --- a/db/fic2014.sql +++ b/db/fic2014.sql @@ -68,7 +68,7 @@ CREATE TABLE IF NOT EXISTS `exercice_tries` ( CREATE TABLE IF NOT EXISTS `exercice_keys` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `id_exercice` varchar(100) COLLATE utf8_unicode_ci NOT NULL, - `format` enum('raw','md5','sha1','sha256','sha512') COLLATE utf8_unicode_ci NOT NULL, + `format` enum('raw','md5','sha1','sha224','sha256','sha384','sha512','whirlpool') COLLATE utf8_unicode_ci NOT NULL, `value` varbinary(150) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; From 7f90fc8c07b0c4ba3b3ff14a8f2acebf9e350597 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 19 Nov 2014 18:01:04 +0100 Subject: [PATCH 0235/2686] Add .dockerignore --- .dockerignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..6b8710a7 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +.git From 9a576420294be0f080719bede3e6c91661d386b5 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 19 Nov 2014 18:11:43 +0100 Subject: [PATCH 0236/2686] All dependencies should have been listed in README --- Dockerfile | 1 + README.md | 12 +++++++++--- TODO | 1 - 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 16415623..f4899490 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,6 +14,7 @@ RUN apt-get -y update && \ mysql-server \ php5-mysql \ php5-mcrypt \ + libmcrypt-dev \ pwgen \ openssl \ && \ diff --git a/README.md b/README.md index ea77dd1c..9bb814e8 100644 --- a/README.md +++ b/README.md @@ -81,20 +81,26 @@ CONNTRACK states. * `php-fpm` with `mysql` module; * `openssl` and `pwgen` for client certificat generation; * `mcrypt`; -* `Mcrypt` from CPAN (`cpan -i Mcrypt`) to decrypt submissions (see https://metacpan.org/pod/Mcrypt); +* `Mcrypt` from CPAN (`cpan -i Mcrypt`, on Debian, it requires `libtool` and + `build-essential`) to decrypt submissions (see + https://metacpan.org/pod/Mcrypt); ##### Firewall rules This machine shouldn't have any network connection, except outgoing one to the frontend for synchronization. +##### Others setups + +Indicate in `/etc/hosts.conf` IP(s) of the frontend. + ### History #### FIC2014 -Two machines were used : one for backend (Phobos) and one for frontend -(Deimos). They ran a GNU/Linux Gentoo Hardened with custom 3.2 kernel without +Two machines were used : one for backend (Deimos) and one for frontend +(Phobos). They ran a GNU/Linux Gentoo Hardened with custom 3.2 kernel without module loading, unused and unecessary components and with all GrSecurity features activated. diff --git a/TODO b/TODO index c755440e..580765a5 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ - Départager les ex-æquo dans le classement - Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe -- Retrouver toutes les dépendances - Ajouter dans la conf de nginx un ssl_dhparam + générer le fichier dans un script - Mettre à jour Smarty (et passer en « secure mode » ?) From 96805a5e1bb993b9b6a6c69396f85f8a28e690c1 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 19 Nov 2014 18:29:46 +0100 Subject: [PATCH 0237/2686] Document some script + centralize script configuration --- backup.sh | 15 +++++++++------ clear_cache.sh | 4 ++++ config.sh | 11 +++++++++++ launch.sh | 6 +++++- nginx_gen_team.sh | 3 +++ stop.sh | 2 ++ synchro.sh | 23 +++++++++++++++-------- 7 files changed, 49 insertions(+), 15 deletions(-) create mode 100644 config.sh diff --git a/backup.sh b/backup.sh index 2a0f9d0e..6b23f068 100755 --- a/backup.sh +++ b/backup.sh @@ -1,21 +1,24 @@ #!/bin/sh -cd `dirname "$0"` -TO_BCKP="/mnt/backup" +# This script mades backup of important things -chown synchro "$TO_BCKP" +cd `dirname "$0"` + +source config.sh + +chown "$SYNCHRO_USER" "$TO_BCKP" if [ "$UID" = "0" ] then SCRIPT=`pwd`/`basename "$0"` - su -c "sh $SCRIPT $@" synchro + su -c "sh $SCRIPT $@" "$SYNCHRO_USER" exit $? fi if mount | grep "$TO_BCKP" > /dev/null then - mysqldump -u backup --password="Riuy6of sae^W0Sh" fic > "$TO_BCKP"/db/`date +%Y%m%d-%H%M`.sql + mysqldump -u backup --password="$BCKP_PASS" fic > "$TO_BCKP"/db/`date +%Y%m%d-%H%M`.sql rsync -avL misc "$TO_BCKP" rsync -avL .git "$TO_BCKP" @@ -24,5 +27,5 @@ then rsync -avL true_files "$TO_BCKP" else - echo No volume mount on $TO_BCKP + echo No volume mounted on $TO_BCKP fi diff --git a/clear_cache.sh b/clear_cache.sh index cb528dd4..5d3d5c2f 100755 --- a/clear_cache.sh +++ b/clear_cache.sh @@ -1,7 +1,11 @@ #!/bin/sh +# This script deletes Onyx framework cache + cd `dirname "$0"` +source config.sh + for n in "$@" do MD5=`echo -n $n | md5sum | cut -d " " -f 1` diff --git a/config.sh b/config.sh new file mode 100644 index 00000000..bc07a615 --- /dev/null +++ b/config.sh @@ -0,0 +1,11 @@ +# The name of the frontend, like indicated in /etc/hosts +FRONTEND_HOSTNAME="phobos" + +# Username of the unpriviledge user that runs scripts +SYNCHRO_USER="synchro" + +# Directory where backup should be made +TO_BCKP="/mnt/backup" + +# Password of the MySQL user backup (with RO rights) +BCKP_PASS="Riuy6of sae^W0Sh" diff --git a/launch.sh b/launch.sh index eee62513..ed33db08 100755 --- a/launch.sh +++ b/launch.sh @@ -1,12 +1,16 @@ #!/bin/sh +# This script does all actions in backend production environment + rm -f /tmp/stop cd `dirname "$0"` +source config.sh + if [ "$UID" = "0" ] then SCRIPT=`pwd`/`basename "$0"` - su -c "sh $SCRIPT" synchro + su -c "sh $SCRIPT" "$SYNCHRO_USER" exit $? fi diff --git a/nginx_gen_team.sh b/nginx_gen_team.sh index ebf28572..6347421c 100644 --- a/nginx_gen_team.sh +++ b/nginx_gen_team.sh @@ -1,3 +1,6 @@ #!/bin/sh +# Generate from database (exported XML from the website) the part of nginx +# configuration file authenticating teams + curl http://localhost/admin/teams/export 2> /dev/null | grep "(.*)<.*$@ if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=\2/") { set $team \1; }@' diff --git a/stop.sh b/stop.sh index 5bd241cc..71f6776f 100755 --- a/stop.sh +++ b/stop.sh @@ -1,3 +1,5 @@ #!/bin/sh +# Best way to stop the launch.sh script + touch /tmp/stop diff --git a/synchro.sh b/synchro.sh index 9406d1cd..e6f81ce7 100755 --- a/synchro.sh +++ b/synchro.sh @@ -1,11 +1,16 @@ #!/bin/sh +# This script synchronizes first, the generated frontend and then +# retrieves submissions + cd `dirname "$0"` +source config.sh + if [ "$UID" = "0" ] then SCRIPT=`pwd`/`basename "$0"` - su -c "sh $SCRIPT $@" synchro + su -c "sh $SCRIPT $@" "$SYNCHRO_USER" exit $? fi @@ -15,13 +20,15 @@ then OPTS="$OPTS --delete" fi -rsync -e ssh -av $OPTS out/errors phobos:~/ -rsync -e ssh -av $OPTS out/htdocs phobos:~/ -rsync -e ssh -av $OPTS out/teams phobos:~/ -rsync -e ssh -avL $OPTS files phobos:~/ -rsync -e ssh -av $OPTS nginx.conf submission.php misc/server.crt misc/server.key misc/pki/cacert.crt misc/pki/crl.pem phobos:~/ +# Synchronize HTML pages +rsync -e ssh -av $OPTS out/errors "$FRONTEND_HOSTNAME":~/ +rsync -e ssh -av $OPTS out/htdocs "$FRONTEND_HOSTNAME":~/ +rsync -e ssh -av $OPTS out/teams "$FRONTEND_HOSTNAME":~/ +rsync -e ssh -avL $OPTS files "$FRONTEND_HOSTNAME":~/ +rsync -e ssh -av $OPTS nginx.conf submission.php misc/server.crt misc/server.key misc/pki/cacert.crt misc/pki/crl.pem "$FRONTEND_HOSTNAME":~/ -rsync -e ssh -av phobos:~/submission/ submission/ -ssh phobos "rm -fv ~/submission/*" +# Synchronize submissions +rsync -e ssh -av "$FRONTEND_HOSTNAME":~/submission/ submission/ +ssh "$FRONTEND_HOSTNAME" "rm -fv ~/submission/*" exit $? From 2d4e7400cb4b200c6dcca4a1194e48dd95d13fbb Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 19 Nov 2014 18:30:07 +0100 Subject: [PATCH 0238/2686] Add themes DTD --- docs/dtd/themes.dtd | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 docs/dtd/themes.dtd diff --git a/docs/dtd/themes.dtd b/docs/dtd/themes.dtd new file mode 100644 index 00000000..98510773 --- /dev/null +++ b/docs/dtd/themes.dtd @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + From d368f0862b2d26247f655b40a8db064b349399c4 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 11:17:45 +0100 Subject: [PATCH 0239/2686] Merge CSS files and introduce dev theme --- TODO | 1 + htdocs/css/dev.css | 3 ++ htdocs/css/home.css | 19 ------------ htdocs/css/{score.css => main.css} | 43 ++++++++++++++++++---------- onyx/tpl/bootstrap/layout.tpl | 8 ++++-- onyx/tpl/bootstrap/public/layout.tpl | 3 +- onyx/tpl/bootstrap/teams/layout.tpl | 3 +- onyx/tpl/bootstrap/teams/lobby.tpl | 3 +- 8 files changed, 40 insertions(+), 43 deletions(-) create mode 100644 htdocs/css/dev.css delete mode 100644 htdocs/css/home.css rename htdocs/css/{score.css => main.css} (61%) diff --git a/TODO b/TODO index 580765a5..2d55d580 100644 --- a/TODO +++ b/TODO @@ -2,3 +2,4 @@ - Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe - Ajouter dans la conf de nginx un ssl_dhparam + générer le fichier dans un script - Mettre à jour Smarty (et passer en « secure mode » ?) +- Mettre à jour les logos diff --git a/htdocs/css/dev.css b/htdocs/css/dev.css new file mode 100644 index 00000000..68f4b0ad --- /dev/null +++ b/htdocs/css/dev.css @@ -0,0 +1,3 @@ +.clock { + display: none; +} diff --git a/htdocs/css/home.css b/htdocs/css/home.css deleted file mode 100644 index 343be509..00000000 --- a/htdocs/css/home.css +++ /dev/null @@ -1,19 +0,0 @@ -.clock #ficlogo { - float: left; - height: 100px; - margin-left: 25px; - width: 12%; -} -.clock #epitalogo { - float: right; - height: 100px; - width: 14%; -} -.clock #ficlogo img { - max-height: 170px; - max-width: 100%; -} -.clock #epitalogo img { - max-height: 170px; - max-width: 100%; -} \ No newline at end of file diff --git a/htdocs/css/score.css b/htdocs/css/main.css similarity index 61% rename from htdocs/css/score.css rename to htdocs/css/main.css index 4b45726a..084763cc 100644 --- a/htdocs/css/score.css +++ b/htdocs/css/main.css @@ -1,4 +1,3 @@ - .clock { background:#202020; margin: 0 auto; @@ -6,14 +5,32 @@ border: 1px solid #333; color: #fff; } - -#Date { - background:#202020; - font-family: bold, sans-serif; - text-align:center; - text-shadow:0 0 5px #00c6ff; +.clock #ficlogo { + float: left; + height: 100px; + margin-left: 25px; + width: 12%; +} +.clock #epitalogo { + float: right; + height: 100px; + width: 14%; +} +.clock #ficlogo img { + max-height: 170px; + max-width: 100%; +} +.clock #epitalogo img { + max-height: 170px; + max-width: 100%; } +#Date { + background:#202020; + font-family: bold, sans-serif; + text-align:center; + text-shadow:0 0 5px #00c6ff; +} #Date + ul { width: 800px; margin: 0 auto; @@ -21,7 +38,6 @@ list-style: none; text-align: center; } - #Date + ul li { display: inline; font-size: 5em; @@ -32,14 +48,12 @@ .point { position: relative; - -moz-animation: mymove 1s ease infinite; - -webkit-animation: mymove 1s ease infinite; + -moz-animation: clockanim 1s ease infinite; + -webkit-animation: clockanim 1s ease infinite; padding-left: 10px; padding-right: 10px; } - -/* Simple Animation */ -@-webkit-keyframes mymove { +@-webkit-keyframes clockanim { 0% { opacity: 1.0; text-shadow: 0 0 20px #00c6ff; @@ -55,8 +69,7 @@ text-shadow: 0 0 20px #00c6ff; } } - -@-moz-keyframes mymove { +@-moz-keyframes clockanim { 0% { opacity: 1.0; text-shadow: 0 0 20px #00c6ff; diff --git a/onyx/tpl/bootstrap/layout.tpl b/onyx/tpl/bootstrap/layout.tpl index 9f812352..2c35d348 100644 --- a/onyx/tpl/bootstrap/layout.tpl +++ b/onyx/tpl/bootstrap/layout.tpl @@ -3,9 +3,10 @@ {block name=title}Challenge FIC2015{/block} - - - + + + + diff --git a/onyx/tpl/bootstrap/public/layout.tpl b/onyx/tpl/bootstrap/public/layout.tpl index cccedb88..062e1dc2 100644 --- a/onyx/tpl/bootstrap/public/layout.tpl +++ b/onyx/tpl/bootstrap/public/layout.tpl @@ -39,7 +39,7 @@ {/block} {block name=end} - + + + From ec69cea4f6447876ffe105b2688a0da23e1a0a84 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 15:33:28 +0100 Subject: [PATCH 0244/2686] Forget one dependancy --- Dockerfile | 1 + README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index f4899490..00fe2e20 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,7 @@ RUN apt-get -y update && \ php5-mysql \ php5-mcrypt \ libmcrypt-dev \ + libwww-perl \ pwgen \ openssl \ && \ diff --git a/README.md b/README.md index 9bb814e8..821cd00b 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ CONNTRACK states. * `php-fpm` with `mysql` module; * `openssl` and `pwgen` for client certificat generation; * `mcrypt`; +* `HTTP::Request::Common` perl module; * `Mcrypt` from CPAN (`cpan -i Mcrypt`, on Debian, it requires `libtool` and `build-essential`) to decrypt submissions (see https://metacpan.org/pod/Mcrypt); From 4fe56db0d62ef2aadd6b8fc195497054fc5c3e0d Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 15:39:54 +0100 Subject: [PATCH 0245/2686] Document gen_site.pl --- gen_site.pl | 258 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 226 insertions(+), 32 deletions(-) diff --git a/gen_site.pl b/gen_site.pl index 5f980509..17928f21 100755 --- a/gen_site.pl +++ b/gen_site.pl @@ -1,4 +1,14 @@ #!/usr/bin/env perl +#============================================================================= +# +# USAGE: ./gen_site.pl [options] [commands] +# +# DESCRIPTION: More efficient wget -m +# +# AUTHOR: Pierre-Olivier Mercier +# ORGANIZATION: EPITA SRS +# +#============================================================================= use v5.10.1; use strict; @@ -16,6 +26,8 @@ use Getopt::Long; use IO::Socket; use Thread::Queue; +### GLOBALS ########################################################### + our $outdir = "outest"; our $outteams = "/teams/"; our $outerrors = "/errors/"; @@ -29,6 +41,16 @@ our $baseerrors = "/errors/"; our $baseteams = "/connected/"; our $threads = 6; +my $deamon; +my $socket; + +my $queue :shared = Thread::Queue->new(); +my $main_thread; + + +### GENERATORS ######################################################## + +# Enqueue error pages in the mirror sub genErrors(;$) { my $m = shift // Mirror->new(); @@ -43,6 +65,7 @@ sub genErrors(;$) return $m; } +# Enqueue public pages in the mirror sub genHome(;$) { my $m = shift // Mirror->new(); @@ -54,6 +77,7 @@ sub genHome(;$) return $m; } +# Enqueue all teams in the mirror sub genFull(;$) { my $m = shift // Mirror->new(); @@ -62,6 +86,7 @@ sub genFull(;$) return $m; } +# Enqueue a team in the mirror sub genTeam($;$) { my $team_id = shift; @@ -72,6 +97,7 @@ sub genTeam($;$) return $m; } +# Enqueue theme pages for a given team in the mirror sub genTeamTheme($$;$) { my $team_id = shift; @@ -84,9 +110,9 @@ sub genTeamTheme($$;$) } -my $queue :shared = Thread::Queue->new(); -my $main_thread; +### TOOLS ############################################################# +# Manage the mirror sub manage { my $m = shift // Mirror->new(); @@ -187,6 +213,7 @@ sub manage } } +# Perform a synchronization of the temporary mirrored directory sub sync { if (shift) @@ -261,6 +288,7 @@ sub sync } } +# Parse input command and enqueue them sub parse($$;$) { my $m = shift; @@ -298,19 +326,9 @@ sub parse($$;$) } -# Parse arguments -my $help; my $deamon; my $socket; -GetOptions ("threads|thread|t=i" => \$threads, - "baseadmin|ba=s" => \$baseadmin, - "basehome|bh=s" => \$basehome, - "baseteams|bt=s" => \$baseteams, - "outdir|out|o=s" => \$outdir, - "deamon|d" => \$deamon, - "socket|s=s" => \$socket, - "help|h|?" => \$help); - -$outdir = abs_path($outdir); +### SOCKETS ########################################################### +# Create the socket and wait for connection sub create_socket { my $m = shift; @@ -332,6 +350,7 @@ sub create_socket } } +# Manage the socket connection sub socket_run { my $m = shift; @@ -348,6 +367,24 @@ sub socket_run close $connection; } + +### MAIN ################################################################ + +# Parse arguments +my $help; +GetOptions ("threads|thread|t=i" => \$threads, + "baseadmin|ba=s" => \$baseadmin, + "basehome|bh=s" => \$basehome, + "baseerrors|be=s" => \$baseerrors, + "baseteams|bt=s" => \$baseteams, + "outdir|out|o=s" => \$outdir, + "deamon|d" => \$deamon, + "socket|s=s" => \$socket, + "help|h|?" => \$help); + +$outdir = abs_path($outdir); + +# Daemon mode: run forever until stdin is open if ($deamon) { my $m :shared = Mirror->new(); @@ -365,6 +402,8 @@ if ($deamon) parse($m, "J"); $main_thread->join(); } + +# Run given commands elsif (@ARGV) { my $m :shared = Mirror->new(); @@ -380,6 +419,8 @@ elsif (@ARGV) parse($m, "J"); $main_thread->join(); } + +# Just performs a full generation else { my $m = genFull(); @@ -390,11 +431,14 @@ else sync(1); } +# Clean tmp remove_tree($main::tmpdir); package Mirror; +# Structure to store a mirror state of a website + use v5.10.1; use strict; use warnings; @@ -403,6 +447,7 @@ use threads::shared; use Thread::Queue; +# Initialize the class sub new($) { my $class = shift; @@ -418,6 +463,7 @@ sub new($) return $self; } +# Launch threads and do more initialization sub start($) { my $self = shift; @@ -434,6 +480,7 @@ sub start($) } } +# Enqueue a RESET sub reset($) { my $self = shift; @@ -441,6 +488,7 @@ sub reset($) $self->{add}->enqueue("#RESET"); } +# Clean queues and wait for stop threads sub end($) { my $self = shift; @@ -470,6 +518,7 @@ sub stop($) return $self->end(); } +# Enqueue URLs sub add_url($@) { my $self = shift; @@ -480,6 +529,7 @@ sub add_url($@) } } +# Function executed to prepare URL to fetch sub run_add { my $self = shift; @@ -520,6 +570,7 @@ sub run_add } } +# Main function to fetch pages sub run { my $self = shift; @@ -563,6 +614,7 @@ sub run } } +# Join sub join($) { my $self = shift; @@ -582,6 +634,8 @@ sub join($) package FicPage; +# Represent a web page in order to perform some treatment on it + use v5.10.1; use strict; use warnings; @@ -591,6 +645,7 @@ use File::Path qw(make_path); use HTTP::Request::Common qw(GET POST); use LWP::UserAgent; +# Initialize the class sub new { my $class = shift; @@ -603,6 +658,18 @@ sub new return $self; } +# Fetch the page content +sub fetch($) +{ + my $self = shift; + my $ua = LWP::UserAgent->new; + + my $res = $ua->request(GET $self->{url}); + + $self->{content} = $res->content; +} + +# If the URL store is a short one, try to expand it by looking to correct URL sub toRightURL($) { my $self = shift; @@ -625,6 +692,7 @@ sub toRightURL($) return $self->{url}; } +# Retrieve all links in the page content sub getLinks($) { my $self = shift; @@ -632,6 +700,7 @@ sub getLinks($) return $self->{content} =~ /(?:src|href|action)="([^"]+)"/g; } +# Search relative (and absolute linking to the site part) links sub getNearLinks($) { my $self = shift; @@ -655,6 +724,7 @@ sub getNearLinks($) } } +# Remove SALT base from URL contained in the page sub treatLinks($) { my $self = shift; @@ -662,24 +732,7 @@ sub treatLinks($) $self->{content} =~ s!(src|href|action)="( \Q$baseteams\E[^/]+/ | \Q$baseadmin\E | \Q$basehome\E)([^"]*)"!$1="/$3"!gx; } -sub fetch($) -{ - my $self = shift; - my $ua = LWP::UserAgent->new; - - my $res = $ua->request(GET $self->{url}); - - $self->{content} = $res->content; -} - -sub alreadySaved($;$) -{ - my $self = shift; - - my $path = $self->getSavePath(@_); - return -f $path || ( -d $path && -f "$path/index.html" ); -} - +# Generate the path where saved the page content sub getSavePath($;$) { my $self = shift; @@ -692,6 +745,16 @@ sub getSavePath($;$) return "$basedir$path"; } +# Is the page already saved? +sub alreadySaved($;$) +{ + my $self = shift; + + my $path = $self->getSavePath(@_); + return -f $path || ( -d $path && -f "$path/index.html" ); +} + +# Really save the page content sub save($;$) { my $self = shift; @@ -724,3 +787,134 @@ sub save($;$) }; print $@ if ($@); } + +__END__ + +=head1 NAME + +Dave Null - The netiquette's guardian angel + +=head1 USAGE + + ./gen_site.pl [OPTIONS] [COMMANDS] + +=head1 DESCRIPTION + +TODO + +=head1 OPTIONS + +=over + +=item B<-baseadmin=string> + +Called SALT_ADMIN in PHP part. Default: C + +=item B<-baseerrors=string> + +There is no equivalent in PHP part, it's harcoded. Default: C + +=item B<-basehome=string> + +Called SALT_PUBLIC in PHP part. Default: C + +=item B<-baseteams=string> + +Called SALT_USER in PHP part. Default: C + +=item B<-deamon> + +Run forever (until JOIN scheduler instruction occurs). + +=item B<-help> + +Displays the help. + +=item B<-outdir=path> + +Path where save generated pages + +=item B<-socket=path> + +Path to the socket to create. + +=item B<-threads=int> + +Number of parallel fetch to perform. + +=back + +=head1 SCHEDULER COMMANDS + +=over + +=item B + +Generate pages for all teams. + +=item B + +Generate pages for the public part. + +=item B + +Generate errors pages. + +=item B + +Generate all pages for the team C<00>. + +=item B + +Generate pages for the C<11> theme for the team C<00>. + +=item B + + + +=item B + +Made a full synchronization of the output directory (remove existing output dir +and replace it by the current temporary content and reset temporary content). + +=item B + +Made a incremental synchronization with the output directory (just copy all +files in the current temporary content to the output dir, don't remove +anything). + +=item B + +Perform a C in the temporary directory content. + +=item B + +Flush the scheduler queue and + +=item B + +Display some help. + +=back + +=head1 DEPENDENCIES + +=over + +=item + +perl >= 5.10.1, compilated with threads support + +=item + +HTTP::Request::Common + +=back + +=head1 AUTHOR + +Pierre-Olivier Mercier + +=head1 LICENSE AND COPYRIGHT + +Copyright (c) 2014 Pierre-Olivier Mercier From 11c27ef2e70272119c0e0384d6b17635808239c0 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 17:16:51 +0100 Subject: [PATCH 0246/2686] Use color in terminal, HTML tag elsewhere --- misc/CA.sh | 71 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 32 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index bfc99b5e..5ed1e97b 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -1,4 +1,4 @@ -#! /bin/sh +#!/bin/sh if [[ -z "${TOP_DIR}" ]]; then TOP_DIR=pki @@ -14,15 +14,22 @@ CACERT=./cacert.crt DAYS=2 -#GREEN="\033[1;32m" -#RED="\033[1;31m" -#COLOR_RST="\033[0m" - -GREEN="" -RED="" -COLOR_RST="" -BOLD="" -END_BOLD="" +if [ -z "$PS1" ] +then + GREEN="" + RED="" + COLOR_RST="" + BOLD="" + END_BOLD="" + ECHO_OPTS="" +else + GREEN="\033[1;32m" + RED="\033[1;31m" + COLOR_RST="\033[0m" + BOLD="" + END_BOLD="" + ECHO_OPTS="-e" +fi usage() { @@ -52,8 +59,8 @@ OUTPUT=$(mktemp) case $1 in "-newca" ) - echo -e -n "${GREEN}Create the directories, take care this will delete" - echo -e "the old directories ${COLOR_RST}" + echo -n $ECHO_OPTS "${GREEN}Create the directories, take care this will delete" + echo $ECHO_OPTS "the old directories ${COLOR_RST}" # sleep 1; echo -n "1 "; sleep 1; echo -n "2 "; sleep 1; echo "3" clean "ca" @@ -61,7 +68,7 @@ case $1 in ESCAPED=$(echo "${TOP_DIR}" | sed 's/[\/\.]/\\&/g') - echo -e "${GREEN}Making CA key and csr${COLOR_RST}" + echo $ECHO_OPTS "${GREEN}Making CA key and csr${COLOR_RST}" sed -i 's/=.*#COMMONNAME/= FIC CA #COMMONNAME/' $OPENSSL_CONF sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF @@ -90,7 +97,7 @@ case $1 in exit 4 fi - echo -e "${GREEN}Self signes the CA certificate${COLOR_RST}" + echo $ECHO_OPTS "${GREEN}Self signes the CA certificate${COLOR_RST}" openssl ca -batch -create_serial -out ${TOP_DIR}/${CACERT} \ -days ${DAYS} -keyfile ${TOP_DIR}/private/${CAKEY} \ -selfsign -extensions CORE_CA -config ${OPENSSL_CONF} \ @@ -102,9 +109,9 @@ case $1 in fi ;; "-newserver" ) - echo -e "${GREEN}Making the Server key and cert${COLOR_RST}" + echo $ECHO_OPTS "${GREEN}Making the Server key and cert${COLOR_RST}" if ! [ -f ${TOP_DIR}/private/${CAKEY} ]; then - echo -e "${RED}Can not found the CA's key${COLOR_RST}" + echo $ECHO_OPTS "${RED}Can not found the CA's key${COLOR_RST}" exit 2 fi sed -i 's/=.*#COMMONNAME/=10.226.3.70#COMMONNAME/' $OPENSSL_CONF @@ -114,17 +121,17 @@ case $1 in cat $OUTPUT exit 4 fi - echo -e "${GREEN}Signing the Server crt${COLOR_RST}" + echo $ECHO_OPTS "${GREEN}Signing the Server crt${COLOR_RST}" openssl ca -policy policy_match -config ${OPENSSL_CONF} \ -out server.crt -extensions SERVER_SSL -infiles server.csr if [ $? -ne 0 ]; then - echo -e "${RED}Signing failed for new server${COLOR_RST}" + echo $ECHO_OPTS "${RED}Signing failed for new server${COLOR_RST}" rm -rf server.key server.crt server.csr cat $OUTPUT exit 3 else rm server.csr # remove ? - echo -e "${GREEN}Signed certificate is in server.crt${COLOR_RST}" + echo $ECHO_OPTS "${GREEN}Signed certificate is in server.crt${COLOR_RST}" fi ;; "-newclient" ) @@ -133,13 +140,13 @@ case $1 in exit 1 fi echo "==============================================================" - echo -e "${GREEN}Making the client key and csr of ${BOLD}${2}${END_BOLD}${COLOR_RST}" + echo $ECHO_OPTS "${GREEN}Making the client key and csr of ${BOLD}${2}${END_BOLD}${COLOR_RST}" ESCAPED=$(echo "${TOP_DIR}" | sed 's/[\/\.]/\\&/g') sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF if ! [ -f ${TOP_DIR}/private/${CAKEY} ]; then - echo -e "${RED}Can not found the CA's key${COLOR_RST}" + echo $ECHO_OPTS "${RED}Can not found the CA's key${COLOR_RST}" exit 2 fi sed -i "s/=.*#COMMONNAME/= $2#COMMONNAME/" $OPENSSL_CONF @@ -160,26 +167,26 @@ case $1 in exit 4 fi - echo -e "${GREEN}Signing the Client crt${COLOR_RST}" + echo $ECHO_OPTS "${GREEN}Signing the Client crt${COLOR_RST}" openssl ca -batch -policy policy_match -out ${TOP_DIR}/${2}.crt \ -config ${OPENSSL_CONF} -extensions CLIENT_SSL -infiles ${TOP_DIR}/${2}.csr > $OUTPUT 2>&1 if [ $? -ne 0 ]; then - echo -e "${RED}Signing failed for $2 ${COLOR_RST}" + echo $ECHO_OPTS "${RED}Signing failed for $2 ${COLOR_RST}" cat $OUTPUT clean "client" $2 exit 3 fi - echo -e "${GREEN}Export the Client files to pkcs12${COLOR_RST}" + echo $ECHO_OPTS "${GREEN}Export the Client files to pkcs12${COLOR_RST}" openssl pkcs12 -export -inkey ${TOP_DIR}/${2}.key -in ${TOP_DIR}/${2}.crt -name ${2} \ -passin pass:$pass -out ${TOP_DIR}/pkcs/${2}.p12 \ -passout pass:$pass > $OUTPUT 2>&1 if [ $? -ne 0 ]; then - echo -e "${RED}pkcs12 export failed for ${BOLD}$2${END_BOLD}${COLOR_RST}" + echo $ECHO_OPTS "${RED}pkcs12 export failed for ${BOLD}$2${END_BOLD}${COLOR_RST}" cat $OUTPUT clean "client" $2 exit 4 else - echo -e "Exported pkcs12 file is ${2}.p12" + echo $ECHO_OPTS "Exported pkcs12 file is ${2}.p12" fi mv ${TOP_DIR}/${2}.crt ${TOP_DIR}/certs echo "$2:$pass" >> ${TOP_DIR}/../teams.pass @@ -191,32 +198,32 @@ case $1 in echo "Usage: $0 -revoke NAME" exit 1 fi - echo -e "${GREEN}Revocate ${BOLD}${2}${END_BOLD}${COLOR_RST}" + echo $ECHO_OPTS "${GREEN}Revocate ${BOLD}${2}${END_BOLD}${COLOR_RST}" openssl ca -revoke ${TOP_DIR}/certs/${2}.crt -config ${OPENSSL_CONF}\ -keyfile ${TOP_DIR}/private/${CAKEY} \ -cert ${TOP_DIR}/${CACERT} > $OUTPUT 2>&1 if [ $? -ne 0 ]; then - echo -e "${RED}Revocation failed for ${BOLD}${2}${END_BOLD}${COLOR_RST}" + echo $ECHO_OPTS "${RED}Revocation failed for ${BOLD}${2}${END_BOLD}${COLOR_RST}" cat $OUTPUT exit 4 fi rm ${TOP_DIR}/certs/${2}.crt rm ${TOP_DIR}/pkcs/${2}.p12 - echo -e "${GREEN}Generate crl.pem${COLOR_RST}" + echo $ECHO_OPTS "${GREEN}Generate crl.pem${COLOR_RST}" openssl ca -config ${OPENSSL_CONF} -gencrl -out ${TOP_DIR}/crl.pem > $OUTPUT 2>&1 if [ $? -ne 0 ]; then - echo -e "${RED}Generate crl.pem failed" + echo $ECHO_OPTS "${RED}Generate crl.pem failed" cat $OUTPUT exit 5 fi ;; "-gencrl" ) - echo -e "${GREEN}Generate crl.pem${COLOR_RST}" + echo $ECHO_OPTS "${GREEN}Generate crl.pem${COLOR_RST}" openssl ca -config ${OPENSSL_CONF} -gencrl -out ${TOP_DIR}/crl.pem > $OUTPUT 2>&1 if [ $? -ne 0 ]; then - echo -e "${RED}Generate crl.pem failed" + echo $ECHO_OPTS "${RED}Generate crl.pem failed" cat $OUTPUT exit 5 fi From f7a25e0afcc166cdb54afbde3664c0f7575175b3 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 17:21:08 +0100 Subject: [PATCH 0247/2686] Update TODO --- TODO | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO b/TODO index 49e1beb4..a9e699d5 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,7 @@ - Départager les ex-æquo dans le classement - Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe - Ajouter un header dans nginx avec $msec ou $time_iso8601 et calculer le timer à partir de cette valeur, au lieu de se baser sur l'horloge de l'utilisateur +- Quand est généré la CRL ? - Ajouter dans la conf de nginx un ssl_dhparam + générer le fichier dans un script - Mettre à jour Smarty (et passer en « secure mode » ?) - Mettre à jour les logos From 099fdf4db14777df23879b122f62db57c87c9690 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 17:32:30 +0100 Subject: [PATCH 0248/2686] Refactor --- misc/CA.sh | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index 5ed1e97b..502915e5 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -53,6 +53,17 @@ clean() rm -rf $OUTPUT } +gen_crl() +{ + echo $ECHO_OPTS "${GREEN}Generate crl.pem${COLOR_RST}" + openssl ca -config ${OPENSSL_CONF} -gencrl -out ${TOP_DIR}/crl.pem > $OUTPUT 2>&1 + if [ $? -ne 0 ]; then + echo $ECHO_OPTS "${RED}Generate crl.pem failed" + cat $OUTPUT + exit 5 + fi +} + [ $# -lt 1 ] && usage OUTPUT=$(mktemp) @@ -108,6 +119,7 @@ case $1 in exit 4 fi ;; + "-newserver" ) echo $ECHO_OPTS "${GREEN}Making the Server key and cert${COLOR_RST}" if ! [ -f ${TOP_DIR}/private/${CAKEY} ]; then @@ -193,6 +205,7 @@ case $1 in echo "$pass" clean "client" $2 ;; + "-revoke" ) if [ $# -ne 2 ]; then echo "Usage: $0 -revoke NAME" @@ -210,24 +223,13 @@ case $1 in rm ${TOP_DIR}/certs/${2}.crt rm ${TOP_DIR}/pkcs/${2}.p12 - echo $ECHO_OPTS "${GREEN}Generate crl.pem${COLOR_RST}" - openssl ca -config ${OPENSSL_CONF} -gencrl -out ${TOP_DIR}/crl.pem > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then - echo $ECHO_OPTS "${RED}Generate crl.pem failed" - cat $OUTPUT - exit 5 - fi - + gen_crl ;; + "-gencrl" ) - echo $ECHO_OPTS "${GREEN}Generate crl.pem${COLOR_RST}" - openssl ca -config ${OPENSSL_CONF} -gencrl -out ${TOP_DIR}/crl.pem > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then - echo $ECHO_OPTS "${RED}Generate crl.pem failed" - cat $OUTPUT - exit 5 - fi + gen_crl ;; + * ) usage ;; From 716e1e7ccdfac9fa681d1dc5ababc74ce914d4b9 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 17:32:46 +0100 Subject: [PATCH 0249/2686] Can revoke server certificate --- misc/CA.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/misc/CA.sh b/misc/CA.sh index 502915e5..fc5245cc 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -146,6 +146,26 @@ case $1 in echo $ECHO_OPTS "${GREEN}Signed certificate is in server.crt${COLOR_RST}" fi ;; + + "-revokeserver" ) + echo $ECHO_OPTS "${GREEN}Revocate server certificate${COLOR_RST}" + if ! [ -f ${TOP_DIR}/private/${CAKEY} ]; then + echo $ECHO_OPTS "${RED}Can not found the CA's key${COLOR_RST}" + exit 2 + fi + openssl ca -revoke server.crt -config ${OPENSSL_CONF}\ + -keyfile ${TOP_DIR}/private/${CAKEY} \ + -cert ${TOP_DIR}/${CACERT} > $OUTPUT 2>&1 + if [ $? -ne 0 ]; then + echo $ECHO_OPTS "${RED}Server certificate revocation failed${COLOR_RST}" + cat $OUTPUT + exit 4 + fi + rm ${TOP_DIR}/server.crt ${TOP_DIR}/server.key + + gen_crl + ;; + "-newclient" ) if [ $# -ne 2 ]; then echo "Usage: $0 -newclient NAME" From 39ca8940e159a406bdee1b5409fe4bfc59e403ab Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 17:42:58 +0100 Subject: [PATCH 0250/2686] If team certificate file not found, propose to generate it --- onyx/include/common.php | 2 ++ onyx/tpl/bootstrap/admin/users.tpl | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/onyx/include/common.php b/onyx/include/common.php index f21a6236..36948af9 100644 --- a/onyx/include/common.php +++ b/onyx/include/common.php @@ -22,5 +22,7 @@ if (is_file($VAR["misc_dir"]."/challenge_started")) $template->assign("END", $VAR['end_challenge']); } +if (!empty($VAR['misc_dir'])) + $template->assign("MISC_DIR", $VAR['misc_dir']); if (!empty($LANG)) $template->assign("LANG", $LANG); diff --git a/onyx/tpl/bootstrap/admin/users.tpl b/onyx/tpl/bootstrap/admin/users.tpl index 387013bb..f0ecb49c 100644 --- a/onyx/tpl/bootstrap/admin/users.tpl +++ b/onyx/tpl/bootstrap/admin/users.tpl @@ -23,7 +23,7 @@ - {if not $t->revoked} + {if not $t->revoked && is_file("{$MISC_DIR}/pki/pkcs/{$t->team_name}.p12")} From 4d1424b29b935bebe24c107823a46fa39e0c80db Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 18:04:39 +0100 Subject: [PATCH 0251/2686] Can revoke/generate server certiticate in admin interface --- htdocs/index.php | 4 ++ misc/CA.sh | 26 ++++++----- onyx/include/admin/certificate.php | 50 +++++++++++++++------ onyx/include/admin/home.php | 20 ++++++--- onyx/tpl/bootstrap/admin/home.tpl | 70 ++++++++++++++++++++---------- onyx/tpl/bootstrap/admin/shell.tpl | 7 +++ 6 files changed, 122 insertions(+), 55 deletions(-) create mode 100644 onyx/tpl/bootstrap/admin/shell.tpl diff --git a/htdocs/index.php b/htdocs/index.php index c0ed32bb..7b582646 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -61,12 +61,16 @@ if ($n && $p[0] == SALT_ADMIN) case "certificate/": case "certificate/newca": case "certificate/newca/": + case "certificate/newsrv": + case "certificate/newsrv/": case "certificate/newclient": case "certificate/newclient/": case "certificate/deleteca": case "certificate/deleteca/": case "certificate/revoke": case "certificate/revoke/": + case "certificate/revokesrv": + case "certificate/revokesrv/": case "certificate/get": case "certificate/get/": $page = require("admin/certificate.php"); diff --git a/misc/CA.sh b/misc/CA.sh index fc5245cc..45fd2f7f 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -1,10 +1,12 @@ #!/bin/sh -if [[ -z "${TOP_DIR}" ]]; then +cd $(dirname "$0") + +if [ -z "${TOP_DIR}" ]; then TOP_DIR=pki fi -if [[ -z "${OPENSSL_CONF}" ]]; then +if [ -z "${OPENSSL_CONF}" ]; then OPENSSL_CONF=openssl.cnf fi @@ -16,24 +18,24 @@ DAYS=2 if [ -z "$PS1" ] then - GREEN="" - RED="" - COLOR_RST="" - BOLD="" - END_BOLD="" - ECHO_OPTS="" -else GREEN="\033[1;32m" RED="\033[1;31m" COLOR_RST="\033[0m" BOLD="" END_BOLD="" ECHO_OPTS="-e" +else + GREEN="" + RED="" + COLOR_RST="" + BOLD="" + END_BOLD="" + ECHO_OPTS="" fi usage() { - echo "Usage: $0 (-newca|-newserver|-newclient NAME|-revoke NAME|-gencrl)" + echo "Usage: $0 (-newca|-newserver|-revokeserver|-newclient NAME|-revoke NAME|-gencrl)" exit 1 } @@ -71,7 +73,7 @@ OUTPUT=$(mktemp) case $1 in "-newca" ) echo -n $ECHO_OPTS "${GREEN}Create the directories, take care this will delete" - echo $ECHO_OPTS "the old directories ${COLOR_RST}" + echo $ECHO_OPTS " the old directories ${COLOR_RST}" # sleep 1; echo -n "1 "; sleep 1; echo -n "2 "; sleep 1; echo "3" clean "ca" @@ -161,7 +163,7 @@ case $1 in cat $OUTPUT exit 4 fi - rm ${TOP_DIR}/server.crt ${TOP_DIR}/server.key + rm server.crt server.key gen_crl ;; diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index 5698f903..a26cf585 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -27,22 +27,19 @@ function new_client($name, $misc_dir) //TODO handle if already exist putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); putenv("TOP_DIR=$misc_dir/pki"); - $output = shell_exec("$misc_dir/CA.sh -newclient $name"); - return $output; + return shell_exec("$misc_dir/CA.sh -newclient $name"); } function revoke_client($name, $misc_dir) { putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); putenv("TOP_DIR=$misc_dir/pki"); - $output = shell_exec("$misc_dir/CA.sh -revoke $name"); + return shell_exec("$misc_dir/CA.sh -revoke $name"); } if (!empty($p[2])) { - if (isset($VAR['misc_dir'])) - $misc_dir = $VAR['misc_dir']; - else + if (empty($VAR['misc_dir'])) { erreur("Merci d'ajouter la variable misc_dir dans root.xml"); return "admin/home"; @@ -54,7 +51,9 @@ if (!empty($p[2])) { putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); putenv("TOP_DIR=$misc_dir/pki"); - $output = shell_exec("$misc_dir/CA.sh -newca"); + $template->assign("output", + shell_exec("$misc_dir/CA.sh -newca")); + return "admin/shell"; } elseif ($p[2] == "deleteca") @@ -62,16 +61,38 @@ if (!empty($p[2])) $dir = "$misc_dir/pki"; remove_directory($dir); } + + elseif ($p[2] == "newsrv") + { + putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); + putenv("TOP_DIR=$misc_dir/pki"); + $template->assign("output", + shell_exec("$misc_dir/CA.sh -newserver")); + return "admin/shell"; + } + + elseif ($p[2] == "revokesrv") + { + putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); + putenv("TOP_DIR=$misc_dir/pki"); + $template->assign("output", + shell_exec("$misc_dir/CA.sh -revokeserver")); + return "admin/shell"; + } + elseif ($p[2] == "revoke") { $name = $_GET['name']; if (isset($name)) { - $output = revoke_client($name, $misc_dir); + $template->assign("output", + revoke_client($name, $misc_dir)); //TODO Check revocation failed Team::set_revoked(TRUE, $name); } + return "admin/shell"; } + // Is new team elseif ($p[2] == "newclient") { @@ -80,12 +101,13 @@ if (!empty($p[2])) //TODO check revoked attribute if (isset($name)) { - $output = new_client($name, $misc_dir); + $template->assign("output", + new_client($name, $misc_dir)); Team::set_revoked(FALSE, $name); - erreur($output, "sucess"); - return "admin/import_users"; + return "admin/shell"; } } + elseif ($p[2] == "get") { $name = $_GET['name']; @@ -95,14 +117,15 @@ if (!empty($p[2])) if (file_exists($path) && is_readable($path)) { header("Content-Type: application/force-download"); - header("Content-Length: ".strval(filesize($path))); + header("Content-Length: ".filesize($path)); header("Content-Disposition: attachment; filename=\"$name.p12\""); readfile($path); + exit; } } - exit; } + if ($p[2] == "deleteca" || $p[2] == "newca") { header("Location: /".SALT_ADMIN."/"); @@ -114,4 +137,3 @@ if (!empty($p[2])) exit; } } - diff --git a/onyx/include/admin/home.php b/onyx/include/admin/home.php index 6268084f..2297635a 100644 --- a/onyx/include/admin/home.php +++ b/onyx/include/admin/home.php @@ -20,20 +20,26 @@ else if (is_writable($misc_dir) && !is_dir("$misc_dir/pki/")) mkdir("$misc_dir/pki/"); -$wright = is_writable("$misc_dir/pki/"); -$template->assign("cert_writable", $wright); +$template->assign("cert_writable", is_writable("$misc_dir/pki/")); $ca_file = "$misc_dir/pki/cacert.crt"; - if (file_exists($ca_file)) { if (!is_readable($ca_file)) erreur("Impossible de lire le fichier"); else - { - $data = openssl_x509_parse(file_get_contents(ONYX . '../misc/pki/cacert.crt')); - $template->assign("cert", $data); - } + $template->assign("cert_CA", + openssl_x509_parse(file_get_contents($ca_file))); +} + +$srv_file = "$misc_dir/server.crt"; +if (file_exists($srv_file)) +{ + if (!is_readable($srv_file)) + erreur("Impossible de lire le fichier"); + else + $template->assign("cert_srv", + openssl_x509_parse(file_get_contents($srv_file))); } return "admin/home"; diff --git a/onyx/tpl/bootstrap/admin/home.tpl b/onyx/tpl/bootstrap/admin/home.tpl index 885c26fe..71cb39bc 100644 --- a/onyx/tpl/bootstrap/admin/home.tpl +++ b/onyx/tpl/bootstrap/admin/home.tpl @@ -1,29 +1,55 @@ {extends file="admin/layout.tpl"} {block name=content} -
    -
    -

    Certificat racine

    +
    +
    +
    +
    +

    Certificat racine

    +
    +
    + {if isset($cert_CA)} +
      + {foreach from=$cert_CA.subject key=k item=crt} +
    • [{$k}] : {$crt}
    • + {/foreach} +
    + Supprimer + {elseif ! $cert_writable} +
    Répertoire non accessible en écriture.
    + Nouveau + {else} + Pas de certificat + Nouveau + {/if} +
    +
    -
    - {if isset($cert)} -
      -
    • [C] : {$cert['subject']['C']}
    • -
    • [ST] : {$cert['subject']['ST']}
    • -
    • [O] : {$cert['subject']['O']}
    • -
    • [OU] : {$cert['subject']['OU']}
    • -
    • [CN] : {$cert['subject']['CN']}
    • -
    • [emailAddress] : {$cert['subject']['emailAddress']}
    • -
    - - {elseif isset($cert_writable) && ! $cert_writable} -
    Répertoire non accessible en écriture.
    - - {else} - Pas de certificat - - {/if} + +
    +
    +
    +

    Certificat serveur

    +
    +
    + {if isset($cert_srv)} +
      + {foreach from=$cert_srv.subject key=k item=crt} +
    • [{$k}] : {$crt}
    • + {/foreach} +
    + Supprimer + {elseif ! $cert_writable} +
    Répertoire non accessible en écriture.
    + Nouveau + {else} + Pas de certificat + Nouveau + {/if} +
    +
    diff --git a/onyx/tpl/bootstrap/admin/shell.tpl b/onyx/tpl/bootstrap/admin/shell.tpl new file mode 100644 index 00000000..cc6c0dc9 --- /dev/null +++ b/onyx/tpl/bootstrap/admin/shell.tpl @@ -0,0 +1,7 @@ +{extends file="admin/layout.tpl"} + +{block name=content} +
    +{$output}
    +
    +{/block} From b02c823f9e74c3840c4dfb620402c0ff106aa516 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 20:29:01 +0100 Subject: [PATCH 0252/2686] Few more dependencies --- Dockerfile | 2 ++ README.md | 4 +++- TODO | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 00fe2e20..80617e9b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,6 +9,7 @@ MAINTAINER Pierre-Olivier Mercier RUN apt-get -y update && \ apt-get install -y \ + realpath \ nginx-light \ php5-fpm \ mysql-server \ @@ -16,6 +17,7 @@ RUN apt-get -y update && \ php5-mcrypt \ libmcrypt-dev \ libwww-perl \ + libdigest-whirlpool-perl \ pwgen \ openssl \ && \ diff --git a/README.md b/README.md index 821cd00b..d8afcc29 100644 --- a/README.md +++ b/README.md @@ -76,12 +76,14 @@ CONNTRACK states. ##### Requirements +* `realpath`; * `mysql`; * `nginx` with `fastcgi` module; * `php-fpm` with `mysql` module; * `openssl` and `pwgen` for client certificat generation; * `mcrypt`; -* `HTTP::Request::Common` perl module; +* `HTTP::Request::Common` perl module (provided by `libwww-perl`); +* `Digest::Whirlpool` perl module (provided by `lib-digest-whirlpool-perl`); * `Mcrypt` from CPAN (`cpan -i Mcrypt`, on Debian, it requires `libtool` and `build-essential`) to decrypt submissions (see https://metacpan.org/pod/Mcrypt); diff --git a/TODO b/TODO index a9e699d5..667bda0b 100644 --- a/TODO +++ b/TODO @@ -7,3 +7,4 @@ - Mettre à jour les logos - versionner la DTD et la doc associée - valider les documents avec la DTD à l'import +- Lors de l'import des XML, retirer l'éventuel / en début de path From 89c2c4a2dcf2d1d8cee47d3fda1e70eefcb7297a Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 21:02:29 +0100 Subject: [PATCH 0253/2686] Fix bad query when checking for already solved exercice --- check.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check.pl b/check.pl index 92fd49ab..ae3c615d 100755 --- a/check.pl +++ b/check.pl @@ -187,7 +187,7 @@ for my $f (readdir $dh) if (! @$row[0] || $sth->rows) { # Check if the team has not already solved this exercice - $sth = query($dbh, "SELECT S.id FROM solved S WHERE S.id_exercice = ".$dbh->quote($exercice)); + $sth = query($dbh, "SELECT S.id FROM solved S WHERE S.id_team = $team AND S.id_exercice = ".$dbh->quote($exercice)); if (! $sth->rows) { say "resetresetreset:TEAM$team,$theme:SYNCSYN:TEAM$team:SYNC:HOME:SYNC:all:DS"; From 5e89d9d31e945ecd3d21dddf9a5cf7a3151a6736 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 21:03:35 +0100 Subject: [PATCH 0254/2686] Use bash for Debian compat --- README.md | 2 +- backup.sh | 2 +- clear_cache.sh | 2 +- gen_site.sh | 2 +- launch.sh | 4 +++- launch_local.sh | 42 ++++++++++++++++++++++++++++++++++++++++++ synchro.sh | 2 +- 7 files changed, 50 insertions(+), 6 deletions(-) create mode 100755 launch_local.sh diff --git a/README.md b/README.md index d8afcc29..cf6efbea 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ CONNTRACK states. * `mcrypt`; * `HTTP::Request::Common` perl module (provided by `libwww-perl`); * `Digest::Whirlpool` perl module (provided by `lib-digest-whirlpool-perl`); -* `Mcrypt` from CPAN (`cpan -i Mcrypt`, on Debian, it requires `libtool` and +* `Mcrypt` from CPAN (`cpan -i Mcrypt`, on Debian, it requires `libltdl-dev` and `build-essential`) to decrypt submissions (see https://metacpan.org/pod/Mcrypt); diff --git a/backup.sh b/backup.sh index 6b23f068..bfdfdee3 100755 --- a/backup.sh +++ b/backup.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # This script mades backup of important things diff --git a/clear_cache.sh b/clear_cache.sh index 5d3d5c2f..024aaf5e 100755 --- a/clear_cache.sh +++ b/clear_cache.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # This script deletes Onyx framework cache diff --git a/gen_site.sh b/gen_site.sh index 6ef98771..4fa11caf 100755 --- a/gen_site.sh +++ b/gen_site.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash BASEURL="localhost" SALT_TEAM="connected" diff --git a/launch.sh b/launch.sh index ed33db08..bf5f15ef 100755 --- a/launch.sh +++ b/launch.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # This script does all actions in backend production environment @@ -14,6 +14,8 @@ then exit $? fi +mkdir -p ./logs + touch ./logs/checks.log tail -f ./logs/checks.log & KP1=$! diff --git a/launch_local.sh b/launch_local.sh new file mode 100755 index 00000000..b86be2c2 --- /dev/null +++ b/launch_local.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# This script does all actions in backend local environment + +rm -f /tmp/stop +cd `dirname "$0"` + +source config.sh + +#if [ "$UID" = "0" ] +#then +# SCRIPT=`pwd`/`basename "$0"` +# su -c "sh $SCRIPT" "$SYNCHRO_USER" +# exit $? +#fi + +mkdir -p ./logs + +touch ./logs/checks.log +tail -f ./logs/checks.log & +KP1=$! + +TMPF=`mktemp` + +tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/test.sock -bt /challenge/ -ba /challenge-admin/ -o ./out & +KP2=$! + +while ! [ -f /tmp/stop ]; +do + if [ `ls submission | wc -l` -gt 1 ] + then + ./clear_cache.sh top + ./check.pl 2>> ./logs/checks.log >> "$TMPF" + + else + sleep 1 + fi +done + +kill -9 $KP1 $KP2 + +rm -rf "$TMPF" diff --git a/synchro.sh b/synchro.sh index e6f81ce7..8cebbb6d 100755 --- a/synchro.sh +++ b/synchro.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # This script synchronizes first, the generated frontend and then # retrieves submissions From e6acdbd68ad950e2036d0c1777fb92f59680c4f4 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 21:56:17 +0100 Subject: [PATCH 0255/2686] Clear theme cache after its edition in admin part --- onyx/include/admin/exercice.php | 1 + 1 file changed, 1 insertion(+) diff --git a/onyx/include/admin/exercice.php b/onyx/include/admin/exercice.php index b007d591..1259b9f5 100644 --- a/onyx/include/admin/exercice.php +++ b/onyx/include/admin/exercice.php @@ -45,6 +45,7 @@ try } $exercice->update(); + Cache::del("ordered_th".$exercice->theme->get_id()); header("Location: /".implode("/", $p)); exit(); } From bbd82406f907d663f640573c88fe92a42e7dbb31 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 21:56:37 +0100 Subject: [PATCH 0256/2686] Optimize exercice numbering --- onyx/include/common/Exercice.class.php | 36 ++++++++++++++------------ 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/onyx/include/common/Exercice.class.php b/onyx/include/common/Exercice.class.php index ad6a8b24..eef3827b 100644 --- a/onyx/include/common/Exercice.class.php +++ b/onyx/include/common/Exercice.class.php @@ -178,26 +178,28 @@ class Exercice { if ($this->require == "") $this->number = 1; - - $db = new BDD(); - - $exo = $this->id; - $ret = 0; - - $checked = array(); - - do + else { - array_push($checked, $exo); - $db->escape($exo); - $res = $db->unique_query("SELECT `require` FROM exercices WHERE id = '".$exo."'"); - $exo = $res['require']; - $ret++; - } while ($exo != "" && !in_array($exo, $checked)); + $db = new BDD(); - $this->number = $ret; + $exo = $this->id; + $ret = 0; - $db->deconnexion(); + $checked = array(); + + do + { + array_push($checked, $exo); + $db->escape($exo); + $res = $db->unique_query("SELECT `require` FROM exercices WHERE id = '".$exo."'"); + $exo = $res['require']; + $ret++; + } while ($exo != "" && !in_array($exo, $checked)); + + $this->number = $ret; + + $db->deconnexion(); + } } function update($create=false) From 8e7273fa88aa93de27846d368162bdd012256e4d Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 22:10:25 +0100 Subject: [PATCH 0257/2686] In deamon mode, argument on CLI are executed first --- gen_site.pl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gen_site.pl b/gen_site.pl index 17928f21..8914b597 100755 --- a/gen_site.pl +++ b/gen_site.pl @@ -393,6 +393,10 @@ if ($deamon) threads->create(\&create_socket, $m, $socket) if ($socket); + while ($_ = shift) { + parse($m, $_); + } + while(<>) { chomp $_; From 6012021caf301fba54e9252ab1a733aea306d6f2 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 22:16:00 +0100 Subject: [PATCH 0258/2686] Generate pages on launch --- Dockerfile | 4 ++-- gen_hash_link_files.sh | 6 ++++++ launch.sh | 2 +- launch_local.sh | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 80617e9b..499f826b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,7 +41,7 @@ RUN cd /var/www/fic-server/misc; bash ./CA.sh -newca RUN service mysql start && echo "CREATE DATABASE fic;" | mysql -u root && cat /var/www/fic-server/db/fic2014.sql | mysql -u root fic # Uncomment the following line to fill with random values -#RUN cat /var/www/fic-server/db/feed.sql | mysql -u root fic +#RUN service mysql start && cat /var/www/fic-server/db/feed.sql | mysql -u root fic # Configure site ###################################################### @@ -54,4 +54,4 @@ RUN chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/tem # ENVIRONNEMENT ####################################################### EXPOSE 80/tcp 443/tcp -CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; service nginx start && service php5-fpm start && service mysql start && /bin/bash"] +CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; service nginx start && service php5-fpm start && service mysql start && mkdir files && ./gen_hash_link_files.sh files-in files && ./launch_local.sh & /bin/bash"] diff --git a/gen_hash_link_files.sh b/gen_hash_link_files.sh index 2cb4873a..a189a623 100755 --- a/gen_hash_link_files.sh +++ b/gen_hash_link_files.sh @@ -1,5 +1,11 @@ #!/bin/bash +if [ $# -lt 2 ] +then + echo "Usage: $0 from to" + exit 1 +fi + FROM=`realpath $1`; shift TO=`realpath $1`; shift diff --git a/launch.sh b/launch.sh index bf5f15ef..aabe646f 100755 --- a/launch.sh +++ b/launch.sh @@ -22,7 +22,7 @@ KP1=$! TMPF=`mktemp` -tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/test.sock -o ./out & +tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/test.sock -o ./out ERRORS HOME all DS & KP2=$! while ! [ -f /tmp/stop ]; diff --git a/launch_local.sh b/launch_local.sh index b86be2c2..d4850c12 100755 --- a/launch_local.sh +++ b/launch_local.sh @@ -22,7 +22,7 @@ KP1=$! TMPF=`mktemp` -tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/test.sock -bt /challenge/ -ba /challenge-admin/ -o ./out & +tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/test.sock -bt /challenge/ -ba /challenge-admin/ -o ./out ERRORS HOME all DS & KP2=$! while ! [ -f /tmp/stop ]; From cc02495886d2b04a82e19aa601ebbc13f392db14 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 22:54:42 +0100 Subject: [PATCH 0259/2686] Setup volume to share with others containers --- Dockerfile | 3 ++- TODO | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 499f826b..3cd4a660 100644 --- a/Dockerfile +++ b/Dockerfile @@ -54,4 +54,5 @@ RUN chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/tem # ENVIRONNEMENT ####################################################### EXPOSE 80/tcp 443/tcp -CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; service nginx start && service php5-fpm start && service mysql start && mkdir files && ./gen_hash_link_files.sh files-in files && ./launch_local.sh & /bin/bash"] +VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submissions"] +CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; service nginx start && service php5-fpm start && service mysql start && mkdir files && ../gen_hash_link_files.sh ../files-in ../files && (../launch_local.sh &); /bin/bash"] diff --git a/TODO b/TODO index 667bda0b..4471d2db 100644 --- a/TODO +++ b/TODO @@ -8,3 +8,4 @@ - versionner la DTD et la doc associée - valider les documents avec la DTD à l'import - Lors de l'import des XML, retirer l'éventuel / en début de path +- Dockerfile de simulation de frontend From e89582bec4806d25c701cc49ae9e36259bb5d5ed Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 22:55:31 +0100 Subject: [PATCH 0260/2686] Avoid removing root tree directory --- gen_hash_link_files.sh | 2 +- gen_site.pl | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/gen_hash_link_files.sh b/gen_hash_link_files.sh index a189a623..1711fe60 100755 --- a/gen_hash_link_files.sh +++ b/gen_hash_link_files.sh @@ -20,7 +20,7 @@ then fi mkdir -p "$TO" || exit 3 -rm -rf "$TO" || exit 3 +rm -rf "$TO/*" || exit 3 for i in `find "$FROM" -mindepth 1 -type f` do diff --git a/gen_site.pl b/gen_site.pl index 8914b597..45175a4c 100755 --- a/gen_site.pl +++ b/gen_site.pl @@ -250,8 +250,7 @@ sub sync abs_path($main::outdir); abs_path($tmpcopy); - remove_tree($main::outdir); - mkdir($main::outdir); + remove_tree($main::outdir, {keep_root => 1}); system("mv '$tmpcopy'/* '$main::outdir/'"); } From f884d42e30c617d1399cd1d9172ae176974d0603 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 23:00:00 +0100 Subject: [PATCH 0261/2686] Updating TODO --- TODO | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TODO b/TODO index 4471d2db..2d7c5a11 100644 --- a/TODO +++ b/TODO @@ -9,3 +9,5 @@ - valider les documents avec la DTD à l'import - Lors de l'import des XML, retirer l'éventuel / en début de path - Dockerfile de simulation de frontend +- Au moment du lancement du chrono, ouvrir la socket de communication avec le scheduler et lui ajouter la directive all:S pour regénérer toutes les équipes +- On peut encore soumettre après la fin... From 65edeb149dc729a1657d9251a606852fc05755c5 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 20 Nov 2014 23:09:05 +0100 Subject: [PATCH 0262/2686] Install Mcrypt through cpanm --- Dockerfile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Dockerfile b/Dockerfile index 3cd4a660..005f30cf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,9 +20,14 @@ RUN apt-get -y update && \ libdigest-whirlpool-perl \ pwgen \ openssl \ + cpanminus \ + build-essential \ + libltdl-dev \ && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +RUN cpanm Mcrypt + # Copying files ####################################################### ADD . /var/www/fic-server/ From 84c3fdd8fafb636a22ea21593b2724c2ca88b2a8 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 10:20:59 +0100 Subject: [PATCH 0263/2686] Catch some SIG to kill sons --- launch.sh | 2 ++ launch_local.sh | 2 ++ 2 files changed, 4 insertions(+) diff --git a/launch.sh b/launch.sh index aabe646f..f99b81e4 100755 --- a/launch.sh +++ b/launch.sh @@ -25,6 +25,8 @@ TMPF=`mktemp` tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/test.sock -o ./out ERRORS HOME all DS & KP2=$! +trap "kill $KP1 $KP2; rm -rf '$TMPF'; echo" SIGINT SIGTERM + while ! [ -f /tmp/stop ]; do ./synchro.sh delete diff --git a/launch_local.sh b/launch_local.sh index d4850c12..87b5a8f1 100755 --- a/launch_local.sh +++ b/launch_local.sh @@ -25,6 +25,8 @@ TMPF=`mktemp` tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/test.sock -bt /challenge/ -ba /challenge-admin/ -o ./out ERRORS HOME all DS & KP2=$! +trap "kill $KP1 $KP2; rm -rf '$TMPF'; echo" SIGINT SIGTERM + while ! [ -f /tmp/stop ]; do if [ `ls submission | wc -l` -gt 1 ] From 016d530b5783b08f3a2180418bb6871a5d67c037 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 10:24:13 +0100 Subject: [PATCH 0264/2686] Make raw copy or hardlink instead of symlink, mainly for container test usage --- Dockerfile | 2 +- gen_hash_link_files.sh | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 005f30cf..844c0529 100644 --- a/Dockerfile +++ b/Dockerfile @@ -60,4 +60,4 @@ RUN chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/tem EXPOSE 80/tcp 443/tcp VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submissions"] -CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; service nginx start && service php5-fpm start && service mysql start && mkdir files && ../gen_hash_link_files.sh ../files-in ../files && (../launch_local.sh &); /bin/bash"] +CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; service nginx start && service php5-fpm start && service mysql start && mkdir files && ../gen_hash_link_files.sh --copy ../files-in ../files && (../launch_local.sh &); /bin/bash"] diff --git a/gen_hash_link_files.sh b/gen_hash_link_files.sh index 1711fe60..5daba142 100755 --- a/gen_hash_link_files.sh +++ b/gen_hash_link_files.sh @@ -6,6 +6,18 @@ then exit 1 fi +if [ "$1" = "--hard" ] +then + LN="ln" + shift +elif [ "$1" = "--copy" ] +then + LN="cp" + shift +else + LN="ln -s" +fi + FROM=`realpath $1`; shift TO=`realpath $1`; shift @@ -28,5 +40,5 @@ do HASH=`echo -n $FILE | sha384sum | cut -d " " -f 1` mkdir -p "$TO/$HASH/" - ln -s "$i" "$TO/$HASH/" + $LN "$i" "$TO/$HASH/" done From 6c69867bcc59cdc1652da9a7b5fcdb6a843fdc73 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 12:47:10 +0100 Subject: [PATCH 0265/2686] Document backend launch --- README.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cf6efbea..44b4a67d 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,14 @@ Use `docker ps` to view to which local ports was assigned the contained webserver. +### Database + +Demo data are available in `/var/www/fic-server/db/feed.sql`. In test +environment, you can run the following command: + + mysql -u root fic < /var/www/fic-server/db/feed.sql + + Production Environnement ------------------------ @@ -88,6 +96,18 @@ CONNTRACK states. `build-essential`) to decrypt submissions (see https://metacpan.org/pod/Mcrypt); +##### Files distribution + +You need to manually place challenge given files in the tree. To avoid path +guessing, files path are hashed. To generate hashed paths, use the script +`gen_hash_link_files.sh`: + + mkdir $TO + ./gen_hash_link_files.sh FROM TO + +Where `FROM` is the directory with the orignal tree and `TO` the directory +where placed symlink. + ##### Firewall rules This machine shouldn't have any network connection, except outgoing one to the @@ -98,14 +118,27 @@ frontend for synchronization. Indicate in `/etc/hosts.conf` IP(s) of the frontend. +### Run + +Two scripts are available, depending if directories synchronization has to be +made or not. + +You don't need to handle synchronization if it's done by a separate container +or if frontend is linked to backend. + +The `launch.sh` and `launch_local.sh` scripts do all backend stuff for you: +synchronization with frontend (only `launch.sh`), submission checking and +smart static pages regeneration. + + ### History #### FIC2014 -Two machines were used : one for backend (Deimos) and one for frontend -(Phobos). They ran a GNU/Linux Gentoo Hardened with custom 3.2 kernel without -module loading, unused and unecessary components and with all GrSecurity -features activated. +Two machines (DC7900: Core 2 Quad) were used : one for backend (Deimos) and one +for frontend (Phobos). They ran a GNU/Linux Gentoo Hardened with custom 3.2 +kernel without module loading, unused and unecessary components and with all +GrSecurity features activated. Each machine was two network interfaces: one was used to permit to the backend machine to connect to the frontend (over IPv6). The second interface on the @@ -113,8 +146,20 @@ backend was used for administration purpose (with a laptop not connected to Internet). The second interface on the frontend was used to provide network connectivity to participants. +Both frontend and backend were 2 500GB hard-drives with software RAID1. The +whole logical RAID disk was LUKS encrypted using Serpent algorithm. + The D Day --------- +### Interact with the scheduler + +When you launch `launch.sh` or `launch_local.sh` script, a socket is open at +`/tmp/test.sock`. Use `perl comm-socket.pl /tmp/test.sock` to connect to the +scheduler. Consult `gen_site.pl` manual (`perldoc gen_site.pl`) for list of +available instructions. + +### More + TODO From bca09af2e02cbed50a79e4af85c33e47bbf92411 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 15:55:38 +0100 Subject: [PATCH 0266/2686] Add a Dockerfile for frontend test container; adapt code to simplify synchronization or Docker linkage --- Dockerfile | 5 +- README.md | 8 ++ front/Dockerfile | 30 +++++ front/nginx.conf | 108 ++++++++++++++++++ front/php-fpm.conf | 81 ++++++++++++++ submission.php => front/submission.php | 6 +- misc/CA.sh | 145 ++++++++++++++----------- misc/openssl.cnf | 4 +- nginx-server.conf | 11 +- nginx.conf | 131 ---------------------- nginx_gen_team.sh | 4 +- onyx/include/admin/home.php | 4 +- onyx/include/admin/import_users.php | 2 +- onyx/include/team/exercice.php | 2 +- synchro.sh | 6 +- 15 files changed, 329 insertions(+), 218 deletions(-) create mode 100644 front/Dockerfile create mode 100644 front/nginx.conf create mode 100644 front/php-fpm.conf rename submission.php => front/submission.php (88%) delete mode 100644 nginx.conf mode change 100644 => 100755 nginx_gen_team.sh diff --git a/Dockerfile b/Dockerfile index 844c0529..ab173c72 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,6 +19,7 @@ RUN apt-get -y update && \ libwww-perl \ libdigest-whirlpool-perl \ pwgen \ + curl \ openssl \ cpanminus \ build-essential \ @@ -59,5 +60,5 @@ RUN chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/tem # ENVIRONNEMENT ####################################################### EXPOSE 80/tcp 443/tcp -VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submissions"] -CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; service nginx start && service php5-fpm start && service mysql start && mkdir files && ../gen_hash_link_files.sh --copy ../files-in ../files && (../launch_local.sh &); /bin/bash"] +VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submission","/var/www/fic-server/misc/shared"] +CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then ./CA.sh -newserver; fi; ./CA.sh -gencrl && service nginx start && service php5-fpm start && service mysql start && ../gen_hash_link_files.sh --copy ../files-in ../files && ../nginx_gen_team.sh > ../misc/shared/nginx-teams.conf && (../launch_local.sh &); /bin/bash"] diff --git a/README.md b/README.md index 44b4a67d..f82ac010 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,14 @@ environment, you can run the following command: mysql -u root fic < /var/www/fic-server/db/feed.sql +### Frontend container + +To run the frontend on the same machine as the backend (but in another +container), run the following command: + + docker run -P -ti --volumes-from BACKEND_CNTNR_NAME FRONTEND_IMG + + Production Environnement ------------------------ diff --git a/front/Dockerfile b/front/Dockerfile new file mode 100644 index 00000000..833e9d89 --- /dev/null +++ b/front/Dockerfile @@ -0,0 +1,30 @@ +# DOCKER-VERSION 1.1.0 + +# /!\ WARNING: the container generated through this Dockerfile is made only for development purpose; it is NOT SAFE or production ready. + +FROM debian:wheezy +MAINTAINER Pierre-Olivier Mercier + +# Install packages #################################################### + +RUN apt-get -y update && \ + apt-get install -y \ + nginx-full \ + php5-fpm \ + php5-mcrypt \ + && \ + apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# Copying files ####################################################### + +ADD . /var/www/fic-server/front/ + +# Configure softwares ################################################# + +RUN ln -sf /var/www/fic-server/front/nginx.conf /etc/nginx/sites-enabled/default +RUN ln -sf /var/www/fic-server/front/php-fpm.conf /etc/php5/fpm/pool.d/www.conf + +# ENVIRONNEMENT ####################################################### + +EXPOSE 80/tcp 443/tcp +CMD ["sh", "-c", "service nginx start && service php5-fpm start && /bin/bash"] diff --git a/front/nginx.conf b/front/nginx.conf new file mode 100644 index 00000000..2760600e --- /dev/null +++ b/front/nginx.conf @@ -0,0 +1,108 @@ +server_tokens off; +client_header_buffer_size 512; +client_max_body_size 512; + +server { + listen 80 default; + listen [::]:80 ipv6only=on default; + + rewrite ^ https://$host$uri; +} + +server { + listen 443 ssl; + listen [::]:443 ipv6only=on ssl; + + root /var/www/fic-server/out/htdocs/; + + access_log /var/log/nginx/fic.access_log; + error_log /var/log/nginx/fic.error_log; + + ssl_certificate /var/www/fic-server/misc/shared/server.crt; + ssl_certificate_key /var/www/fic-server/misc/shared/server.key; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; +# ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; + ssl_ciphers AES256+EECDH:AES256+EDH; + ssl_client_certificate /var/www/fic-server/misc/shared/cacert.crt; + ssl_verify_client optional; + ssl_crl /var/www/fic-server/misc/shared/crl.pem; + + add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; + add_header X-Frame-Options DENY; + add_header X-Content-Type-Options nosniff; + + error_page 400 /errors/400/index.html; + error_page 403 /errors/403/index.html; + error_page 404 /errors/404/index.html; + error_page 413 414 /errors/413/index.html; + error_page 500 503 /errors/500/index.html; + error_page 502 504 /errors/502/index.html; + + location / + { + default_type text/html; + expires epoch; + + set $team 0; + + include /var/www/fic-server/misc/shared/nginx-teams.conf; + + if ($team) { + root /var/www/fic-server/out/teams/$team$1; + rewrite ^/([0-9]+-?[a-zA-Z0-9_-]*)/([a-zA-Z0-9_]+)/submission$ /submission.php?team=$team&theme=$1&exercice=$2 last; + } + if ($team = 0) { + root /var/www/fic-server/out/htdocs/; + } + } + + location /errors + { + root /var/www/fic-server/out/; + } + + location /connected + { + return 403; + } + + location /files + { + root /var/www/fic-server/; + + # option to accelerate file delivery, require a custom nginx + #aio on; + directio 512; + output_buffers 1 128k; + } + + location ~* \favicon.ico$ { + root /var/www/fic-server/out/htdocs/; + access_log off; + expires 1d; + add_header Cache-Control public; + } + + location ~ ^/(assets|img|js|css|fonts)/ { + root /var/www/fic-server/out/htdocs/; + access_log off; + expires 7d; + add_header Cache-Control public; + } + + location ~ /(\.ht|\.git|\.svn|\.onyx) { + return 403; + } + + location /submission.php + { + root /var/www/fic-server/front/; + + limit_rate 4k; + + include /etc/nginx/fastcgi_params; + fastcgi_pass unix:/var/run/php-fpm.sock; + break; + } +} diff --git a/front/php-fpm.conf b/front/php-fpm.conf new file mode 100644 index 00000000..e972ebe8 --- /dev/null +++ b/front/php-fpm.conf @@ -0,0 +1,81 @@ +; Start a new pool named 'www'. +; the variable $pool can we used in any directive and will be replaced by the +; pool name ('www' here) +[www] + +; Unix user/group of processes +; Note: The user is mandatory. If the group is not set, the default user's group +; will be used. +user = www-data +group = www-data + +; The address on which to accept FastCGI requests. +; Valid syntaxes are: +; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on +; a specific port; +; 'port' - to listen on a TCP socket to all addresses on a +; specific port; +; '/path/to/unix/socket' - to listen on a unix socket. +; Note: This value is mandatory. +listen = /var/run/php-fpm.sock + +; Set permissions for unix socket, if one is used. In Linux, read/write +; permissions must be set in order to allow connections from a web server. Many +; BSD-derived systems allow connections regardless of permissions. +; Default Values: user and group are set as the running user +; mode is set to 0666 +listen.owner = www-data +listen.group = www-data +listen.mode = 0640 + +; Choose how the process manager will control the number of child processes. +; Possible Values: +; static - a fixed number (pm.max_children) of child processes; +; dynamic - the number of child processes are set dynamically based on the +; following directives. With this process management, there will be +; always at least 1 children. +; pm.max_children - the maximum number of children that can +; be alive at the same time. +; pm.start_servers - the number of children created on startup. +; pm.min_spare_servers - the minimum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is less than this +; number then some children will be created. +; pm.max_spare_servers - the maximum number of children in 'idle' +; state (waiting to process). If the number +; of 'idle' processes is greater than this +; number then some children will be killed. +; ondemand - no children are created at startup. Children will be forked when +; new requests will connect. The following parameter are used: +; pm.max_children - the maximum number of children that +; can be alive at the same time. +; pm.process_idle_timeout - The number of seconds after which +; an idle process will be killed. +; Note: This value is mandatory. +pm = dynamic + +; The number of child processes to be created when pm is set to 'static' and the +; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'. +; This value sets the limit on the number of simultaneous requests that will be +; served. Equivalent to the ApacheMaxClients directive with mpm_prefork. +; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP +; CGI. The below defaults are based on a server without much resources. Don't +; forget to tweak pm.* to fit your needs. +; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand' +; Note: This value is mandatory. +pm.max_children = 200 + +; The number of child processes created on startup. +; Note: Used only when pm is set to 'dynamic' +; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2 +pm.start_servers = 10 + +; The desired minimum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.min_spare_servers = 5 + +; The desired maximum number of idle server processes. +; Note: Used only when pm is set to 'dynamic' +; Note: Mandatory when pm is set to 'dynamic' +pm.max_spare_servers = 10 diff --git a/submission.php b/front/submission.php similarity index 88% rename from submission.php rename to front/submission.php index f99d2386..7897d759 100644 --- a/submission.php +++ b/front/submission.php @@ -5,15 +5,15 @@ if (!function_exists("show_submission_result")) { function show_submission_result($path) { - if (file_exists(__DIR__."/teams/".$path."/index.html")) - print file_get_contents(__DIR__."/teams/".$path."/index.html"); + if (file_exists(__DIR__."/../out/teams/".$path."/index.html")) + print file_get_contents(__DIR__."/../out/teams/".$path."/index.html"); else header("HTTP/1.1 403 Forbidden"); } } $filename = intval($_GET["team"])."-".intval($_GET["theme"])."-".urlencode($_GET["exercice"]); -$file = __DIR__."/submission/".$filename; +$file = __DIR__."/../submission/".$filename; if (file_exists($file)) diff --git a/misc/CA.sh b/misc/CA.sh index 45fd2f7f..d5248ce7 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -10,10 +10,15 @@ if [ -z "${OPENSSL_CONF}" ]; then OPENSSL_CONF=openssl.cnf fi -CAKEY=./cakey.key -CAREQ=./careq.csr -CACERT=./cacert.crt +CAKEY=${TOP_DIR}/private/cakey.key +CAREQ=${TOP_DIR}/careq.csr +CACRT=./shared/cacert.crt +SRVKEY=./shared/server.key +SRVREQ=./shared/server.csr +SRVCRT=./shared/server.crt + +# Generate certificates valid for: DAYS=2 if [ -z "$PS1" ] @@ -42,12 +47,13 @@ usage() clean() { if [ "$1" = "ca" ]; then - rm -rf ${TOP_DIR} + rm -rf ${TOP_DIR} ./shared/* mkdir -p ${TOP_DIR}/certs mkdir -p ${TOP_DIR}/crl mkdir -p ${TOP_DIR}/newcerts mkdir -p ${TOP_DIR}/private mkdir -p ${TOP_DIR}/pkcs + mkdir -p ./shared echo "01" > ${TOP_DIR}/crlnumber elif [ "$1" = "client" ]; then rm -rf ${TOP_DIR}/${2}.key ${TOP_DIR}/${2}.csr @@ -57,10 +63,10 @@ clean() gen_crl() { - echo $ECHO_OPTS "${GREEN}Generate crl.pem${COLOR_RST}" - openssl ca -config ${OPENSSL_CONF} -gencrl -out ${TOP_DIR}/crl.pem > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then - echo $ECHO_OPTS "${RED}Generate crl.pem failed" + echo $ECHO_OPTS "${GREEN}Generate shared/crl.pem${COLOR_RST}" + if ! openssl ca -config ${OPENSSL_CONF} -gencrl -out shared/crl.pem > $OUTPUT 2>&1 + then + echo $ECHO_OPTS "${RED}Generate shared/crl.pem failed" cat $OUTPUT exit 5 fi @@ -72,9 +78,7 @@ OUTPUT=$(mktemp) case $1 in "-newca" ) - echo -n $ECHO_OPTS "${GREEN}Create the directories, take care this will delete" - echo $ECHO_OPTS " the old directories ${COLOR_RST}" -# sleep 1; echo -n "1 "; sleep 1; echo -n "2 "; sleep 1; echo "3" + echo $ECHO_OPTS "${GREEN}Create the directories, take care this will delete the old directories ${COLOR_RST}" clean "ca" touch ${TOP_DIR}/index.txt @@ -92,30 +96,30 @@ case $1 in fi pass=`pwgen -n -B -y 12 1` - openssl req -batch -new -keyout ${TOP_DIR}/private/${CAKEY} \ - -out ${TOP_DIR}/${CAREQ} -passout pass:$pass \ - -config $OPENSSL_CONF -extensions CORE_CA > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then + if ! openssl req -batch -new -keyout ${CAKEY} \ + -out ${CAREQ} -passout pass:$pass \ + -config ${OPENSSL_CONF} -extensions CORE_CA > $OUTPUT 2>&1 + then cat $OUTPUT clean "ca" exit 4 fi # This line deleted the passphase for the FIC 2014 automatisation - openssl rsa -passin pass:$pass -in ${TOP_DIR}/private/${CAKEY} \ - -out ${TOP_DIR}/private/${CAKEY} > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then + if ! openssl rsa -passin pass:$pass -in ${CAKEY} \ + -out ${CAKEY} > $OUTPUT 2>&1 + then cat $OUTPUT clean "ca" exit 4 fi echo $ECHO_OPTS "${GREEN}Self signes the CA certificate${COLOR_RST}" - openssl ca -batch -create_serial -out ${TOP_DIR}/${CACERT} \ - -days ${DAYS} -keyfile ${TOP_DIR}/private/${CAKEY} \ - -selfsign -extensions CORE_CA -config ${OPENSSL_CONF} \ - -infiles ${TOP_DIR}/${CAREQ} > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then + if ! openssl ca -batch -create_serial -out ${CACRT} \ + -days ${DAYS} -keyfile ${CAKEY} \ + -selfsign -extensions CORE_CA -config ${OPENSSL_CONF} \ + -infiles ${CAREQ} > $OUTPUT 2>&1 + then cat $OUTPUT clean "ca" exit 4 @@ -124,46 +128,45 @@ case $1 in "-newserver" ) echo $ECHO_OPTS "${GREEN}Making the Server key and cert${COLOR_RST}" - if ! [ -f ${TOP_DIR}/private/${CAKEY} ]; then + if ! [ -f ${CAKEY} ]; then echo $ECHO_OPTS "${RED}Can not found the CA's key${COLOR_RST}" exit 2 fi sed -i 's/=.*#COMMONNAME/=10.226.3.70#COMMONNAME/' $OPENSSL_CONF - openssl req -batch -new -keyout server.key -out server.csr \ - -days ${DAYS} -config ${OPENSSL_CONF} -extensions SERVER_SSL > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then + if ! openssl req -batch -new -keyout ${SRVKEY} -out ${SRVREQ} \ + -days ${DAYS} -config ${OPENSSL_CONF} -extensions SERVER_SSL > $OUTPUT 2>&1 + then cat $OUTPUT exit 4 fi echo $ECHO_OPTS "${GREEN}Signing the Server crt${COLOR_RST}" - openssl ca -policy policy_match -config ${OPENSSL_CONF} \ - -out server.crt -extensions SERVER_SSL -infiles server.csr - if [ $? -ne 0 ]; then + if ! openssl ca -policy policy_match -config ${OPENSSL_CONF} \ + -out ${SRVCRT} -extensions SERVER_SSL -infiles ${SRVREQ} + then echo $ECHO_OPTS "${RED}Signing failed for new server${COLOR_RST}" - rm -rf server.key server.crt server.csr + rm -f ${SRVKEY} ${SRVREQ} ${SRVCRT} cat $OUTPUT exit 3 else - rm server.csr # remove ? - echo $ECHO_OPTS "${GREEN}Signed certificate is in server.crt${COLOR_RST}" + rm ${SRVREQ} + echo $ECHO_OPTS "${GREEN}Signed certificate is in ${SRVCRT}${COLOR_RST}" fi ;; "-revokeserver" ) echo $ECHO_OPTS "${GREEN}Revocate server certificate${COLOR_RST}" - if ! [ -f ${TOP_DIR}/private/${CAKEY} ]; then + if ! [ -f ${CAKEY} ]; then echo $ECHO_OPTS "${RED}Can not found the CA's key${COLOR_RST}" exit 2 fi - openssl ca -revoke server.crt -config ${OPENSSL_CONF}\ - -keyfile ${TOP_DIR}/private/${CAKEY} \ - -cert ${TOP_DIR}/${CACERT} > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then + if ! openssl ca -revoke ${SRVCRT} -config ${OPENSSL_CONF} \ + -keyfile ${CAKEY} -cert ${CACRT} > $OUTPUT 2>&1 + then echo $ECHO_OPTS "${RED}Server certificate revocation failed${COLOR_RST}" cat $OUTPUT exit 4 fi - rm server.crt server.key + rm ${SRVKEY} ${SRVCRT} gen_crl ;; @@ -173,13 +176,20 @@ case $1 in echo "Usage: $0 -newclient NAME" exit 1 fi + + CLTNAM=$2 + CLTREQ=${TOP_DIR}/${CLTNAM}.csr + CLTCRT=${TOP_DIR}/${CLTNAM}.crt + CLTKEY=${TOP_DIR}/${CLTNAM}.key + CLTP12=${TOP_DIR}/pkcs/${CLTNAM}.p12 + echo "==============================================================" echo $ECHO_OPTS "${GREEN}Making the client key and csr of ${BOLD}${2}${END_BOLD}${COLOR_RST}" ESCAPED=$(echo "${TOP_DIR}" | sed 's/[\/\.]/\\&/g') sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF - if ! [ -f ${TOP_DIR}/private/${CAKEY} ]; then + if ! [ -f ${CAKEY} ]; then echo $ECHO_OPTS "${RED}Can not found the CA's key${COLOR_RST}" exit 2 fi @@ -193,39 +203,39 @@ case $1 in pass=`pwgen -n -B -y 12 1` - openssl req -batch -new -keyout ${TOP_DIR}/${2}.key -out ${TOP_DIR}/${2}.csr \ - -config ${OPENSSL_CONF} -passout pass:$pass -days ${DAYS} -extensions CLIENT_SSL > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then + if ! openssl req -batch -new -keyout "${CLTKEY}" -out "${CLTREQ}" \ + -config ${OPENSSL_CONF} -passout pass:$pass -days ${DAYS} -extensions CLIENT_SSL > $OUTPUT 2>&1 + then cat $OUTPUT - clean "client" $2 + clean "client" ${CLTNAM} exit 4 fi echo $ECHO_OPTS "${GREEN}Signing the Client crt${COLOR_RST}" - openssl ca -batch -policy policy_match -out ${TOP_DIR}/${2}.crt \ - -config ${OPENSSL_CONF} -extensions CLIENT_SSL -infiles ${TOP_DIR}/${2}.csr > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then + if ! openssl ca -batch -policy policy_match -out "${CLTCRT}" \ + -config ${OPENSSL_CONF} -extensions CLIENT_SSL -infiles "${CLTREQ}" > $OUTPUT 2>&1 + then echo $ECHO_OPTS "${RED}Signing failed for $2 ${COLOR_RST}" cat $OUTPUT - clean "client" $2 + clean "client" ${CLTNAM} exit 3 fi echo $ECHO_OPTS "${GREEN}Export the Client files to pkcs12${COLOR_RST}" - openssl pkcs12 -export -inkey ${TOP_DIR}/${2}.key -in ${TOP_DIR}/${2}.crt -name ${2} \ - -passin pass:$pass -out ${TOP_DIR}/pkcs/${2}.p12 \ - -passout pass:$pass > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then + if ! openssl pkcs12 -export -inkey "${CLTKEY}" -in "${CLTCRT}" -name ${2} \ + -passin pass:$pass -out "${CLTP12}" \ + -passout pass:$pass > $OUTPUT 2>&1 + then echo $ECHO_OPTS "${RED}pkcs12 export failed for ${BOLD}$2${END_BOLD}${COLOR_RST}" cat $OUTPUT - clean "client" $2 + clean "client" ${CLTNAM} exit 4 else - echo $ECHO_OPTS "Exported pkcs12 file is ${2}.p12" + echo $ECHO_OPTS "Exported pkcs12 file is ${CLTP12}" fi - mv ${TOP_DIR}/${2}.crt ${TOP_DIR}/certs - echo "$2:$pass" >> ${TOP_DIR}/../teams.pass - echo "$pass" - clean "client" $2 + mv ${CLTCRT} ${TOP_DIR}/certs + echo "$CLTNAM:$pass" >> ${TOP_DIR}/../teams.pass + echo "$CLTNAM:$pass" + clean "client" ${CLTNAM} ;; "-revoke" ) @@ -233,17 +243,20 @@ case $1 in echo "Usage: $0 -revoke NAME" exit 1 fi - echo $ECHO_OPTS "${GREEN}Revocate ${BOLD}${2}${END_BOLD}${COLOR_RST}" - openssl ca -revoke ${TOP_DIR}/certs/${2}.crt -config ${OPENSSL_CONF}\ - -keyfile ${TOP_DIR}/private/${CAKEY} \ - -cert ${TOP_DIR}/${CACERT} > $OUTPUT 2>&1 - if [ $? -ne 0 ]; then - echo $ECHO_OPTS "${RED}Revocation failed for ${BOLD}${2}${END_BOLD}${COLOR_RST}" + + CLTNAM=$2 + CLTCRT=${TOP_DIR}/${CLTNAM}.crt + CLTP12=${TOP_DIR}/pkcs/${CLTNAM}.p12 + + echo $ECHO_OPTS "${GREEN}Revocate ${BOLD}${CLTNAM}${END_BOLD}${COLOR_RST}" + if ! openssl ca -revoke ${CLTCRT} -config ${OPENSSL_CONF}\ + -keyfile ${CAKEY} -cert ${CACRT} > $OUTPUT 2>&1 + then + echo $ECHO_OPTS "${RED}Revocation failed for ${BOLD}${CLTNAM}${END_BOLD}${COLOR_RST}" cat $OUTPUT exit 4 fi - rm ${TOP_DIR}/certs/${2}.crt - rm ${TOP_DIR}/pkcs/${2}.p12 + rm "${CLTCRT}" "${CLTP12}" gen_crl ;; diff --git a/misc/openssl.cnf b/misc/openssl.cnf index 1fc532fd..a90cd294 100644 --- a/misc/openssl.cnf +++ b/misc/openssl.cnf @@ -47,11 +47,11 @@ database = $dir/index.txt # database index file. # several ctificates with same subject. new_certs_dir = $dir/newcerts # default place for new certs. -certificate = $dir/cacert.crt # The CA certificate +certificate = $dir/../shared/cacert.crt # The CA certificate serial = $dir/serial # The current serial number crlnumber = $dir/crlnumber # the current crl number # must be commented out to leave a V1 CRL -crl = $dir/crl.pem # The current CRL +crl = $dir/../shared/crl.pem # The current CRL private_key = $dir/private/cakey.key # The private key RANDFILE = $dir/private/.rand # private random number file diff --git a/nginx-server.conf b/nginx-server.conf index 3e8e0cc3..250949e9 100644 --- a/nginx-server.conf +++ b/nginx-server.conf @@ -2,11 +2,12 @@ server { listen 443 ssl; listen [::]:443 ipv6only=on ssl; - ssl_certificate /var/www/fic-server/misc/server.crt; - ssl_certificate_key /var/www/fic-server/misc/server.key; -# ssl_protocols TLSv1 TLSv1.1 TLSv1.2; -# ssl_prefer_server_ciphers on; -# ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; + ssl_certificate /var/www/fic-server/misc/shared/server.crt; + ssl_certificate_key /var/www/fic-server/misc/shared/server.key; + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_prefer_server_ciphers on; +# ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; + ssl_ciphers AES256+EECDH:AES256+EDH; include /var/www/fic-server/nginx-server-common.conf; } diff --git a/nginx.conf b/nginx.conf deleted file mode 100644 index 170fd8f3..00000000 --- a/nginx.conf +++ /dev/null @@ -1,131 +0,0 @@ -server_tokens off; -client_header_buffer_size 512; -client_max_body_size 512; - -server { - listen 80 default; - listen [::]:80 ipv6only=on default; - - rewrite ^ https://$host$uri; -} - -server { - listen 443 ssl; - listen [::]:443 ipv6only=on ssl; - - root /var/www/fic-server/htdocs/; - - server_tokens off; - - access_log /var/log/nginx/fic.access_log; - error_log /var/log/nginx/fic.error_log; - - ssl_certificate /var/www/fic-server/server.crt; - ssl_certificate_key /var/www/fic-server/server.key; - ssl_protocols TLSv1 TLSv1.1 TLSv1.2; - ssl_prefer_server_ciphers on; -# ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; - ssl_ciphers AES256+EECDH:AES256+EDH; - ssl_client_certificate /var/www/fic-server/cacert.crt; - ssl_verify_client optional; - ssl_crl /var/www/fic-server/crl.pem; - - add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; - add_header X-Frame-Options DENY; - add_header X-Content-Type-Options nosniff; - - error_page 400 /errors/400/index.html; - error_page 403 /errors/403/index.html; - error_page 404 /errors/404/index.html; - error_page 413 414 /errors/413/index.html; - error_page 500 503 /errors/500/index.html; - error_page 502 504 /errors/502/index.html; - - location / - { - default_type text/html; - expires epoch; - - set $team 0; - - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Amin_Martin/") { set $team 343; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Bernard_Angoustures/") { set $team 344; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Cacace_Diallo/") { set $team 345; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Delaporte_Notebaert/") { set $team 346; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Dibe/") { set $team 347; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Dubief_Roccia/") { set $team 348; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Ezzahoui/") { set $team 349; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Fall/") { set $team 350; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Guerin_Chapiron/") { set $team 351; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Hugot_Hincelin/") { set $team 352; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Jawor_Giraud/") { set $team 353; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Konan/") { set $team 354; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Le_Mignan_Yadaba/") { set $team 355; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Michel-villaz_Gzenayi/") { set $team 356; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Muller_Perrin/") { set $team 357; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Pourcelot/") { set $team 358; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Quint_Kaczmarek/") { set $team 359; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Ruff_Czarny/") { set $team 360; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Sinet_Girault/") { set $team 361; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Therrode/") { set $team 362; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Sabono_Calmeji/") { set $team 363; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=Renaud_Vandemeulebroucke/") { set $team 364; } - if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=De_Priest_Tjonck/") { set $team 365; } - - if ($team) { - root /var/www/fic-server/teams/$team$1; - rewrite ^/([0-9]+-?[a-zA-Z0-9_-]*)/([a-zA-Z0-9_]+)/submission$ /submission.php?team=$team&theme=$1&exercice=$2 last; - } - if ($team = 0) { - root /var/www/fic-server/htdocs/; - } - } - - location /errors - { - root /var/www/fic-server/; - } - - location /connected - { - return 403; - } - - location /files - { - root /var/www/fic-server/; - - aio on; - directio 512; - output_buffers 1 128k; - } - - location ~* \favicon.ico$ { - root /var/www/fic-server/htdocs/; - access_log off; - expires 1d; - add_header Cache-Control public; - } - - location ~ ^/(assets|img|js|css|fonts)/ { - root /var/www/fic-server/htdocs/; - access_log off; - expires 7d; - add_header Cache-Control public; - } - - location ~ /(\.ht|\.git|\.svn|\.onyx) { - return 403; - } - - location /submission.php - { - root /var/www/fic-server/; - - limit_rate 4k; - - include /etc/nginx/fastcgi.conf; - fastcgi_pass unix:/var/run/php-fpm.sock; - break; - } -} diff --git a/nginx_gen_team.sh b/nginx_gen_team.sh old mode 100644 new mode 100755 index 6347421c..5ac57349 --- a/nginx_gen_team.sh +++ b/nginx_gen_team.sh @@ -3,4 +3,6 @@ # Generate from database (exported XML from the website) the part of nginx # configuration file authenticating teams -curl http://localhost/admin/teams/export 2> /dev/null | grep "(.*)<.*$@ if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=\2/") { set $team \1; }@' +cd $(dirname "$0") + +curl http://localhost/$(grep prefix_admin onyx/config/root.xml | sed -E 's@.*(.*).*@\1@')/teams/export 2> /dev/null | grep "(.*)<.*$@ if ($ssl_client_s_dn ~ "/C=FR/ST=France/O=Epita/OU=SRS/CN=\2/") { set $team \1; }@' diff --git a/onyx/include/admin/home.php b/onyx/include/admin/home.php index 2297635a..9f1c1b71 100644 --- a/onyx/include/admin/home.php +++ b/onyx/include/admin/home.php @@ -22,7 +22,7 @@ if (is_writable($misc_dir) && !is_dir("$misc_dir/pki/")) $template->assign("cert_writable", is_writable("$misc_dir/pki/")); -$ca_file = "$misc_dir/pki/cacert.crt"; +$ca_file = "$misc_dir/shared/cacert.crt"; if (file_exists($ca_file)) { if (!is_readable($ca_file)) @@ -32,7 +32,7 @@ if (file_exists($ca_file)) openssl_x509_parse(file_get_contents($ca_file))); } -$srv_file = "$misc_dir/server.crt"; +$srv_file = "$misc_dir/shared/server.crt"; if (file_exists($srv_file)) { if (!is_readable($srv_file)) diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index dece7040..0a3342aa 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -14,7 +14,7 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) return "admin/import_users"; } - if (!file_exists("$misc_dir/pki/cacert.crt")) + if (!file_exists("$misc_dir/shared/cacert.crt")) { erreur("The root certificate file not found, please create this first"); return "admin/import_users"; diff --git a/onyx/include/team/exercice.php b/onyx/include/team/exercice.php index fa6af0d0..9bc2f90c 100644 --- a/onyx/include/team/exercice.php +++ b/onyx/include/team/exercice.php @@ -51,7 +51,7 @@ if (isset($VAR['submission_dir'])) $_GET["theme"] = $p[2]; $_GET["exercice"] = $p[3]; - require("../submission.php"); + require("../front/submission.php"); } // Fallback error diff --git a/synchro.sh b/synchro.sh index 8cebbb6d..aac801eb 100755 --- a/synchro.sh +++ b/synchro.sh @@ -21,11 +21,9 @@ then fi # Synchronize HTML pages -rsync -e ssh -av $OPTS out/errors "$FRONTEND_HOSTNAME":~/ -rsync -e ssh -av $OPTS out/htdocs "$FRONTEND_HOSTNAME":~/ -rsync -e ssh -av $OPTS out/teams "$FRONTEND_HOSTNAME":~/ +rsync -e ssh -av $OPTS out "$FRONTEND_HOSTNAME":~/ rsync -e ssh -avL $OPTS files "$FRONTEND_HOSTNAME":~/ -rsync -e ssh -av $OPTS nginx.conf submission.php misc/server.crt misc/server.key misc/pki/cacert.crt misc/pki/crl.pem "$FRONTEND_HOSTNAME":~/ +rsync -e ssh -av $OPTS front/ misc/shared/ "$FRONTEND_HOSTNAME":~/ # Synchronize submissions rsync -e ssh -av "$FRONTEND_HOSTNAME":~/submission/ submission/ From a23089d841cb9f4501443146b8ff9f790983e1e9 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 16:02:46 +0100 Subject: [PATCH 0267/2686] Don't in dev mode anymore --- onyx/tpl/bootstrap/layout.tpl | 1 - 1 file changed, 1 deletion(-) diff --git a/onyx/tpl/bootstrap/layout.tpl b/onyx/tpl/bootstrap/layout.tpl index a482e1ae..2556a186 100644 --- a/onyx/tpl/bootstrap/layout.tpl +++ b/onyx/tpl/bootstrap/layout.tpl @@ -20,7 +20,6 @@ {block name=head}{/block} - {block name=body} From 4a5f30f967629cbef2921940538a315213e5f472 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 22:39:39 +0100 Subject: [PATCH 0268/2686] Force bash on container launch --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index ab173c72..67eed903 100644 --- a/Dockerfile +++ b/Dockerfile @@ -61,4 +61,4 @@ RUN chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/tem EXPOSE 80/tcp 443/tcp VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submission","/var/www/fic-server/misc/shared"] -CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then ./CA.sh -newserver; fi; ./CA.sh -gencrl && service nginx start && service php5-fpm start && service mysql start && ../gen_hash_link_files.sh --copy ../files-in ../files && ../nginx_gen_team.sh > ../misc/shared/nginx-teams.conf && (../launch_local.sh &); /bin/bash"] +CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; bash ./CA.sh -gencrl && service nginx start && service php5-fpm start && service mysql start && echo "Copying files..." && ../gen_hash_link_files.sh --copy ../files-in ../files && ../nginx_gen_team.sh > ../misc/shared/nginx-teams.conf && (../launch_local.sh &); /bin/bash"] From 87c4275ba9471447cc1bddd48cd4306b48649954 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 22:39:45 +0100 Subject: [PATCH 0269/2686] Updating TODO --- TODO | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO b/TODO index 2d7c5a11..63de4697 100644 --- a/TODO +++ b/TODO @@ -11,3 +11,4 @@ - Dockerfile de simulation de frontend - Au moment du lancement du chrono, ouvrir la socket de communication avec le scheduler et lui ajouter la directive all:S pour regénérer toutes les équipes - On peut encore soumettre après la fin... +- Gerer les espaces dans les fichiers From 80a0396500396f25506ec989701c87c34faae93b Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 22:44:54 +0100 Subject: [PATCH 0270/2686] Replace invalid character in ID --- onyx/include/admin/import_exercices.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onyx/include/admin/import_exercices.php b/onyx/include/admin/import_exercices.php index 9471d913..79592a4a 100644 --- a/onyx/include/admin/import_exercices.php +++ b/onyx/include/admin/import_exercices.php @@ -40,7 +40,7 @@ if ($SESS->level > 1) { $ex = new Exercice(); - $ex->id = $element->getAttribute("id"); + $ex->id = preg_replace("/[^a-zA-Z0-9_]/g", "_", $element->getAttribute("id")); $ex->level = $element->getAttribute("level"); if ($element->hasAttribute("depends")) $ex->require = $element->getAttribute("depends"); From 16ede02de52308adf0ef64a85658c22be96764b0 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 22:46:47 +0100 Subject: [PATCH 0271/2686] Typo --- onyx/lang/fr/erreurs.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onyx/lang/fr/erreurs.json b/onyx/lang/fr/erreurs.json index 3bfc1b57..82d60471 100644 --- a/onyx/lang/fr/erreurs.json +++ b/onyx/lang/fr/erreurs.json @@ -1,6 +1,6 @@ { "400":{"title":"Erreur 400","subtitle":"Requête erronée","content":"Vérifiez les paramètres de votre navigateur, il est très probable que ce problème soit lié à un mauvais certificat client : invalide, révoqué, ..."}, - "403":{"title":"Erreur 403","subtitle":"Accés réglementé","content":"Vous n'êtes pas autorisé à accéder à cette page."}, + "403":{"title":"Erreur 403","subtitle":"Accès réglementé","content":"Vous n'êtes pas autorisé à accéder à cette page."}, "404":{"title":"Erreur 404","subtitle":"Page introuvable","content":"La page à laquelle vous tentez d'accéder n'existe pas ou l'adresse que vous avez tapée est incorrecte."}, "413":{"title":"Erreur 413","subtitle":"Requête trop grande","content":"Vous tentez d'envoyer trop de données que ce que le serveur est prêt ou est capable de traiter."}, "500":{"title":"Erreur 500","subtitle":"Erreur interne","content":"Le serveur est actuellement dans l'incapacité de repondre à votre requête.

    Veuillez recommencer plus tard."}, From 453845090841e8cecb019141bc88cdf2a3f4f909 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 23:07:01 +0100 Subject: [PATCH 0272/2686] Fix CA path --- misc/CA.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index d5248ce7..362984c9 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -179,7 +179,7 @@ case $1 in CLTNAM=$2 CLTREQ=${TOP_DIR}/${CLTNAM}.csr - CLTCRT=${TOP_DIR}/${CLTNAM}.crt + CLTCRT=${TOP_DIR}/certs/${CLTNAM}.crt CLTKEY=${TOP_DIR}/${CLTNAM}.key CLTP12=${TOP_DIR}/pkcs/${CLTNAM}.p12 @@ -232,7 +232,6 @@ case $1 in else echo $ECHO_OPTS "Exported pkcs12 file is ${CLTP12}" fi - mv ${CLTCRT} ${TOP_DIR}/certs echo "$CLTNAM:$pass" >> ${TOP_DIR}/../teams.pass echo "$CLTNAM:$pass" clean "client" ${CLTNAM} @@ -245,12 +244,12 @@ case $1 in fi CLTNAM=$2 - CLTCRT=${TOP_DIR}/${CLTNAM}.crt + CLTCRT=${TOP_DIR}/certs/${CLTNAM}.crt CLTP12=${TOP_DIR}/pkcs/${CLTNAM}.p12 echo $ECHO_OPTS "${GREEN}Revocate ${BOLD}${CLTNAM}${END_BOLD}${COLOR_RST}" - if ! openssl ca -revoke ${CLTCRT} -config ${OPENSSL_CONF}\ - -keyfile ${CAKEY} -cert ${CACRT} > $OUTPUT 2>&1 + if ! openssl ca -revoke "${CLTCRT}" -config "${OPENSSL_CONF}" \ + -keyfile "${CAKEY}" -cert "${CACRT}" > $OUTPUT 2>&1 then echo $ECHO_OPTS "${RED}Revocation failed for ${BOLD}${CLTNAM}${END_BOLD}${COLOR_RST}" cat $OUTPUT From cf26754ad6fcdb31b47500f2e220da6c6cb66886 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 23:16:57 +0100 Subject: [PATCH 0273/2686] Fix access to exercice after static generation --- onyx/tpl/bootstrap/teams/theme.tpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/onyx/tpl/bootstrap/teams/theme.tpl b/onyx/tpl/bootstrap/teams/theme.tpl index 14b4052f..0e9c4118 100644 --- a/onyx/tpl/bootstrap/teams/theme.tpl +++ b/onyx/tpl/bootstrap/teams/theme.tpl @@ -6,9 +6,9 @@

    {foreach from=$cur_theme->get_exercices_ordered() item=exercice} {if $exercice->has_solved($my_team)} - {link class="btn btn-success" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}" label="{$exercice->get_name()}"} + {link class="btn btn-success" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}/" label="{$exercice->get_name()}"} {elseif $exercice->is_unlocked($my_team)} - {link class="btn btn-primary" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}" label="{$exercice->get_name()}"} + {link class="btn btn-primary" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}/" label="{$exercice->get_name()}"} {else} {$exercice->get_name()} {/if} From 96828dc1d17baf14d0af72be1c4e6b56ee95b437 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 23:39:51 +0100 Subject: [PATCH 0274/2686] Updating TODO --- TODO | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 63de4697..639d595d 100644 --- a/TODO +++ b/TODO @@ -11,4 +11,5 @@ - Dockerfile de simulation de frontend - Au moment du lancement du chrono, ouvrir la socket de communication avec le scheduler et lui ajouter la directive all:S pour regénérer toutes les équipes - On peut encore soumettre après la fin... -- Gerer les espaces dans les fichiers +- Gerer les espaces dans les fichiers (gen_hash_file plante) +- Ajouter une instruction dans le scheduler pour regen le nginx des teams From 604a2589bd2166a1df968fad62b94fb902228c22 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 21 Nov 2014 23:45:21 +0100 Subject: [PATCH 0275/2686] Alert when no team found --- onyx/include/admin/import_users.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index 0a3342aa..a0275c8b 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -94,6 +94,8 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) } $template->assign("output", $output); } + else + $error = "Aucune team trouvée"; if ($error != "") erreur($error); From 5af236931605fa33f721121964a51d91cb8dabbf Mon Sep 17 00:00:00 2001 From: nemunaire Date: Sat, 22 Nov 2014 21:48:29 +0100 Subject: [PATCH 0276/2686] Updating TODO --- TODO | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 639d595d..cfc7799d 100644 --- a/TODO +++ b/TODO @@ -8,8 +8,12 @@ - versionner la DTD et la doc associée - valider les documents avec la DTD à l'import - Lors de l'import des XML, retirer l'éventuel / en début de path -- Dockerfile de simulation de frontend - Au moment du lancement du chrono, ouvrir la socket de communication avec le scheduler et lui ajouter la directive all:S pour regénérer toutes les équipes - On peut encore soumettre après la fin... - Gerer les espaces dans les fichiers (gen_hash_file plante) - Ajouter une instruction dans le scheduler pour regen le nginx des teams +- image dans la description +- upload/MAJ de fichiers depuis l'interface d'admin? +- trop de thèmes dans l'interface d'admin => menu +- numéro des exercices +- lors de l'import, vérifier que les ID existent => afficher les erreurs MySQL From 335505ef6c74e96945d940e89530b01251b86a09 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Sat, 22 Nov 2014 21:49:10 +0100 Subject: [PATCH 0277/2686] Fix generation of me, rank and summary pages --- onyx/tpl/bootstrap/teams/layout.tpl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/onyx/tpl/bootstrap/teams/layout.tpl b/onyx/tpl/bootstrap/teams/layout.tpl index 05ebc41f..7a01b72f 100644 --- a/onyx/tpl/bootstrap/teams/layout.tpl +++ b/onyx/tpl/bootstrap/teams/layout.tpl @@ -30,12 +30,12 @@

    From edce0a99f6702213f42c26d32dc189961b1b7411 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Sun, 23 Nov 2014 16:02:45 +0100 Subject: [PATCH 0278/2686] New instruction to regen nginx team file --- README.md | 6 +++--- TODO | 1 - gen_site.pl | 18 +++++++++++++++--- launch.sh | 2 +- launch_local.sh | 2 +- onyx/config/sample.root.xml | 1 + onyx/include/admin/import_users.php | 2 +- 7 files changed, 22 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index f82ac010..af557a0d 100644 --- a/README.md +++ b/README.md @@ -164,9 +164,9 @@ The D Day ### Interact with the scheduler When you launch `launch.sh` or `launch_local.sh` script, a socket is open at -`/tmp/test.sock`. Use `perl comm-socket.pl /tmp/test.sock` to connect to the -scheduler. Consult `gen_site.pl` manual (`perldoc gen_site.pl`) for list of -available instructions. +`/tmp/scheduler.sock`. Use `perl comm-socket.pl /tmp/scheduler.sock` to connect +to the scheduler. Consult `gen_site.pl` manual (`perldoc gen_site.pl`) for list +of available instructions. ### More diff --git a/TODO b/TODO index cfc7799d..244af6a2 100644 --- a/TODO +++ b/TODO @@ -11,7 +11,6 @@ - Au moment du lancement du chrono, ouvrir la socket de communication avec le scheduler et lui ajouter la directive all:S pour regénérer toutes les équipes - On peut encore soumettre après la fin... - Gerer les espaces dans les fichiers (gen_hash_file plante) -- Ajouter une instruction dans le scheduler pour regen le nginx des teams - image dans la description - upload/MAJ de fichiers depuis l'interface d'admin? - trop de thèmes dans l'interface d'admin => menu diff --git a/gen_site.pl b/gen_site.pl index 45175a4c..c21da15f 100755 --- a/gen_site.pl +++ b/gen_site.pl @@ -181,6 +181,14 @@ sub manage $m->stop(); return 1; } + elsif (/^RT(E(A(M(S)?)?)?)?/) + { + if (-x "nginx_gen_team.sh") { + qx(./nginx_gen_team.sh > ./misc/shared/nginx-teams.conf) + } else { + say "Unable to find nginx_gen_team.sh" + } + } elsif (/^help/i) { say "TODO, sorry :("; @@ -795,7 +803,7 @@ __END__ =head1 NAME -Dave Null - The netiquette's guardian angel +FIC parallel WGET =head1 USAGE @@ -873,7 +881,7 @@ Generate pages for the C<11> theme for the team C<00>. =item B - +Clean the temporary directory. =item B @@ -892,7 +900,11 @@ Perform a C in the temporary directory content. =item B -Flush the scheduler queue and +Flush the scheduler queue and wait for all jobs done. + +=item B + +Regenerate the nginx file containing teams IDs. =item B diff --git a/launch.sh b/launch.sh index f99b81e4..d157f502 100755 --- a/launch.sh +++ b/launch.sh @@ -22,7 +22,7 @@ KP1=$! TMPF=`mktemp` -tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/test.sock -o ./out ERRORS HOME all DS & +tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/scheduler.sock -o ./out ERRORS HOME all DS & KP2=$! trap "kill $KP1 $KP2; rm -rf '$TMPF'; echo" SIGINT SIGTERM diff --git a/launch_local.sh b/launch_local.sh index 87b5a8f1..49d9afb3 100755 --- a/launch_local.sh +++ b/launch_local.sh @@ -22,7 +22,7 @@ KP1=$! TMPF=`mktemp` -tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/test.sock -bt /challenge/ -ba /challenge-admin/ -o ./out ERRORS HOME all DS & +tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/scheduler.sock -bt /challenge/ -ba /challenge-admin/ -o ./out ERRORS HOME all DS & KP2=$! trap "kill $KP1 $KP2; rm -rf '$TMPF'; echo" SIGINT SIGTERM diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml index 748b5433..eceae299 100644 --- a/onyx/config/sample.root.xml +++ b/onyx/config/sample.root.xml @@ -5,6 +5,7 @@ /var/www/fic-server/files/ /var/www/fic-server/misc/ /var/www/fic-server/submission/ + /tmp/scheduler.sock challenge-public challenge challenge-admin diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index a0275c8b..f68ad7b1 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -73,7 +73,7 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) if (!$user->update()) { - $error .= "Unable to add user $user->firstname $user->lastname $user->nickname
    "; + $error .= "Unable to add user $user->firstname $user->lastname $user->nickname
    "; $team->drop(); continue; } From 469b7046f2fb4e4bc49a8ab9a7771df99f00a1e6 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Sun, 23 Nov 2014 17:53:13 +0100 Subject: [PATCH 0279/2686] org-mode --- TODO | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/TODO b/TODO index 244af6a2..1cbf1114 100644 --- a/TODO +++ b/TODO @@ -1,18 +1,24 @@ -- Départager les ex-æquo dans le classement -- Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe -- Ajouter un header dans nginx avec $msec ou $time_iso8601 et calculer le timer à partir de cette valeur, au lieu de se baser sur l'horloge de l'utilisateur -- Quand est généré la CRL ? -- Ajouter dans la conf de nginx un ssl_dhparam + générer le fichier dans un script -- Mettre à jour Smarty (et passer en « secure mode » ?) -- Mettre à jour les logos -- versionner la DTD et la doc associée -- valider les documents avec la DTD à l'import -- Lors de l'import des XML, retirer l'éventuel / en début de path -- Au moment du lancement du chrono, ouvrir la socket de communication avec le scheduler et lui ajouter la directive all:S pour regénérer toutes les équipes -- On peut encore soumettre après la fin... -- Gerer les espaces dans les fichiers (gen_hash_file plante) -- image dans la description -- upload/MAJ de fichiers depuis l'interface d'admin? -- trop de thèmes dans l'interface d'admin => menu -- numéro des exercices -- lors de l'import, vérifier que les ID existent => afficher les erreurs MySQL +* HTML/CSS/Templates +** TODO Mettre à jour les logos +** TODO trop de thèmes dans l'interface d'admin => menu +* PHP +** TODO Départager les ex-æquo dans le classement +** TODO On peut encore soumettre après la fin... +** TODO numéro des exercices +** Onyx +*** TODO Mettre à jour Smarty (et passer en « secure mode » ?) +** Admin +*** TODO Au moment du lancement du chrono, ouvrir la socket de communication avec le scheduler et lui ajouter la directive all:S pour regénérer toutes les équipes +*** TODO Lors de l'import des XML, retirer l'éventuel / en début de path +*** TODO valider les documents avec la DTD à l'import +*** TODO upload/MAJ de fichiers depuis l'interface d'admin? +*** TODO lors de l'import, vérifier que les ID existent => afficher les erreurs MySQL +* Perl/shell +** TODO Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe +** TODO Gerer les espaces dans les fichiers (gen_hash_file plante) +* Security +** TODO Quand est généré la CRL ? +** TODO Ajouter dans la conf de nginx un ssl_dhparam + générer le fichier dans un script +* Other +** TODO versionner la DTD et la doc associée +** TODO image dans la description des XML From 87af2e3506f5f31f680d274079d8008b66601107 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Sun, 23 Nov 2014 18:06:18 +0100 Subject: [PATCH 0280/2686] Add communication with the scheduler (through socket) --- TODO | 1 - onyx/include/admin/chrono.php | 1 + onyx/include/admin/import_users.php | 3 +++ onyx/include/common.php | 10 ++++++++++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/TODO b/TODO index 1cbf1114..cf48e0f2 100644 --- a/TODO +++ b/TODO @@ -8,7 +8,6 @@ ** Onyx *** TODO Mettre à jour Smarty (et passer en « secure mode » ?) ** Admin -*** TODO Au moment du lancement du chrono, ouvrir la socket de communication avec le scheduler et lui ajouter la directive all:S pour regénérer toutes les équipes *** TODO Lors de l'import des XML, retirer l'éventuel / en début de path *** TODO valider les documents avec la DTD à l'import *** TODO upload/MAJ de fichiers depuis l'interface d'admin? diff --git a/onyx/include/admin/chrono.php b/onyx/include/admin/chrono.php index 99350ee0..1fd4de44 100644 --- a/onyx/include/admin/chrono.php +++ b/onyx/include/admin/chrono.php @@ -10,6 +10,7 @@ if (count($p) > 2) { case "start": file_put_contents($VAR["misc_dir"]."/challenge_started", time() + (intval($_POST["time"]) - 240) * 60); + pipe_backend_scheduler("resetreset:HOME:all:SY"); break; case "init": diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index f68ad7b1..971a836f 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -100,7 +100,10 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) if ($error != "") erreur($error); else + { + pipe_backend_scheduler("resetreset:RTEAMS:HOME:all:SY"); erreur("Fichier XML importé avec succès.", "success"); + } } return "admin/import_users"; diff --git a/onyx/include/common.php b/onyx/include/common.php index 36948af9..38578fce 100644 --- a/onyx/include/common.php +++ b/onyx/include/common.php @@ -22,6 +22,16 @@ if (is_file($VAR["misc_dir"]."/challenge_started")) $template->assign("END", $VAR['end_challenge']); } +function pipe_backend_scheduler($instruct) +{ + $socket = socket_create(AF_UNIX, SOCK_STREAM, 0); + if (is_writable($VAR["scheduler_socket"]) && socket_connect($socket, $VAR["scheduler_socket"])) + { + socket_write($socket, $instruct); + socket_close($socket); + } +} + if (!empty($VAR['misc_dir'])) $template->assign("MISC_DIR", $VAR['misc_dir']); if (!empty($LANG)) From 011233ca49dadc7d41a36980722bd67262e87710 Mon Sep 17 00:00:00 2001 From: Thomas Joole Date: Fri, 12 Dec 2014 19:25:54 +0100 Subject: [PATCH 0281/2686] Replace a double to a simple quote --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 67eed903..987fd9dd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -61,4 +61,4 @@ RUN chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/tem EXPOSE 80/tcp 443/tcp VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submission","/var/www/fic-server/misc/shared"] -CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; bash ./CA.sh -gencrl && service nginx start && service php5-fpm start && service mysql start && echo "Copying files..." && ../gen_hash_link_files.sh --copy ../files-in ../files && ../nginx_gen_team.sh > ../misc/shared/nginx-teams.conf && (../launch_local.sh &); /bin/bash"] +CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; bash ./CA.sh -gencrl && service nginx start && service php5-fpm start && service mysql start && echo 'Copying files...' && ../gen_hash_link_files.sh --copy ../files-in ../files && ../nginx_gen_team.sh > ../misc/shared/nginx-teams.conf && (../launch_local.sh &); /bin/bash"] From 3f773dffb04ea8e9edc75ac8f8630942e8ba9deb Mon Sep 17 00:00:00 2001 From: Thomas Joole Date: Fri, 12 Dec 2014 21:07:11 +0100 Subject: [PATCH 0282/2686] Update epita's logo --- htdocs/img/epita.png | Bin 445849 -> 44042 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/htdocs/img/epita.png b/htdocs/img/epita.png index f311058479c8affdf2f0c0eb8cced76957d6dc53..4bfbb41bed4ca299e6e3b0d77fcb7c6783e328a7 100644 GIT binary patch literal 44042 zcmeFZ_cvVK8#g?N-lOH#B@s-D9-WC2onZ#i34&2W^cp=9C0aypGiF8*y%Qu_f<%o@ z^xnHM&+&cM`!BpdJuB<1aoXPdYM-m@>*O6&N0pj_l>!6;QLC#d>w`eIia{VE4Kfno ziY4xGIq*aBQd3nKgunTh*HWAeTp@Q?Gxh|5C>d@J0#HWQ9pEDA8+C0J(pf61+fR7K z>;*+ZAa0Pl@-w*aJ(PKmtwglnTYra$eBb1Vau$H{bDt4V*(8@;5 zkDUAtp@171xenPa!u-gW8NwXX!X#$4#+7!)mA1z-2Bu!UB4f=VYE3=Z)1BFX)nC6> zJ4FY>k)u1)qV|2~JG)r|yy~}srGU7pabg5Fe>l?X-25i8E->DlV*cOh|KrC0Ps)&j zIf^y9Z$bddYs@Jo2Z7?hyg6SEP{Qb|+kimu&+ZhUc_DvA0T2lBT#^{%PKJC~rUus_ z0FC4Tx2zO^Q|M!25LC5802CUeVPt_Zp#bF#M8H6hh19ZU{TfF17oy(V>dfLN$!0_& zF~CdwV(pCXlEB5+K_D~{pz%;Oq*1HKZr-q%{5;()80dId7cg0sVFoP%_Ky580c$46 zHad$CL{WIe7gAtCA^C`a5h4u-OeXU8%`=Kp?J0W{c~5VyG#DE4BaWZIhG6X4W0sOIz zhf?qxm4;#dlL^j!gb2<_(hddF0c-fI-*~a{ol$)?Ciy9S0->!i zDPoXvaRF3Ag^6+Y!}j2P$LlQ>qRS>af}^*<1Th+I+1tB{EyDijD!18|xyGPpdb zl;8ohHeFF*6b1^q2e4Itd^f`hSd|^@F>#_GAV+R-Tv^L*q(xT+>`R(lsBL8JVQTZh^74o99du=c#c zi01sf)ZP*Mz-lkr7cUF&GrDzP;O7=ff~PeDRK2n~Qo#3Q?rM)r&6aN8tyE@(6F`B+PeR= zR^V>T@ ziF=_#1dINuMd*V@^cA#0pz{$9EtPzD-&~q#5OqV3V0+3_VzhWF43sF^-Mq*VKq}{# z+hy-yh&`aNOj1Z`!NXI}pG)At;W+cm?s8M`-^q^t^ds&UQwSt5^pDoR7j{InAepKl!(o-ij|ii9SPAo-73ZxK2Z>R|2}~dGbHY{_;fs# z3P4pABmk279>1DqOHE>@^;J?i+u^kd*`XBt1;H60&_+2xNMX;*Q8?#`TnPZ`wjTle zKo`nK>Vv=ZaJwCrZ~@FQz8Pd=Dcz@yj~uDLcKm!{33H&vWU#F@Q~#J=YkAWbL7e9R z;4>tS<8bGc5s{~NyXf_uv3#ujGZK*BjqaJuI?Q>R-~Ey=abV(Tn_+pZHS^U#D0R`M z$@a`@l?<9?{|eA3@%r}GRq61qzvR>~WGwa+P_?C<31bEjB-O2K+&q^|e(in1m%;ma z*eomTi*A!+Mrit~J@BGIBgVp~<=H)Wk67D*_DsF_9}Upbfs_gGCYKwkB1#`yCxSt{ z)xcD|d|?vUG(zsV3r9lGTFa_Aezpa6_HvrrCYJRV$2+UO{c#EiPYwpajiY}g{8|2;!Dr)RfInKU#>JNu74<^ zrOWf1xj#$vpUzr+d+|n`iq}A!qftAS846e(|B`3z15l`lYkCkl3U2(YoXIgG*NP&v zL*B`W5G2_VcMx^D&GCpL-9xbd-WLS6`DvdMgg2!iOa3K-D{<4_6`(k}LEW1arkdFF zF^n!gW?487Q0`Db!Dxo?LA$z&Wcl~e`806t7)*a3@!a_3H|$h+iaPf*_m#PVj$0hYK*7H54PT7u)~cER`^{Q1;>hGwfEL)dl|C zvi@98d@%4|ZU9pZSux^XZ76oOJw?ZWO4C4>K&sG#B25a8^SGF7J3Zy=DrD&VvlM(~1oupSf9n-V*INxvDCvXDy4x+f$D zh+DXgF7V5iOo!IyiD~4bJ|>Y;GbgmY4BDe|#>RPd9Gas=2y)aQYEL$|7s%7-IOZd$;w5(WN5 z>tpM=lj99lctN1hNq{$r|KSw&#+haLJmK1Qn=d%-K*^Ckgig8y#(cn%{BLfOMAvYy zg@K$@)5BXoy$=W8pKjQeJ@mh8hO0PXi+ z1HdWbxsbs~IV)NP=(rB&qE?UWy^{+!|_A-VgDMjO8V_KcJe}g8U{E zEbA>+h@fnZzxkWXYD9OHbzl_*7$kWc;8@U@`=aXYx3@o!MPFb3s=5fKdP#+9ES;?I z$(WPmVFIxy0TWp`)$iZ?Vev?b+sJotYu#SBDn+ga;qvOl>-c0Y`ZbYUFw8P}a-8p{ z);7`I)g3a(4_5huKm07Rq_Mo3?QjVKV4Pps^r5jww_vvKxhpnuM6(Ck>NcLNI0mX# z`CslTkv&sWnL+0ezFdtbgBY{QU-)2=Rv`nCa9gPq>E9dMZFMwEpj*It?bgUqd1E5C z&tBY;<4~nWiM(ikmBDo^;@ID4JMs796AMVnG&zCf7p+Kr?2F%X9*^H|YNq}aQvk&d zaL|P+A7Lty&>MuxJoJ*hc}BQ@F4z|BAx$G5J-VvkE!#gfFik z4WQ`d@&G9$Au1urtcH>OZ4GK;6_c7BiQ6ivlVeaMv!2eomL>#60?y3Jji30ELErGf zYYGF{$8Zd;bhgnHqB5#&((=^!scXu6SvsZ#Mo7DXT>5Q9qWy)BHaU`})_+Qr5DfCr zl_Z8jsk!i%->ovu&@isxmD7yIv|F%fdq64u0L$f1&w*msB0Sb4{?KWqsxmQ+0-#UF z1`POC>sJRY0j ziJ z$q?ay+r?%La80}MjK{jsbc%Omik{i*v15xvtARz_9XWd!qW4(E)fUO3fcs#DHN%j? z6u)C%RQVa*k*U^G0wqcVgxUg*;fuO?UDVi+w3%OyN$vA{OTRMun>y0-!Dx`$CxA`2 zwJ#MhT5$=HtV_z`SX5G0F3r!J+gi&8mn$tmSOSlr>-e6!-5X18Gd=&d5r_(v^VTip zKa=_AQPoK6W(BL>PX|Yx^y^Xr<3$4Fsc7R5)L~~E&-S|MUpQ^-Md<&hkMydal=!@& zO2%OHMcq(~eRG9;1b|3xUhUi~BOnc|PJ3)#N+0`b?lC54ZtAMbHS?k=+^obOnT_J^V09@H9LglAGiO@-Q zx|sBTw71|bDdAuJ{~e6>#@clIeFJSM0tQ5?jlXaMf@49cwLx74oHLa3h*VL4h6P>i zHu)dm2f+U;gFu!3?_=A#5LGh{eTJY1zb}y zEfCb=FooH@s#;UP^Mnfwh9A8R1>+-NkWwIxSS!>bfe}(uAjXFS5R-VDYvkMk??W#T zqGRgn!0jLGVKP%PpRe!#==`nOFM+$9)kEiz#t--ILH4nONV#-{>AXmAq23Gp`=e ze$jZ>Sjw(|lsoSM03HA+Bj??3rRhBkpg+o@)1nWL*OpPrbPNWi0O5l>qc}C{7AyNZ zwULG~$}oYKLlu6XLcywVU4j}w5hOpX;LqN87w?gaOR~Rpa3x2^7<8|g^F(kLY2YTl zbrR4CE--%M5yM{=%e8Z;p`Sh9o;<$1I9^O43Hiw)IJoQQ1j%OOFqgqL0Y0Ju2)q93 z9)?^M6A$v-Mk2DKr4({$*|Z|L|MEz4WO`GeMO-_QmV5g!-TqKQERZ>W)dgZ!RO+qw zTlTBh1~4hl?@)@nV|wrF05AfeFK@3=Ng$tO392*b)XwNP?-D#AzR+ve+vk`pD@kAg zh?>G>zE~ld45=0wY~<-znqgAwU`#yoC_XqX-J-|(M)SJRd4&8xlm}HKQow!Qicg7P zg{q}S=+8tb+CIB%bqrR-Is=IyJlUOsKkF_2d_wsf5mV3nd8Oy7XoK{vpESt{fJ`okHFTmwa@F3ArlQwt4Baj#ZhWZY7^(L17c>{T~mo)w@lJJeUd zLbih@nbRPx+cMogJAchncau-%TXpl{;_{l4x11tJ|J2-zpo@V2CltI7>&31o%UKZw z0TI2&O(xq+GvB+s|3yQHDJ(Qv>!&hPswY(*7#R4;C~wMb2gsX)uVe7hFoB-8G@DQr zx2pnVFZMr}EF(b>AXg9jd3y!>cFzO#wgE3Ta-^E2mH{M0@{`O-OTVrfaiV310Jj85 z@QEj4)AQ+zXbsy21Y&|glLO)#AMUmeh$`aGHr`LM6EG@B{y~0;S z*z-q-dq0YtyAXiRwy*!b8kUf!eK`$UP#Luefm^^gLq5|C?$laPz$z2Y-^ z@)=30f3LQ`(ZEU9SYd}w-lkt@3Z5dXoSMAQAQ7Mvr|k4QBt)1#3G(ddpV?dmZe22b z1V=K8A%Q`mH%y^>l$MkBIzdp!kV|5Qi2cTn>9U{UaVl*a#j+imcX?C7j=WqadGZK* z$beg^jl?iT>Yi#28E@49PD&IvXCxI`YnAwaQ(6CJxwhX;PWc@pJ5>H&^ntTw=D7-z z8rz#WP`1r;YxruzaXL(;cVp4M{+z%LC|O`O$x%Jm-)?VMb)OU$P8AmgZ3p8QlAb?b zmVF`KPs?oq&?p|>dd54dPsg@uv%GkY3&*T^>p-6y>VBC#ngNEjezOVLHYEi-p$1uT zC>)3vm%<_8(i0UfMrMnv;@LD5=kx)~@YIuX&&66gMLK-~Wo1d?k& zjUsa3KT$WlJiMty#06}gGc3pxCAEnVG&iX#o^QRfJ#@7R7zKUyjeyCx>9y$!A+{vCCW21! z%=VWX4Y4Ez03Zh8ZC9f$_jq{78I?E&jsXu@bh59t82-=rW`Tp`n7cIo2`fL^lw`hRUD_mPwhh|kgjj=Zly0LsH(1Wmm?~`#;1(uI+ zNohO_*tbNhQFI#i)ST(lZC*{mRJK44uvXO=rB6uBpR#T0J%(%E^%SxLbHEprKP<|| z24&3sjHX#X$A`$iQ3DEZ#&*x%qIX@_Jidl*QD*~La4PH7DBf!!bZuwtoKk7iKs@z}tHRb?(DCDP z+Vb3|QW;$>R@Vhf5^NHiyYT&6?waNBM@;ZjP6;`!^*OxMcyYA%j)q06uj9yeu|I_* zV=4?X5uq=I?0A1S;pg}p+f8=0+t!3dTZus3tEwuBN}4~Nf+u1)lU37(jpV*l&g?dX z;4=VueI8ID-rso?Ivm5yPaK@y2P=GXnPN6{o$~&jD>z#(>?{gGzrcLh?5^#XLHK7& z0oyCl-dFQ)tsO!V;ztHn?1QYAa z50aaZ$QZc;pCNW}Sy<$=ZEMCGnVa`^%`|lqu|16{1AYtHB%&TS`9$-wJ(cdE*Dx#< z*rl{--Z3zdGWapLcM9W+P;mY4-z!M}mBVn_Qmho^$+c=*@aMm)HRe;BoKWiES>b%7 z^*2oP<)wPRc5xIPXM9b6m;Awt%9RubGtJOdK*rI*d*_qm$>kPT1z(Sk$9;W!5-E4< zMg8jKWGH1mdEEB5_&sR?FzKgig8bSpv+G>W6}sh~Y>kU)eR-jhl|htCCc;QcPwxjj zVt6%4qf-C|>cz?hh*Xt0NjOvUL$RLwJpb3zW?yovBKbfKyS(0rt1YJYgt84{}ctCyyFym%L#b>?nFE;%CchB z8Y&3?FqwivZ5C@~x#LV9=#VX>BnNb0Wu#>~w;vitY!h2{VwnwKiUN5SV=mK%!=VVX z&QN!M*rJ}>kr6eA{zY*VK`&zSF5!PbXrf5QLv?;3!H`cfGUwTW6&)nQA1oy;l?@EI zpB^yP;1`5*4w3o>#Ra@2Q->^nQPnGqBdt!Wi!LdfHwlPwxMQ$U!X3ktaf>l&vA}$r z?08~ZpcFvi+B4pUF#)S?h)|WTSdD)>=ibeIT61*m21a|&J>FY1E=4r-VlcCv7V$U6T#WQ+qxa>>2VS=~45 zQMV%>xsaxN@3mPML2p2Te&Ql`ptwewA#DX&-{J{Rnsb>zSrYu&EGEzMjS5^e?M-wG ze7H_7LQ_Yemkx+?-KM)AJad`!)3wp{M8Fzqqa?X;o>}2Ch1xb~I7vBv+PV{3oJEZ; z|B`L=ROQ|O*9#C}XQnzUtP0yL$&m9s}&CQoQVuaMOtjJX|SCdTXKX3)0)5!7#UMA(6DX ze$O4)L?lyAva5`zYrT$L`qV2C{j*jYp%lulxQoXv6zvw%lT8%ps*FsxhH5*95dzDp zEWaT)pzNh0w3I2)w9cYJ5>9@xf`b*OFt;4>B5AW<```I1#9f7}t$Pct^zh2ZM&2IP zS$d(L*xD4_IrcSpjt$p$oVL*Ek2{j~%3KCT-ydi_Wb~6(^qZMpJ{7r9x6Q87R6+k%j~XJXrM?R<(~b+T z=(4*ULwG-HZ`fjL5bi$~8dhIq8p+ECSz%ds{11JS@+Cs}==ni2*REr~hFU&Zcnnhl zhRu_5cN(1h$a0<93!B~3^rabDPBL{-lSzw+zrmp!!K^z~<%~`T{^ad6DUd(H7U%tq zfF%+sxn0L+O7TSO9DlE@`uxfy0G5$ahHpO{d=hl_VYnkN28*tBeH2oPvHgK<+0?{b zX!_*Qj!XkX=X%bzIDX&52JL>Lz~t(n!TDSdbRM@{#H-isrF~H z#`6x!jw9>R*IUqr;j`GrH7V$enc=H0@uv}@85!8Lq_)Nyq*z(SGa@3r+d4p&M2!UX z`B-RbuCE*pG_1!u!Vs6?@wX*iw!ynh8@&gqG^~u;Z;OvP>dnW*&>Q^$#!gGHOU{hV zb7l%4E&A^;8X*wcr|pPny#867ZPK{^Yq&G7D~i9kgZHNq1?nYxJ(1V(*y}=9?8#}M zCQ~u_*p@UgBM>TxDD$frzYMa;RXHv6=v-1qX5!bb8g&n4CQSg845fR*Au6Kf=uqD} zIp?zxN`S12qKTL8aShnB9&Ca_28VCawdK!UTMRKskH{>6JT{xt(uVq1J(JHBKS$<#*})c{q8+A{u9w21DAVFCoTATB=42$Ff)!iCf1$e?l{n6 zF!BvZvc@ee-gku)A-L2~Q7S_iHco1MjB|^t-w?dZ^)7 zgF=3awvGP@bx0p0{m6Q;y~`UWuz`ewk+t;Eg1OR7M_tCEh?ze$!EC@D&AgO_{42P2 z8{W9Tzs_t(L~P^7ysCmwH&EU9&?gY{0TSCvb4@ING^Wj$1I>_iw>tP3%~^JFI_nWr zgG#b{C?@@lU{>_CbAL!zrfNLdoOzRl4bdMuooC7>t%o?}ub`s!sNQ4^o`{TF@R_9I zG^e%MT5}{NO;d4Vi;l%wLdZ#swY4G4reAkjG&56kk(DiJv?(XP_VIHCA-;9lLopU% zejwsk&Rdq5GkQ#{ym&KOCkd6B{Mp|0*X{M0pzGkva&g{tY{$2jr1mD2U%fB61iu=M z`Dy^N5cN<#`@~doB*jfJmKByljzVLVzN|AGKd&z1kf=Q>JshMCXC;BV{Srtgl>E|; zyNou9=M09m1kX}NQMKxq5LEz_XxvazG}xXp4?^c3nwVU$LtQ4mO5OiyxMgnHSA&!W z8^5?CGFp?2W?3&gK1mWT>_~}<+T0wSwHKF|^Vr`TLtlPhyX5lV2@eB?qcCX=(7Y>4 zSUG>AAlY-nVOY0R5;Au+->ekUsUP(;&o%ZcRLmRdDH+l;-)QMo#yMufI`x;%YwE-G zOn6RqKIl;ljo00j0!|I%5-f}${XYpUY42UrtCe4mH#h5K8{qY@WY6dBkO8J@{S|74 zF4RetAe;Q7z}H?)t)xYOWr>d+v~b-gS%7d(3$6bhf=$)&S^B-)w{Cm&Gg#>+*B@A5JVH0R|;Gg5Q zQ62Z^L5XuvCvhp0+)QP*^Cd$F^tipAkQIjG0Gm`qgDV`4r@O_$PR6Gbr{`9|g zKK#ckhqoMsQv<=_^7MVrpg>)p)yKb7TM=7pBc}@)diOe`YhA|iH`UR+*a-da5U8?T zphMSDCi5GY#+~*{F6r;{L&&eM7EkVzGnHO1y-1vywTRJ`^0xBy-TeCpGgq(6A-31o zj>|p8l@4CX1A!K9iZp3pHFuqd)C1s#!O#WHG`TsF5EsGD_$!)4;q&y-T9}doBQ5Kl zE^22Qo(Ok+P0c%#Z6T6XNM0(o-wIhWZyXkM(r#QfzVmfeSySMwjdgdKdB`0dZ@#e^1H#UuQO}Fi}cz{q@{*8 zO9o*p>9zLTz5VN0CQ3})JoofzgToPeDA&?A_~1|O+)13*nK=H%YdlW zXXwn~WVz3}v%}{eZSiy5%C+sblzqb=2n~609_=ld7bn@=Y334LK8RHQn>{~!OzGrT zIQX~`$Lu!Aesi=opDL7R&Q5yFG~82-z>BW`6)J3ys-qo}$nnr$&mXAiO;{cHx%^Fd zh&~XkaH6}@q7V`GtH%E%_Gf{#eL};s{kz~C1^YNw`d8u-D#PPXIHZfjYB9pbRi2+V zA3=e=$+bwc2z}!(u4_twBd@J@g1wlo5eW4AlWgtpqQeR0K=UANvG zKahq@5cHnk6t-dkF(1|^%NRZXN_X+Lj8k0XYO|7wh6d^bG&;ah$7x&-aX`@Us~E)ruRrtTk@D94JIp0q-OR&NkWl7j5WH>bF7Tk?M0J()>D65kIoUy zLV{|1kBUj)pEW(?Y0KHarNz1{C>ORn^wU2MpIj-UCu|B20KXFB>e6A{uZ@Hy{FgXg z+bBon#k1OKzvu@1l$k^ixDvJgF|O*Lnee#+hwd(+`EN{ciJ*}K<96IP&6aocTb z$G)SO`4Lt3Ot8Jj+)DrF7Mh?H;?>j#@oXi6K#LxLl5OHAL4mtGD2^^>=;uk&^SfDL zK@s|jw=x|+R;>MPz1O_8<7}iCbXEDD7XL{->M8&2Q73Vq{d!?*MWxQ=irv-MM46hR zrcs=4%;F{cbrlFMzD->K?E?Or2@FKbRK)sFx?Gd5LcgY(rOvt?$| z{+05^rR2u!+%ZmZp$;<*jdIOft#cNiemDkO`mg`U zceH|$Aroh)^EA4sSntfr2W!15dsNOLb20XenuzA|bcTlsB2HG!|0thv%LZX7>+(9i z)TVpD{n%}n*3xmeXT+sD7z>emcxlQ?MU83Mb>ya&V}>`mxx>zAx$G zV9AnnU)_rc2n;8n8bYa~R6kg?$AZ9RE={@Q;|h{|)73BSP-T|6e(iq9h0bULN%?qt zxn%z0V`9_&u#b0xcdm|0*ih`54FQ8r4>)nl%xp4a(QzE>26}NCHgDka%awg4Jz3m7o|7q_?Qd2C zX^BxhyB@3PS1HH2S{&N4sUpby&eK;#;nYX501xwzqZQOmLe3a;y&>8uC)#-Ixc6eS zYNsh@&?C|D>I4P+QC~@M=*1y(ZAMLJ>VKI-b#3F?^0ixo4X^tr;TJ!90)n@txI}a$ zRd&dcbO`0NR%0y z)&+^x&{k?MGd55ns|kObB0sdY?{%FgL}L2;dw)KsO7LG*xVjQWz~l__e#_HmFu~{( z{B-0!r}Ew|bd06_vMibvwl-TA1R}25?OF5vwwd}@E)E9Ih}k3i1U#(&CIn}Yq1Hx2 z$I>=Xx4-(&p6^Y&2dqw_%fnr?(wjq}+uOFk6cmCCuGOQa{>cZdJqn&n&b1Ra1(9Ycv<$UCqt$2n#2!h;=csq+uQp zIZb(2w}K34cAH$1uTwSRC_X2ccxl2lL5&Q)sw(393gZ8&o$v&}zCF0As_&)wY3^!@rh0oO@{7xb;BbPe(-Mpb&RZmT`sr15?fv&p zPquxy%}ZpIHvj60PYu%h;K0WCFiI*qZX3AHM|HV&#>6sN!*V-x*Vo+Yl5zTCV$Nf>a(SU~ zPA+}=&B=dy7P6LNUK(fH&8i%iv7!__iqB}9pZ27)p|l6K?E|)p_7^VSe}W$ecpE`$ z;@L_MAXd zwe4nrw>?7ZPt89QKc5}VS^-L$l`4`dDN(qk)pu6lFaqBCDm#{S zm$ftag0c|A9rW>5eI_Sn)?W*MG)3C!l#qSL9A+tMgYXSmB7okWy5?0^JK5?r3(=`+ z@z@szORW@b43RH(+}QZxwNwI^*w>?icZ3*X9}71A zc6-GGAaIcmzsf6&V&QY3fhY2-&+8+<%%^;ObyRWK;ab4&bAA6FP%5nG z<=?^J&qoo|ppi!@8z+kmhaJsTgE3|P8(#nzt7E@D*uFudPnXW}BPE1SP#R5CCo@in zdNtoK7IK~@XaBByvgW#7~O>ztW{O<$=>)AwfUp@_yh&+$I*aqk|URKPO=g?5d`m4Wij!KTA^ zDm=|+1?b7VC!0D1%X(6yPJ$U?6?ByOTx%WHrO5S8ljI+4PsdKL8(wMy05L{x(|2*P zP&f10x&ADYlamM7%i6e`W~Gt$(PhTqK_clfusum;-92EwFqiuxtJ!|#2(43OY||aV z^w3B}+EDl36xaJK7F_^By5tW_9%%DBpEi51RPRZg&g2fXys-jl~j%DW3MOp&K+lkovLGb5?dxWa7RH0=*%c_*~{CrPkz9B^6XGM`GIWGhFr}r z$KX!4CRimcJxofap9+8O;tHY@ed{tah1^{5!-O;kusosQ5Nt)4lvY##TG3|J@z>$9 z(9#*oZ=5~$=^(hxcIdmJPi6%*byazm)Z_E(jvtt9CFJl`=owitS~{Q6n3^UJMLR(2 zgMTT7lfRmXd~fQS6{Iib;yH0vfm~Y|JpSN!&zwE;rEsYrVmDK&bkF=qJee;_tP_(H zQ0f?b6C>&ws8XRccukol@^)!|(hgDr7A84>0W>_OEG~-L>3HlZx2F!5%!4c;U+4l? zdKv4mAp)o<&Sd|s;){?AP#iz#Y_qaC6Wn#Tj#k5D6@a7g|4xedLJ9ek?wOr7uE^eA zelqw@C=0>%^pW$I!>Jq*bqB-g#b7jEccbjl9#EKVe04Fh*GsyhTp>6^V6geUf`-aA zqEFz$_Ds-K7uYk+3&b8M#_XvOBf*9&@)GG91(V)e)BmlwOtO#GTq?gW_{63EH`YkF zI73h)oRzI3^MP)lvgX$Dia_`CI^7v3Jr2p>*VPb7m4PsU(!@ikQl3rY{g!|`^5~aX z#+j2AyVnM~HBZGiBq1m>+4H|bwfWYyX@55(+QT&jvjUypSRZ}_T7>q6N)uv_e~mu< zM&cV^CgrL0Xj6luUn$$Ea5C4E?*kmk)6x|idv-_1e`Vyiv3Hfc(xJ7?kWrWoI5`*vqq!A31mb~6F`E>5 zCDC@A5wk^bnjcL&3R~m~@h+nTHbZ=Dj6?!nILXR1+b6VN==rFo>hdt{r>kCno|ACO zi2O~vNDYgRlg^^Bc7u%WdRpq7G%uRarqPivFh+}C)ykAUCU&nUol+u!@z@re+0W&< z%{Ee7pL`v2@OJtevtYd#75BQv!1)xi02h{8(erChQD;_E2xE!AW04{6;almueX%x} z{5s*WhGDKyrxod4t9}6*3?ESJ8OoD$bGk@rY8_FUq0Hq%l&q1C1!+o;p9aQX8kWAp zo=-(lzvmOZ8HR^V6a+( zdo1T4piPRLTSb)?>HqxWe!QE^nA~a`*E?suH+^!6Oh>|}I*8Faii_#fBuw&gvd9M) zhxDNHebHnt*;*mkCD6=Pq$;U$2Y~6ZG(yR+gK&)VM5Rq}c%~27m0dNr0XyrHRd!TP8Xc*=t zI8}qmO_+rA>7e@Y*ZsHA9t=Qig01y+erzseV-onDi|DxJiAvy(IsLlgno~}&zw4Li zvzlYGJ3)gv7H-=<_>CAICTIY-7}!URW(BEK>|c`x;1ljOTRhly>f{;kxZP^&_6Uee z3SPwe{<_yBPwnhX=Jr{7{o|d?jrY3pUK(UP=a~$zRD6j1e^&P{%msUfpqdICgP~mD zVhY>u96o$lF%V5T9K2ncwh=69>sISf;-f+8R<;YWYjD_Dy0KsH50@vY#FU-eC1c7H zu6#8AnKimkrd(WoWi_;m%WM<+Pa-6LZVf_>$pVMc`%G^uQjBT~RX-ce5Gkv5ww%dn zy8c-0Du!tVbK?Or^MArKh>?&2f|^ntW&cd!xhEU-#30 zynnbBPntrQy3Bmr>DyjSUq$wAB)@9NSEME@_RtYx8s#@*gBMcQ+^e7+DA+DE{yer? z>osyBTw3mX!-~eVcuwj2%??X3{DM2VzDN5xPUkEvg4DUPxRkY%eK(zSgNx$J;7`tT z$8VlAqCzPUoz<;btglz)dVxq#{X$Iqhv5u$&p;@Dtz%Hj^fgpGmD&(mQau7GBH)QJSMEa!IcbuW4M=)(2PX(?_eppOO(w3sX~+TDVg5X4wmD4FK_ zmb=VU4EyPA6TGlcFe;UBv6*taJY=v}X`s6(&Na($4!NKmRm;w-i*PG7;aHZOj~gzw zU1`=%D%x_{YVM9}%G1!=WYBmEAmPDqV}G$=YMdpGT`xl#VOwdt-8g+bS8>RxJC+rg_5ShE zM|UvaEg0v(``33kRH=6SgJxvD2WLxK2L_HKR{i8J?@dU?U;KP#VNfp7Z?N{~v1xJ> zi=5x@+&O7{#n+YTs+F!g=$8F6Yj| zFApgXh|!1Lbj1W#+ONG&{f#=lhCW(;N8WQL?nYcrlPUaMm2K`3b#p=1`$MqnlkdR7 zSL<|g4|<|^>n~GeeM}ADzXLijA2!I5c@UjDVruu;e=M5TMV2<@N?ou}R8wy#k_|`G zigL?s?9|UF>b3YzjyRldXC^$61lkFf{}A(Zxg(sFI=76nd;>i;=}+X+E>*j;eGJUx zMh~U9j1#{|E&I}%KzSB`#vl|wHY7*3H}0C>LK^>P={hb`Oxa|JOoWDvHTh&fDLNtg zZ{5d_20C)B4u7l_j7(l;>SUp_JY4c!XSuAu0jFV>ZA#FvTF7-j%jY|c3 z_X-1C8*Mx4-8ZkgJ?4D6fDKb@Yhs zC;FBea)z7a!qME^=YU*qXZ)()G>MlZ+b#qrr~8QJa8QBo-Rtcy4^g_*o}bG3ZSkx! zrxnV?Ozc|AaNFmzhnvcyl#p1WZ>`Rb+b0?Eu?nWn@AC)ED@3xrR4V_fo^A<*{QTDV zM9;PCZKNDYp-EKKojDH{MY7y5{7sY5I`a8qUopZAxVps?8N_WUrXXxp zUy4bOAITIdFUs^z4u9Uh60zQ-GPwmf8OU^ zKmn*N+s`B=cNGAKD6akhv3oNWPjRn*btXL6F3wqNrw;4G@ROlL#O4M6uIP~e=WF$( z7_kAWD3xGRB%@?`>>>1aBxt^9vCxbRr@$=tdFyXO$-j^~*Ws1Dex`?o>`rDOeea~r z{<1+GiGdGwupiqR1=q>tL3ui5SxiQfqpdc@q@LVfEWffiw-wjsb~=xm%N6!*eYGDm zbMF?ue;)Tp`#(9b@nl1-^xW4dH{Fp-;6teY`~L#eY&CD62wnVpk2t|K5rGZhz}I$Q zV!3=q2#JBGoQ%`rv9=o))s?`-Wg+r95KfJM&s3t1`1YYp$_{HmpnLLNN{_TWLteZO zm(k{@c~H`wyLQ}$|1<5EzZmA(_>yYY;;D_v+35+*>X|(1T+bG$^?tUZKqC>Y(EP80 zCOtzhzqOpT3Q8TPtYut{KQuHxYTVj!tT<3SpnEo<+z<-V9+-QAzy z%W;0UUllaJ#PHM(neb-TJHULPQ`mEbO;BI$#+QG-<4iQNUy!_+a5^x&NLd_w9C3^a zebeIGb@V@|`n7v_dbR<`ERMcxf8?eH-(8%Qa)qYI71kwi@_~#7PpXqBGDf*$b;iuy zT^&bS+UTJKOU4{rACgD6fldiyQTqs3H0}GHXFdxZd`H@j@C@|V0oAMRo$ zHnq30td)gDZgiI3b=NG@Ow1qt<}_3@KASFB%qK_3m&|76m+mb%W29q{SM|x2r`e0p z$)7`}JT{zHtL_@VmW%u2U2}sQU#99wBw~|+++T-P`hH*L5MJJ*rEf@3(2U*gvJFTR zhkDZTKd(K^uA8wq&2`M+QsK$MR@JQL!fxw-O#Rl8qLC%>I?BHVlY!unm%Um%A57RO zy1rgS9X%7HXxtfRs(PjDCn@c{z0nBdv<6PYyK=YPyoN>rc6=6JA3D3~uTTdLMWCg1 zJnI{Bu1AbX*!;kDsHv&+g+{ly%8ZB1MA;~MYVP@b%UR|KPzhl2v- zVj%v24;h7644q=SoA8^SbCriXeHfO3Ec!`SHd7nt#&S*s2TK0hV=>C?VogAUlU_h|rNO{QSU7{oNv9RTy6Y<`TNxcAY`G#*duVCy!;nkZT zSljVh7roQu`?c3r&yHS#{|T25+qcROMgCrOnaq+M{iAoh8?f8K*U_xaa{s0zvSYn) zU@Y3vy!`WcP^4P!NbR;F8Aow$K}P5_REp_c&8l2m^-1$;Q~i>hkPs7Hj!pkT>c?#C z>)hntjgwe>|Jgf+P6Z3PRrtZKLTgVAnOc8OTAKUosWpB<5&V_=_E_}ARfpt5Lj{kG zUgSzwm-B}i{jABlww*+Z1BfKkRHQ3Dv`<=nEFdh)BxGF98fSj$5F>ro^zd48GU#$W ztAU2@dy&;J%0ljP$$|FA>59C5RV{9;GeP;X!BW!mxi{)WrLsm&(g+gi9t&(n6H;>* zkIng=a?ScOOu$p`uhbEhngNB^hP7$Wj?DN>`eo|n;)jO3C5B(VmZ`;GIF!{EL_H_I z{KW-i?kSY{_{$EJ-U0I_gb&wjwLqZFc`QFs+@@}vgpjPmFJ|>)pzL2QCn-U%|IuqK zEB5%M&&~uA*qiX0+cmQdJy5X#wj$!2*bAi{on2`xgO-05&a?^279p^@;oj_rcc%vt zYt6=@h2~_qmF`@$pXJ$HH*?fDr;KppU@*Y6p(4G)Bs=jJZY5-soLQM~vV=`jiGVNc zVy7oP2cM9m{{`0*#Ov^ncE4W7iUUSFZt03|+u-EqE;+QW zhCRQk+nF?Jxq>Xjf!W%=^1?>n9)qg{O?-y;Q~Bj_0<#+Egy${ z4g#dSl0No{z-dsfsrqEPN^{J$a+bmNqZL+zwvEZzK1W(6@VfGSK?~>_P_`l`oPW1? zM{DwgqZ{-s{o}_Ajf=0I`^8;Nhy5R#t~x5}?&;%0NlQuBQqrAEDJk7ulG3nrqjWdY zA>G~GAze#{ba&VL^>@zu59hFZc5ckfXY$?~==`LWrFAYQ6Jc}CQDX$=Y5Ii-c!7S6+@f z;3++CXYKx|nqz`U>IKXAOl9Ki56V)eT$a=JM$2`;UR=}2^9=(7^S{Q0#0|;^j1KN5 zFah-gPHyBmC<#L}RauT~J1NUrU!ttl4f=Sq%d@qwtAUWJ8uc^2!9gR$Xj zK;_w$641Z#Gz!T7wD6Mu;RaH0t@hydJYgIi9KI|e3H=Bq;idY zl5j2eYD|aYXzA|d)?dJJYqrvW?EM^!_VF&eytzsO*eG~r=Y~|VCsF+! z;qFTIqoteeh5bOhMX8q-XIcu)yS>_D(IO;0SV~BrUcy>!-@e>34}6eGGTTb|M5*$0 z%k$WXL6b2d+?yTysVIFUXWVg|5vjm0Rmcxmi6OnI7BY|)-HdmATl(z3uybz{P8n1m zBr{Ma?%w|Fiy@f)$o8;e94)y>E$p#$tgNDv+ZZrExxX&->4gTlr#L;%PxSMgv3Ie- zTGBdV^LtY3cwC0)N3Jaz*&$U{F7ub5?OV??F4iF(x0pSkbRjsH^-!W>F6pVg&c3%f z8$H~(CqQiT)V6WI#qJoYe^;AjewoSx2oaTjo%oXM5rc>bHCknlA=$#y~Na`uj z{2H+JyS1_H?pmc+fy_;cw!(j^)1ACJi4C|k30GwAYT}dDd6a;g;Zs!J(V{t5AExz# zx6P8|C$++hJ*D~7mi_0eUK=|vxdKu`&yoV*%7Rm*K}jG$ZKO<)R%_?f5$I-)GX3QsF(U4Jr|oC z1W1K7O{|YUB-UMh0SlS2mr0%X+ZGsX1{kcQXsF`UIl5>ac7DP)2lJ3htNJp=cWrWo zSm^Q5s>dMH-Ex=z?bkprufkEHM%K`IqCp{+Dx1 zwC6#&bbMRyz2zPY${_PoqlFG*b4ag7C#g4)d8H?EVK&yU^z*mH*0ZLP5n=R=tRpG- zYSpT~K<(j4;`f$(4yLJ|iMxz4Q=_9=ok4uH?5?8yTFmyF>YQArMfsrYg5>w~yjTHc zqgPL`pHH_>pVA$L&Y(vfKEekOzB|4xp@}`8ti5}bR-2>f@W!a=s9GdHzs=bhY8lH^ zxOcFa&=molc zKy|(G_TlLil$Zo>wQDRJsC4LR`Jli5pp40u4hn`>MJ>kvj_>vUPMuR8>3e`TujatGo`8Wa z+pC8vms-ylnrN$Ye@2Q5r$4NhskfYucYpLswb(X9?+7kr@vg(y;8APizyf5avkc?A z7_h?QdaP>VX0R#62}=)oFMmW?9wQALR)>0ml;PVI!)B7xW#T^I6O#Zq12Db9ZnYjV>0s&50hpqO7_mzjg}SERq0*swv)c-MgtuD06Do3;QDvS)b`aM79@Ott_&=*^1 z@v>{4@bq+mUFUr`p2HykOt#H6J>K%p#n>>-0VYmhej_dr3{KA96<~4h zZ=ZGuGfn^eb~W^F+c_(3QbdMXTj`MGclZnET9>QU@`=4N#pK|EdK|Ii2D%K{A^*F& z3uCCB?o|=Lp1~I`&XkJWsF!;PXE=V^KJ;+J;t*|+C}&k+f3JDUDIBC~0vn`aG98)y zNC@M$dvAwY9D?K5o#5!6#1!7}+JTR=5!`^ArDPqN977JJ`@=c%H z`5L|l#TzG>v~E3QGM#^=WGlS(#_`l086J)uV{USP;@$(bSec*H-#F7=h$4WgaPzxBZmGi?y(muRo;eI%uRSDDO7$LN?U8l@Ykgj?5 z_%lMbT=mj4F6iV%@$^_d&(pBb{z&u_DoohU%+F{SCl#v#`|!IrS1eet z^z3-ObT!gGxO1T@$4r<=VciKk`jw}-?(HoYL_MhA%;WR&iFy}5h*3pc0$qTkDD{EF z?|nV_^&3teEu4ryHd@oHxp1M^*zuZ9d{~&YD(3us!G9f|FqQre7dHxMI@tCw)I)=% z2UW8sfFzfF9>O@iF7Be~^-m70h++vQ?hnnbak_Bm9Gw8U8$$Gqdv=*2lEu`oCU$|3e zc{PVlv~Qlo57fKsV@-CYE$Lkf3y|DvZYnf_5j#*t=|Mp%+mn9M40%RU*%64t(vL~y z)^L!bx^&{=tDdt9SNSN*3V%X+4%$( z1Nk;I4y=Opu$77^7BpD_0Srv&trGnLf<|lJtPN*PgGkz3WxK`D(~eY zxMZ#I`^+PiI!ZD2oqG;Hw3x|k{l2m@Z*_{T#%^7-P##vW1-aSA#u7Tv;xBxao*3Ka zcWCy<>=_~CvKkV0{6?{|0Y7$wz;gaYR5d2I;DRj~M5|=XDxSyBo>8GyqDt4MqcM7* zcZH+K1rOuWAKR;Icm7{#(J|)t56gWa z*K%ozY#%_Ifs8uT`Fb6rK^yL(D|=r$_I6ojyE*cuL;3PqXw=!B?EV~ZBr|Wc=--U| znzvupL)FTrykuL0joDbL`N%VIu|;4uhk&Ue||;rbY`%IH0~kY7Ef~5DzGdS zBl&Q-GuZ*5rVy4*dU4TqIC(j-U@N5S&}l@MZf+jly-HMhk_}ePlP^mL6$Yu6{RU|$ zj;uD=idjRRHwJNGnX%*n&Rri)C-M>y4Gw(Z$|F~P4Y7`h z>TWF8e&47!kwBksar=eDBKlMKM4BV>g|=;s`Rv5>Sj@-gTjf9iX;gO96o)DD{+{&q zTfs(3+Z~;rD~1*M0g^}eeL!P_Pz9AJ_O#o;kBI5N6MGPjPj;c2*Val2fwp6 zp^ipd8d>{#9_B4^c#?vSgstR*Jc+wEM;FK8-in0}YO!kI%;OMs1++4E7==*G`$Oo4 zgj+yOp-GG)zAR>JI%mn#&nlE0$zclzTa**Nx7L{DIbeh2+$S!LtWgVBmUcFq-^jt? z^gTd_SBlk*r4>x}U%QL8{SO58lmb1?zA-svCF1(8qKCqEY^P=>RcvB|hQFS4(FWCH zdpbqW)Xv~3T%mT2wlZvm^5ETmG9jmjr{$|ZO1fvWpRw5RkEcH2uiM2>c*wV<;#EAq z`cIe7GcA5qdk1JF1bR3(58!=mQC`W3hyEwE1<(3B@}IE!b75`I!LyD7zwW`bX^}au z+ETx5K1`@NlZG66P6P(9?g;!5?JG8gsk(1e`4S)%bv-=w-3!{1Xuo{37#`V=R*0HD z*w|<*+B{x)NvIKW8BJe=uS`eOONaH-R;1s;IZqwR6I6>iRBSdt{7Xo$;b%7v<|5}% zL+h8vpEif{xDD>yBi~mktxld#aL5gLZ)A&=Qze`YVvKyi{a0UqjGTeVS1o74V8sKC zc*T2$(suW}4;d>b^Q5`qRoG7!q>f{nRU5OorPCTw1YUj^sNxHmyR8*D3|OtmC{xXjpfp1)hO2e@A&Yi@L{FN0^k9@>Wz-^((pF=amP4t#{ z9q|-K_EdoKSgR`V8fI_xkI?O<5s=XCate{6>^8}xE6kg}Av>|l@ z$zt!@KG2?WPPP&Ih9;=KcU#8PuZf@J*cIu(FaO zoO7G{m~gc}O?r_CD!MVL#D*4LKRI27AuD52=EfiBQo??gLi95~T%6id6-=QWZl*Em zI0%D-_iDou*4q_Y<~qUg+QzZ#|mwgxx zMR`<~1Vi>;LZNLVsL$i@rmrY0Jn^1@hRtPnhyQe(O>9%zxO0Ap)Iv_fTowfW2EA;e zfU5M`?LeGyu}z$N+0*<;J>g_DaO$LZrJ@}RhBXfh(0b*FI({F*vwJF^IT7YW4JK-c zJ(X%dZYN3I$bvUwUcL?!YCa>{f6aC{ybH9aj_w_MHJO?B**=2k^uzR>NcYc>5;| z2k9Ceqn%ns!TK_A{lH|Y%Ny+ex4YZ_jTa?>a1GWWki22f-{&(8QqS=jV^PeQ#S&89 z>T1S>Pm~!eFy6Q zRq{EX43fEz#)yj17$o`d68h^s2K)3e@)_N@F8 zo`hla%$cB)3)369*~%fIzR1HX{5aeX9O*u<1%gP`BY(K{4yzI5__B01jf~- zUy+n}@eZ_LqH6QMd}`5dr`TF<>Crax2`3^hbCp^uUYim2VNi=jBat0`VBLwzFIi9+ z7*Tq5jinN`W9y=oe_>x!X|cAjOy{r2E1v0CFG`Z)gM%R{1xd4R_|ediZL#c$rW#!O zjYLZ|J`t)`kIHYbqu~nyPf05;NqhN+3E?X#;IT>-M1BACkWHLo?UJ{vvfs+=U{${S za^2zaurO3%H_bnQQ0W<)>i2Fr z`dl}^4UN$0`zElkvc{m~#P_0JUd=^ZT*keQ4#kXdzcpKMWFC$LPU+=aZ=)l@oH}^~ zLa7k}GpH(3vhIjlq#Bij<8VImgZ+-nA*)sWEL-H%5mH1tmiFynz@8gUD-ZZt=)1%% zKwzh15ASsUr=~qq-#O9C7o>DL(*1Ee5PO-Q$FXBVhLAEZFMIBTeh@#$ibj6N|I}$8 zW+3}M=eXfyIzt0|Nw@aDL_*ozS_k3_zUSOc0{&!7g42bMtw2d4@K*Iev zjvM#ggwk}x z6R*K6Ldc09KMqLP_iadgEo&Fe`hG&Lym36#pyW|yYq8(wCrv;qq&lYaQe^6QY6l6^ z|NMg&6K^nxytF!OqyxZXlc2VkumozGMfL|Znd;wv-2HuZ)-f0;^k%rlsB|Wto^pQ_ z(khrh!jL|raZ#_Vn%0l`N?02St5iuYmd8GS9FqS>6l2KFBhZR zC#-73c9CZF;F2Deo&iWq)qJrmPem;I#7F;W!$r_$L`=_Nl33kO=Yx#&(VO&6`NvM|%mRqt$9+4K@g z=ddj>xg_vdG)1B~zC7llRApG06$+nyy2Wa$iiPlV_9-{E#}(Xa$2!Z;?jXwQ8QT{( z$(nM=NHftNl7R-!KPtHN*|`c_`cA{tYZ&M~&(1{Wt}YGM4G$CN?*)br=`Jd5(u$|U zZvMX)pi$b_6pMkLcLFPCVMQko7K^B2Cu4;KuCB+Sm9Fk;PmI}fv+21X& zz#^t15wMSe>eqk~RCfW##zeAs0y@c>4M~^JU!9sQPtckWbiL%s?)_6@l^e-c-Q@hl zjqy?Ec^rI=8Ec3mG@0>nI_@c1_b_sUoH&BN>*zneK9#fvDVTHfMrPDv*?&wmM=c^Y zw$_5rF;tt z{{X%c5$O+FPvEu-%6@>SvL86ES4QV0b9d?K(vQ*pOPa*zU#^m*#gBZ3SAPn>exldfpW+ppv2xSQIsDmR9UTnqYEi zSo>}tF48pl)RBX2(Na^zm?}9TDoCqbdAH$mU6lqH=`NILe<#0~42SB45WAN|%*+_y zR2Z01x|qD0YWg_sRW}#7&stddoMOZ{Az{n6TnDLHPiAXE`kQe14mu>8wBAZ4qvYv5 zbn|%i6Fvl`P*ZS6*Y|dR;76Q4fKQO$ZS*Ddod&x@KSM%7`u_H9TrDouWA5)zZUW)(8QYYE|vd)l=Cm$7@PJ_*syfR&oQbjL7 zMI2ud6B9F*Fwx$1Q1f$dapiC0t`dU5Coq_Z!`LVv7&;K;zcuTXpI zNeoiW`8vIcQ`B6zZh%JMznNt14&G!AsXsUTl3Lv3nQ+jDnpQa2vjXM@X>s$xVcjRw zSia^}laq!U`J-(szuMiD>h(oz1vTwex*Bg-_(!%K&GBg%-Hr-M?zQ z5=f026Y=ywg&AYlo&5$`PHzvpVWbNHg+!vsH{<%33)Owm;S7-gTW8eG+eM z58*ypW-;O2IXSJcAjJZaEOll<;Ry`M^HBk5flDwDcRoNCrLSpoWXMIYpjv8>#yUTz zh^EAH?HW21A`NEek(;!)JbwLja8|}hY9;S-H-N?{h|PjluAM*8g$IVa;`2wH% z)UowwsUfmzxxxKRC{u%3h`SM)P@bzy@v}>;Zu0kLIaX#_5Rf^u>gk zh~+9Ngox$M{~$-4LWME;4vY&V;p1k^w;Ky${;Pb4r;yQeaqU$6EfBfK*+_e?IC4FT zG*Qjd%yt0=A8uUOG^Ubg{lTuhVA?$&eTF8FhIAbv|HnzJmo}P0YlfR{GZf)Moj;J4H%geL+B+`xZh0 znIMgvPj#sM;2#|pZU;GD)2oYvrY&%-9hu9Ap$b6M>H2W9Mt}|#6U-p=%bn3~97Nl{ zC!R95NE41VeZ9dhzQYocL?}-#cf>m&=x;6GYkZo{1+k_Rk9sq-F%B+EDJYA+>WMjR z?S00$bvf8`zFF`qABjTRgD zd|oeS;?9v3%TlO{xwxib+vt!<*HkEyXKv*!kg)t2v!&g*W+Zo|xK7TMbZ2~Tc^7No zXR8;u%nVFVuC~D@zt{72s6?=KzC2hmYt2L097g;%;Q!{?Ym}%>1F-A>UbOyC%Q%o4 zGljL*8%)t?b;}}op`iZJH746uw=Kj5kL4>!eYO2!Iy^>)H*tAAF6QCU>UokT2k?cI z-yx{d_mm(*ZZ9MR21EB!-^nf4`-dDMyz81bh`LP1S~*_zJUH<7vXS-c1E3i7ZXW}YkZQeG^Izp23iy2;MxcK!@$Z~4-3(nQ3Q zC)4>d@WRr?W+XitO9|9NabTP*mJxu)BOKe-Flh0Zags?SAZR1H#fRn9RM{XS^YmG7 zUa7w%S%3qqhozfhp4lDD(*9|iM_0w=WRs5y_HCs#n633r%5kX?`;?b(?mEAxmyVXi zSo;S~v{fA6T6wfoV1??7~bnYEGv8L?$&~!-40}r zM~g8OmX7^6FbJ=bB>Sc+PcSQ)GvxpmDKb$-jJ^PfQY^ei2#SWx9H}oFg4YE`qL(W4 z1SIC%ZGOcn$r)flS_?=Y#7Ej(A_wDTbstZ7`c|7L;00gm?C~CA9&hZIkUpDtJLiTZ zME#@ZnqSh0K#1l~2a3DvT2;aT<&$l>_^4Lu;DLgWV5+*;5_#!Mj39HyYnzl`GUI?1 z&IoLt+TPvi2y_`7eLI8t8vUj6sfw)voNKWr<$R-4qXRnV{g3>F�Jm*Vks>C5(<3 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 literal 445849 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%0A^luL2lw{rAHvdV~3et~|sX#0!*J^M& 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 z z<{&(KyqMT&*fV=|urd0djxRa%FUZlabNCis=^#-6!|R{^if_)Mx;rzK=S=vtjwc&N z(*G`7x8YlVe2Fl?%l#uClj?bV{e2|&ZtuuYWoH9l;y)BOG&$^UNQl(uL*N>k#Bux6 z7f$G15I{d5NJM1~-ZR})=4b61Bggj|7C;-*w;oO7D0xJvFOnr|l4~ROcziDlZ6VXd zHiAf82;KZzf1nmMtY*(RuCEqJc+6L!nQ;&2bd}yLJ91lxauF)=j|Aba51A~bTZYu=kq60P8S z3#dJ!n4TkfI)Uw5t~jUSstnJ7g4Cne8YN0TEc$8+2vV=mYt8Vz*JdANZE!KkXK^g! zKQ~4DSYDgAb+Nxsfp#a$3bd7YzbIPYF#^}j8q9B9qMq1TpO7Qp$W^?Rn-B<7_>ogW zugRmO97u>PZeQ%eUeyc6P&@{cCvx?wcdrfOVo{f><&Fz#x6jEz& zX2BE5N%b@yO<5A%K;)g5r_ayb(wkqRA%P2z|BD?Y6Rg6kiPYX2`5JjAcT^k;)2j9{ z+$&mKDI0#|LLTvLe(_> zzs&N*ynnW^on3W#)r#MrtI8jmy%sckBQyr9x<4mk01=Zl5#;UYK!zu9s!P#C_m^v9 zM^zm8jW^Xxm;R>~z{eR$9l2pnc&QyP^U@1{aTeWT0!W!2$vP|#Vx=b)k$~vSLQZ%~ zpRL`PF_e+&?{${6Kd7FNrteD5SRS>)WXuA6hZ2JGcF`}AY~guWG

    Hx(O9i3vZ?{ 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%0D{zS0^rK18?0}(mVBaRX3%_Q94Z< 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%0AnFk8+?8p&t#W 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⩔2;oO;aJm1Y21xS;7515?>`k+(xxI%e{XgdenR^rf!9!~S9C9!ex2*v;7F_EqTs>BM%Ns9w z&)%^q%@1Kq8BSEPwfsE>BF^9ZS9buW4+w;SFAgKHNq#uw`8yF;6=I9Cwo6peeyXEN zQvI;XoL(e}Cf~<8V+}>L>|}iMmSKyMnBjMqEoMVK0{fT>l_@5VTuI}HO1nE65Y%)m zu9ED;H44lAVG!Tu2KLzgYYX5I=>x48zn5@4{ER#6a9oAniZ)_rD12hF{DkRBvovB~ zJEr~eEduXd%cK%wh~dRTx9j-&*&ptzhJcW@k&bccx0tup>3Ny<)GtkYraL!K##29w zje*-6@0+gK^&HLs)bu1CQU)uI4Hjn&PhF$ez`?u-6|jz5Ho@XO6bI;Sk3&TY0I3fb zqczb!-n7d%IJ7n_fjUiEc!_&~haCLRgMP7?XExniH$@zr&UStbAG2|NE8ZWks2NvK zPVP~eV;aFTD??AuumjMcI@pG}hZe=EY$faZJwwM?#qh2QpAc4poQ@b`hCSn!|L;p0 z&r18V5fX2MhsK#KTK}c^m2)rHrWbtr{MuZS|AW8F$SvTkvd3fKC?oE>371i@i4*O2 zW5~N*$PSQ^0nTQ8rqTc24}7FXP}2p`5E1-Ot&-8;4n40pq_MKa@uf%Yo41LOp1R0Kacr;p7;Ot z#*z6y{p0H~HZKG!AWDp Date: Sun, 14 Dec 2014 11:04:17 +0100 Subject: [PATCH 0283/2686] Store exercice title XML in DB --- db/feed.sql | 81 ++++++++++++----------- db/fic2014.sql | 1 + onyx/include/admin/exercice.php | 1 + onyx/include/common/Exercice.class.php | 21 ++++-- onyx/tpl/bootstrap/admin/exercice.tpl | 6 +- onyx/tpl/bootstrap/admin/export_theme.tpl | 2 +- onyx/tpl/bootstrap/admin/layout.tpl | 2 +- onyx/tpl/bootstrap/admin/themes.tpl | 2 +- onyx/tpl/bootstrap/teams/exercice.tpl | 2 +- onyx/tpl/bootstrap/teams/theme.tpl | 6 +- 10 files changed, 69 insertions(+), 55 deletions(-) diff --git a/db/feed.sql b/db/feed.sql index bb064b01..a76b5e18 100644 --- a/db/feed.sql +++ b/db/feed.sql @@ -128,49 +128,50 @@ INSERT INTO `exercices` ( `require` , `level` , `points` , +`title`, `statement` ) VALUES -('1', '1', '', '1', '1', 'Description 1'), -('2', '1', '1', '2', '5', 'Description 2'), -('3', '1', '2', '3', '10', 'Description 3'), -('4', '1', '3', '4', '20', 'Description 4'), -('5', '1', '4', '5', '40', 'Description 5'), -('6', '2', '', '1', '1', 'Description 6'), -('7', '2', '6', '2', '5', 'Description 7'), -('8', '2', '7', '3', '10', 'Description 8'), -('9', '2', '8', '4', '20', 'Description 9'), -('10', '2', '9', '5', '40', 'Description 10'), -('11', '3', '', '1', '1', 'Description 11'), -('12', '3', '11', '2', '5', 'Description 12'), -('13', '3', '12', '3', '10', 'Description 13'), -('14', '3', '13', '4', '20', 'Description 14'), -('15', '3', '14', '5', '40', 'Description 15'), -('16', '4', '', '1', '1', 'Description 16'), -('17', '4', '16', '2', '5', 'Description 17'), -('18', '4', '17', '3', '10', 'Description 18'), -('19', '4', '18', '4', '20', 'Description 19'), -('20', '4', '19', '5', '40', 'Description 20'), -('21', '5', '', '1', '1', 'Description 21'), -('22', '5', '23', '2', '5', 'Description 22'), -('23', '5', '25', '3', '10', 'Description 23'), -('24', '5', '21', '4', '20', 'Description 24'), -('25', '5', '24', '5', '40', 'Description 25'), -('26', '6', '', '1', '1', 'Description 26'), -('27', '6', '26', '2', '5', 'Description 27'), -('28', '6', '28', '3', '10', 'Description 28'), -('29', '6', '27', '4', '20', 'Description 29'), -('30', '6', '29', '5', '40', 'Description 30'), -('31', '7', '', '1', '1', 'Description 31'), -('32', '7', '35', '2', '5', 'Description 32'), -('33', '7', '31', '3', '10', 'Description 33'), -('34', '7', '32', '4', '20', 'Description 34'), -('35', '7', '33', '5', '40', 'Description 35'), -('36', '8', '', '1', '1', 'Description 36'), -('37', '8', '40', '2', '5', 'Description 37'), -('38', '8', '36', '3', '10', 'Description 38'), -('39', '8', '37', '4', '20', 'Description 39'), -('40', '8', '38', '5', '40', 'Description 40'); +('1', '1', '', '1', '1', 'Title X', 'Description 1'), +('2', '1', '1', '2', '5', 'Title X', 'Description 2'), +('3', '1', '2', '3', '10', 'Title X', 'Description 3'), +('4', '1', '3', '4', '20', 'Title X', 'Description 4'), +('5', '1', '4', '5', '40', 'Title X', 'Description 5'), +('6', '2', '', '1', '1', 'Title X', 'Description 6'), +('7', '2', '6', '2', '5', 'Title X', 'Description 7'), +('8', '2', '7', '3', '10', 'Title X', 'Description 8'), +('9', '2', '8', '4', '20', 'Title X', 'Description 9'), +('10', '2', '9', '5', '40', 'Title X', 'Description 10'), +('11', '3', '', '1', '1', 'Title X', 'Description 11'), +('12', '3', '11', '2', '5', 'Title X', 'Description 12'), +('13', '3', '12', '3', '10', 'Title X', 'Description 13'), +('14', '3', '13', '4', '20', 'Title X', 'Description 14'), +('15', '3', '14', '5', '40', 'Title X', 'Description 15'), +('16', '4', '', '1', '1', 'Title X', 'Description 16'), +('17', '4', '16', '2', '5', 'Title X', 'Description 17'), +('18', '4', '17', '3', '10', 'Title X', 'Description 18'), +('19', '4', '18', '4', '20', 'Title X', 'Description 19'), +('20', '4', '19', '5', '40', 'Title X', 'Description 20'), +('21', '5', '', '1', '1', 'Title X', 'Description 21'), +('22', '5', '23', '2', '5', 'Title X', 'Description 22'), +('23', '5', '25', '3', '10', 'Title X', 'Description 23'), +('24', '5', '21', '4', '20', 'Title X', 'Description 24'), +('25', '5', '24', '5', '40', 'Title X', 'Description 25'), +('26', '6', '', '1', '1', 'Title X', 'Description 26'), +('27', '6', '26', '2', '5', 'Title X', 'Description 27'), +('28', '6', '28', '3', '10', 'Title X', 'Description 28'), +('29', '6', '27', '4', '20', 'Title X', 'Description 29'), +('30', '6', '29', '5', '40', 'Title X', 'Description 30'), +('31', '7', '', '1', '1', 'Title X', 'Description 31'), +('32', '7', '35', '2', '5', 'Title X', 'Description 32'), +('33', '7', '31', '3', '10', 'Title X', 'Description 33'), +('34', '7', '32', '4', '20', 'Title X', 'Description 34'), +('35', '7', '33', '5', '40', 'Title X', 'Description 35'), +('36', '8', '', '1', '1', 'Title X', 'Description 36'), +('37', '8', '40', '2', '5', 'Title X', 'Description 37'), +('38', '8', '36', '3', '10', 'Title X', 'Description 38'), +('39', '8', '37', '4', '20', 'Title X', 'Description 39'), +('40', '8', '38', '5', '40', 'Title X', 'Description 40'); INSERT INTO `solved` ( `id` , diff --git a/db/fic2014.sql b/db/fic2014.sql index ea48d5c5..fc5713ac 100644 --- a/db/fic2014.sql +++ b/db/fic2014.sql @@ -26,6 +26,7 @@ CREATE TABLE IF NOT EXISTS `exercices` ( `require` varchar(100) COLLATE utf8_unicode_ci NULL, `level` tinyint(4) NOT NULL, `points` smallint(6) NOT NULL, + `title` varchar(255) COLLATE utf8_unicode_ci NULL, `statement` text COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; diff --git a/onyx/include/admin/exercice.php b/onyx/include/admin/exercice.php index 1259b9f5..e87e894b 100644 --- a/onyx/include/admin/exercice.php +++ b/onyx/include/admin/exercice.php @@ -26,6 +26,7 @@ try if (!empty($_POST)) { $exercice->points = intval($_POST["points"]); + $exercice->title = $_POST["title"]; $exercice->statement = $_POST["desc"]; $exercice->require = $_POST["require"]; $exercice->level = intval($_POST["level"]); diff --git a/onyx/include/common/Exercice.class.php b/onyx/include/common/Exercice.class.php index eef3827b..e924968e 100644 --- a/onyx/include/common/Exercice.class.php +++ b/onyx/include/common/Exercice.class.php @@ -10,6 +10,7 @@ class Exercice var $require; var $level; var $points; + var $title; var $statement; var $files = array(); var $keys = array(); @@ -24,7 +25,7 @@ class Exercice $db->escape($id); $res = $db->unique_query("SELECT `id`, `id_theme`, `require`, `level`, - `points`, `statement` + `points`, `title`, `statement` FROM exercices WHERE id = '$id'"); if (!empty($res)) @@ -64,6 +65,7 @@ class Exercice $this->require = $res['require']; $this->level = $res['level']; $this->points = $res['points']; + $this->title = $res['title']; $this->statement = $res['statement']; $this->set_number(); @@ -86,6 +88,7 @@ class Exercice $tmp->require = $array["require"]; $tmp->level = $array["level"]; $tmp->points = $array["points"]; + $tmp->title = $array["title"]; $tmp->statement = $array["statement"]; $tmp->files = $array["files"]; $tmp->keys = $array["keys"]; @@ -98,9 +101,12 @@ class Exercice return $this->id; } - function get_name() + function get_title($menu=false) { - return "Exercice ".$this->number; + if ($menu || empty($this->title)) + return "Exercice ".$this->number; + else + return $this->title; } function get_statement() @@ -108,8 +114,7 @@ class Exercice return $this->statement; } - // retourne le nombre d'equipes qui ont résolues l'exercice - // trié par date + // retourne les équipes qui ont résolues l'exercice triées par date function get_solved() { $id = $this->id; @@ -209,6 +214,7 @@ class Exercice $require = $this->require; $level = intval($this->level); $points = intval($this->points); + $title = $this->title; $statement = $this->statement; $files = $this->files; $keys = $this->keys; @@ -217,17 +223,18 @@ class Exercice $db->escape($id); $db->escape($theme); $db->escape($require); + $db->escape($title); $db->escape($statement); if ($create) { $db->query("INSERT INTO exercices - VALUES ('".$id."', '".$theme."', '".$require."', '".$level."', '".$points."','".$statement."');"); + VALUES ('".$id."', '".$theme."', '".$require."', '".$level."', '".$points."','".$title."','".$statement."');"); } else { $db->query("UPDATE exercices - SET `id_theme` = '".$theme."', `require` = '".$require."', `level` = '".$level."', `points` = '".$points."', `statement` = '".$statement."' + SET `id_theme` = '".$theme."', `require` = '".$require."', `level` = '".$level."', `points` = '".$points."', `title` = '".$title."', `statement` = '".$statement."' WHERE id = '$id'"); $aff = $db->affected(); diff --git a/onyx/tpl/bootstrap/admin/exercice.tpl b/onyx/tpl/bootstrap/admin/exercice.tpl index affd82af..cb11fcbe 100644 --- a/onyx/tpl/bootstrap/admin/exercice.tpl +++ b/onyx/tpl/bootstrap/admin/exercice.tpl @@ -3,6 +3,10 @@ {if isset($ex)}

    {$theme->name} {$ex->id}

    +
    + + +
    @@ -85,7 +89,7 @@

    diff --git a/onyx/tpl/bootstrap/admin/export_theme.tpl b/onyx/tpl/bootstrap/admin/export_theme.tpl index 208ac16a..5e86eaaa 100644 --- a/onyx/tpl/bootstrap/admin/export_theme.tpl +++ b/onyx/tpl/bootstrap/admin/export_theme.tpl @@ -4,7 +4,7 @@ {if $theme->get_exercices_ordered()} {foreach from=$theme->get_exercices_ordered() item=e} require} depends="{$e->require}"{/if}> - {$e->get_name()} + {$e->get_title()} {$e->points} {$e->statement} {if $e->keys} diff --git a/onyx/tpl/bootstrap/admin/layout.tpl b/onyx/tpl/bootstrap/admin/layout.tpl index db385e5d..d56229cd 100644 --- a/onyx/tpl/bootstrap/admin/layout.tpl +++ b/onyx/tpl/bootstrap/admin/layout.tpl @@ -39,7 +39,7 @@ {link href_prefix="/{$SALT_ADMIN}/" href="ex/{$t->get_id()}-{$t->get_name()}" class="dropdown-toggle" data-toggle="dropdown" label="{$t->get_name()} "} diff --git a/onyx/tpl/bootstrap/admin/themes.tpl b/onyx/tpl/bootstrap/admin/themes.tpl index 939638d5..be5fa1c7 100644 --- a/onyx/tpl/bootstrap/admin/themes.tpl +++ b/onyx/tpl/bootstrap/admin/themes.tpl @@ -22,7 +22,7 @@
    {$my_team->get_name()}{$my_team->get_name()|replace:"_":" "}Exercice {$i}{$t->name} diff --git a/onyx/tpl/bootstrap/teams/exercice.tpl b/onyx/tpl/bootstrap/teams/exercice.tpl index 48ae7f99..078b07d8 100644 --- a/onyx/tpl/bootstrap/teams/exercice.tpl +++ b/onyx/tpl/bootstrap/teams/exercice.tpl @@ -3,7 +3,7 @@ {block name=exercices}
    -

    Exercice {$cur_exercice->number} {$solved} équipe{if $solved > 1}s ont{else} a{/if} résolu cet exercice

    +

    {$cur_exercice->get_title()} {$solved} équipe{if $solved > 1}s ont{else} a{/if} résolu cet exercice

      diff --git a/onyx/tpl/bootstrap/teams/theme.tpl b/onyx/tpl/bootstrap/teams/theme.tpl index 0e9c4118..f10dbe0b 100644 --- a/onyx/tpl/bootstrap/teams/theme.tpl +++ b/onyx/tpl/bootstrap/teams/theme.tpl @@ -6,11 +6,11 @@

      {foreach from=$cur_theme->get_exercices_ordered() item=exercice} {if $exercice->has_solved($my_team)} - {link class="btn btn-success" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}/" label="{$exercice->get_name()}"} + {link class="btn btn-success" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}/" label="{$exercice->get_title(true)}"} {elseif $exercice->is_unlocked($my_team)} - {link class="btn btn-primary" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}/" label="{$exercice->get_name()}"} + {link class="btn btn-primary" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}/" label="{$exercice->get_title(true)}"} {else} - {$exercice->get_name()} + {$exercice->get_title(true)} {/if} {/foreach}

      From 28b5d91b9a5b0c39e9b24a7f9c60ac37cf6d9ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sun, 14 Dec 2014 13:16:22 +0100 Subject: [PATCH 0284/2686] Sanitize Dockerfile --- Dockerfile | 43 +++++++++---- front/Dockerfile | 13 ++-- gen_site.sh | 156 ----------------------------------------------- 3 files changed, 39 insertions(+), 173 deletions(-) delete mode 100755 gen_site.sh diff --git a/Dockerfile b/Dockerfile index 987fd9dd..b7e19797 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,36 +29,53 @@ RUN apt-get -y update && \ RUN cpanm Mcrypt +WORKDIR /var/www/fic-server/misc + # Copying files ####################################################### ADD . /var/www/fic-server/ # Configure softwares ################################################# -RUN ln -sf /var/www/fic-server/nginx-server.conf /etc/nginx/sites-enabled/default -RUN ln -sf /var/www/fic-server/php-fpm.conf /etc/php5/fpm/pool.d/www.conf +RUN ln -sf /var/www/fic-server/nginx-server.conf /etc/nginx/sites-enabled/default && \ + ln -sf /var/www/fic-server/php-fpm.conf /etc/php5/fpm/pool.d/www.conf # Generate test certificates ########################################## -RUN cd /var/www/fic-server/misc; bash ./CA.sh -newca +RUN bash ./CA.sh -newca # Import DB ########################################################### -RUN service mysql start && echo "CREATE DATABASE fic;" | mysql -u root && cat /var/www/fic-server/db/fic2014.sql | mysql -u root fic +RUN service mysql start && \ + echo "CREATE DATABASE fic;" | mysql -u root && \ + cat /var/www/fic-server/db/fic2014.sql | mysql -u root fic # Uncomment the following line to fill with random values -#RUN service mysql start && cat /var/www/fic-server/db/feed.sql | mysql -u root fic +RUN service mysql start && cat /var/www/fic-server/db/feed.sql | mysql -u root fic # Configure site ###################################################### -RUN ln -sf /var/www/fic-server/onyx/config/sample.root.xml /var/www/fic-server/onyx/config/root.xml -RUN sed -i "s/1386827772/`date -d 'now + 4 hours' +%s`/" /var/www/fic-server/onyx/config/root.xml -RUN sed -i "s/challenge-public//" /var/www/fic-server/onyx/config/root.xml - -RUN chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/templates/cache/ /var/www/fic-server/onyx/cache/templates/compile/ +RUN ln -sf /var/www/fic-server/onyx/config/sample.root.xml /var/www/fic-server/onyx/config/root.xml && \ + sed -i "s/1386827772/`date -d 'now + 4 hours' +%s`/" /var/www/fic-server/onyx/config/root.xml && \ + sed -i "s/challenge-public//" /var/www/fic-server/onyx/config/root.xml && \ + chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/templates/cache/ /var/www/fic-server/onyx/cache/templates/compile/ # ENVIRONNEMENT ####################################################### -EXPOSE 80/tcp 443/tcp -VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submission","/var/www/fic-server/misc/shared"] -CMD ["sh", "-c", "chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; cd /var/www/fic-server/misc; if ! [ -f server.crt ]; then bash ./CA.sh -newserver; fi; bash ./CA.sh -gencrl && service nginx start && service php5-fpm start && service mysql start && echo 'Copying files...' && ../gen_hash_link_files.sh --copy ../files-in ../files && ../nginx_gen_team.sh > ../misc/shared/nginx-teams.conf && (../launch_local.sh &); /bin/bash"] +EXPOSE 80/tcp 443/tcp +VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submission","/var/www/fic-server/misc/shared"] + +CMD chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; \ + if ! [ -f server.crt ]; \ + then \ + bash ./CA.sh -newserver; \ + fi; \ + bash ./CA.sh -gencrl && \ + service nginx start && \ + service php5-fpm start && \ + service mysql start && \ + ../nginx_gen_team.sh > ../misc/shared/nginx-teams.conf && \ + echo 'Copying files...' && \ + ../gen_hash_link_files.sh --copy ../files-in ../files; \ + (../launch_local.sh &); \ + /bin/bash diff --git a/front/Dockerfile b/front/Dockerfile index 833e9d89..d2c63d0a 100644 --- a/front/Dockerfile +++ b/front/Dockerfile @@ -15,16 +15,21 @@ RUN apt-get -y update && \ && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* +WORKDIR /var/www/fic-server/front/ + # Copying files ####################################################### ADD . /var/www/fic-server/front/ # Configure softwares ################################################# -RUN ln -sf /var/www/fic-server/front/nginx.conf /etc/nginx/sites-enabled/default -RUN ln -sf /var/www/fic-server/front/php-fpm.conf /etc/php5/fpm/pool.d/www.conf +RUN ln -sf /var/www/fic-server/front/nginx.conf /etc/nginx/sites-enabled/default && \ + ln -sf /var/www/fic-server/front/php-fpm.conf /etc/php5/fpm/pool.d/www.conf # ENVIRONNEMENT ####################################################### -EXPOSE 80/tcp 443/tcp -CMD ["sh", "-c", "service nginx start && service php5-fpm start && /bin/bash"] +EXPOSE 80/tcp 443/tcp + +CMD service nginx start && \ + service php5-fpm start && \ + /bin/bash diff --git a/gen_site.sh b/gen_site.sh deleted file mode 100755 index 4fa11caf..00000000 --- a/gen_site.sh +++ /dev/null @@ -1,156 +0,0 @@ -#!/bin/bash - -BASEURL="localhost" -SALT_TEAM="connected" -OUT_TEAM="./teams" -OUT_HTDOCS="./htdocs" - -MAX_PARAL=10 - -DEBUG=0 - - -cd `dirname "$0"` - -if [ "$UID" = "0" ] -then - SCRIPT=`pwd`/`basename "$0"` - su -c "sh -c '$SCRIPT $@'" synchro - exit $? -fi - -if [ -f "/tmp/generate_site" ] -then - echo "This script is already running" 1>&2 - echo "Remove the file /tmp/generate_site if you are sure this is not true" 1>&2 - exit 1 -fi - -touch /tmp/generate_site - -WGET_OPT="--no-check-certificate -c" - -if [ $DEBUG -ne 1 ] -then - WGET_OPT="-q" -fi - -./clear_cache.sh top - -mkdir -p out - -ORIG_DIR=`pwd` -MYTMPDIR=`mktemp -d` -cd "$MYTMPDIR" - -# First, remove existing version if any -rm -rf "$BASEURL" "$OUT_TEAM" - -wget $WGET_OPT -m -b "http://$BASEURL/" -o /dev/null - -mkdir -p "$BASEURL" -ln -sf "$ORIG_DIR/files/" "$BASEURL/files" - -# Get list of teams -TEAMS= -if [ $# -gt 0 ] -then - while [ $# -gt 0 ] - do - TEAMS="$TEAMS /$SALT_TEAM/$1/" - shift - done - FULLSYNC=0 -else - for l in $(curl -k "http://$BASEURL/$SALT_TEAM/" 2> /dev/null | grep -oE "/[^/]+/[0-9]+/") - do - TEAMS="$TEAMS $l" - done - FULLSYNC=1 -fi - -echo "Team list to generate: $TEAMS" - -NB=0 -PIDLIST= -# Fetch them in parallel -for l in $TEAMS -do - ( - if ! wget $WGET_OPT -m "http://$BASEURL/$l" - then - exit 1 - fi - - for m in $(grep -R "&2 - exit $ERR - -else - MOREOPT= - if [ "$FULL" -eq "1" ] - then - MOREOPT="--delete" - fi - # Ok, now, sync files with prod - rsync -av $MOREOPT * "$ORIG_DIR/out" - - cd "$ORIG_DIR" - rm -rf "$MYTMPDIR" -fi From e8e0b4478b7b9bbb8b6c2c798f4f2735615c8139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Mon, 15 Dec 2014 00:17:03 +0100 Subject: [PATCH 0285/2686] Fix favicon display on front --- front/nginx.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/front/nginx.conf b/front/nginx.conf index 2760600e..a7ea76e9 100644 --- a/front/nginx.conf +++ b/front/nginx.conf @@ -62,7 +62,7 @@ server { root /var/www/fic-server/out/; } - location /connected + location /challenge { return 403; } @@ -77,7 +77,7 @@ server { output_buffers 1 128k; } - location ~* \favicon.ico$ { + location = /favicon.ico { root /var/www/fic-server/out/htdocs/; access_log off; expires 1d; From 7865fbdf1fcb5d6c42fe0a4ee092615763a2064a Mon Sep 17 00:00:00 2001 From: Nemunaire Date: Sun, 28 Dec 2014 11:13:50 +0100 Subject: [PATCH 0286/2686] Fix PHP communication with socket --- onyx/include/admin/chrono.php | 3 ++- onyx/include/common.php | 9 ++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/onyx/include/admin/chrono.php b/onyx/include/admin/chrono.php index 1fd4de44..a134f47a 100644 --- a/onyx/include/admin/chrono.php +++ b/onyx/include/admin/chrono.php @@ -15,9 +15,10 @@ if (count($p) > 2) case "init": unlink($VAR["misc_dir"]."/challenge_started"); + pipe_backend_scheduler("resetreset:HOME:all:SY"); break; } } header("Location: /".SALT_ADMIN."/"); -exit(); \ No newline at end of file +exit(); diff --git a/onyx/include/common.php b/onyx/include/common.php index 38578fce..6b293188 100644 --- a/onyx/include/common.php +++ b/onyx/include/common.php @@ -24,15 +24,22 @@ if (is_file($VAR["misc_dir"]."/challenge_started")) function pipe_backend_scheduler($instruct) { + global $VAR; + $socket = socket_create(AF_UNIX, SOCK_STREAM, 0); if (is_writable($VAR["scheduler_socket"]) && socket_connect($socket, $VAR["scheduler_socket"])) { socket_write($socket, $instruct); socket_close($socket); } + else if(defined("DEBUG") && DEBUG) + { + print("Socket '".$VAR["scheduler_socket"]."' is not writable by ".$_SERVER["USER"]." user!"); + exit(1); + } } if (!empty($VAR['misc_dir'])) $template->assign("MISC_DIR", $VAR['misc_dir']); if (!empty($LANG)) - $template->assign("LANG", $LANG); + $template->assign("LANG", $LANG); From da1e9da4952386c7f18ec3d88cc61400ffb62d0a Mon Sep 17 00:00:00 2001 From: Nemunaire Date: Sun, 28 Dec 2014 14:51:40 +0100 Subject: [PATCH 0287/2686] Fix some permission issues --- Dockerfile | 7 ++++++- gen_site.pl | 1 + launch_local.sh | 12 ++++++------ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index b7e19797..bfb00138 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,8 @@ RUN apt-get -y update && \ RUN cpanm Mcrypt +RUN useradd -d /var/www/fic-server/misc/ -M -N -g www-data synchro + WORKDIR /var/www/fic-server/misc # Copying files ####################################################### @@ -65,7 +67,10 @@ RUN ln -sf /var/www/fic-server/onyx/config/sample.root.xml /var/www/fic-server/o EXPOSE 80/tcp 443/tcp VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submission","/var/www/fic-server/misc/shared"] -CMD chown -R www-data:www-data /var/www/fic-server/misc /var/www/fic-server/submission; \ +CMD mkdir -p /var/www/fic-server/logs; \ + chown -R www-data:www-data /var/www/fic-server/misc; \ + chown -R synchro:www-data /var/www/fic-server/submission /var/www/fic-server/logs /var/www/fic-server/out; \ + chmod 660 /var/www/fic-server/submission; \ if ! [ -f server.crt ]; \ then \ bash ./CA.sh -newserver; \ diff --git a/gen_site.pl b/gen_site.pl index c21da15f..0345b674 100755 --- a/gen_site.pl +++ b/gen_site.pl @@ -348,6 +348,7 @@ sub create_socket Type => SOCK_STREAM, Listen => SOMAXCONN, ); + chmod 0660, $socket_path; say "Socket listening on $socket_path; waiting for connections..."; while(my $connection = $socket->accept) diff --git a/launch_local.sh b/launch_local.sh index 49d9afb3..a96bb433 100755 --- a/launch_local.sh +++ b/launch_local.sh @@ -7,12 +7,12 @@ cd `dirname "$0"` source config.sh -#if [ "$UID" = "0" ] -#then -# SCRIPT=`pwd`/`basename "$0"` -# su -c "sh $SCRIPT" "$SYNCHRO_USER" -# exit $? -#fi +if [ "$UID" = "0" ] +then + SCRIPT=`pwd`/`basename "$0"` + su -c "sh $SCRIPT" "$SYNCHRO_USER" + exit $? +fi mkdir -p ./logs From 739d5b5722fabcbb3e22807a4d1a299edaec2600 Mon Sep 17 00:00:00 2001 From: Nemunaire Date: Mon, 29 Dec 2014 01:34:18 +0100 Subject: [PATCH 0288/2686] Use team 0 to display solutions --- htdocs/css/main.css | 11 +++++++++++ onyx/include/common/Team.class.php | 2 +- onyx/tpl/bootstrap/teams/exercice.tpl | 21 +++++++++++++++++++-- onyx/tpl/bootstrap/teams/layout.tpl | 21 ++++++++++++++++++++- onyx/tpl/bootstrap/teams/theme.tpl | 4 +++- 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/htdocs/css/main.css b/htdocs/css/main.css index 084763cc..4a04e24d 100644 --- a/htdocs/css/main.css +++ b/htdocs/css/main.css @@ -46,6 +46,17 @@ text-shadow: 0 0 5px #00c6ff; } +.samptest { + display: block !important; + overflow-x: scroll; + text-overflow: ellipsis; +} +samp { + display: block; + overflow-x: scroll; + text-overflow: ellipsis; +} + .point { position: relative; -moz-animation: clockanim 1s ease infinite; diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 88b4c8ec..9aa3100f 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -126,7 +126,7 @@ class Team } function get_id() { - return $this->id; + return intval($this->id); } function get_slogan() { diff --git a/onyx/tpl/bootstrap/teams/exercice.tpl b/onyx/tpl/bootstrap/teams/exercice.tpl index 078b07d8..662ff74b 100644 --- a/onyx/tpl/bootstrap/teams/exercice.tpl +++ b/onyx/tpl/bootstrap/teams/exercice.tpl @@ -49,10 +49,27 @@
      -

      Soumettre une solution

      +

      {if $my_team->id}Soumettre une solution{else}Solutions{/if}

      -{if $cur_exercice->has_solved($my_team)} +{if empty($my_team->id)} + Vérifiez votre solution parmi les algorithmes suivants : + + + + + + + + {foreach from=$cur_exercice->keys item=key} + + + + + {/foreach} + +
      AlgorithmeHash
      {$key.format}
      {$key.value}
      +{else if $cur_exercice->has_solved($my_team)} Résolu à {$cur_exercice->has_solved($my_team)|date_format:"%H:%M:%S"} :) {else} {if $cur_exercice->last_try($my_team)} diff --git a/onyx/tpl/bootstrap/teams/layout.tpl b/onyx/tpl/bootstrap/teams/layout.tpl index 7a01b72f..33fc8ae0 100644 --- a/onyx/tpl/bootstrap/teams/layout.tpl +++ b/onyx/tpl/bootstrap/teams/layout.tpl @@ -15,7 +15,24 @@ {/block} {block name=body} + {if $my_team->id} {include file="clock.tpl"} + {else} +
      + + +
      +
      • Challenge forensic
      +
      + {/if}
      {if $ERRmessage} @@ -27,6 +44,7 @@
      + {if $my_team->id} + {/if}
      {foreach from=$themes item=t key=k} get_id()}/" href="{$t->get_id()}-{$t->get_name_url()}/"}"> - {$my_team->get_nb_res_exercises_by_theme($t->get_id())}/{$t->get_nb_exercices()} + {if $my_team->id}{$my_team->get_nb_res_exercises_by_theme($t->get_id())}/{/if}{$t->get_nb_exercices()} {$t->get_name()} {/foreach} diff --git a/onyx/tpl/bootstrap/teams/theme.tpl b/onyx/tpl/bootstrap/teams/theme.tpl index f10dbe0b..907bd957 100644 --- a/onyx/tpl/bootstrap/teams/theme.tpl +++ b/onyx/tpl/bootstrap/teams/theme.tpl @@ -5,7 +5,9 @@

      {$cur_theme->get_name()}

      {foreach from=$cur_theme->get_exercices_ordered() item=exercice} - {if $exercice->has_solved($my_team)} + {if empty($my_team->id)} + {link class="btn btn-primary" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}/" label="{$exercice->get_title(true)}"} + {elseif $exercice->has_solved($my_team)} {link class="btn btn-success" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}/" label="{$exercice->get_title(true)}"} {elseif $exercice->is_unlocked($my_team)} {link class="btn btn-primary" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}/" label="{$exercice->get_title(true)}"} From 242408d59eace519f037827ca085ff98838086e2 Mon Sep 17 00:00:00 2001 From: Nemunaire Date: Tue, 20 Jan 2015 11:22:32 +0100 Subject: [PATCH 0289/2686] DS are very, VERY bad --- check.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check.pl b/check.pl index ae3c615d..bc3ec707 100755 --- a/check.pl +++ b/check.pl @@ -190,7 +190,7 @@ for my $f (readdir $dh) $sth = query($dbh, "SELECT S.id FROM solved S WHERE S.id_team = $team AND S.id_exercice = ".$dbh->quote($exercice)); if (! $sth->rows) { - say "resetresetreset:TEAM$team,$theme:SYNCSYN:TEAM$team:SYNC:HOME:SYNC:all:DS"; + say "resetresetreset:TEAM$team,$theme:SYNCSYN:TEAM$team:SYNC:HOME:SYNC:all:SY"; say STDERR localtime().": Team $team solve exercice $exercice in $theme"; query($dbh, "INSERT INTO solved (id_team, id_exercice, time) VALUES ($team, ".$dbh->quote($exercice).", CURRENT_TIMESTAMP);"); From 95be134c508a2ea9993da456a668d0ab797e0b9e Mon Sep 17 00:00:00 2001 From: Nemunaire Date: Tue, 20 Jan 2015 11:31:36 +0100 Subject: [PATCH 0290/2686] Update TOTO --- TODO | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/TODO b/TODO index cf48e0f2..4377cddf 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,17 @@ * HTML/CSS/Templates ** TODO Mettre à jour les logos ** TODO trop de thèmes dans l'interface d'admin => menu +** TODO avoir la page avec le résumé * PHP ** TODO Départager les ex-æquo dans le classement ** TODO On peut encore soumettre après la fin... ** TODO numéro des exercices +** TODO pouvoir désactiver les équipes qui ne participent pas (pour accélérer la génération) +** TODO ajouter des teams sans passer par l'import XML +** TODO page de statistiques +select count(*) as t, id_exercice, name from solved S inner join exercices E ON E.id = S.id_exercice INNER JOIN themes T ON E.id_theme = T.id group by id_exercice order by t DESC; +select id_team, COUNT(*) AS t from exercice_tries group by id_team ORDER BY t; + ** Onyx *** TODO Mettre à jour Smarty (et passer en « secure mode » ?) ** Admin @@ -15,6 +22,8 @@ * Perl/shell ** TODO Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe ** TODO Gerer les espaces dans les fichiers (gen_hash_file plante) +** TODO Couleur l'output de check.pl +** TODO Pouvoir regénérer une série d'exercices pour toutes les teams * Security ** TODO Quand est généré la CRL ? ** TODO Ajouter dans la conf de nginx un ssl_dhparam + générer le fichier dans un script From ef78e8816ff370fe5784af75b83e7352981cf063 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 13 Jan 2015 06:27:39 +0100 Subject: [PATCH 0291/2686] Team isn't authenticated --- onyx/include/common/Team.class.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 9aa3100f..1f421bd3 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -249,11 +249,6 @@ class Team return NULL; } - function authenticate($certificate) - { - //TODO - } - // Static methods public static function set_revoked($bool, $name) { From 158426f37286a8b223f481af868bb397c2ed8614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Tue, 13 Jan 2015 07:05:35 +0100 Subject: [PATCH 0292/2686] Tiebreaker if tied --- TODO | 1 - onyx/include/common/Team.class.php | 11 +++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/TODO b/TODO index 4377cddf..fcd288e8 100644 --- a/TODO +++ b/TODO @@ -3,7 +3,6 @@ ** TODO trop de thèmes dans l'interface d'admin => menu ** TODO avoir la page avec le résumé * PHP -** TODO Départager les ex-æquo dans le classement ** TODO On peut encore soumettre après la fin... ** TODO numéro des exercices ** TODO pouvoir désactiver les équipes qui ne participent pas (pour accélérer la génération) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index 1f421bd3..32cb0be2 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -7,16 +7,15 @@ function cmp_team_pts($i1, $i2) if ($i1->get_pts() == $i2->get_pts()){ $db = new BDD(); - $timestampi1 = $db->unique_query("SELECT MAX( s.time ) AS maxTime + $timestampi1 = $db->unique_query("SELECT MAX(s.time) AS maxTime FROM solved AS s - WHERE s.id_team =".$i1->get_id()); - $timestampi2 = $db->unique_query("SELECT MAX( s.time ) AS maxTime + WHERE s.id_team = ".$i1->get_id()); + $timestampi2 = $db->unique_query("SELECT MAX(s.time) AS maxTime FROM solved AS s - WHERE s.id_team =".$i2->get_id()); - + WHERE s.id_team = ".$i2->get_id()); $db->deconnexion(); - if ($timestampi1['maxTime'] > $timestampi2['maxTime']) + if (strtotime($timestampi1['maxTime']) > strtotime($timestampi2['maxTime'])) return 1; else return -1; From f1870a8555ed8d723a8f86ef5354a88d637ad15e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Tue, 13 Jan 2015 07:07:26 +0100 Subject: [PATCH 0293/2686] Remove first / when importing files --- TODO | 1 - onyx/include/admin/import_themes.php | 8 +++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index fcd288e8..8c87720c 100644 --- a/TODO +++ b/TODO @@ -14,7 +14,6 @@ select id_team, COUNT(*) AS t from exercice_tries group by id_team ORDER BY t; ** Onyx *** TODO Mettre à jour Smarty (et passer en « secure mode » ?) ** Admin -*** TODO Lors de l'import des XML, retirer l'éventuel / en début de path *** TODO valider les documents avec la DTD à l'import *** TODO upload/MAJ de fichiers depuis l'interface d'admin? *** TODO lors de l'import, vérifier que les ID existent => afficher les erreurs MySQL diff --git a/onyx/include/admin/import_themes.php b/onyx/include/admin/import_themes.php index fcc8a5b0..052ddc3a 100644 --- a/onyx/include/admin/import_themes.php +++ b/onyx/include/admin/import_themes.php @@ -61,10 +61,16 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) $child->nodeValue); else if ($child->nodeName == "file") + { + $path = $child->getAttribute("path"); + if ($path[0] == "/") + $path = substr($path, 1); + $ex->add_file( - $child->getAttribute("path"), + $path, $child->nodeValue, $child->getAttribute("sha1")); + } } if (!$theme->add_exercice($ex)) From d4e0f4966890a1b7b92c368e1d5b5453b13678bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Tue, 13 Jan 2015 07:46:27 +0100 Subject: [PATCH 0294/2686] Fix socket communication --- onyx/include/common.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/onyx/include/common.php b/onyx/include/common.php index 6b293188..dc38c1d8 100644 --- a/onyx/include/common.php +++ b/onyx/include/common.php @@ -29,7 +29,9 @@ function pipe_backend_scheduler($instruct) $socket = socket_create(AF_UNIX, SOCK_STREAM, 0); if (is_writable($VAR["scheduler_socket"]) && socket_connect($socket, $VAR["scheduler_socket"])) { - socket_write($socket, $instruct); + socket_write($socket, $instruct."\r\n") or die(socket_strerror(socket_last_error())); + sleep(1); + socket_shutdown($socket); socket_close($socket); } else if(defined("DEBUG") && DEBUG) From 7ac1fdcf079010b6d23872648d25b845e7c955c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Tue, 13 Jan 2015 08:13:49 +0100 Subject: [PATCH 0295/2686] Various script fixes --- backup.sh | 2 +- clear_cache.sh | 2 +- launch.sh | 4 ++-- launch_local.sh | 4 ++-- synchro.sh | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/backup.sh b/backup.sh index bfdfdee3..3af478fa 100755 --- a/backup.sh +++ b/backup.sh @@ -4,7 +4,7 @@ cd `dirname "$0"` -source config.sh +. ./config.sh chown "$SYNCHRO_USER" "$TO_BCKP" diff --git a/clear_cache.sh b/clear_cache.sh index 024aaf5e..1dde7628 100755 --- a/clear_cache.sh +++ b/clear_cache.sh @@ -4,7 +4,7 @@ cd `dirname "$0"` -source config.sh +. ./config.sh for n in "$@" do diff --git a/launch.sh b/launch.sh index d157f502..a1762534 100755 --- a/launch.sh +++ b/launch.sh @@ -5,7 +5,7 @@ rm -f /tmp/stop cd `dirname "$0"` -source config.sh +. ./config.sh if [ "$UID" = "0" ] then @@ -25,7 +25,7 @@ TMPF=`mktemp` tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/scheduler.sock -o ./out ERRORS HOME all DS & KP2=$! -trap "kill $KP1 $KP2; rm -rf '$TMPF'; echo" SIGINT SIGTERM +trap "kill $KP1 $KP2; rm -rf '$TMPF'; echo; kill $$" INT TERM while ! [ -f /tmp/stop ]; do diff --git a/launch_local.sh b/launch_local.sh index a96bb433..48f6202f 100755 --- a/launch_local.sh +++ b/launch_local.sh @@ -5,7 +5,7 @@ rm -f /tmp/stop cd `dirname "$0"` -source config.sh +. ./config.sh if [ "$UID" = "0" ] then @@ -25,7 +25,7 @@ TMPF=`mktemp` tail -f "$TMPF" | ./gen_site.pl -d -s /tmp/scheduler.sock -bt /challenge/ -ba /challenge-admin/ -o ./out ERRORS HOME all DS & KP2=$! -trap "kill $KP1 $KP2; rm -rf '$TMPF'; echo" SIGINT SIGTERM +trap "kill $KP1 $KP2; rm -rf '$TMPF'; echo; kill $$" INT TERM while ! [ -f /tmp/stop ]; do diff --git a/synchro.sh b/synchro.sh index aac801eb..06c4de68 100755 --- a/synchro.sh +++ b/synchro.sh @@ -5,7 +5,7 @@ cd `dirname "$0"` -source config.sh +. ./config.sh if [ "$UID" = "0" ] then From cdf28980d3d16bdcfb15791b9cbb9ddce1774308 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 13 Jan 2015 15:13:02 +0100 Subject: [PATCH 0296/2686] New Dockerfile that generate a Debian package for Mcrypt perl module --- .dockerignore | 2 ++ TODO | 1 + perl-mcrypt/Dockerfile | 15 +++++++++++++++ perl-mcrypt/README.md | 23 +++++++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 perl-mcrypt/Dockerfile create mode 100644 perl-mcrypt/README.md diff --git a/.dockerignore b/.dockerignore index 6b8710a7..be3095ed 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1 +1,3 @@ .git +TODO +perl-mcrypt/ diff --git a/TODO b/TODO index 8c87720c..10c51013 100644 --- a/TODO +++ b/TODO @@ -19,6 +19,7 @@ select id_team, COUNT(*) AS t from exercice_tries group by id_team ORDER BY t; *** TODO lors de l'import, vérifier que les ID existent => afficher les erreurs MySQL * Perl/shell ** TODO Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe +** TODO Éviter cpanm et build-essential en compilant un .deb avant ** TODO Gerer les espaces dans les fichiers (gen_hash_file plante) ** TODO Couleur l'output de check.pl ** TODO Pouvoir regénérer une série d'exercices pour toutes les teams diff --git a/perl-mcrypt/Dockerfile b/perl-mcrypt/Dockerfile new file mode 100644 index 00000000..12e6e339 --- /dev/null +++ b/perl-mcrypt/Dockerfile @@ -0,0 +1,15 @@ +FROM debian:wheezy +MAINTAINER Pierre-Olivier Mercier + +# Install packages #################################################### + +RUN apt-get -y update && \ + apt-get install -y \ + libmcrypt-dev \ + libltdl-dev \ + build-essential \ + dh-make-perl \ + && \ + apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +CMD cpan2deb Mcrypt diff --git a/perl-mcrypt/README.md b/perl-mcrypt/README.md new file mode 100644 index 00000000..d032ada3 --- /dev/null +++ b/perl-mcrypt/README.md @@ -0,0 +1,23 @@ +# Mcrypt module + +This container creates Debian package for the `Mcrypt` module. + + +## Usage + +First, build the container: + +``` +docker build -t mcrypt-builder . +``` + +Run the container then retrieve the package: + +``` +docker run --name mcrypt_builder mcrypt-builder +docker cp mcrypt_builder:$(docker diff mcrypt_builder | grep -oE '[^ ]+deb$') ./ +docker rm mcrypt_builder +``` + +In your current directory, you will have a file named like: +`libmcrypt-perl_2.5.7.0-1_amd64.deb`. From 3aedea2cabad4aa327a40aa119da7860f374ab2e Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 13 Jan 2015 15:28:21 +0100 Subject: [PATCH 0297/2686] Use binary version of perl mcrypt module instead of having build-essential in container --- .dockerignore | 1 + .gitignore | 1 + Dockerfile | 15 ++++++--------- TODO | 1 - 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/.dockerignore b/.dockerignore index be3095ed..6547bec8 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ .git TODO +docs/guide perl-mcrypt/ diff --git a/.gitignore b/.gitignore index 8d74cfc1..c6e9d82c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ onyx/db/*.profile.php onyx/tpl/*/*.html submission/* misc/openssl.cnf +libmcrypt-perl_2.5.7.0-1_amd64.deb diff --git a/Dockerfile b/Dockerfile index bfb00138..41b1524c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,31 +15,28 @@ RUN apt-get -y update && \ mysql-server \ php5-mysql \ php5-mcrypt \ - libmcrypt-dev \ + libmcrypt4 \ libwww-perl \ libdigest-whirlpool-perl \ pwgen \ curl \ openssl \ - cpanminus \ - build-essential \ - libltdl-dev \ && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -RUN cpanm Mcrypt - RUN useradd -d /var/www/fic-server/misc/ -M -N -g www-data synchro -WORKDIR /var/www/fic-server/misc - # Copying files ####################################################### +WORKDIR /var/www/fic-server/misc + ADD . /var/www/fic-server/ # Configure softwares ################################################# -RUN ln -sf /var/www/fic-server/nginx-server.conf /etc/nginx/sites-enabled/default && \ +RUN dpkg -i /var/www/fic-server/libmcrypt-perl*.deb || \ + (echo "Please build perl-mcrypt first. Consult the given README!"; exit 1) && \ + ln -sf /var/www/fic-server/nginx-server.conf /etc/nginx/sites-enabled/default && \ ln -sf /var/www/fic-server/php-fpm.conf /etc/php5/fpm/pool.d/www.conf # Generate test certificates ########################################## diff --git a/TODO b/TODO index 10c51013..8c87720c 100644 --- a/TODO +++ b/TODO @@ -19,7 +19,6 @@ select id_team, COUNT(*) AS t from exercice_tries group by id_team ORDER BY t; *** TODO lors de l'import, vérifier que les ID existent => afficher les erreurs MySQL * Perl/shell ** TODO Résoudre le problème potentiel de famine de l'ordonnanceur en cas de brute-force d'une équipe -** TODO Éviter cpanm et build-essential en compilant un .deb avant ** TODO Gerer les espaces dans les fichiers (gen_hash_file plante) ** TODO Couleur l'output de check.pl ** TODO Pouvoir regénérer une série d'exercices pour toutes les teams From 1d65c5a836a2a856dd3ac43c82ad4f260537660f Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 13 Jan 2015 15:34:52 +0100 Subject: [PATCH 0298/2686] Rename TOP_DIR to PKI_DIR --- misc/CA.sh | 44 +++++++++++++++--------------- onyx/include/admin/certificate.php | 10 +++---- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/misc/CA.sh b/misc/CA.sh index 362984c9..e54efc7d 100755 --- a/misc/CA.sh +++ b/misc/CA.sh @@ -2,16 +2,16 @@ cd $(dirname "$0") -if [ -z "${TOP_DIR}" ]; then - TOP_DIR=pki +if [ -z "${PKI_DIR}" ]; then + PKI_DIR=pki fi if [ -z "${OPENSSL_CONF}" ]; then OPENSSL_CONF=openssl.cnf fi -CAKEY=${TOP_DIR}/private/cakey.key -CAREQ=${TOP_DIR}/careq.csr +CAKEY=${PKI_DIR}/private/cakey.key +CAREQ=${PKI_DIR}/careq.csr CACRT=./shared/cacert.crt SRVKEY=./shared/server.key @@ -47,16 +47,16 @@ usage() clean() { if [ "$1" = "ca" ]; then - rm -rf ${TOP_DIR} ./shared/* - mkdir -p ${TOP_DIR}/certs - mkdir -p ${TOP_DIR}/crl - mkdir -p ${TOP_DIR}/newcerts - mkdir -p ${TOP_DIR}/private - mkdir -p ${TOP_DIR}/pkcs + rm -rf ${PKI_DIR}/* ./shared/* + mkdir -p ${PKI_DIR}/certs + mkdir -p ${PKI_DIR}/crl + mkdir -p ${PKI_DIR}/newcerts + mkdir -p ${PKI_DIR}/private + mkdir -p ${PKI_DIR}/pkcs mkdir -p ./shared - echo "01" > ${TOP_DIR}/crlnumber + echo "01" > ${PKI_DIR}/crlnumber elif [ "$1" = "client" ]; then - rm -rf ${TOP_DIR}/${2}.key ${TOP_DIR}/${2}.csr + rm -rf ${PKI_DIR}/${2}.key ${PKI_DIR}/${2}.csr fi rm -rf $OUTPUT } @@ -81,9 +81,9 @@ case $1 in echo $ECHO_OPTS "${GREEN}Create the directories, take care this will delete the old directories ${COLOR_RST}" clean "ca" - touch ${TOP_DIR}/index.txt + touch ${PKI_DIR}/index.txt - ESCAPED=$(echo "${TOP_DIR}" | sed 's/[\/\.]/\\&/g') + ESCAPED=$(echo "${PKI_DIR}" | sed 's/[\/\.]/\\&/g') echo $ECHO_OPTS "${GREEN}Making CA key and csr${COLOR_RST}" sed -i 's/=.*#COMMONNAME/= FIC CA #COMMONNAME/' $OPENSSL_CONF @@ -178,15 +178,15 @@ case $1 in fi CLTNAM=$2 - CLTREQ=${TOP_DIR}/${CLTNAM}.csr - CLTCRT=${TOP_DIR}/certs/${CLTNAM}.crt - CLTKEY=${TOP_DIR}/${CLTNAM}.key - CLTP12=${TOP_DIR}/pkcs/${CLTNAM}.p12 + CLTREQ=${PKI_DIR}/${CLTNAM}.csr + CLTCRT=${PKI_DIR}/certs/${CLTNAM}.crt + CLTKEY=${PKI_DIR}/${CLTNAM}.key + CLTP12=${PKI_DIR}/pkcs/${CLTNAM}.p12 echo "==============================================================" echo $ECHO_OPTS "${GREEN}Making the client key and csr of ${BOLD}${2}${END_BOLD}${COLOR_RST}" - ESCAPED=$(echo "${TOP_DIR}" | sed 's/[\/\.]/\\&/g') + ESCAPED=$(echo "${PKI_DIR}" | sed 's/[\/\.]/\\&/g') sed -i "s/=.*#DIR/= ${ESCAPED} #DIR/" $OPENSSL_CONF if ! [ -f ${CAKEY} ]; then @@ -232,7 +232,7 @@ case $1 in else echo $ECHO_OPTS "Exported pkcs12 file is ${CLTP12}" fi - echo "$CLTNAM:$pass" >> ${TOP_DIR}/../teams.pass + echo "$CLTNAM:$pass" >> ${PKI_DIR}/../teams.pass echo "$CLTNAM:$pass" clean "client" ${CLTNAM} ;; @@ -244,8 +244,8 @@ case $1 in fi CLTNAM=$2 - CLTCRT=${TOP_DIR}/certs/${CLTNAM}.crt - CLTP12=${TOP_DIR}/pkcs/${CLTNAM}.p12 + CLTCRT=${PKI_DIR}/certs/${CLTNAM}.crt + CLTP12=${PKI_DIR}/pkcs/${CLTNAM}.p12 echo $ECHO_OPTS "${GREEN}Revocate ${BOLD}${CLTNAM}${END_BOLD}${COLOR_RST}" if ! openssl ca -revoke "${CLTCRT}" -config "${OPENSSL_CONF}" \ diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index a26cf585..d0cb5196 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -26,14 +26,14 @@ function new_client($name, $misc_dir) { //TODO handle if already exist putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); - putenv("TOP_DIR=$misc_dir/pki"); + putenv("PKI_DIR=$misc_dir/pki"); return shell_exec("$misc_dir/CA.sh -newclient $name"); } function revoke_client($name, $misc_dir) { putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); - putenv("TOP_DIR=$misc_dir/pki"); + putenv("PKI_DIR=$misc_dir/pki"); return shell_exec("$misc_dir/CA.sh -revoke $name"); } @@ -50,7 +50,7 @@ if (!empty($p[2])) if ($p[2] == "newca") { putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); - putenv("TOP_DIR=$misc_dir/pki"); + putenv("PKI_DIR=$misc_dir/pki"); $template->assign("output", shell_exec("$misc_dir/CA.sh -newca")); return "admin/shell"; @@ -65,7 +65,7 @@ if (!empty($p[2])) elseif ($p[2] == "newsrv") { putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); - putenv("TOP_DIR=$misc_dir/pki"); + putenv("PKI_DIR=$misc_dir/pki"); $template->assign("output", shell_exec("$misc_dir/CA.sh -newserver")); return "admin/shell"; @@ -74,7 +74,7 @@ if (!empty($p[2])) elseif ($p[2] == "revokesrv") { putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); - putenv("TOP_DIR=$misc_dir/pki"); + putenv("PKI_DIR=$misc_dir/pki"); $template->assign("output", shell_exec("$misc_dir/CA.sh -revokeserver")); return "admin/shell"; From de48af8ef8fc33afe302e940f36dd3ccde2cce4c Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 13 Jan 2015 17:04:35 +0100 Subject: [PATCH 0299/2686] Move PKI scripts to pki directory --- onyx/include/admin/certificate.php | 25 ++++++++++--------------- {misc => pki}/CA.sh | 30 +++++++++++++----------------- {misc => pki}/openssl.cnf | 0 3 files changed, 23 insertions(+), 32 deletions(-) rename {misc => pki}/CA.sh (93%) mode change 100755 => 100644 rename {misc => pki}/openssl.cnf (100%) diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index d0cb5196..c6e23f86 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -25,16 +25,14 @@ function remove_directory($dir) function new_client($name, $misc_dir) { //TODO handle if already exist - putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); - putenv("PKI_DIR=$misc_dir/pki"); - return shell_exec("$misc_dir/CA.sh -newclient $name"); + putenv("PKI_BASEDIR=$misc_dir"); + return shell_exec("$misc_dir/../pki/CA.sh -newclient $name"); } function revoke_client($name, $misc_dir) { - putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); - putenv("PKI_DIR=$misc_dir/pki"); - return shell_exec("$misc_dir/CA.sh -revoke $name"); + putenv("PKI_BASEDIR=$misc_dir"); + return shell_exec("$misc_dir/../pki/CA.sh -revoke $name"); } if (!empty($p[2])) @@ -49,10 +47,9 @@ if (!empty($p[2])) if ($p[2] == "newca") { - putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); - putenv("PKI_DIR=$misc_dir/pki"); + putenv("PKI_BASEDIR=$misc_dir"); $template->assign("output", - shell_exec("$misc_dir/CA.sh -newca")); + shell_exec("$misc_dir/../pki/CA.sh -newca")); return "admin/shell"; } @@ -64,19 +61,17 @@ if (!empty($p[2])) elseif ($p[2] == "newsrv") { - putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); - putenv("PKI_DIR=$misc_dir/pki"); + putenv("PKI_BASEDIR=$misc_dir"); $template->assign("output", - shell_exec("$misc_dir/CA.sh -newserver")); + shell_exec("$misc_dir/../pki/CA.sh -newserver")); return "admin/shell"; } elseif ($p[2] == "revokesrv") { - putenv("OPENSSL_CONF=$misc_dir/openssl.cnf"); - putenv("PKI_DIR=$misc_dir/pki"); + putenv("PKI_BASEDIR=$misc_dir"); $template->assign("output", - shell_exec("$misc_dir/CA.sh -revokeserver")); + shell_exec("$misc_dir/../pki/CA.sh -revokeserver")); return "admin/shell"; } diff --git a/misc/CA.sh b/pki/CA.sh old mode 100755 new mode 100644 similarity index 93% rename from misc/CA.sh rename to pki/CA.sh index e54efc7d..596a6a8a --- a/misc/CA.sh +++ b/pki/CA.sh @@ -2,21 +2,21 @@ cd $(dirname "$0") -if [ -z "${PKI_DIR}" ]; then - PKI_DIR=pki +if [ -z "${PKI_BASEDIR}" ]; then + PKI_BASEDIR=pki fi -if [ -z "${OPENSSL_CONF}" ]; then - OPENSSL_CONF=openssl.cnf -fi +PKI_DIR=${PKI_BASEDIR}/pki +SHARED_DIR=${PKI_BASEDIR}/shared +OPENSSL_CONF=`pwd`/openssl.cnf CAKEY=${PKI_DIR}/private/cakey.key CAREQ=${PKI_DIR}/careq.csr -CACRT=./shared/cacert.crt +CACRT=${SHARED_DIR}/cacert.crt -SRVKEY=./shared/server.key -SRVREQ=./shared/server.csr -SRVCRT=./shared/server.crt +SRVKEY=${SHARED_DIR}/server.key +SRVREQ=${SHARED_DIR}/server.csr +SRVCRT=${SHARED_DIR}/server.crt # Generate certificates valid for: DAYS=2 @@ -47,13 +47,9 @@ usage() clean() { if [ "$1" = "ca" ]; then - rm -rf ${PKI_DIR}/* ./shared/* - mkdir -p ${PKI_DIR}/certs - mkdir -p ${PKI_DIR}/crl - mkdir -p ${PKI_DIR}/newcerts - mkdir -p ${PKI_DIR}/private - mkdir -p ${PKI_DIR}/pkcs - mkdir -p ./shared + rm -rf ${PKI_DIR}/* ${SHARED_DIR}/* + mkdir -p ${PKI_DIR}/certs ${PKI_DIR}/crl ${PKI_DIR}/newcerts \ + ${PKI_DIR}/private ${PKI_DIR}/pkcs ${SHARED_DIR} echo "01" > ${PKI_DIR}/crlnumber elif [ "$1" = "client" ]; then rm -rf ${PKI_DIR}/${2}.key ${PKI_DIR}/${2}.csr @@ -64,7 +60,7 @@ clean() gen_crl() { echo $ECHO_OPTS "${GREEN}Generate shared/crl.pem${COLOR_RST}" - if ! openssl ca -config ${OPENSSL_CONF} -gencrl -out shared/crl.pem > $OUTPUT 2>&1 + if ! openssl ca -config ${OPENSSL_CONF} -gencrl -out ${SHARED_DIR}/crl.pem > $OUTPUT 2>&1 then echo $ECHO_OPTS "${RED}Generate shared/crl.pem failed" cat $OUTPUT diff --git a/misc/openssl.cnf b/pki/openssl.cnf similarity index 100% rename from misc/openssl.cnf rename to pki/openssl.cnf From d6879207792863924c2eb230cde13b7dd66114e3 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 13 Jan 2015 17:38:30 +0100 Subject: [PATCH 0300/2686] Externalize DB creation --- .dockerignore | 1 + Dockerfile | 13 ------------- db/Dockerfile | 23 +++++++++++++++++++++++ 3 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 db/Dockerfile diff --git a/.dockerignore b/.dockerignore index 6547bec8..15f6c53b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,5 @@ .git TODO +db/ docs/guide perl-mcrypt/ diff --git a/Dockerfile b/Dockerfile index 41b1524c..c90b0ab8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,19 +39,6 @@ RUN dpkg -i /var/www/fic-server/libmcrypt-perl*.deb || \ ln -sf /var/www/fic-server/nginx-server.conf /etc/nginx/sites-enabled/default && \ ln -sf /var/www/fic-server/php-fpm.conf /etc/php5/fpm/pool.d/www.conf -# Generate test certificates ########################################## - -RUN bash ./CA.sh -newca - -# Import DB ########################################################### - -RUN service mysql start && \ - echo "CREATE DATABASE fic;" | mysql -u root && \ - cat /var/www/fic-server/db/fic2014.sql | mysql -u root fic - -# Uncomment the following line to fill with random values -RUN service mysql start && cat /var/www/fic-server/db/feed.sql | mysql -u root fic - # Configure site ###################################################### RUN ln -sf /var/www/fic-server/onyx/config/sample.root.xml /var/www/fic-server/onyx/config/root.xml && \ diff --git a/db/Dockerfile b/db/Dockerfile new file mode 100644 index 00000000..51663ca0 --- /dev/null +++ b/db/Dockerfile @@ -0,0 +1,23 @@ +FROM debian:wheezy +MAINTAINER Pierre-Olivier Mercier + +# Install packages #################################################### + +RUN apt-get -y update && \ + apt-get install -y \ + mysql-client \ + && \ + apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# Copying files ####################################################### + +WORKDIR /var/www/fic-server + +ADD fic2014.sql feed.sql /var/www/fic-server/db/ + +# Import DB ########################################################### + +CMD echo "CREATE DATABASE IF NOT EXISTS $DB_ENV_MYSQL_DATABASE;" | mysql -h $DB_PORT_3306_TCP_ADDR -u root --password=$DB_ENV_MYSQL_ROOT_PASSWORD && \ + cat /var/www/fic-server/db/fic2014.sql | mysql -h $DB_PORT_3306_TCP_ADDR -u root --password=$DB_ENV_MYSQL_ROOT_PASSWORD $DB_ENV_MYSQL_DATABASE && \ + cat /var/www/fic-server/db/feed.sql | mysql -h $DB_PORT_3306_TCP_ADDR -u $DB_ENV_MYSQL_USER --password=$DB_ENV_MYSQL_PASSWORD $DB_ENV_MYSQL_DATABASE && \ + echo "Import ok" From a67912e89e103379eec89328f6c79d04350852cc Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 13 Jan 2015 17:55:24 +0100 Subject: [PATCH 0301/2686] Fill README with some steps for production env --- README.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/README.md b/README.md index af557a0d..e8186912 100644 --- a/README.md +++ b/README.md @@ -13,21 +13,26 @@ The easiest way to have a working server is to build a Docker container. ### Docker First, build the container with the following command: + ``` docker build -t fic . ``` Then, run it with: + ``` docker run -t -i -P fic ``` + It will ask you for a passphrase, you must provide one with at least 4 characters. This key is used to generate the server certificate. When you see: + ``` root@xxxxxxxxxxxx:/var/www/fic-server/misc# ``` + congratulations, the container is running! Use `docker ps` to view to which local ports was assigned the contained @@ -90,6 +95,53 @@ CONNTRACK states. #### Backend +##### Docker containers + +Main Docker backend container relies on several other container: + +* MySQL database ; +* Database storage (as data only container) ; +* PKI storage ; +* PKI shared storage ; +* challenge files containers ; +* the backend. + +To have a fully working backend: + +1. Create a data-only container: + +``` +docker run --name mysql_data -v /var/lib/mysql busybox +``` + +2. Setup the MySQL server: + +``` +docker run -d --name db_setup --volumes-from mysql_data -e MYSQL_ROOT_PASSWORD=mysecretpassword -e MYSQL_USER=fic -e MYSQL_PASSWORD=anotherpassword -e MYSQL_DATABASE=fic mysql +``` + +Fill the database: + +``` +docker build -t db_filler db/ +docker run --rm -it --link db_setup:db db_filler +``` + +Stop it: + +``` +docker stop db_setup +docker rm db_setup +``` + +3. Run the database container: + +``` +docker run -d --name db --volumes-from mysql_data mysql +``` + + + ##### Requirements * `realpath`; From 8cab91f51abd07d3f3474a7908ee0db0a91496e6 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 13 Jan 2015 17:58:33 +0100 Subject: [PATCH 0302/2686] Remove misc directory --- .gitignore | 1 - Dockerfile | 19 +++++++------------ README.md | 12 ++++++------ backup.sh | 3 ++- check.pl | 4 ++-- front/nginx.conf | 10 +++++----- gen_site.pl | 2 +- nginx-server.conf | 4 ++-- onyx/config/sample.root.xml | 2 +- onyx/include/admin/chrono.php | 4 ++-- onyx/include/admin/home.php | 4 ++-- onyx/include/common.php | 4 ++-- pki/CA.sh | 4 ++-- pki/openssl.cnf | 2 +- synchro.sh | 2 +- 15 files changed, 36 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index c6e9d82c..ce41b890 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,4 @@ onyx/config/root.xml onyx/db/*.profile.php onyx/tpl/*/*.html submission/* -misc/openssl.cnf libmcrypt-perl_2.5.7.0-1_amd64.deb diff --git a/Dockerfile b/Dockerfile index c90b0ab8..1b99827a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,11 +24,11 @@ RUN apt-get -y update && \ && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -RUN useradd -d /var/www/fic-server/misc/ -M -N -g www-data synchro +RUN useradd -d /var/www/fic-server -M -N -g www-data synchro # Copying files ####################################################### -WORKDIR /var/www/fic-server/misc +WORKDIR /var/www/fic-server ADD . /var/www/fic-server/ @@ -49,22 +49,17 @@ RUN ln -sf /var/www/fic-server/onyx/config/sample.root.xml /var/www/fic-server/o # ENVIRONNEMENT ####################################################### EXPOSE 80/tcp 443/tcp -VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submission","/var/www/fic-server/misc/shared"] +VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submission","/var/www/fic-server/shared"] CMD mkdir -p /var/www/fic-server/logs; \ - chown -R www-data:www-data /var/www/fic-server/misc; \ + chown -R www-data:www-data /var/www/fic-server/shared /var/www/fic-server/PKI; \ chown -R synchro:www-data /var/www/fic-server/submission /var/www/fic-server/logs /var/www/fic-server/out; \ chmod 660 /var/www/fic-server/submission; \ - if ! [ -f server.crt ]; \ - then \ - bash ./CA.sh -newserver; \ - fi; \ - bash ./CA.sh -gencrl && \ service nginx start && \ service php5-fpm start && \ service mysql start && \ - ../nginx_gen_team.sh > ../misc/shared/nginx-teams.conf && \ + ./nginx_gen_team.sh > ./shared/nginx-teams.conf && \ echo 'Copying files...' && \ - ../gen_hash_link_files.sh --copy ../files-in ../files; \ - (../launch_local.sh &); \ + ./gen_hash_link_files.sh --copy ./files-in ./files; \ + (./launch_local.sh &); \ /bin/bash diff --git a/README.md b/README.md index e8186912..a28a9c7d 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ characters. This key is used to generate the server certificate. When you see: ``` -root@xxxxxxxxxxxx:/var/www/fic-server/misc# +root@xxxxxxxxxxxx:/var/www/fic-server# ``` congratulations, the container is running! @@ -99,11 +99,11 @@ CONNTRACK states. Main Docker backend container relies on several other container: -* MySQL database ; -* Database storage (as data only container) ; -* PKI storage ; -* PKI shared storage ; -* challenge files containers ; +* MySQL database; +* Database storage (as data only container); +* PKI storage; +* PKI shared storage; +* challenge files containers; * the backend. To have a fully working backend: diff --git a/backup.sh b/backup.sh index 3af478fa..03b25030 100755 --- a/backup.sh +++ b/backup.sh @@ -20,7 +20,8 @@ then mysqldump -u backup --password="$BCKP_PASS" fic > "$TO_BCKP"/db/`date +%Y%m%d-%H%M`.sql - rsync -avL misc "$TO_BCKP" + rsync -avL shared "$TO_BCKP" + rsync -avL pki "$TO_BCKP" rsync -avL .git "$TO_BCKP" rsync -avL logs "$TO_BCKP" rsync -avL /var/log "$TO_BCKP" diff --git a/check.pl b/check.pl index bc3ec707..64bad518 100755 --- a/check.pl +++ b/check.pl @@ -63,9 +63,9 @@ for my $p (<$conf>) close $conf; my $end_time = 1999999999; -if (-f "$root/misc/challenge_started") +if (-f "$root/shared/challenge_started") { - open my $conf, "<", "$root/misc/challenge_started"; + open my $conf, "<", "$root/shared/challenge_started"; $end_time = <$conf>; close $conf; chomp($end_time); diff --git a/front/nginx.conf b/front/nginx.conf index a7ea76e9..699820df 100644 --- a/front/nginx.conf +++ b/front/nginx.conf @@ -18,15 +18,15 @@ server { access_log /var/log/nginx/fic.access_log; error_log /var/log/nginx/fic.error_log; - ssl_certificate /var/www/fic-server/misc/shared/server.crt; - ssl_certificate_key /var/www/fic-server/misc/shared/server.key; + ssl_certificate /var/www/fic-server/shared/server.crt; + ssl_certificate_key /var/www/fic-server/shared/server.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; # ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; ssl_ciphers AES256+EECDH:AES256+EDH; - ssl_client_certificate /var/www/fic-server/misc/shared/cacert.crt; + ssl_client_certificate /var/www/fic-server/shared/cacert.crt; ssl_verify_client optional; - ssl_crl /var/www/fic-server/misc/shared/crl.pem; + ssl_crl /var/www/fic-server/shared/crl.pem; add_header Strict-Transport-Security "max-age=2592000; includeSubdomains"; add_header X-Frame-Options DENY; @@ -46,7 +46,7 @@ server { set $team 0; - include /var/www/fic-server/misc/shared/nginx-teams.conf; + include /var/www/fic-server/shared/nginx-teams.conf; if ($team) { root /var/www/fic-server/out/teams/$team$1; diff --git a/gen_site.pl b/gen_site.pl index 0345b674..bcfb3399 100755 --- a/gen_site.pl +++ b/gen_site.pl @@ -184,7 +184,7 @@ sub manage elsif (/^RT(E(A(M(S)?)?)?)?/) { if (-x "nginx_gen_team.sh") { - qx(./nginx_gen_team.sh > ./misc/shared/nginx-teams.conf) + qx(./nginx_gen_team.sh > ./shared/nginx-teams.conf) } else { say "Unable to find nginx_gen_team.sh" } diff --git a/nginx-server.conf b/nginx-server.conf index 250949e9..36fe7e31 100644 --- a/nginx-server.conf +++ b/nginx-server.conf @@ -2,8 +2,8 @@ server { listen 443 ssl; listen [::]:443 ipv6only=on ssl; - ssl_certificate /var/www/fic-server/misc/shared/server.crt; - ssl_certificate_key /var/www/fic-server/misc/shared/server.key; + ssl_certificate /var/www/fic-server/shared/server.crt; + ssl_certificate_key /var/www/fic-server/shared/server.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; # ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:!ADH:!AECDH:!MD5:!DSS; diff --git a/onyx/config/sample.root.xml b/onyx/config/sample.root.xml index eceae299..b77fa14a 100644 --- a/onyx/config/sample.root.xml +++ b/onyx/config/sample.root.xml @@ -3,7 +3,7 @@ 1386827772 /var/www/fic-server/files/ - /var/www/fic-server/misc/ + /var/www/fic-server/ /var/www/fic-server/submission/ /tmp/scheduler.sock challenge-public diff --git a/onyx/include/admin/chrono.php b/onyx/include/admin/chrono.php index a134f47a..f86bbb1d 100644 --- a/onyx/include/admin/chrono.php +++ b/onyx/include/admin/chrono.php @@ -9,12 +9,12 @@ if (count($p) > 2) switch($p[2]) { case "start": - file_put_contents($VAR["misc_dir"]."/challenge_started", time() + (intval($_POST["time"]) - 240) * 60); + file_put_contents($VAR["misc_dir"]."/shared/challenge_started", time() + (intval($_POST["time"]) - 240) * 60); pipe_backend_scheduler("resetreset:HOME:all:SY"); break; case "init": - unlink($VAR["misc_dir"]."/challenge_started"); + unlink($VAR["misc_dir"]."/shared/challenge_started"); pipe_backend_scheduler("resetreset:HOME:all:SY"); break; } diff --git a/onyx/include/admin/home.php b/onyx/include/admin/home.php index 9f1c1b71..971f7f86 100644 --- a/onyx/include/admin/home.php +++ b/onyx/include/admin/home.php @@ -5,9 +5,9 @@ if(!defined('ONYX')) exit; if (isset($VAR['misc_dir'])) { $misc_dir = $VAR['misc_dir']; - if (!is_writable($misc_dir)) + if (!is_writable("$misc_dir/shared")) { - erreur("Dossier misc/ non accessible en écriture. ($misc_dir)"); + erreur("Dossier shared/ non accessible en écriture. ($misc_dir)"); return "admin/home"; } } diff --git a/onyx/include/common.php b/onyx/include/common.php index dc38c1d8..80ca4622 100644 --- a/onyx/include/common.php +++ b/onyx/include/common.php @@ -15,9 +15,9 @@ $template = new Template(); $template->assign("ERRmessage", false); -if (is_file($VAR["misc_dir"]."/challenge_started")) +if (is_file($VAR["misc_dir"]."/shared/challenge_started")) { - $VAR["start_challenge"] = intval(file_get_contents($VAR["misc_dir"]."/challenge_started")); + $VAR["start_challenge"] = intval(file_get_contents($VAR["misc_dir"]."/shared/challenge_started")); $VAR["end_challenge"] = $VAR["start_challenge"] + 14400; $template->assign("END", $VAR['end_challenge']); } diff --git a/pki/CA.sh b/pki/CA.sh index 596a6a8a..53fef8f1 100644 --- a/pki/CA.sh +++ b/pki/CA.sh @@ -3,10 +3,10 @@ cd $(dirname "$0") if [ -z "${PKI_BASEDIR}" ]; then - PKI_BASEDIR=pki + PKI_BASEDIR=$(dirname `pwd`) # equivalent to $(realpath `pwd`/.. fi -PKI_DIR=${PKI_BASEDIR}/pki +PKI_DIR=${PKI_BASEDIR}/PKI SHARED_DIR=${PKI_BASEDIR}/shared OPENSSL_CONF=`pwd`/openssl.cnf diff --git a/pki/openssl.cnf b/pki/openssl.cnf index a90cd294..c88fa734 100644 --- a/pki/openssl.cnf +++ b/pki/openssl.cnf @@ -39,7 +39,7 @@ default_ca = CA_default # The default ca section #################################################################### [ CA_default ] -dir = /var/www/fic-server/misc//pki #DIR # Where everything is kept +dir = /var/www/fic-server/pki #DIR # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. diff --git a/synchro.sh b/synchro.sh index 06c4de68..cb66e751 100755 --- a/synchro.sh +++ b/synchro.sh @@ -23,7 +23,7 @@ fi # Synchronize HTML pages rsync -e ssh -av $OPTS out "$FRONTEND_HOSTNAME":~/ rsync -e ssh -avL $OPTS files "$FRONTEND_HOSTNAME":~/ -rsync -e ssh -av $OPTS front/ misc/shared/ "$FRONTEND_HOSTNAME":~/ +rsync -e ssh -av $OPTS front/ shared/ "$FRONTEND_HOSTNAME":~/ # Synchronize submissions rsync -e ssh -av "$FRONTEND_HOSTNAME":~/submission/ submission/ From 34f3747a3bdb383fa6c7e8780a67fe46543a91a8 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 13 Jan 2015 18:08:22 +0100 Subject: [PATCH 0303/2686] Dockerfile for PKI --- README.md | 27 +++++++++++++++++++++++++++ pki/Dockerfile | 25 +++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 pki/Dockerfile diff --git a/README.md b/README.md index a28a9c7d..03233e11 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,33 @@ docker rm db_setup docker run -d --name db --volumes-from mysql_data mysql ``` +4. Setup the PKI storages: + +``` +docker run --name pki_storage -v /var/www/fic-server/PKI busybox +docker run --name shared_storage -v /var/www/fic-server/shared busybox +``` + +5. Build the PKI configuration container: + +``` +docker build -t pki_setup pki/ +``` + +6. Configure the PKI + +For development purpose, you can run the default setup: + +``` +docker run --rm -it --volumes-from pki_storage --volumes-from shared_storage pki_setup +``` + +For production environment: + +``` +docker run --rm -it --volumes-from pki_storage --volumes-from shared_storage pki_setup /bin/bash +TODO next steps +``` ##### Requirements diff --git a/pki/Dockerfile b/pki/Dockerfile new file mode 100644 index 00000000..da5694a5 --- /dev/null +++ b/pki/Dockerfile @@ -0,0 +1,25 @@ +FROM debian:wheezy +MAINTAINER Pierre-Olivier Mercier + +# Install packages #################################################### + +RUN apt-get -y update && \ + apt-get install -y \ + pwgen \ + openssl \ + && \ + apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* + +# Copying files ####################################################### + +ADD CA.sh openssl.cnf /var/www/fic-server/pki/ + +# ENVIRONNEMENT ####################################################### + +VOLUME ["/var/www/fic-server/PKI"] + +WORKDIR /var/www/fic-server/pki + +CMD bash ./CA.sh -newca && \ + bash ./CA.sh -newserver && \ + bash ./CA.sh -gencrl From 2ce348a7ed408fcb51af70fd3a8e7c4a5b858fd0 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 13 Jan 2015 19:51:13 +0100 Subject: [PATCH 0304/2686] Don't overwrite environment variables --- config.sh | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/config.sh b/config.sh index bc07a615..b60bc4b6 100644 --- a/config.sh +++ b/config.sh @@ -1,11 +1,20 @@ # The name of the frontend, like indicated in /etc/hosts -FRONTEND_HOSTNAME="phobos" +if [ -z "$FRONTEND_HOSTNAME" ] +then + export FRONTEND_HOSTNAME="phobos" +fi # Username of the unpriviledge user that runs scripts SYNCHRO_USER="synchro" # Directory where backup should be made -TO_BCKP="/mnt/backup" +if [ -z "$TO_BCKP" ] +then + TO_BCKP="/mnt/backup" +fi # Password of the MySQL user backup (with RO rights) -BCKP_PASS="Riuy6of sae^W0Sh" +if [ -z "$BCKP_PASS" ] +then + BCKP_PASS="Riuy6of sae^W0Sh" +fi From a82ccb10ecaf3629f32b9b12afc9e08e0abac4ed Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 13 Jan 2015 20:11:37 +0100 Subject: [PATCH 0305/2686] Clean backend container --- Dockerfile | 13 ++++--------- README.md | 20 +++++++++++++++++++- entrypoint.sh | 21 +++++++++++++++++++++ 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100755 entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 1b99827a..93ca00f9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,6 +36,7 @@ ADD . /var/www/fic-server/ RUN dpkg -i /var/www/fic-server/libmcrypt-perl*.deb || \ (echo "Please build perl-mcrypt first. Consult the given README!"; exit 1) && \ + rm /var/www/fic-server/libmcrypt-perl*.deb && \ ln -sf /var/www/fic-server/nginx-server.conf /etc/nginx/sites-enabled/default && \ ln -sf /var/www/fic-server/php-fpm.conf /etc/php5/fpm/pool.d/www.conf @@ -51,15 +52,9 @@ RUN ln -sf /var/www/fic-server/onyx/config/sample.root.xml /var/www/fic-server/o EXPOSE 80/tcp 443/tcp VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submission","/var/www/fic-server/shared"] -CMD mkdir -p /var/www/fic-server/logs; \ - chown -R www-data:www-data /var/www/fic-server/shared /var/www/fic-server/PKI; \ - chown -R synchro:www-data /var/www/fic-server/submission /var/www/fic-server/logs /var/www/fic-server/out; \ - chmod 660 /var/www/fic-server/submission; \ - service nginx start && \ +ENTRYPOINT ["/var/www/fic-server/entrypoint.sh"] + +CMD service nginx start && \ service php5-fpm start && \ - service mysql start && \ - ./nginx_gen_team.sh > ./shared/nginx-teams.conf && \ - echo 'Copying files...' && \ - ./gen_hash_link_files.sh --copy ./files-in ./files; \ (./launch_local.sh &); \ /bin/bash diff --git a/README.md b/README.md index 03233e11..4228a280 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ docker rm db_setup 3. Run the database container: ``` -docker run -d --name db --volumes-from mysql_data mysql +docker run -d --name db --volumes-from mysql_data -e MYSQL_USER=fic -e MYSQL_PASSWORD=anotherpassword -e MYSQL_DATABASE=fic mysql ``` 4. Setup the PKI storages: @@ -168,6 +168,24 @@ docker run --rm -it --volumes-from pki_storage --volumes-from shared_storage pki TODO next steps ``` +7. Build the perl `Mcrypt` debian package + +``` +docker build -t perl-mcrypt perl-mcrypt/ +docker run --name mcrypt_builder perl-mcrypt +docker cp mcrypt_builder:$(docker diff mcrypt_builder | grep -oE '[^ ]+deb$') ./ +docker rm mcrypt_builder +``` + +8. Build and run the backend: + +``` +docker build -t backend . +docker run --rm -it --link db:db --volumes-from pki_storage --volumes-from shared_storage -v /home/files:/var/www/fic-server/files-in backend +``` + +Where `/home/files` is your local directory containing all challenge files. + ##### Requirements diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 00000000..d7367118 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +mkdir -p /var/www/fic-server/logs; \ +chown -R www-data:www-data /var/www/fic-server/shared /var/www/fic-server/PKI; \ +chown -R synchro:www-data /var/www/fic-server/submission /var/www/fic-server/logs /var/www/fic-server/out; \ +chmod 660 /var/www/fic-server/submission; \ +./nginx_gen_team.sh > ./shared/nginx-teams.conf && + cat < /var/www/fic-server/onyx/db/docker.profile.php && +sampledocker Date: Wed, 14 Jan 2015 07:56:07 +0100 Subject: [PATCH 0306/2686] No need for mysql-server in backend Dockerfile --- Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 93ca00f9..cc4a16fa 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,12 +12,13 @@ RUN apt-get -y update && \ realpath \ nginx-light \ php5-fpm \ - mysql-server \ php5-mysql \ php5-mcrypt \ libmcrypt4 \ libwww-perl \ libdigest-whirlpool-perl \ + libdbi-perl \ + libdbd-mysql-perl \ pwgen \ curl \ openssl \ From fbba7a41f730ba90e70b1343d76a7b8c2afc91da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Wed, 14 Jan 2015 08:41:45 +0100 Subject: [PATCH 0307/2686] DB schema compatible with newer MySQL version --- db/feed.sql | 4 ++-- db/fic2014.sql | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/db/feed.sql b/db/feed.sql index a76b5e18..c900a1ed 100644 --- a/db/feed.sql +++ b/db/feed.sql @@ -231,5 +231,5 @@ VALUES ( INSERT INTO `exercice_files` (`id`, `id_exercice`, `path`, `name`, `sha1`) VALUES -('1', '22', 'theme/exo/file1.txt', 'file1.txt', '38be7d1b981f2fb6a4a0a052453f887373dc1fe8'), -('2', '22', 'theme/exo/file2.txt', 'file2.txt', '639daad06642a8eb86821ff7649e86f5f59c6139'); +('1', '22', 'theme/exo/file1.txt', 'file1.txt', 0x38be7d1b981f2fb6a4a0a052453f887373dc1fe8), +('2', '22', 'theme/exo/file2.txt', 'file2.txt', 0x639daad06642a8eb86821ff7649e86f5f59c6139); diff --git a/db/fic2014.sql b/db/fic2014.sql index fc5713ac..cb5bd8b9 100644 --- a/db/fic2014.sql +++ b/db/fic2014.sql @@ -118,7 +118,7 @@ CREATE TABLE IF NOT EXISTS `teams` ( `key_hash` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `auth_level` tinyint(1) NOT NULL, `slogan` varchar(64) COLLATE utf8_unicode_ci NOT NULL, - `revoked` boolean NOT NULL, + `revoked` boolean NOT NULL DEFAULT 0, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; @@ -133,8 +133,8 @@ CREATE TABLE IF NOT EXISTS `team_members` ( `id_team` int(10) unsigned NOT NULL, `firstname` varchar(32) COLLATE utf8_unicode_ci NOT NULL, `lastname` varchar(32) COLLATE utf8_unicode_ci NOT NULL, - `nickname` varchar(32) COLLATE utf8_unicode_ci NOT NULL UNIQUE, - `company` varchar(32) COLLATE utf8_unicode_ci NOT NULL, + `nickname` varchar(32) COLLATE utf8_unicode_ci NOT NULL UNIQUE DEFAULT "", + `company` varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT "", PRIMARY KEY (`id`), UNIQUE (firstname, lastname) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; From 1001cdf87a96cd6ed3f90f4000eadcc64e8ec3b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Wed, 14 Jan 2015 08:42:05 +0100 Subject: [PATCH 0308/2686] 770 permissions for submission dir --- entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entrypoint.sh b/entrypoint.sh index d7367118..41ed96a4 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -3,7 +3,7 @@ mkdir -p /var/www/fic-server/logs; \ chown -R www-data:www-data /var/www/fic-server/shared /var/www/fic-server/PKI; \ chown -R synchro:www-data /var/www/fic-server/submission /var/www/fic-server/logs /var/www/fic-server/out; \ -chmod 660 /var/www/fic-server/submission; \ +chmod 770 /var/www/fic-server/submission; \ ./nginx_gen_team.sh > ./shared/nginx-teams.conf && cat < /var/www/fic-server/onyx/db/docker.profile.php && Date: Wed, 14 Jan 2015 10:47:17 +0100 Subject: [PATCH 0309/2686] Cleaner entrypoint --- Dockerfile | 6 ++---- config.sh | 2 ++ entrypoint.sh | 32 ++++++++++++++++++++++---------- 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/Dockerfile b/Dockerfile index cc4a16fa..666665b9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,3 @@ -# DOCKER-VERSION 1.1.0 - # /!\ WARNING: the container generated through this Dockerfile is made only for development purpose; it is NOT SAFE or production ready. FROM debian:wheezy @@ -31,7 +29,7 @@ RUN useradd -d /var/www/fic-server -M -N -g www-data synchro WORKDIR /var/www/fic-server -ADD . /var/www/fic-server/ +COPY . /var/www/fic-server/ # Configure softwares ################################################# @@ -44,7 +42,6 @@ RUN dpkg -i /var/www/fic-server/libmcrypt-perl*.deb || \ # Configure site ###################################################### RUN ln -sf /var/www/fic-server/onyx/config/sample.root.xml /var/www/fic-server/onyx/config/root.xml && \ - sed -i "s/1386827772/`date -d 'now + 4 hours' +%s`/" /var/www/fic-server/onyx/config/root.xml && \ sed -i "s/challenge-public//" /var/www/fic-server/onyx/config/root.xml && \ chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/templates/cache/ /var/www/fic-server/onyx/cache/templates/compile/ @@ -57,5 +54,6 @@ ENTRYPOINT ["/var/www/fic-server/entrypoint.sh"] CMD service nginx start && \ service php5-fpm start && \ + ./nginx_gen_team.sh > ./shared/nginx-teams.conf && \ (./launch_local.sh &); \ /bin/bash diff --git a/config.sh b/config.sh index b60bc4b6..8ad81576 100644 --- a/config.sh +++ b/config.sh @@ -7,6 +7,8 @@ fi # Username of the unpriviledge user that runs scripts SYNCHRO_USER="synchro" +BASEDIR="/var/www/fic-server" + # Directory where backup should be made if [ -z "$TO_BCKP" ] then diff --git a/entrypoint.sh b/entrypoint.sh index 41ed96a4..365393fb 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,11 +1,19 @@ #!/bin/bash -mkdir -p /var/www/fic-server/logs; \ -chown -R www-data:www-data /var/www/fic-server/shared /var/www/fic-server/PKI; \ -chown -R synchro:www-data /var/www/fic-server/submission /var/www/fic-server/logs /var/www/fic-server/out; \ -chmod 770 /var/www/fic-server/submission; \ -./nginx_gen_team.sh > ./shared/nginx-teams.conf && - cat < /var/www/fic-server/onyx/db/docker.profile.php && +# Docker entrypoint + +cd `dirname "$0"` + +. ./config.sh + +# Creating directory and set permissions +mkdir -p ${BASEDIR}/logs +chown -R www-data:www-data ${BASEDIR}/shared ${BASEDIR}/PKI +chown -R ${SYNCHRO_USER}:www-data ${BASEDIR}/submission ${BASEDIR}/logs ${BASEDIR}/out +chmod 770 ${BASEDIR}/submission + +# Update database profile +cat < ${BASEDIR}/onyx/db/docker.profile.php && sampledockersampledocker Date: Wed, 14 Jan 2015 10:56:08 +0100 Subject: [PATCH 0310/2686] DEBUG mode now relies on config.xml --- entrypoint.sh | 9 +++++++++ htdocs/index.php | 5 ----- onyx/config/sample.root.xml | 2 +- onyx/include/common.php | 4 ++++ 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/entrypoint.sh b/entrypoint.sh index 365393fb..8cb86199 100755 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -25,6 +25,15 @@ if(!defined('ONYX')) exit; EOF sed -i 's/"profile">sampledocker01 - 1386827772 + 0 /var/www/fic-server/files/ /var/www/fic-server/ /var/www/fic-server/submission/ diff --git a/onyx/include/common.php b/onyx/include/common.php index 80ca4622..9cf17c05 100644 --- a/onyx/include/common.php +++ b/onyx/include/common.php @@ -4,6 +4,10 @@ if(!defined('ONYX')) exit; if (empty($sess->values["connected"]) && !defined("xCSRF")) define("xCSRF", true); +// Enable debugging in development environment +if (!empty($VAR["development"])) + define("DEBUG", true); + require_once("functions.php"); //Inclusion des principales fonctions require_once("common/Exercice.class.php"); From 1c7c45ea56208df50f7628e9063ef8349aac6547 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 14 Jan 2015 10:56:27 +0100 Subject: [PATCH 0311/2686] Clean functions.php --- onyx/include/common.php | 21 +--- onyx/include/functions.php | 98 +++---------------- .../templates/smarty/plugins/modifier.url.php | 36 +++---- 3 files changed, 31 insertions(+), 124 deletions(-) diff --git a/onyx/include/common.php b/onyx/include/common.php index 9cf17c05..bd9326d8 100644 --- a/onyx/include/common.php +++ b/onyx/include/common.php @@ -8,7 +8,7 @@ if (empty($sess->values["connected"]) && !defined("xCSRF")) if (!empty($VAR["development"])) define("DEBUG", true); -require_once("functions.php"); //Inclusion des principales fonctions +require_once("functions.php"); require_once("common/Exercice.class.php"); require_once("common/Member.class.php"); @@ -26,25 +26,6 @@ if (is_file($VAR["misc_dir"]."/shared/challenge_started")) $template->assign("END", $VAR['end_challenge']); } -function pipe_backend_scheduler($instruct) -{ - global $VAR; - - $socket = socket_create(AF_UNIX, SOCK_STREAM, 0); - if (is_writable($VAR["scheduler_socket"]) && socket_connect($socket, $VAR["scheduler_socket"])) - { - socket_write($socket, $instruct."\r\n") or die(socket_strerror(socket_last_error())); - sleep(1); - socket_shutdown($socket); - socket_close($socket); - } - else if(defined("DEBUG") && DEBUG) - { - print("Socket '".$VAR["scheduler_socket"]."' is not writable by ".$_SERVER["USER"]." user!"); - exit(1); - } -} - if (!empty($VAR['misc_dir'])) $template->assign("MISC_DIR", $VAR['misc_dir']); if (!empty($LANG)) diff --git a/onyx/include/functions.php b/onyx/include/functions.php index 0b836009..d3bda362 100644 --- a/onyx/include/functions.php +++ b/onyx/include/functions.php @@ -1,25 +1,5 @@ AddAddress($to); - $mail->Subject = $subject; - $mail->Body = $body; - - return $mail->Send(); -} - function erreur($message, $color="danger") { global $template; @@ -28,69 +8,21 @@ function erreur($message, $color="danger") $template->assign('ERRcolor', $color); } -function format_url($string) +function pipe_backend_scheduler($instruct) { - $string = trim($string); + global $VAR; - if ( ctype_digit($string) ) - { - return $string; - } - else - { - // replace accented chars - $accents = '/&([A-Za-z]{1,2})(grave|acute|circ|cedil|uml|lig);/'; - $string_encoded = htmlentities($string,ENT_NOQUOTES,'UTF-8'); - - $string = preg_replace($accents,'$1',$string_encoded); - - // clean out the rest - $replace = array('([\40\'/])','([^a-zA-Z0-9-])','(-{2,})'); - $with = array('-','','-'); - $string = preg_replace($replace,$with,$string); - } - - return strtolower($string); + $socket = socket_create(AF_UNIX, SOCK_STREAM, 0); + if (is_writable($VAR["scheduler_socket"]) && socket_connect($socket, $VAR["scheduler_socket"])) + { + socket_write($socket, $instruct."\r\n") or die(socket_strerror(socket_last_error())); + sleep(1); + socket_shutdown($socket); + socket_close($socket); + } + else if(defined("DEBUG") && DEBUG) + { + print("Socket '".$VAR["scheduler_socket"]."' is not writable by ".$_SERVER["USER"]." user!"); + exit(1); + } } - -function pagination($nbPages, $page, $link = "documents-recents-") -{ - $nbPages++; - $cntPages = array(); - if ($nbPages < 10) - { - for ($i = 1 ; $i <= $nbPages ; $i++) - $cntPages[] = $i; - } - else - { - for ($i = 1 ; $i <= 4 ; $i++) - $cntPages[] = $i; - if (6 != max(6, $page)) - $cntPages[] = "..."; - for ($i = max(6, $page) - 1 ; $i < min(max(6, $page) + 3, $nbPages - 2) ; $i++) - $cntPages[] = $i; - if ($nbPages - 2 != max(6, $page) + 3 && $nbPages - 2 != $i) - $cntPages[] = "..."; - for ($i = $nbPages - 2 ; $i <= $nbPages ; $i++) - $cntPages[] = $i; - } - - $out = ""; - foreach($cntPages as $p) - { - if ($p == "...") - $out .= " ... "; - else - $out .= ' '.$p.' '; - } - - return '<<'.$out.'>>'; -} - -function eregmenu($pattern, $string) -{ - return preg_match("#".$pattern."#ui", $string); -} - -?> diff --git a/onyx/modules/templates/smarty/plugins/modifier.url.php b/onyx/modules/templates/smarty/plugins/modifier.url.php index 4518b2b3..7fc8f398 100644 --- a/onyx/modules/templates/smarty/plugins/modifier.url.php +++ b/onyx/modules/templates/smarty/plugins/modifier.url.php @@ -20,29 +20,23 @@ */ function smarty_modifier_url($string) { - $string = trim($string); - - if ( ctype_digit($string) ) + $string = trim($string); + + if (!ctype_digit($string)) { - return $string; + // replace accented chars + $accents = '/&([A-Za-z]{1,2})(grave|acute|circ|cedil|uml|lig);/'; + $string_encoded = htmlentities($string,ENT_NOQUOTES,'UTF-8'); + + $string = preg_replace($accents, '$1', $string_encoded); + + // clean out the rest + $replace = array('([\40\'/])','([^a-zA-Z0-9-])','(-{2,})'); + $with = array('-','','-'); + $string = preg_replace($replace, $with, $string); } - else - { - // replace accented chars - $accents = '/&([A-Za-z]{1,2})(grave|acute|circ|cedil|uml|lig);/'; - $string_encoded = htmlentities($string,ENT_NOQUOTES,'UTF-8'); - - $string = preg_replace($accents,'$1',$string_encoded); - - // clean out the rest - $replace = array('([\40\'/])','([^a-zA-Z0-9-])','(-{2,})'); - $with = array('-','','-'); - $string = preg_replace($replace,$with,$string); - } - - return strtolower($string); + + return strtolower($string); } /* vim: set expandtab: */ - -?> \ No newline at end of file From b8708408c06cbc0ccedfa35dc68e122c42f704de Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 14 Jan 2015 10:59:49 +0100 Subject: [PATCH 0312/2686] Move teams.pass to a writable directory --- onyx/include/admin/import_users.php | 6 +++--- pki/CA.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index 971a836f..b75c5f8c 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -87,10 +87,10 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) $output .= new_client($team->team_name, $misc_dir); } } - if (file_exists("$misc_dir/teams.pass")) + if (file_exists("$misc_dir/PKI/teams.pass")) { - $output .= file_get_contents("$misc_dir/teams.pass"); - unlink("$misc_dir/teams.pass"); + $output .= file_get_contents("$misc_dir/PKI/teams.pass"); + unlink("$misc_dir/PKI/teams.pass"); } $template->assign("output", $output); } diff --git a/pki/CA.sh b/pki/CA.sh index 53fef8f1..0ac76ffc 100644 --- a/pki/CA.sh +++ b/pki/CA.sh @@ -228,7 +228,7 @@ case $1 in else echo $ECHO_OPTS "Exported pkcs12 file is ${CLTP12}" fi - echo "$CLTNAM:$pass" >> ${PKI_DIR}/../teams.pass + echo "$CLTNAM:$pass" >> ${PKI_DIR}/teams.pass echo "$CLTNAM:$pass" clean "client" ${CLTNAM} ;; From 428a1def46a01b15c3508165de35e3ce078be255 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 14 Jan 2015 11:10:55 +0100 Subject: [PATCH 0313/2686] Fix various paths (misc remove related) --- onyx/include/admin/certificate.php | 12 ++++++------ onyx/include/admin/home.php | 21 ++++++++------------- onyx/include/admin/import_users.php | 2 +- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/onyx/include/admin/certificate.php b/onyx/include/admin/certificate.php index c6e23f86..3ad64bd4 100644 --- a/onyx/include/admin/certificate.php +++ b/onyx/include/admin/certificate.php @@ -26,13 +26,13 @@ function new_client($name, $misc_dir) { //TODO handle if already exist putenv("PKI_BASEDIR=$misc_dir"); - return shell_exec("$misc_dir/../pki/CA.sh -newclient $name"); + return shell_exec("$misc_dir/pki/CA.sh -newclient $name"); } function revoke_client($name, $misc_dir) { putenv("PKI_BASEDIR=$misc_dir"); - return shell_exec("$misc_dir/../pki/CA.sh -revoke $name"); + return shell_exec("$misc_dir/pki/CA.sh -revoke $name"); } if (!empty($p[2])) @@ -49,7 +49,7 @@ if (!empty($p[2])) { putenv("PKI_BASEDIR=$misc_dir"); $template->assign("output", - shell_exec("$misc_dir/../pki/CA.sh -newca")); + shell_exec("$misc_dir/pki/CA.sh -newca")); return "admin/shell"; } @@ -63,7 +63,7 @@ if (!empty($p[2])) { putenv("PKI_BASEDIR=$misc_dir"); $template->assign("output", - shell_exec("$misc_dir/../pki/CA.sh -newserver")); + shell_exec("$misc_dir/pki/CA.sh -newserver")); return "admin/shell"; } @@ -71,7 +71,7 @@ if (!empty($p[2])) { putenv("PKI_BASEDIR=$misc_dir"); $template->assign("output", - shell_exec("$misc_dir/../pki/CA.sh -revokeserver")); + shell_exec("$misc_dir/pki/CA.sh -revokeserver")); return "admin/shell"; } @@ -108,7 +108,7 @@ if (!empty($p[2])) $name = $_GET['name']; if (isset($name)) { - $path = "$misc_dir/pki/pkcs/$name.p12"; + $path = "$misc_dir/PKI/pkcs/$name.p12"; if (file_exists($path) && is_readable($path)) { header("Content-Type: application/force-download"); diff --git a/onyx/include/admin/home.php b/onyx/include/admin/home.php index 971f7f86..43cf1ea4 100644 --- a/onyx/include/admin/home.php +++ b/onyx/include/admin/home.php @@ -2,25 +2,20 @@ if(!defined('ONYX')) exit; -if (isset($VAR['misc_dir'])) +if (empty($VAR['misc_dir'])) { - $misc_dir = $VAR['misc_dir']; - if (!is_writable("$misc_dir/shared")) - { - erreur("Dossier shared/ non accessible en écriture. ($misc_dir)"); + erreur("Please add misc_dir variable into root.xml configuration."); return "admin/home"; - } } -else +$misc_dir = $VAR['misc_dir']; + +if (!is_dir("$misc_dir/shared") || !is_writable("$misc_dir/shared")) { - erreur("Merci d'ajouter la variable misc_dir dans root.xml"); - return "admin/home"; + erreur("$misc_dir/shared/ directory not writable."); + return "admin/home"; } -if (is_writable($misc_dir) && !is_dir("$misc_dir/pki/")) - mkdir("$misc_dir/pki/"); - -$template->assign("cert_writable", is_writable("$misc_dir/pki/")); +$template->assign("cert_writable", is_writable("$misc_dir/shared/") && is_writable("$misc_dir/PKI/")); $ca_file = "$misc_dir/shared/cacert.crt"; if (file_exists($ca_file)) diff --git a/onyx/include/admin/import_users.php b/onyx/include/admin/import_users.php index b75c5f8c..ab9b318c 100644 --- a/onyx/include/admin/import_users.php +++ b/onyx/include/admin/import_users.php @@ -16,7 +16,7 @@ if (!empty($_FILES["inputFile"]['tmp_name'])) if (!file_exists("$misc_dir/shared/cacert.crt")) { - erreur("The root certificate file not found, please create this first"); + erreur("Root certificate not found, please create it first"); return "admin/import_users"; } From 8540aa23407b299316a7176fdbecb37972398ecc Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 14 Jan 2015 11:18:20 +0100 Subject: [PATCH 0314/2686] Remove unreachable code --- htdocs/index.php | 5 -- onyx/include/admin/import_exercices.php | 83 ------------------------- 2 files changed, 88 deletions(-) delete mode 100644 onyx/include/admin/import_exercices.php diff --git a/htdocs/index.php b/htdocs/index.php index 12b80d19..d139944c 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -80,11 +80,6 @@ if ($n && $p[0] == SALT_ADMIN) $page = require("admin/chrono.php"); break; - case "exercices/import": - case "exercices/import/": - $page = require("admin/import_exercices.php"); - break; - // Theme case "themes": case "themes/": diff --git a/onyx/include/admin/import_exercices.php b/onyx/include/admin/import_exercices.php deleted file mode 100644 index 79592a4a..00000000 --- a/onyx/include/admin/import_exercices.php +++ /dev/null @@ -1,83 +0,0 @@ -level > 1) -{ - $page = "admin/import_exercices"; - - if (!empty($_FILES["inputFile"]['tmp_name'])) - { - $doc = new DOMDocument(); - if (!$doc->load($_FILES["inputFile"]['tmp_name'])) - { - erreur("Unable to parse given file. A XML file was expected."); - return; - } - - // Define thema information - $theme = new Theme(); - - $xpath = new DOMXpath($doc); - $elements = $xpath->query("//theme/title"); - if (!is_null($elements)) - { - foreach ($elements as $element) - $theme->title = $element->nodeValue; - } - - // Insert thema into BDD - if (!$theme->update()) - { - erreur("Unable to add a new theme."); - return; - } - - $elements = $xpath->query("//theme/exercice"); - if (!is_null($elements)) - { - foreach ($elements as $element) - { - $ex = new Exercice(); - - $ex->id = preg_replace("/[^a-zA-Z0-9_]/g", "_", $element->getAttribute("id")); - $ex->level = $element->getAttribute("level"); - if ($element->hasAttribute("depends")) - $ex->require = $element->getAttribute("depends"); - - foreach ($element->childNodes as $child) - { - if ($child->nodeName == "title") - $ex->title = $child->nodeValue; - - else if ($child->nodeName == "points") - $ex->points = intval($child->nodeValue); - - else if ($child->nodeName == "statement") - $ex->statement = $child->nodeValue; - - else if ($child->nodeName == "key") - $ex->add_key( - $child->hasAttribute("format")?$child->getAttribute("format"):"sha512", - $child->nodeValue); - - else if ($child->nodeName == "file") - $ex->add_file( - $child->getAttribute("path"), - $child->nodeValue, - $child->getAttribute("sha1")); - } - - if (!$theme->add_exercice($ex)) - erreur("Unable to add '".$ex->id."' exercice."); - } - } - - erreur("XML file successfully imported.", "success"); - } -} -else -{ - header("Location: /"); - exit; -} From efeacf5f226c25436914e0d2f46d9a0498410971 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 14 Jan 2015 11:20:29 +0100 Subject: [PATCH 0315/2686] Clean admin pages --- onyx/include/admin/chrono.php | 2 -- onyx/include/admin/exercice.php | 31 +++++++++++++++---------------- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/onyx/include/admin/chrono.php b/onyx/include/admin/chrono.php index f86bbb1d..97cb9bc9 100644 --- a/onyx/include/admin/chrono.php +++ b/onyx/include/admin/chrono.php @@ -2,8 +2,6 @@ if(!defined('ONYX')) exit; -$p = $out[0]; - if (count($p) > 2) { switch($p[2]) diff --git a/onyx/include/admin/exercice.php b/onyx/include/admin/exercice.php index e87e894b..fb560218 100644 --- a/onyx/include/admin/exercice.php +++ b/onyx/include/admin/exercice.php @@ -2,11 +2,16 @@ if(!defined('ONYX')) exit; -$template->assign("fortyp", array("raw" => "RAW", "sha1" => "SHA-1", "md5" => "MD5", "sha224" => "SHA-224", "sha256" => "SHA-256", "sha384" => "SHA-384", "sha512" => "SHA-512", "whirlpool" => "Whirlpool")); +$template->assign("fortyp", array( + "raw" => "RAW", + "sha1" => "SHA-1", + "md5" => "MD5", + "sha224" => "SHA-224", + "sha256" => "SHA-256", + "sha384" => "SHA-384", + "sha512" => "SHA-512", + "whirlpool" => "Whirlpool")); -$p = $out[0]; - -//TODO maybe move the try catch to index.html ? try { if (isset($p[2])) @@ -53,18 +58,12 @@ try $template->assign("ex", $exercice); } -} -catch (ThemeNotFoundException $e) -{ - return "404"; -} -catch(ExerciceNotFoundException $e) -{ - return "404"; -} -catch(ExerciceNotFoundException $e) -{ - return "404"; +} catch (ThemeNotFoundException $e) { + return "404"; +} catch(ExerciceNotFoundException $e) { + return "404"; +} catch(ExerciceNotFoundException $e) { + return "404"; } return "admin/exercice"; From 93918f575676be43a421641675d6edc8d68d2136 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 14 Jan 2015 11:28:47 +0100 Subject: [PATCH 0316/2686] Upgrade Smarty --- TODO | 3 - .../modules/templates/smarty/Smarty.class.php | 323 +- .../templates/smarty/SmartyBC.class.php | 80 +- onyx/modules/templates/smarty/debug.tpl | 214 +- .../smarty/plugins/block.textformat.php | 10 +- .../smarty/plugins/function.counter.php | 26 +- .../smarty/plugins/function.cycle.php | 30 +- .../smarty/plugins/function.fetch.php | 44 +- .../plugins/function.html_checkboxes.php | 44 +- .../smarty/plugins/function.html_image.php | 18 +- .../smarty/plugins/function.html_options.php | 45 +- .../smarty/plugins/function.html_radios.php | 26 +- .../plugins/function.html_select_date.php | 74 +- .../plugins/function.html_select_time.php | 64 +- .../smarty/plugins/function.html_table.php | 34 +- .../smarty/plugins/function.mailto.php | 37 +- .../smarty/plugins/function.math.php | 41 +- .../smarty/plugins/modifier.capitalize.php | 45 +- .../smarty/plugins/modifier.date_format.php | 17 +- .../plugins/modifier.debug_print_var.php | 31 +- .../smarty/plugins/modifier.escape.php | 15 +- .../smarty/plugins/modifier.regex_replace.php | 22 +- .../smarty/plugins/modifier.replace.php | 8 +- .../smarty/plugins/modifier.spacify.php | 10 +- .../smarty/plugins/modifier.truncate.php | 10 +- .../smarty/plugins/modifiercompiler.cat.php | 13 +- .../modifiercompiler.count_characters.php | 9 +- .../modifiercompiler.count_paragraphs.php | 11 +- .../modifiercompiler.count_sentences.php | 11 +- .../plugins/modifiercompiler.count_words.php | 11 +- .../plugins/modifiercompiler.default.php | 9 +- .../plugins/modifiercompiler.escape.php | 58 +- .../plugins/modifiercompiler.from_charset.php | 7 +- .../plugins/modifiercompiler.indent.php | 10 +- .../smarty/plugins/modifiercompiler.lower.php | 12 +- .../plugins/modifiercompiler.noprint.php | 6 +- .../modifiercompiler.string_format.php | 9 +- .../smarty/plugins/modifiercompiler.strip.php | 9 +- .../plugins/modifiercompiler.strip_tags.php | 13 +- .../plugins/modifiercompiler.to_charset.php | 7 +- .../plugins/modifiercompiler.unescape.php | 7 +- .../smarty/plugins/modifiercompiler.upper.php | 11 +- .../plugins/modifiercompiler.wordwrap.php | 14 +- .../plugins/outputfilter.trimwhitespace.php | 28 +- .../plugins/shared.escape_special_chars.php | 8 +- .../plugins/shared.literal_compiler_param.php | 7 +- .../smarty/plugins/shared.make_timestamp.php | 12 +- .../smarty/plugins/shared.mb_str_replace.php | 10 +- .../smarty/plugins/shared.mb_unicode.php | 14 +- .../smarty/plugins/shared.mb_wordwrap.php | 45 +- .../variablefilter.htmlspecialchars.php | 8 +- .../sysplugins/smarty_cacheresource.php | 307 +- .../smarty_cacheresource_custom.php | 71 +- .../smarty_cacheresource_keyvaluestore.php | 101 +- .../sysplugins/smarty_config_source.php | 18 +- .../smarty_internal_cacheresource_file.php | 510 +- .../smarty_internal_compile_append.php | 9 +- .../smarty_internal_compile_assign.php | 9 +- .../smarty_internal_compile_block.php | 74 +- .../smarty_internal_compile_break.php | 16 +- .../smarty_internal_compile_call.php | 18 +- .../smarty_internal_compile_capture.php | 13 +- .../smarty_internal_compile_config_load.php | 19 +- .../smarty_internal_compile_continue.php | 15 +- .../smarty_internal_compile_debug.php | 9 +- .../smarty_internal_compile_eval.php | 15 +- .../smarty_internal_compile_extends.php | 30 +- .../smarty_internal_compile_for.php | 29 +- .../smarty_internal_compile_foreach.php | 43 +- .../smarty_internal_compile_function.php | 43 +- .../sysplugins/smarty_internal_compile_if.php | 138 +- .../smarty_internal_compile_include.php | 60 +- .../smarty_internal_compile_include_php.php | 17 +- .../smarty_internal_compile_insert.php | 13 +- .../smarty_internal_compile_ldelim.php | 11 +- .../smarty_internal_compile_nocache.php | 26 +- ..._internal_compile_private_block_plugin.php | 21 +- ...ternal_compile_private_function_plugin.php | 9 +- ...arty_internal_compile_private_modifier.php | 9 +- ..._compile_private_object_block_function.php | 13 +- ...ternal_compile_private_object_function.php | 15 +- ...ernal_compile_private_print_expression.php | 85 +- ...ernal_compile_private_registered_block.php | 49 +- ...al_compile_private_registered_function.php | 25 +- ...ernal_compile_private_special_variable.php | 16 +- .../smarty_internal_compile_rdelim.php | 11 +- .../smarty_internal_compile_section.php | 40 +- .../smarty_internal_compile_setfilter.php | 14 +- .../smarty_internal_compile_while.php | 15 +- .../smarty_internal_compilebase.php | 14 +- .../sysplugins/smarty_internal_config.php | 55 +- .../smarty_internal_config_file_compiler.php | 43 +- .../smarty_internal_configfilelexer.php | 504 +- .../smarty_internal_configfileparser.php | 761 +- .../sysplugins/smarty_internal_data.php | 109 +- .../sysplugins/smarty_internal_debug.php | 12 +- .../smarty_internal_filter_handler.php | 11 +- .../smarty_internal_function_call_handler.php | 9 +- .../smarty_internal_get_include_path.php | 10 +- .../smarty_internal_nocache_insert.php | 9 +- .../sysplugins/smarty_internal_parsetree.php | 144 +- .../smarty_internal_resource_eval.php | 27 +- .../smarty_internal_resource_extends.php | 18 +- .../smarty_internal_resource_file.php | 16 +- .../smarty_internal_resource_php.php | 28 +- .../smarty_internal_resource_registered.php | 17 +- .../smarty_internal_resource_stream.php | 75 +- .../smarty_internal_resource_string.php | 28 +- ...smarty_internal_smartytemplatecompiler.php | 27 +- .../sysplugins/smarty_internal_template.php | 122 +- .../smarty_internal_templatebase.php | 218 +- .../smarty_internal_templatecompilerbase.php | 108 +- .../smarty_internal_templatelexer.php | 1487 ++-- .../smarty_internal_templateparser.php | 6514 ++++++++++------- .../sysplugins/smarty_internal_utility.php | 358 +- .../sysplugins/smarty_internal_write_file.php | 23 +- .../smarty/sysplugins/smarty_resource.php | 157 +- .../sysplugins/smarty_resource_custom.php | 21 +- .../sysplugins/smarty_resource_recompiled.php | 9 +- .../sysplugins/smarty_resource_uncompiled.php | 9 +- .../smarty/sysplugins/smarty_security.php | 93 +- 121 files changed, 8360 insertions(+), 6242 deletions(-) diff --git a/TODO b/TODO index 8c87720c..77ddedef 100644 --- a/TODO +++ b/TODO @@ -10,9 +10,6 @@ ** TODO page de statistiques select count(*) as t, id_exercice, name from solved S inner join exercices E ON E.id = S.id_exercice INNER JOIN themes T ON E.id_theme = T.id group by id_exercice order by t DESC; select id_team, COUNT(*) AS t from exercice_tries group by id_team ORDER BY t; - -** Onyx -*** TODO Mettre à jour Smarty (et passer en « secure mode » ?) ** Admin *** TODO valider les documents avec la DTD à l'import *** TODO upload/MAJ de fichiers depuis l'interface d'admin? diff --git a/onyx/modules/templates/smarty/Smarty.class.php b/onyx/modules/templates/smarty/Smarty.class.php index 732b2df3..832b0d30 100644 --- a/onyx/modules/templates/smarty/Smarty.class.php +++ b/onyx/modules/templates/smarty/Smarty.class.php @@ -2,33 +2,29 @@ /** * Project: Smarty: the PHP compiling template engine * File: Smarty.class.php - * SVN: $Id: Smarty.class.php 4778 2013-09-17 20:44:41Z Uwe.Tews@googlemail.com $ - * + * SVN: $Id: Smarty.class.php 4897 2014-10-14 22:29:58Z Uwe.Tews@googlemail.com $ * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * * This library 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 * Lesser General Public License for more details. - * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * * For questions, help, comments, discussion, etc., please join the * Smarty mailing list. Send a blank e-mail to * smarty-discussion-subscribe@googlegroups.com * - * @link http://www.smarty.net/ + * @link http://www.smarty.net/ * @copyright 2008 New Digital Group, Inc. - * @author Monte Ohrt - * @author Uwe Tews - * @author Rodney Rehm - * @package Smarty - * @version 3.1.15 + * @author Monte Ohrt + * @author Uwe Tews + * @author Rodney Rehm + * @package Smarty + * @version 3.1.21 */ /** @@ -92,16 +88,17 @@ if (SMARTY_SPL_AUTOLOAD && set_include_path(get_include_path() . PATH_SEPARATOR /** * Load always needed external class files */ -include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_data.php'; -include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_templatebase.php'; -include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_template.php'; -include_once SMARTY_SYSPLUGINS_DIR.'smarty_resource.php'; -include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_resource_file.php'; -include_once SMARTY_SYSPLUGINS_DIR.'smarty_cacheresource.php'; -include_once SMARTY_SYSPLUGINS_DIR.'smarty_internal_cacheresource_file.php'; +include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php'; +include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php'; +include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php'; +include_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php'; +include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_resource_file.php'; +include_once SMARTY_SYSPLUGINS_DIR . 'smarty_cacheresource.php'; +include_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_cacheresource_file.php'; /** * This is the main Smarty class + * * @package Smarty */ class Smarty extends Smarty_Internal_TemplateBase @@ -113,7 +110,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = 'Smarty-3.1.15'; + const SMARTY_VERSION = 'Smarty-3.1.21-dev'; /** * define variable scopes @@ -131,7 +128,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * define constant for clearing cache files be saved expiration datees */ - const CLEAR_EXPIRED = -1; + const CLEAR_EXPIRED = - 1; /** * define compile check modes @@ -206,106 +203,133 @@ class Smarty extends Smarty_Internal_TemplateBase /** * auto literal on delimiters with whitspace + * * @var boolean */ public $auto_literal = true; /** * display error on not assigned variables + * * @var boolean */ public $error_unassigned = false; /** * look up relative filepaths in include_path + * * @var boolean */ public $use_include_path = false; /** * template directory + * * @var array */ private $template_dir = array(); /** * joined template directory string used in cache keys + * * @var string */ public $joined_template_dir = null; /** * joined config directory string used in cache keys + * * @var string */ public $joined_config_dir = null; /** * default template handler + * * @var callable */ public $default_template_handler_func = null; /** * default config handler + * * @var callable */ public $default_config_handler_func = null; /** * default plugin handler + * * @var callable */ public $default_plugin_handler_func = null; /** * compile directory + * * @var string */ private $compile_dir = null; /** * plugins directory + * * @var array */ private $plugins_dir = array(); /** * cache directory + * * @var string */ private $cache_dir = null; /** * config directory + * * @var array */ private $config_dir = array(); /** * force template compiling? + * * @var boolean */ public $force_compile = false; /** * check template for modifications? + * * @var boolean */ public $compile_check = true; /** * use sub dirs for compiled/cached files? + * * @var boolean */ public $use_sub_dirs = false; /** * allow ambiguous resources (that are made unique by the resource handler) + * * @var boolean */ public $allow_ambiguous_resources = false; /** * caching enabled + * * @var boolean */ public $caching = false; /** * merge compiled includes + * * @var boolean */ public $merge_compiled_includes = false; + /** + * template inheritance merge compiled includes + * + * @var boolean + */ + public $inheritance_merge_compiled_includes = true; /** * cache lifetime in seconds + * * @var integer */ public $cache_lifetime = 3600; /** * force cache file creation + * * @var boolean */ public $force_cache = false; @@ -325,11 +349,13 @@ class Smarty extends Smarty_Internal_TemplateBase public $compile_id = null; /** * template left-delimiter + * * @var string */ public $left_delimiter = "{"; /** * template right-delimiter + * * @var string */ public $right_delimiter = "}"; @@ -338,7 +364,6 @@ class Smarty extends Smarty_Internal_TemplateBase */ /** * class name - * * This should be instance of Smarty_Security. * * @var string @@ -365,7 +390,6 @@ class Smarty extends Smarty_Internal_TemplateBase public $allow_php_templates = false; /** * Should compiled-templates be prevented from being called directly? - * * {@internal * Currently used by Smarty_Internal_Template only. * }} @@ -376,7 +400,6 @@ class Smarty extends Smarty_Internal_TemplateBase /**#@-*/ /** * debug mode - * * Setting this to true enables the debug-console. * * @var boolean @@ -388,12 +411,12 @@ class Smarty extends Smarty_Internal_TemplateBase *

    • NONE => no debugging control allowed
    • *
    • URL => enable debugging when SMARTY_DEBUG is found in the URL.
    • *
    + * * @var string */ public $debugging_ctrl = 'NONE'; /** * Name of debugging URL-param. - * * Only used when $debugging_ctrl is set to 'URL'. * The name of the URL-parameter that activates debugging. * @@ -402,16 +425,19 @@ class Smarty extends Smarty_Internal_TemplateBase public $smarty_debug_id = 'SMARTY_DEBUG'; /** * Path of debug template. + * * @var string */ public $debug_tpl = null; /** * When set, smarty uses this value as error_reporting-level. + * * @var int */ public $error_reporting = null; /** * Internal flag for getTags() + * * @var boolean */ public $get_used_tags = false; @@ -422,16 +448,19 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Controls whether variables with the same name overwrite each other. + * * @var boolean */ public $config_overwrite = true; /** * Controls whether config values of on/true/yes and off/false/no get converted to boolean. + * * @var boolean */ public $config_booleanize = true; /** * Controls whether hidden config sections/vars are read from the file. + * * @var boolean */ public $config_read_hidden = false; @@ -444,16 +473,19 @@ class Smarty extends Smarty_Internal_TemplateBase /** * locking concurrent compiles + * * @var boolean */ public $compile_locking = true; /** * Controls whether cache resources should emply locking mechanism + * * @var boolean */ public $cache_locking = false; /** * seconds to wait for acquiring a lock before ignoring the write lock + * * @var float */ public $locking_timeout = 10; @@ -462,19 +494,19 @@ class Smarty extends Smarty_Internal_TemplateBase /** * global template functions + * * @var array */ public $template_functions = array(); /** * resource type used if none given - * * Must be an valid key of $registered_resources. + * * @var string */ public $default_resource_type = 'file'; /** * caching type - * * Must be an element of $cache_resource_types. * * @var string @@ -482,121 +514,145 @@ class Smarty extends Smarty_Internal_TemplateBase public $caching_type = 'file'; /** * internal config properties + * * @var array */ public $properties = array(); /** * config type + * * @var string */ public $default_config_type = 'file'; /** * cached template objects + * * @var array */ public $template_objects = array(); /** * check If-Modified-Since headers + * * @var boolean */ public $cache_modified_check = false; /** * registered plugins + * * @var array */ public $registered_plugins = array(); /** * plugin search order + * * @var array */ public $plugin_search_order = array('function', 'block', 'compiler', 'class'); /** * registered objects + * * @var array */ public $registered_objects = array(); /** * registered classes + * * @var array */ public $registered_classes = array(); /** * registered filters + * * @var array */ public $registered_filters = array(); /** * registered resources + * * @var array */ public $registered_resources = array(); /** * resource handler cache + * * @var array */ public $_resource_handlers = array(); /** * registered cache resources + * * @var array */ public $registered_cache_resources = array(); /** * cache resource handler cache + * * @var array */ public $_cacheresource_handlers = array(); /** * autoload filter + * * @var array */ public $autoload_filters = array(); /** * default modifier + * * @var array */ public $default_modifiers = array(); /** * autoescape variable output + * * @var boolean */ public $escape_html = false; /** * global internal smarty vars + * * @var array */ public static $_smarty_vars = array(); /** * start time for execution time calculation + * * @var int */ public $start_time = 0; /** * default file permissions + * * @var int */ public $_file_perms = 0644; /** * default dir permissions + * * @var int */ public $_dir_perms = 0771; /** * block tag hierarchy + * * @var array */ public $_tag_stack = array(); /** * self pointer to Smarty object + * * @var Smarty */ public $smarty; /** * required by the compiler for BC + * * @var string */ public $_current_file = null; /** * internal flag to enable parser debugging + * * @var bool */ public $_parserdebug = false; @@ -606,11 +662,19 @@ class Smarty extends Smarty_Internal_TemplateBase * @var array */ public $merged_templates_func = array(); + + /** + * Cache of is_file results of loadPlugin() + * + * @var array + */ + public static $_is_file_cache= array(); + /**#@-*/ /** * Initialize new Smarty object - * + */ public function __construct() { @@ -651,33 +715,32 @@ class Smarty extends Smarty_Internal_TemplateBase /** * <> Generic getter. - * * Calls the appropriate getter function. * Issues an E_USER_NOTICE if no valid getter is found. * * @param string $name property name + * * @return mixed */ public function __get($name) { $allowed = array( - 'template_dir' => 'getTemplateDir', - 'config_dir' => 'getConfigDir', - 'plugins_dir' => 'getPluginsDir', - 'compile_dir' => 'getCompileDir', - 'cache_dir' => 'getCacheDir', + 'template_dir' => 'getTemplateDir', + 'config_dir' => 'getConfigDir', + 'plugins_dir' => 'getPluginsDir', + 'compile_dir' => 'getCompileDir', + 'cache_dir' => 'getCacheDir', ); if (isset($allowed[$name])) { return $this->{$allowed[$name]}(); } else { - trigger_error('Undefined property: '. get_class($this) .'::$'. $name, E_USER_NOTICE); + trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE); } } /** * <> Generic setter. - * * Calls the appropriate setter function. * Issues an E_USER_NOTICE if no valid setter is found. * @@ -687,11 +750,11 @@ class Smarty extends Smarty_Internal_TemplateBase public function __set($name, $value) { $allowed = array( - 'template_dir' => 'setTemplateDir', - 'config_dir' => 'setConfigDir', - 'plugins_dir' => 'setPluginsDir', - 'compile_dir' => 'setCompileDir', - 'cache_dir' => 'setCacheDir', + 'template_dir' => 'setTemplateDir', + 'config_dir' => 'setConfigDir', + 'plugins_dir' => 'setPluginsDir', + 'compile_dir' => 'setCompileDir', + 'cache_dir' => 'setCacheDir', ); if (isset($allowed[$name])) { @@ -704,7 +767,8 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Check if a template resource exists * - * @param string $resource_name template name + * @param string $resource_name template name + * * @return boolean status */ public function templateExists($resource_name) @@ -722,8 +786,8 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Returns a single or all global variables * - * @param object $smarty * @param string $varname variable name or null + * * @return string variable value or or array of variables */ public function getGlobal($varname = null) @@ -749,6 +813,7 @@ class Smarty extends Smarty_Internal_TemplateBase * * @param integer $exp_time expiration time * @param string $type resource type + * * @return integer number of cache files deleted */ public function clearAllCache($exp_time = null, $type = null) @@ -768,6 +833,7 @@ class Smarty extends Smarty_Internal_TemplateBase * @param string $compile_id compile id * @param integer $exp_time expiration time * @param string $type resource type + * * @return integer number of cache files deleted */ public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null) @@ -783,6 +849,7 @@ class Smarty extends Smarty_Internal_TemplateBase * Loads security class and enables security * * @param string|Smarty_Security $security_class if a string is used, it must be class-name + * * @return Smarty current Smarty instance for chaining * @throws SmartyException when an invalid class name is provided */ @@ -811,6 +878,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Disable security + * * @return Smarty current Smarty instance for chaining */ public function disableSecurity() @@ -824,13 +892,14 @@ class Smarty extends Smarty_Internal_TemplateBase * Set template directory * * @param string|array $template_dir directory(s) of template sources + * * @return Smarty current Smarty instance for chaining */ public function setTemplateDir($template_dir) { $this->template_dir = array(); foreach ((array) $template_dir as $k => $v) { - $this->template_dir[$k] = rtrim($v, '/\\') . DS; + $this->template_dir[$k] = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS; } $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir); @@ -841,32 +910,37 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Add template directory(s) * - * @param string|array $template_dir directory(s) of template sources - * @param string $key of the array element to assign the template dir to + * @param string|array $template_dir directory(s) of template sources + * @param string $key of the array element to assign the template dir to + * * @return Smarty current Smarty instance for chaining * @throws SmartyException when the given template directory is not valid */ - public function addTemplateDir($template_dir, $key=null) + public function addTemplateDir($template_dir, $key = null) { // make sure we're dealing with an array $this->template_dir = (array) $this->template_dir; if (is_array($template_dir)) { foreach ($template_dir as $k => $v) { + $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS; if (is_int($k)) { // indexes are not merged but appended - $this->template_dir[] = rtrim($v, '/\\') . DS; + $this->template_dir[] = $v; } else { // string indexes are overridden - $this->template_dir[$k] = rtrim($v, '/\\') . DS; + $this->template_dir[$k] = $v; } } - } elseif ($key !== null) { - // override directory at specified index - $this->template_dir[$key] = rtrim($template_dir, '/\\') . DS; } else { - // append new directory - $this->template_dir[] = rtrim($template_dir, '/\\') . DS; + $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($template_dir, '/\\')) . DS; + if ($key !== null) { + // override directory at specified index + $this->template_dir[$key] = $v; + } else { + // append new directory + $this->template_dir[] = $v; + } } $this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir); @@ -876,10 +950,11 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Get template directories * - * @param mixed index of directory to get, null to get all + * @param mixed $index index of directory to get, null to get all + * * @return array|string list of template directories, or directory of $index */ - public function getTemplateDir($index=null) + public function getTemplateDir($index = null) { if ($index !== null) { return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null; @@ -891,14 +966,15 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Set config directory * - * @param string|array $template_dir directory(s) of configuration sources + * @param $config_dir + * * @return Smarty current Smarty instance for chaining */ public function setConfigDir($config_dir) { $this->config_dir = array(); foreach ((array) $config_dir as $k => $v) { - $this->config_dir[$k] = rtrim($v, '/\\') . DS; + $this->config_dir[$k] = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS; } $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir); @@ -909,31 +985,36 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Add config directory(s) * - * @param string|array $config_dir directory(s) of config sources - * @param string key of the array element to assign the config dir to + * @param string|array $config_dir directory(s) of config sources + * @param mixed $key key of the array element to assign the config dir to + * * @return Smarty current Smarty instance for chaining */ - public function addConfigDir($config_dir, $key=null) + public function addConfigDir($config_dir, $key = null) { // make sure we're dealing with an array $this->config_dir = (array) $this->config_dir; if (is_array($config_dir)) { foreach ($config_dir as $k => $v) { + $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS; if (is_int($k)) { // indexes are not merged but appended - $this->config_dir[] = rtrim($v, '/\\') . DS; + $this->config_dir[] = $v; } else { // string indexes are overridden - $this->config_dir[$k] = rtrim($v, '/\\') . DS; + $this->config_dir[$k] = $v; } } - } elseif ($key !== null) { - // override directory at specified index - $this->config_dir[$key] = rtrim($config_dir, '/\\') . DS; } else { - // append new directory - $this->config_dir[] = rtrim($config_dir, '/\\') . DS; + $v = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($config_dir, '/\\')) . DS; + if ($key !== null) { + // override directory at specified index + $this->config_dir[$key] = rtrim($v, '/\\') . DS; + } else { + // append new directory + $this->config_dir[] = rtrim($v, '/\\') . DS; + } } $this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir); @@ -944,10 +1025,11 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Get config directory * - * @param mixed index of directory to get, null to get all + * @param mixed $index index of directory to get, null to get all + * * @return array|string configuration directory */ - public function getConfigDir($index=null) + public function getConfigDir($index = null) { if ($index !== null) { return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null; @@ -960,6 +1042,7 @@ class Smarty extends Smarty_Internal_TemplateBase * Set plugins directory * * @param string|array $plugins_dir directory(s) of plugins + * * @return Smarty current Smarty instance for chaining */ public function setPluginsDir($plugins_dir) @@ -975,8 +1058,8 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Adds directory of plugin files * - * @param object $smarty - * @param string $ |array $ plugins folder + * @param $plugins_dir + * * @return Smarty current Smarty instance for chaining */ public function addPluginsDir($plugins_dir) @@ -1018,6 +1101,7 @@ class Smarty extends Smarty_Internal_TemplateBase * Set compile directory * * @param string $compile_dir directory to store compiled templates in + * * @return Smarty current Smarty instance for chaining */ public function setCompileDir($compile_dir) @@ -1044,6 +1128,7 @@ class Smarty extends Smarty_Internal_TemplateBase * Set cache directory * * @param string $cache_dir directory to store cached templates in + * * @return Smarty current Smarty instance for chaining */ public function setCacheDir($cache_dir) @@ -1070,6 +1155,7 @@ class Smarty extends Smarty_Internal_TemplateBase * Set default modifiers * * @param array|string $modifiers modifier or list of modifiers to set + * * @return Smarty current Smarty instance for chaining */ public function setDefaultModifiers($modifiers) @@ -1083,6 +1169,7 @@ class Smarty extends Smarty_Internal_TemplateBase * Add default modifiers * * @param array|string $modifiers modifier or list of modifiers to add + * * @return Smarty current Smarty instance for chaining */ public function addDefaultModifiers($modifiers) @@ -1106,15 +1193,15 @@ class Smarty extends Smarty_Internal_TemplateBase return $this->default_modifiers; } - /** * Set autoload filters * * @param array $filters filters to load automatically * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types + * * @return Smarty current Smarty instance for chaining */ - public function setAutoloadFilters($filters, $type=null) + public function setAutoloadFilters($filters, $type = null) { if ($type !== null) { $this->autoload_filters[$type] = (array) $filters; @@ -1130,9 +1217,10 @@ class Smarty extends Smarty_Internal_TemplateBase * * @param array $filters filters to load automatically * @param string $type "pre", "output", … specify the filter type to set. Defaults to none treating $filters' keys as the appropriate types + * * @return Smarty current Smarty instance for chaining */ - public function addAutoloadFilters($filters, $type=null) + public function addAutoloadFilters($filters, $type = null) { if ($type !== null) { if (!empty($this->autoload_filters[$type])) { @@ -1157,9 +1245,10 @@ class Smarty extends Smarty_Internal_TemplateBase * Get autoload filters * * @param string $type type of filter to get autoloads for. Defaults to all autoload filters + * * @return array array( 'type1' => array( 'filter1', 'filter2', … ) ) or array( 'filter1', 'filter2', …) if $type was specified */ - public function getAutoloadFilters($type=null) + public function getAutoloadFilters($type = null) { if ($type !== null) { return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array(); @@ -1181,7 +1270,8 @@ class Smarty extends Smarty_Internal_TemplateBase /** * set the debug template * - * @param string $tpl_name + * @param string $tpl_name + * * @return Smarty current Smarty instance for chaining * @throws SmartyException if file is not readable */ @@ -1203,15 +1293,16 @@ class Smarty extends Smarty_Internal_TemplateBase * @param mixed $compile_id compile id to be used with this template * @param object $parent next higher level of Smarty variables * @param boolean $do_clone flag is Smarty object shall be cloned + * * @return object template object */ public function createTemplate($template, $cache_id = null, $compile_id = null, $parent = null, $do_clone = true) { - if (!empty($cache_id) && (is_object($cache_id) || is_array($cache_id))) { + if ($cache_id !== null && (is_object($cache_id) || is_array($cache_id))) { $parent = $cache_id; $cache_id = null; } - if (!empty($parent) && is_array($parent)) { + if ($parent !== null && is_array($parent)) { $data = $parent; $parent = null; } else { @@ -1262,7 +1353,6 @@ class Smarty extends Smarty_Internal_TemplateBase return $tpl; } - /** * Takes unknown classes and loads plugin files for them * class name format: Smarty_PluginType_PluginName @@ -1270,6 +1360,8 @@ class Smarty extends Smarty_Internal_TemplateBase * * @param string $plugin_name class plugin name to load * @param bool $check check if already loaded + * + * @throws SmartyException * @return string |boolean filepath of loaded file or false */ public function loadPlugin($plugin_name, $check = true) @@ -1284,15 +1376,12 @@ class Smarty extends Smarty_Internal_TemplateBase // count($_name_parts) < 3 === !isset($_name_parts[2]) if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') { throw new SmartyException("plugin {$plugin_name} is not a valid name format"); - - return false; } // if type is "internal", get plugin from sysplugins if (strtolower($_name_parts[1]) == 'internal') { $file = SMARTY_SYSPLUGINS_DIR . strtolower($plugin_name) . '.php'; - if (file_exists($file)) { + if (isset(self::$_is_file_cache[$file]) ? self::$_is_file_cache[$file] : self::$_is_file_cache[$file] = is_file($file)) { require_once($file); - return $file; } else { return false; @@ -1310,9 +1399,8 @@ class Smarty extends Smarty_Internal_TemplateBase $_plugin_dir . strtolower($_plugin_filename), ); foreach ($names as $file) { - if (file_exists($file)) { + if (isset(self::$_is_file_cache[$file]) ? self::$_is_file_cache[$file] : self::$_is_file_cache[$file] = is_file($file)) { require_once($file); - return $file; } if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) { @@ -1338,10 +1426,11 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Compile all template files * - * @param string $extension file extension - * @param bool $force_compile force all to recompile - * @param int $time_limit - * @param int $max_errors + * @param string $extension file extension + * @param bool $force_compile force all to recompile + * @param int $time_limit + * @param int $max_errors + * * @return integer number of template files recompiled */ public function compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null) @@ -1352,10 +1441,11 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Compile all config files * - * @param string $extension file extension - * @param bool $force_compile force all to recompile - * @param int $time_limit - * @param int $max_errors + * @param string $extension file extension + * @param bool $force_compile force all to recompile + * @param int $time_limit + * @param int $max_errors + * * @return integer number of template files recompiled */ public function compileAllConfig($extension = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null) @@ -1369,6 +1459,7 @@ class Smarty extends Smarty_Internal_TemplateBase * @param string $resource_name template name * @param string $compile_id compile id * @param integer $exp_time expiration time + * * @return integer number of template files deleted */ public function clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) @@ -1376,11 +1467,11 @@ class Smarty extends Smarty_Internal_TemplateBase return Smarty_Internal_Utility::clearCompiledTemplate($resource_name, $compile_id, $exp_time, $this); } - /** * Return array of tag/attributes of all tags used by an template * - * @param object $templae template object + * @param Smarty_Internal_Template $template + * * @return array of tag/attributes */ public function getTags(Smarty_Internal_Template $template) @@ -1391,10 +1482,11 @@ class Smarty extends Smarty_Internal_TemplateBase /** * Run installation test * - * @param array $errors Array to write errors into, rather than outputting them + * @param array $errors Array to write errors into, rather than outputting them + * * @return boolean true if setup is fine, false if something is wrong */ - public function testInstall(&$errors=null) + public function testInstall(&$errors = null) { return Smarty_Internal_Utility::testInstall($this, $errors); } @@ -1403,7 +1495,13 @@ class Smarty extends Smarty_Internal_TemplateBase * Error Handler to mute expected messages * * @link http://php.net/set_error_handler + * * @param integer $errno Error level + * @param $errstr + * @param $errfile + * @param $errline + * @param $errcontext + * * @return boolean */ public static function mutingErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) @@ -1415,7 +1513,7 @@ class Smarty extends Smarty_Internal_TemplateBase $smarty_dir = realpath(SMARTY_DIR); if ($smarty_dir !== false) { Smarty::$_muted_directories[SMARTY_DIR] = array( - 'file' => $smarty_dir, + 'file' => $smarty_dir, 'length' => strlen($smarty_dir), ); } @@ -1432,7 +1530,7 @@ class Smarty extends Smarty_Internal_TemplateBase continue; } $dir = array( - 'file' => $file, + 'file' => $file, 'length' => strlen($file), ); } @@ -1506,6 +1604,7 @@ if (Smarty::$_CHARSET !== 'UTF-8') { /** * Smarty exception class + * * @package Smarty */ class SmartyException extends Exception @@ -1514,12 +1613,13 @@ class SmartyException extends Exception public function __toString() { - return ' --> Smarty: ' . (self::$escape ? htmlentities($this->message) : $this->message) . ' <-- '; + return ' --> Smarty: ' . (self::$escape ? htmlentities($this->message) : $this->message) . ' <-- '; } } /** * Smarty compiler exception class + * * @package Smarty */ class SmartyCompilerException extends SmartyException @@ -1528,23 +1628,28 @@ class SmartyCompilerException extends SmartyException { return ' --> Smarty Compiler: ' . $this->message . ' <-- '; } + /** * The line number of the template error + * * @type int|null */ public $line = null; /** * The template source snippet relating to the error + * * @type string|null */ public $source = null; /** * The raw text of the error message + * * @type string|null */ public $desc = null; /** * The resource identifier or template name + * * @type string|null */ public $template = null; @@ -1557,16 +1662,16 @@ function smartyAutoload($class) { $_class = strtolower($class); static $_classes = array( - 'smarty_config_source' => true, - 'smarty_config_compiled' => true, - 'smarty_security' => true, - 'smarty_cacheresource' => true, - 'smarty_cacheresource_custom' => true, + 'smarty_config_source' => true, + 'smarty_config_compiled' => true, + 'smarty_security' => true, + 'smarty_cacheresource' => true, + 'smarty_cacheresource_custom' => true, 'smarty_cacheresource_keyvaluestore' => true, - 'smarty_resource' => true, - 'smarty_resource_custom' => true, - 'smarty_resource_uncompiled' => true, - 'smarty_resource_recompiled' => true, + 'smarty_resource' => true, + 'smarty_resource_custom' => true, + 'smarty_resource_uncompiled' => true, + 'smarty_resource_recompiled' => true, ); if (!strncmp($_class, 'smarty_internal_', 16) || isset($_classes[$_class])) { diff --git a/onyx/modules/templates/smarty/SmartyBC.class.php b/onyx/modules/templates/smarty/SmartyBC.class.php index 32f22289..cec94674 100644 --- a/onyx/modules/templates/smarty/SmartyBC.class.php +++ b/onyx/modules/templates/smarty/SmartyBC.class.php @@ -3,36 +3,32 @@ * Project: Smarty: the PHP compiling template engine * File: SmartyBC.class.php * SVN: $Id: $ - * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * * This library 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 * Lesser General Public License for more details. - * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * * For questions, help, comments, discussion, etc., please join the * Smarty mailing list. Send a blank e-mail to * smarty-discussion-subscribe@googlegroups.com * - * @link http://www.smarty.net/ + * @link http://www.smarty.net/ * @copyright 2008 New Digital Group, Inc. - * @author Monte Ohrt - * @author Uwe Tews - * @author Rodney Rehm - * @package Smarty + * @author Monte Ohrt + * @author Uwe Tews + * @author Rodney Rehm + * @package Smarty */ /** * @ignore */ -require(dirname(__FILE__) . '/Smarty.class.php'); +require_once(dirname(__FILE__) . '/Smarty.class.php'); /** * Smarty Backward Compatability Wrapper Class @@ -43,6 +39,7 @@ class SmartyBC extends Smarty { /** * Smarty 2 BC + * * @var string */ public $_version = self::SMARTY_VERSION; @@ -52,7 +49,7 @@ class SmartyBC extends Smarty * * @param array $options options to set during initialization, e.g. array( 'forceCompile' => false ) */ - public function __construct(array $options=array()) + public function __construct(array $options = array()) { parent::__construct($options); // register {php} tag @@ -100,7 +97,7 @@ class SmartyBC extends Smarty * @param bool $cacheable * @param mixed $cache_attrs */ - public function register_function($function, $function_impl, $cacheable=true, $cache_attrs=null) + public function register_function($function, $function_impl, $cacheable = true, $cache_attrs = null) { $this->registerPlugin('function', $function, $function_impl, $cacheable, $cache_attrs); } @@ -118,11 +115,14 @@ class SmartyBC extends Smarty /** * Registers object to be used in templates * - * @param string $object name of template object - * @param object $object_impl the referenced PHP object to register - * @param array $allowed list of allowed methods (empty = all) - * @param boolean $smarty_args smarty argument format, else traditional - * @param array $block_functs list of methods that are block format + * @param string $object name of template object + * @param object $object_impl the referenced PHP object to register + * @param array $allowed list of allowed methods (empty = all) + * @param boolean $smarty_args smarty argument format, else traditional + * @param array $block_methods list of methods that are block format + * + * @throws SmartyException + * @internal param array $block_functs list of methods that are block format */ public function register_object($object, $object_impl, $allowed = array(), $smarty_args = true, $block_methods = array()) { @@ -144,12 +144,12 @@ class SmartyBC extends Smarty /** * Registers block function to be used in templates * - * @param string $block name of template block - * @param string $block_impl PHP function to register + * @param string $block name of template block + * @param string $block_impl PHP function to register * @param bool $cacheable * @param mixed $cache_attrs */ - public function register_block($block, $block_impl, $cacheable=true, $cache_attrs=null) + public function register_block($block, $block_impl, $cacheable = true, $cache_attrs = null) { $this->registerPlugin('block', $block, $block_impl, $cacheable, $cache_attrs); } @@ -171,7 +171,7 @@ class SmartyBC extends Smarty * @param string $function_impl name of PHP function to register * @param bool $cacheable */ - public function register_compiler_function($function, $function_impl, $cacheable=true) + public function register_compiler_function($function, $function_impl, $cacheable = true) { $this->registerPlugin('compiler', $function, $function_impl, $cacheable); } @@ -305,10 +305,11 @@ class SmartyBC extends Smarty /** * clear cached content for the given template and cache id * - * @param string $tpl_file name of template file - * @param string $cache_id name of cache_id - * @param string $compile_id name of compile_id - * @param string $exp_time expiration time + * @param string $tpl_file name of template file + * @param string $cache_id name of cache_id + * @param string $compile_id name of compile_id + * @param string $exp_time expiration time + * * @return boolean */ public function clear_cache($tpl_file = null, $cache_id = null, $compile_id = null, $exp_time = null) @@ -319,7 +320,8 @@ class SmartyBC extends Smarty /** * clear the entire contents of cache (all templates) * - * @param string $exp_time expire time + * @param string $exp_time expire time + * * @return boolean */ public function clear_all_cache($exp_time = null) @@ -330,9 +332,10 @@ class SmartyBC extends Smarty /** * test to see if valid cache exists for this template * - * @param string $tpl_file name of template file - * @param string $cache_id - * @param string $compile_id + * @param string $tpl_file name of template file + * @param string $cache_id + * @param string $compile_id + * * @return boolean */ public function is_cached($tpl_file, $cache_id = null, $compile_id = null) @@ -353,9 +356,10 @@ class SmartyBC extends Smarty * or all compiled template files if one is not specified. * This function is for advanced use only, not normally needed. * - * @param string $tpl_file - * @param string $compile_id - * @param string $exp_time + * @param string $tpl_file + * @param string $compile_id + * @param string $exp_time + * * @return boolean results of {@link smarty_core_rm_auto()} */ public function clear_compiled_tpl($tpl_file = null, $compile_id = null, $exp_time = null) @@ -366,7 +370,8 @@ class SmartyBC extends Smarty /** * Checks whether requested template exists. * - * @param string $tpl_file + * @param string $tpl_file + * * @return boolean */ public function template_exists($tpl_file) @@ -378,9 +383,10 @@ class SmartyBC extends Smarty * Returns an array containing template variables * * @param string $name + * * @return array */ - public function get_template_vars($name=null) + public function get_template_vars($name = null) { return $this->getTemplateVars($name); } @@ -389,9 +395,10 @@ class SmartyBC extends Smarty * Returns an array containing config variables * * @param string $name + * * @return array */ - public function get_config_vars($name=null) + public function get_config_vars($name = null) { return $this->getConfigVars($name); } @@ -412,6 +419,7 @@ class SmartyBC extends Smarty * return a reference to a registered object * * @param string $name + * * @return object */ public function get_registered_object($name) @@ -439,7 +447,6 @@ class SmartyBC extends Smarty { trigger_error("Smarty error: $error_msg", $error_type); } - } /** @@ -449,6 +456,7 @@ class SmartyBC extends Smarty * @param string $content contents of the block * @param object $template template object * @param boolean &$repeat repeat flag + * * @return string content re-formatted */ function smarty_php_tag($params, $content, $template, &$repeat) diff --git a/onyx/modules/templates/smarty/debug.tpl b/onyx/modules/templates/smarty/debug.tpl index 12eef0ff..61b8876a 100644 --- a/onyx/modules/templates/smarty/debug.tpl +++ b/onyx/modules/templates/smarty/debug.tpl @@ -1,133 +1,137 @@ {capture name='_smarty_debug' assign=debug_output} - - - - Smarty Debug Console - - - + #table_config_vars th { + color: maroon; + } -

    Smarty Debug Console - {if isset($template_name)}{$template_name|debug_print_var nofilter}{else}Total Time {$execution_time|string_format:"%.5f"}{/if}

    + {/literal} + + + -{if !empty($template_data)} -

    included templates & config files (load time in seconds)

    +

    Smarty Debug Console + - {if isset($template_name)}{$template_name|debug_print_var nofilter}{else}Total Time {$execution_time|string_format:"%.5f"}{/if}

    -
    -{foreach $template_data as $template} - {$template.name} - - (compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"}) + {if !empty($template_data)} +

    included templates & config files (load time in seconds)

    +
    + {foreach $template_data as $template} + {$template.name} + + (compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"} + ) -
    -{/foreach} -
    -{/if} +
    + {/foreach} +
    + {/if} -

    assigned template variables

    +

    assigned template variables

    - - {foreach $assigned_vars as $vars} - - - - {/foreach} -
    ${$vars@key|escape:'html'}{$vars|debug_print_var nofilter}
    + + {foreach $assigned_vars as $vars} + + + + + {/foreach} +
    ${$vars@key|escape:'html'}{$vars|debug_print_var nofilter}
    -

    assigned config file variables (outer template scope)

    +

    assigned config file variables (outer template scope)

    - - {foreach $config_vars as $vars} - - - - {/foreach} +
    {$vars@key|escape:'html'}{$vars|debug_print_var nofilter}
    + {foreach $config_vars as $vars} + + + + + {/foreach} -
    {$vars@key|escape:'html'}{$vars|debug_print_var nofilter}
    - - +
    + + {/capture} diff --git a/onyx/modules/templates/smarty/plugins/block.textformat.php b/onyx/modules/templates/smarty/plugins/block.textformat.php index b62a4f8e..abf54493 100644 --- a/onyx/modules/templates/smarty/plugins/block.textformat.php +++ b/onyx/modules/templates/smarty/plugins/block.textformat.php @@ -2,13 +2,12 @@ /** * Smarty plugin to format text blocks * - * @package Smarty + * @package Smarty * @subpackage PluginsBlock */ /** * Smarty {textformat}{/textformat} block plugin - * * Type: block function
    * Name: textformat
    * Purpose: format text a certain way with preset styles @@ -23,12 +22,14 @@ * - wrap_boundary - boolean (true) * * - * @link http://www.smarty.net/manual/en/language.function.textformat.php {textformat} - * (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.function.textformat.php {textformat} + * (Smarty online manual) + * * @param array $params parameters * @param string $content contents of the block * @param Smarty_Internal_Template $template template object * @param boolean &$repeat repeat flag + * * @return string content re-formatted * @author Monte Ohrt */ @@ -76,7 +77,6 @@ function smarty_block_textformat($params, $content, $template, &$repeat) } // split into paragraphs $_paragraphs = preg_split('![\r\n]{2}!', $content); - $_output = ''; foreach ($_paragraphs as &$_paragraph) { if (!$_paragraph) { diff --git a/onyx/modules/templates/smarty/plugins/function.counter.php b/onyx/modules/templates/smarty/plugins/function.counter.php index cd147634..4da85a14 100644 --- a/onyx/modules/templates/smarty/plugins/function.counter.php +++ b/onyx/modules/templates/smarty/plugins/function.counter.php @@ -1,22 +1,24 @@ * Name: counter
    * Purpose: print out a counter value * * @author Monte Ohrt - * @link http://www.smarty.net/manual/en/language.function.counter.php {counter} - * (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.function.counter.php {counter} + * (Smarty online manual) + * * @param array $params parameters * @param Smarty_Internal_Template $template template object + * * @return string|null */ function smarty_function_counter($params, $template) @@ -26,11 +28,11 @@ function smarty_function_counter($params, $template) $name = (isset($params['name'])) ? $params['name'] : 'default'; if (!isset($counters[$name])) { $counters[$name] = array( - 'start'=>1, - 'skip'=>1, - 'direction'=>'up', - 'count'=>1 - ); + 'start' => 1, + 'skip' => 1, + 'direction' => 'up', + 'count' => 1 + ); } $counter =& $counters[$name]; @@ -66,11 +68,11 @@ function smarty_function_counter($params, $template) $counter['direction'] = $params['direction']; } - if ($counter['direction'] == "down") + if ($counter['direction'] == "down") { $counter['count'] -= $counter['skip']; - else + } else { $counter['count'] += $counter['skip']; + } return $retval; - } diff --git a/onyx/modules/templates/smarty/plugins/function.cycle.php b/onyx/modules/templates/smarty/plugins/function.cycle.php index 9bf26f8c..8dc5cd9d 100644 --- a/onyx/modules/templates/smarty/plugins/function.cycle.php +++ b/onyx/modules/templates/smarty/plugins/function.cycle.php @@ -2,13 +2,12 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsFunction */ /** * Smarty {cycle} function plugin - * * Type: function
    * Name: cycle
    * Date: May 3, 2002
    @@ -31,15 +30,17 @@ * {cycle name=row} * * - * @link http://www.smarty.net/manual/en/language.function.cycle.php {cycle} - * (Smarty online manual) - * @author Monte Ohrt - * @author credit to Mark Priatel - * @author credit to Gerard - * @author credit to Jason Sweat + * @link http://www.smarty.net/manual/en/language.function.cycle.php {cycle} + * (Smarty online manual) + * @author Monte Ohrt + * @author credit to Mark Priatel + * @author credit to Gerard + * @author credit to Jason Sweat * @version 1.3 + * * @param array $params parameters * @param Smarty_Internal_Template $template template object + * * @return string|null */ @@ -59,8 +60,9 @@ function smarty_function_cycle($params, $template) return; } } else { - if(isset($cycle_vars[$name]['values']) - && $cycle_vars[$name]['values'] != $params['values'] ) { + if (isset($cycle_vars[$name]['values']) + && $cycle_vars[$name]['values'] != $params['values'] + ) { $cycle_vars[$name]['index'] = 0; } $cycle_vars[$name]['values'] = $params['values']; @@ -75,10 +77,10 @@ function smarty_function_cycle($params, $template) if (is_array($cycle_vars[$name]['values'])) { $cycle_array = $cycle_vars[$name]['values']; } else { - $cycle_array = explode($cycle_vars[$name]['delimiter'],$cycle_vars[$name]['values']); + $cycle_array = explode($cycle_vars[$name]['delimiter'], $cycle_vars[$name]['values']); } - if (!isset($cycle_vars[$name]['index']) || $reset ) { + if (!isset($cycle_vars[$name]['index']) || $reset) { $cycle_vars[$name]['index'] = 0; } @@ -94,10 +96,10 @@ function smarty_function_cycle($params, $template) } if ($advance) { - if ( $cycle_vars[$name]['index'] >= count($cycle_array) -1 ) { + if ($cycle_vars[$name]['index'] >= count($cycle_array) - 1) { $cycle_vars[$name]['index'] = 0; } else { - $cycle_vars[$name]['index']++; + $cycle_vars[$name]['index'] ++; } } diff --git a/onyx/modules/templates/smarty/plugins/function.fetch.php b/onyx/modules/templates/smarty/plugins/function.fetch.php index a4eaef37..3506d4a8 100644 --- a/onyx/modules/templates/smarty/plugins/function.fetch.php +++ b/onyx/modules/templates/smarty/plugins/function.fetch.php @@ -2,28 +2,30 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsFunction */ /** * Smarty {fetch} plugin - * * Type: function
    * Name: fetch
    * Purpose: fetch file, web or ftp data and display results * - * @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch} - * (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.function.fetch.php {fetch} + * (Smarty online manual) * @author Monte Ohrt + * * @param array $params parameters * @param Smarty_Internal_Template $template template object + * + * @throws SmartyException * @return string|null if the assign parameter is passed, Smarty assigns the result to a template variable */ function smarty_function_fetch($params, $template) { if (empty($params['file'])) { - trigger_error("[plugin] fetch parameter 'file' cannot be empty",E_USER_NOTICE); + trigger_error("[plugin] fetch parameter 'file' cannot be empty", E_USER_NOTICE); return; } @@ -60,7 +62,7 @@ function smarty_function_fetch($params, $template) $host = $server_name = $uri_parts['host']; $timeout = 30; $accept = "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*"; - $agent = "Smarty Template Engine ". Smarty::SMARTY_VERSION; + $agent = "Smarty Template Engine " . Smarty::SMARTY_VERSION; $referer = ""; $uri = !empty($uri_parts['path']) ? $uri_parts['path'] : '/'; $uri .= !empty($uri_parts['query']) ? '?' . $uri_parts['query'] : ''; @@ -100,8 +102,8 @@ function smarty_function_fetch($params, $template) break; case "header": if (!empty($param_value)) { - if (!preg_match('![\w\d-]+: .+!',$param_value)) { - trigger_error("[plugin] invalid header format '".$param_value."'",E_USER_NOTICE); + if (!preg_match('![\w\d-]+: .+!', $param_value)) { + trigger_error("[plugin] invalid header format '" . $param_value . "'", E_USER_NOTICE); return; } else { @@ -118,7 +120,7 @@ function smarty_function_fetch($params, $template) if (!preg_match('!\D!', $param_value)) { $proxy_port = (int) $param_value; } else { - trigger_error("[plugin] invalid value for attribute '".$param_key."'",E_USER_NOTICE); + trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE); return; } @@ -137,26 +139,26 @@ function smarty_function_fetch($params, $template) if (!preg_match('!\D!', $param_value)) { $timeout = (int) $param_value; } else { - trigger_error("[plugin] invalid value for attribute '".$param_key."'",E_USER_NOTICE); + trigger_error("[plugin] invalid value for attribute '" . $param_key . "'", E_USER_NOTICE); return; } break; default: - trigger_error("[plugin] unrecognized attribute '".$param_key."'",E_USER_NOTICE); + trigger_error("[plugin] unrecognized attribute '" . $param_key . "'", E_USER_NOTICE); return; } } if (!empty($proxy_host) && !empty($proxy_port)) { $_is_proxy = true; - $fp = fsockopen($proxy_host,$proxy_port,$errno,$errstr,$timeout); + $fp = fsockopen($proxy_host, $proxy_port, $errno, $errstr, $timeout); } else { - $fp = fsockopen($server_name,$port,$errno,$errstr,$timeout); + $fp = fsockopen($server_name, $port, $errno, $errstr, $timeout); } if (!$fp) { - trigger_error("[plugin] unable to fetch: $errstr ($errno)",E_USER_NOTICE); + trigger_error("[plugin] unable to fetch: $errstr ($errno)", E_USER_NOTICE); return; } else { @@ -179,35 +181,35 @@ function smarty_function_fetch($params, $template) } if (isset($extra_headers) && is_array($extra_headers)) { foreach ($extra_headers as $curr_header) { - fputs($fp, $curr_header."\r\n"); + fputs($fp, $curr_header . "\r\n"); } } if (!empty($user) && !empty($pass)) { - fputs($fp, "Authorization: BASIC ".base64_encode("$user:$pass")."\r\n"); + fputs($fp, "Authorization: BASIC " . base64_encode("$user:$pass") . "\r\n"); } fputs($fp, "\r\n"); while (!feof($fp)) { - $content .= fgets($fp,4096); + $content .= fgets($fp, 4096); } fclose($fp); - $csplit = preg_split("!\r\n\r\n!",$content,2); + $csplit = preg_split("!\r\n\r\n!", $content, 2); $content = $csplit[1]; if (!empty($params['assign_headers'])) { - $template->assign($params['assign_headers'],preg_split("!\r\n!",$csplit[0])); + $template->assign($params['assign_headers'], preg_split("!\r\n!", $csplit[0])); } } } else { - trigger_error("[plugin fetch] unable to parse URL, check syntax",E_USER_NOTICE); + trigger_error("[plugin fetch] unable to parse URL, check syntax", E_USER_NOTICE); return; } } else { $content = @file_get_contents($params['file']); if ($content === false) { - throw new SmartyException("{fetch} cannot read resource '" . $params['file'] ."'"); + throw new SmartyException("{fetch} cannot read resource '" . $params['file'] . "'"); } } diff --git a/onyx/modules/templates/smarty/plugins/function.html_checkboxes.php b/onyx/modules/templates/smarty/plugins/function.html_checkboxes.php index ad0e9cd4..d7868036 100644 --- a/onyx/modules/templates/smarty/plugins/function.html_checkboxes.php +++ b/onyx/modules/templates/smarty/plugins/function.html_checkboxes.php @@ -2,13 +2,12 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsFunction */ /** * Smarty {html_checkboxes} function plugin - * * File: function.html_checkboxes.php
    * Type: function
    * Name: html_checkboxes
    @@ -32,15 +31,17 @@ * - escape (optional) - escape the content (not value), defaults to true * * - * @link http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes} - * (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.function.html.checkboxes.php {html_checkboxes} + * (Smarty online manual) * @author Christopher Kvarme - * @author credits to Monte Ohrt + * @author credits to Monte Ohrt * @version 1.0 - * @param array $params parameters + * + * @param array $params parameters * @param object $template template object + * * @return string - * @uses smarty_function_escape_special_chars() + * @uses smarty_function_escape_special_chars() */ function smarty_function_html_checkboxes($params, $template) { @@ -89,7 +90,7 @@ function smarty_function_html_checkboxes($params, $template) if (method_exists($_sel, "__toString")) { $_sel = smarty_function_escape_special_chars((string) $_sel->__toString()); } else { - trigger_error("html_checkboxes: selected attribute contains an object of class '". get_class($_sel) ."' without __toString() method", E_USER_NOTICE); + trigger_error("html_checkboxes: selected attribute contains an object of class '" . get_class($_sel) . "' without __toString() method", E_USER_NOTICE); continue; } } else { @@ -101,7 +102,7 @@ function smarty_function_html_checkboxes($params, $template) if (method_exists($_val, "__toString")) { $selected = smarty_function_escape_special_chars((string) $_val->__toString()); } else { - trigger_error("html_checkboxes: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE); + trigger_error("html_checkboxes: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE); } } else { $selected = smarty_function_escape_special_chars((string) $_val); @@ -116,7 +117,8 @@ function smarty_function_html_checkboxes($params, $template) case 'assign': break; - case 'strict': break; + case 'strict': + break; case 'disabled': case 'readonly': @@ -131,11 +133,11 @@ function smarty_function_html_checkboxes($params, $template) break; } - // omit break; to fall through! + // omit break; to fall through! default: if (!is_array($_val)) { - $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; + $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"'; } else { trigger_error("html_checkboxes: extra attribute '$_key' cannot be an array", E_USER_NOTICE); } @@ -143,17 +145,18 @@ function smarty_function_html_checkboxes($params, $template) } } - if (!isset($options) && !isset($values)) - return ''; /* raise error here? */ + if (!isset($options) && !isset($values)) { + return ''; + } /* raise error here? */ $_html_result = array(); if (isset($options)) { - foreach ($options as $_key=>$_val) { + foreach ($options as $_key => $_val) { $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape); } } else { - foreach ($values as $_i=>$_key) { + foreach ($values as $_i => $_key) { $_val = isset($output[$_i]) ? $output[$_i] : ''; $_html_result[] = smarty_function_html_checkboxes_output($name, $_key, $_val, $selected, $extra, $separator, $labels, $label_ids, $escape); } @@ -164,10 +167,9 @@ function smarty_function_html_checkboxes($params, $template) } else { return implode("\n", $_html_result); } - } -function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape=true) +function smarty_function_html_checkboxes_output($name, $value, $output, $selected, $extra, $separator, $labels, $label_ids, $escape = true) { $_output = ''; @@ -175,7 +177,7 @@ function smarty_function_html_checkboxes_output($name, $value, $output, $selecte if (method_exists($value, "__toString")) { $value = (string) $value->__toString(); } else { - trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE); + trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE); return ''; } @@ -187,7 +189,7 @@ function smarty_function_html_checkboxes_output($name, $value, $output, $selecte if (method_exists($output, "__toString")) { $output = (string) $output->__toString(); } else { - trigger_error("html_options: output is an object of class '". get_class($output) ."' without __toString() method", E_USER_NOTICE); + trigger_error("html_options: output is an object of class '" . get_class($output) . "' without __toString() method", E_USER_NOTICE); return ''; } @@ -229,7 +231,7 @@ function smarty_function_html_checkboxes_output($name, $value, $output, $selecte $_output .= ''; } - $_output .= $separator; + $_output .= $separator; return $_output; } diff --git a/onyx/modules/templates/smarty/plugins/function.html_image.php b/onyx/modules/templates/smarty/plugins/function.html_image.php index 1674a262..5037e8bd 100644 --- a/onyx/modules/templates/smarty/plugins/function.html_image.php +++ b/onyx/modules/templates/smarty/plugins/function.html_image.php @@ -2,13 +2,12 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsFunction */ /** * Smarty {html_image} function plugin - * * Type: function
    * Name: html_image
    * Date: Feb 24, 2003
    @@ -24,15 +23,18 @@ * - path_prefix - prefix for path output (optional, default empty) * * - * @link http://www.smarty.net/manual/en/language.function.html.image.php {html_image} - * (Smarty online manual) - * @author Monte Ohrt - * @author credits to Duda + * @link http://www.smarty.net/manual/en/language.function.html.image.php {html_image} + * (Smarty online manual) + * @author Monte Ohrt + * @author credits to Duda * @version 1.0 + * * @param array $params parameters * @param Smarty_Internal_Template $template template object + * + * @throws SmartyException * @return string - * @uses smarty_function_escape_special_chars() + * @uses smarty_function_escape_special_chars() */ function smarty_function_html_image($params, $template) { @@ -112,7 +114,7 @@ function smarty_function_html_image($params, $template) } } else { // local file - if (!$template->smarty->security_policy->isTrustedResourceDir($params['file'])) { + if (!$template->smarty->security_policy->isTrustedResourceDir($_image_path)) { return; } } diff --git a/onyx/modules/templates/smarty/plugins/function.html_options.php b/onyx/modules/templates/smarty/plugins/function.html_options.php index 5ff98750..7ec3e065 100644 --- a/onyx/modules/templates/smarty/plugins/function.html_options.php +++ b/onyx/modules/templates/smarty/plugins/function.html_options.php @@ -2,13 +2,12 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsFunction */ /** * Smarty {html_options} function plugin - * * Type: function
    * Name: html_options
    * Purpose: Prints the list of ' . "\n"; - $idx++; + $idx ++; } else { $_idx = 0; - $_html_result = smarty_function_html_options_optgroup($key, $value, $selected, !empty($id) ? ($id.'-'.$idx) : null, $class, $_idx); - $idx++; + $_html_result = smarty_function_html_options_optgroup($key, $value, $selected, !empty($id) ? ($id . '-' . $idx) : null, $class, $_idx); + $idx ++; } return $_html_result; diff --git a/onyx/modules/templates/smarty/plugins/function.html_radios.php b/onyx/modules/templates/smarty/plugins/function.html_radios.php index 16606ebf..f121d5ea 100644 --- a/onyx/modules/templates/smarty/plugins/function.html_radios.php +++ b/onyx/modules/templates/smarty/plugins/function.html_radios.php @@ -2,13 +2,12 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsFunction */ /** * Smarty {html_radios} function plugin - * * File: function.html_radios.php
    * Type: function
    * Name: html_radios
    @@ -32,15 +31,17 @@ * {html_radios values=$ids checked=$checked separator='
    ' output=$names} * * - * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios} - * (Smarty online manual) - * @author Christopher Kvarme - * @author credits to Monte Ohrt + * @link http://smarty.php.net/manual/en/language.function.html.radios.php {html_radios} + * (Smarty online manual) + * @author Christopher Kvarme + * @author credits to Monte Ohrt * @version 1.0 + * * @param array $params parameters * @param Smarty_Internal_Template $template template object + * * @return string - * @uses smarty_function_escape_special_chars() + * @uses smarty_function_escape_special_chars() */ function smarty_function_html_radios($params, $template) { @@ -72,7 +73,7 @@ function smarty_function_html_radios($params, $template) if (method_exists($_val, "__toString")) { $selected = smarty_function_escape_special_chars((string) $_val->__toString()); } else { - trigger_error("html_radios: selected attribute is an object of class '". get_class($_val) ."' without __toString() method", E_USER_NOTICE); + trigger_error("html_radios: selected attribute is an object of class '" . get_class($_val) . "' without __toString() method", E_USER_NOTICE); } } else { $selected = (string) $_val; @@ -102,7 +103,8 @@ function smarty_function_html_radios($params, $template) case 'assign': break; - case 'strict': break; + case 'strict': + break; case 'disabled': case 'readonly': @@ -117,7 +119,7 @@ function smarty_function_html_radios($params, $template) break; } - // omit break; to fall through! + // omit break; to fall through! default: if (!is_array($_val)) { @@ -163,7 +165,7 @@ function smarty_function_html_radios_output($name, $value, $output, $selected, $ if (method_exists($value, "__toString")) { $value = (string) $value->__toString(); } else { - trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE); + trigger_error("html_options: value is an object of class '" . get_class($value) . "' without __toString() method", E_USER_NOTICE); return ''; } @@ -175,7 +177,7 @@ function smarty_function_html_radios_output($name, $value, $output, $selected, $ if (method_exists($output, "__toString")) { $output = (string) $output->__toString(); } else { - trigger_error("html_options: output is an object of class '". get_class($output) ."' without __toString() method", E_USER_NOTICE); + trigger_error("html_options: output is an object of class '" . get_class($output) . "' without __toString() method", E_USER_NOTICE); return ''; } diff --git a/onyx/modules/templates/smarty/plugins/function.html_select_date.php b/onyx/modules/templates/smarty/plugins/function.html_select_date.php index b1bfee2b..d6625665 100644 --- a/onyx/modules/templates/smarty/plugins/function.html_select_date.php +++ b/onyx/modules/templates/smarty/plugins/function.html_select_date.php @@ -2,7 +2,7 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsFunction */ @@ -17,11 +17,9 @@ require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'); /** * Smarty {html_select_date} plugin - * * Type: function
    * Name: html_select_date
    * Purpose: Prints the dropdowns for date selection. - * * ChangeLog: *
      *            - 1.0 initial release
    @@ -41,17 +39,18 @@ require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
      *              added attributes month_names, *_id
      * 
    * - * @link http://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date} - * (Smarty online manual) - * @version 2.0 - * @author Andrei Zmievski - * @author Monte Ohrt - * @author Rodney Rehm - * @param array $params parameters - * @param Smarty_Internal_Template $template template object + * @link http://www.smarty.net/manual/en/language.function.html.select.date.php {html_select_date} + * (Smarty online manual) + * @version 2.0 + * @author Andrei Zmievski + * @author Monte Ohrt + * @author Rodney Rehm + * + * @param array $params parameters + * * @return string */ -function smarty_function_html_select_date($params, $template) +function smarty_function_html_select_date($params) { // generate timestamps used for month names only static $_month_timestamps = null; @@ -59,7 +58,7 @@ function smarty_function_html_select_date($params, $template) if ($_month_timestamps === null) { $_current_year = date('Y'); $_month_timestamps = array(); - for ($i = 1; $i <= 12; $i++) { + for ($i = 1; $i <= 12; $i ++) { $_month_timestamps[$i] = mktime(0, 0, 0, $i, 1, 2000); } } @@ -181,22 +180,20 @@ function smarty_function_html_select_date($params, $template) if (isset($params['time']) && is_array($params['time'])) { if (isset($params['time'][$prefix . 'Year'])) { // $_REQUEST[$field_array] given - foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) { + foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) { $_variableName = '_' . strtolower($_elementName); $$_variableName = isset($params['time'][$prefix . $_elementName]) ? $params['time'][$prefix . $_elementName] : date($_elementKey); } - $time = mktime(0, 0, 0, $_month, $_day, $_year); } elseif (isset($params['time'][$field_array][$prefix . 'Year'])) { // $_REQUEST given - foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) { + foreach (array('Y' => 'Year', 'm' => 'Month', 'd' => 'Day') as $_elementKey => $_elementName) { $_variableName = '_' . strtolower($_elementName); $$_variableName = isset($params['time'][$field_array][$prefix . $_elementName]) ? $params['time'][$field_array][$prefix . $_elementName] : date($_elementKey); } - $time = mktime(0, 0, 0, $_month, $_day, $_year); } else { // no date found, use NOW list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d')); @@ -219,9 +216,9 @@ function smarty_function_html_select_date($params, $template) if ($t === null) { $$key = (int) $_current_year; } elseif ($t[0] == '+') { - $$key = (int) ($_current_year + trim(substr($t, 1))); + $$key = (int) ($_current_year + (int)trim(substr($t, 1))); } elseif ($t[0] == '-') { - $$key = (int) ($_current_year - trim(substr($t, 1))); + $$key = (int) ($_current_year - (int)trim(substr($t, 1))); } else { $$key = (int) $$key; } @@ -236,7 +233,6 @@ function smarty_function_html_select_date($params, $template) // generate year if ($display_years) { - $_html_years = ''; $_extra = ''; $_name = $field_array ? ($field_array . '[' . $prefix . 'Year]') : ($prefix . 'Year'); if ($all_extra) { @@ -252,8 +248,8 @@ function smarty_function_html_select_date($params, $template) $_html_years = ' or if ($display_months) { - $_html_month = ''; $_extra = ''; $_name = $field_array ? ($field_array . '[' . $prefix . 'Month]') : ($prefix . 'Month'); if ($all_extra) { @@ -290,8 +285,8 @@ function smarty_function_html_select_date($params, $template) $_html_months = ' or if ($display_days) { - $_html_day = ''; $_extra = ''; $_name = $field_array ? ($field_array . '[' . $prefix . 'Day]') : ($prefix . 'Day'); if ($all_extra) { @@ -329,8 +323,8 @@ function smarty_function_html_select_date($params, $template) $_html_days = '' . $option_separator; if (isset($hour_empty) || isset($all_empty)) { - $_html_hours .= '' . $option_separator; + $_html_hours .= '' . $option_separator; } $start = $use_24_hours ? 0 : 1; $end = $use_24_hours ? 23 : 12; - for ($i=$start; $i <= $end; $i++) { + for ($i = $start; $i <= $end; $i ++) { $_val = sprintf('%02d', $i); $_text = $hour_format == '%02d' ? $_val : sprintf($hour_format, $i); $_value = $hour_value_format == '%02d' ? $_val : sprintf($hour_value_format, $i); @@ -226,7 +226,7 @@ function smarty_function_html_select_time($params, $template) if (!$use_24_hours) { $_hour12 = $_hour == 0 ? 12 - : ($_hour <= 12 ? $_hour : $_hour -12); + : ($_hour <= 12 ? $_hour : $_hour - 12); } $selected = $_hour !== null ? ($use_24_hours ? $_hour == $_val : $_hour12 == $_val) : null; @@ -253,8 +253,8 @@ function smarty_function_html_select_time($params, $template) $_html_minutes = '' . $option_separator; if (isset($second_empty) || isset($all_empty)) { - $_html_seconds .= '' . $option_separator; + $_html_seconds .= '' . $option_separator; } $selected = $_second !== null ? ($_second - $_second % $second_interval) : null; - for ($i=0; $i <= 59; $i += $second_interval) { + for ($i = 0; $i <= 59; $i += $second_interval) { $_val = sprintf('%02d', $i); $_text = $second_format == '%02d' ? $_val : sprintf($second_format, $i); $_value = $second_value_format == '%02d' ? $_val : sprintf($second_value_format, $i); @@ -333,8 +333,8 @@ function smarty_function_html_select_time($params, $template) $_html_meridian = ''; } diff --git a/onyx/modules/templates/smarty/plugins/function.html_table.php b/onyx/modules/templates/smarty/plugins/function.html_table.php index 275f6c24..ec7ba48a 100644 --- a/onyx/modules/templates/smarty/plugins/function.html_table.php +++ b/onyx/modules/templates/smarty/plugins/function.html_table.php @@ -2,13 +2,12 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsFunction */ /** * Smarty {html_table} function plugin - * * Type: function
    * Name: html_table
    * Date: Feb 17, 2003
    @@ -37,17 +36,18 @@ * {table loop=$data cols="first,second,third" tr_attr=$colors} * * - * @author Monte Ohrt - * @author credit to Messju Mohr - * @author credit to boots - * @version 1.1 - * @link http://www.smarty.net/manual/en/language.function.html.table.php {html_table} - * (Smarty online manual) - * @param array $params parameters - * @param Smarty_Internal_Template $template template object + * @author Monte Ohrt + * @author credit to Messju Mohr + * @author credit to boots + * @version 1.1 + * @link http://www.smarty.net/manual/en/language.function.html.table.php {html_table} + * (Smarty online manual) + * + * @param array $params parameters + * * @return string */ -function smarty_function_html_table($params, $template) +function smarty_function_html_table($params) { $table_attr = 'border="1"'; $tr_attr = ''; @@ -63,7 +63,7 @@ function smarty_function_html_table($params, $template) $loop = null; if (!isset($params['loop'])) { - trigger_error("html_table: missing 'loop' parameter",E_USER_WARNING); + trigger_error("html_table: missing 'loop' parameter", E_USER_WARNING); return; } @@ -130,7 +130,7 @@ function smarty_function_html_table($params, $template) $cols = ($hdir == 'right') ? $cols : array_reverse($cols); $output .= "\n"; - for ($r = 0; $r < $cols_count; $r++) { + for ($r = 0; $r < $cols_count; $r ++) { $output .= ''; $output .= $cols[$r]; $output .= "\n"; @@ -139,12 +139,12 @@ function smarty_function_html_table($params, $template) } $output .= "\n"; - for ($r = 0; $r < $rows; $r++) { + for ($r = 0; $r < $rows; $r ++) { $output .= "\n"; - $rx = ($vdir == 'down') ? $r * $cols_count : ($rows-1 - $r) * $cols_count; + $rx = ($vdir == 'down') ? $r * $cols_count : ($rows - 1 - $r) * $cols_count; - for ($c = 0; $c < $cols_count; $c++) { - $x = ($hdir == 'right') ? $rx + $c : $rx + $cols_count-1 - $c; + for ($c = 0; $c < $cols_count; $c ++) { + $x = ($hdir == 'right') ? $rx + $c : $rx + $cols_count - 1 - $c; if ($inner != 'cols') { /* shuffle x to loop over rows*/ $x = floor($x / $cols_count) + ($x % $cols_count) * $rows; diff --git a/onyx/modules/templates/smarty/plugins/function.mailto.php b/onyx/modules/templates/smarty/plugins/function.mailto.php index ac94ae04..520fb7aa 100644 --- a/onyx/modules/templates/smarty/plugins/function.mailto.php +++ b/onyx/modules/templates/smarty/plugins/function.mailto.php @@ -2,13 +2,12 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsFunction */ /** * Smarty {mailto} function plugin - * * Type: function
    * Name: mailto
    * Date: May 21, 2002 @@ -39,22 +38,23 @@ * {mailto address="me@domain.com" extra='class="mailto"'} * * - * @link http://www.smarty.net/manual/en/language.function.mailto.php {mailto} - * (Smarty online manual) - * @version 1.2 - * @author Monte Ohrt - * @author credits to Jason Sweat (added cc, bcc and subject functionality) - * @param array $params parameters - * @param Smarty_Internal_Template $template template object + * @link http://www.smarty.net/manual/en/language.function.mailto.php {mailto} + * (Smarty online manual) + * @version 1.2 + * @author Monte Ohrt + * @author credits to Jason Sweat (added cc, bcc and subject functionality) + * + * @param array $params parameters + * * @return string */ -function smarty_function_mailto($params, $template) +function smarty_function_mailto($params) { static $_allowed_encoding = array('javascript' => true, 'javascript_charcode' => true, 'hex' => true, 'none' => true); $extra = ''; if (empty($params['address'])) { - trigger_error("mailto: missing 'address' parameter",E_USER_WARNING); + trigger_error("mailto: missing 'address' parameter", E_USER_WARNING); return; } else { @@ -72,8 +72,9 @@ function smarty_function_mailto($params, $template) case 'cc': case 'bcc': case 'followupto': - if (!empty($value)) - $mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value)); + if (!empty($value)) { + $mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value)); + } break; case 'subject': @@ -104,7 +105,7 @@ function smarty_function_mailto($params, $template) $string = 'document.write(\'' . $text . '\');'; $js_encode = ''; - for ($x = 0, $_length = strlen($string); $x < $_length; $x++) { + for ($x = 0, $_length = strlen($string); $x < $_length; $x ++) { $js_encode .= '%' . bin2hex($string[$x]); } @@ -112,7 +113,7 @@ function smarty_function_mailto($params, $template) } elseif ($encode == 'javascript_charcode') { $string = '' . $text . ''; - for ($x = 0, $y = strlen($string); $x < $y; $x++) { + for ($x = 0, $y = strlen($string); $x < $y; $x ++) { $ord[] = ord($string[$x]); } @@ -127,12 +128,12 @@ function smarty_function_mailto($params, $template) } elseif ($encode == 'hex') { preg_match('!^(.*)(\?.*)$!', $address, $match); if (!empty($match[2])) { - trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.",E_USER_WARNING); + trigger_error("mailto: hex encoding does not work with extra attributes. Try javascript.", E_USER_WARNING); return; } $address_encode = ''; - for ($x = 0, $_length = strlen($address); $x < $_length; $x++) { + for ($x = 0, $_length = strlen($address); $x < $_length; $x ++) { if (preg_match('!\w!' . Smarty::$_UTF8_MODIFIER, $address[$x])) { $address_encode .= '%' . bin2hex($address[$x]); } else { @@ -140,7 +141,7 @@ function smarty_function_mailto($params, $template) } } $text_encode = ''; - for ($x = 0, $_length = strlen($text); $x < $_length; $x++) { + for ($x = 0, $_length = strlen($text); $x < $_length; $x ++) { $text_encode .= '&#x' . bin2hex($text[$x]) . ';'; } diff --git a/onyx/modules/templates/smarty/plugins/function.math.php b/onyx/modules/templates/smarty/plugins/function.math.php index 7bcc8acf..aba76e82 100644 --- a/onyx/modules/templates/smarty/plugins/function.math.php +++ b/onyx/modules/templates/smarty/plugins/function.math.php @@ -1,36 +1,37 @@ * Name: math
    * Purpose: handle math computations in template * - * @link http://www.smarty.net/manual/en/language.function.math.php {math} - * (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.function.math.php {math} + * (Smarty online manual) * @author Monte Ohrt + * * @param array $params parameters * @param Smarty_Internal_Template $template template object + * * @return string|null */ function smarty_function_math($params, $template) { static $_allowed_funcs = array( - 'int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true, - 'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true, - 'rand' => true, 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true ,'tan' => true + 'int' => true, 'abs' => true, 'ceil' => true, 'cos' => true, 'exp' => true, 'floor' => true, + 'log' => true, 'log10' => true, 'max' => true, 'min' => true, 'pi' => true, 'pow' => true, + 'rand' => true, 'round' => true, 'sin' => true, 'sqrt' => true, 'srand' => true, 'tan' => true ); // be sure equation parameter is present if (empty($params['equation'])) { - trigger_error("math: missing equation parameter",E_USER_WARNING); + trigger_error("math: missing equation parameter", E_USER_WARNING); return; } @@ -38,18 +39,18 @@ function smarty_function_math($params, $template) $equation = $params['equation']; // make sure parenthesis are balanced - if (substr_count($equation,"(") != substr_count($equation,")")) { - trigger_error("math: unbalanced parenthesis",E_USER_WARNING); + if (substr_count($equation, "(") != substr_count($equation, ")")) { + trigger_error("math: unbalanced parenthesis", E_USER_WARNING); return; } // match all vars in equation, make sure all are passed - preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]*)!",$equation, $match); + preg_match_all("!(?:0x[a-fA-F0-9]+)|([a-zA-Z][a-zA-Z0-9_]*)!", $equation, $match); foreach ($match[1] as $curr_var) { if ($curr_var && !isset($params[$curr_var]) && !isset($_allowed_funcs[$curr_var])) { - trigger_error("math: function call $curr_var not allowed",E_USER_WARNING); + trigger_error("math: function call $curr_var not allowed", E_USER_WARNING); return; } @@ -58,13 +59,13 @@ function smarty_function_math($params, $template) foreach ($params as $key => $val) { if ($key != "equation" && $key != "format" && $key != "assign") { // make sure value is not empty - if (strlen($val)==0) { - trigger_error("math: parameter $key is empty",E_USER_WARNING); + if (strlen($val) == 0) { + trigger_error("math: parameter $key is empty", E_USER_WARNING); return; } if (!is_numeric($val)) { - trigger_error("math: parameter $key: is not numeric",E_USER_WARNING); + trigger_error("math: parameter $key: is not numeric", E_USER_WARNING); return; } @@ -72,19 +73,19 @@ function smarty_function_math($params, $template) } } $smarty_math_result = null; - eval("\$smarty_math_result = ".$equation.";"); + eval("\$smarty_math_result = " . $equation . ";"); if (empty($params['format'])) { if (empty($params['assign'])) { return $smarty_math_result; } else { - $template->assign($params['assign'],$smarty_math_result); + $template->assign($params['assign'], $smarty_math_result); } } else { if (empty($params['assign'])) { - printf($params['format'],$smarty_math_result); + printf($params['format'], $smarty_math_result); } else { - $template->assign($params['assign'],sprintf($params['format'],$smarty_math_result)); + $template->assign($params['assign'], sprintf($params['format'], $smarty_math_result)); } } } diff --git a/onyx/modules/templates/smarty/plugins/modifier.capitalize.php b/onyx/modules/templates/smarty/plugins/modifier.capitalize.php index b3036b86..a8ad7637 100644 --- a/onyx/modules/templates/smarty/plugins/modifier.capitalize.php +++ b/onyx/modules/templates/smarty/plugins/modifier.capitalize.php @@ -2,22 +2,21 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifier */ /** * Smarty capitalize modifier plugin - * * Type: modifier
    * Name: capitalize
    * Purpose: capitalize words in the string - * * {@internal {$string|capitalize:true:true} is the fastest option for MBString enabled systems }} * * @param string $string string to capitalize * @param boolean $uc_digits also capitalize "x123" to "X123" * @param boolean $lc_rest capitalize first letters, lowercase all following letters "aAa" to "Aaa" + * * @return string capitalized string * @author Monte Ohrt * @author Rodney Rehm @@ -27,10 +26,10 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals if (Smarty::$_MBSTRING) { if ($lc_rest) { // uppercase (including hyphenated words) - $upper_string = mb_convert_case( $string, MB_CASE_TITLE, Smarty::$_CHARSET ); + $upper_string = mb_convert_case($string, MB_CASE_TITLE, Smarty::$_CHARSET); } else { // uppercase word breaks - $upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, create_function ('$matches', 'return stripslashes($matches[1]).mb_convert_case(stripslashes($matches[2]),MB_CASE_UPPER, "' . addslashes(Smarty::$_CHARSET) . '");'), $string); + $upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_mbconvert_cb', $string); } // check uc_digits case if (!$uc_digits) { @@ -40,8 +39,7 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals } } } - $upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, create_function ('$matches', 'return stripslashes($matches[1]).mb_convert_case(stripslashes($matches[3]),MB_CASE_UPPER, "' . addslashes(Smarty::$_CHARSET) . '");'), $upper_string); - + $upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_mbconvert2_cb', $upper_string); return $upper_string; } @@ -50,7 +48,7 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals $string = strtolower($string); } // uppercase (including hyphenated words) - $upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, create_function ('$matches', 'return stripslashes($matches[1]).ucfirst(stripslashes($matches[2]));'), $string); + $upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_ucfirst_cb', $string); // check uc_digits case if (!$uc_digits) { if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) { @@ -59,7 +57,34 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals } } } - $upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, create_function ('$matches', 'return stripslashes($matches[1]).ucfirst(stripslashes($matches[3]));'), $upper_string); - + $upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, 'smarty_mod_cap_ucfirst2_cb', $upper_string); return $upper_string; } + +/* + * + * Bug: create_function() use exhausts memory when used in long loops + * Fix: use declared functions for callbacks instead of using create_function() + * Note: This can be fixed using anonymous functions instead, but that requires PHP >= 5.3 + * + * @author Kyle Renfrow + */ +function smarty_mod_cap_mbconvert_cb($matches) +{ + return stripslashes($matches[1]) . mb_convert_case(stripslashes($matches[2]), MB_CASE_UPPER, Smarty::$_CHARSET); +} + +function smarty_mod_cap_mbconvert2_cb($matches) +{ + return stripslashes($matches[1]) . mb_convert_case(stripslashes($matches[3]), MB_CASE_UPPER, Smarty::$_CHARSET); +} + +function smarty_mod_cap_ucfirst_cb($matches) +{ + return stripslashes($matches[1]) . ucfirst(stripslashes($matches[2])); +} + +function smarty_mod_cap_ucfirst2_cb($matches) +{ + return stripslashes($matches[1]) . ucfirst(stripslashes($matches[3])); +} diff --git a/onyx/modules/templates/smarty/plugins/modifier.date_format.php b/onyx/modules/templates/smarty/plugins/modifier.date_format.php index e1a9d33e..5ad7540b 100644 --- a/onyx/modules/templates/smarty/plugins/modifier.date_format.php +++ b/onyx/modules/templates/smarty/plugins/modifier.date_format.php @@ -2,13 +2,12 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifier */ /** * Smarty date_format modifier plugin - * * Type: modifier
    * Name: date_format
    * Purpose: format datestamps via strftime
    @@ -17,23 +16,25 @@ * - format: strftime format for output * - default_date: default date if $string is empty * - * @link http://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.modifier.date.format.php date_format (Smarty online manual) * @author Monte Ohrt + * * @param string $string input date string * @param string $format strftime format for output * @param string $default_date default date if $string is empty * @param string $formatter either 'strftime' or 'auto' + * * @return string |void - * @uses smarty_make_timestamp() + * @uses smarty_make_timestamp() */ -function smarty_modifier_date_format($string, $format=null, $default_date='', $formatter='auto') +function smarty_modifier_date_format($string, $format = null, $default_date = '', $formatter = 'auto') { if ($format === null) { $format = Smarty::$_DATE_FORMAT; } /** - * Include the {@link shared.make_timestamp.php} plugin - */ + * Include the {@link shared.make_timestamp.php} plugin + */ require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'); if ($string != '' && $string != '0000-00-00' && $string != '0000-00-00 00:00:00') { $timestamp = smarty_make_timestamp($string); @@ -42,7 +43,7 @@ function smarty_modifier_date_format($string, $format=null, $default_date='', $f } else { return; } - if ($formatter=='strftime'||($formatter=='auto'&&strpos($format,'%')!==false)) { + if ($formatter == 'strftime' || ($formatter == 'auto' && strpos($format, '%') !== false)) { if (DS == '\\') { $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T'); $_win_to = array('%m/%d/%y', '%b', "\n", '%I:%M:%S %p', '%H:%M', "\t", '%H:%M:%S'); diff --git a/onyx/modules/templates/smarty/plugins/modifier.debug_print_var.php b/onyx/modules/templates/smarty/plugins/modifier.debug_print_var.php index ea63c8a7..66363d25 100644 --- a/onyx/modules/templates/smarty/plugins/modifier.debug_print_var.php +++ b/onyx/modules/templates/smarty/plugins/modifier.debug_print_var.php @@ -2,38 +2,39 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage Debug */ /** * Smarty debug_print_var modifier plugin - * * Type: modifier
    * Name: debug_print_var
    * Purpose: formats variable contents for display in the console * * @author Monte Ohrt - * @param array|object $var variable to be formatted - * @param integer $depth maximum recursion depth if $var is an array - * @param integer $length maximum string length if $var is a string + * + * @param array|object $var variable to be formatted + * @param integer $depth maximum recursion depth if $var is an array + * @param integer $length maximum string length if $var is a string + * * @return string */ -function smarty_modifier_debug_print_var ($var, $depth = 0, $length = 40) +function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40) { $_replace = array("\n" => '\n', - "\r" => '\r', - "\t" => '\t' - ); + "\r" => '\r', + "\t" => '\t' + ); switch (gettype($var)) { case 'array' : $results = 'Array (' . count($var) . ')'; foreach ($var as $curr_key => $curr_val) { $results .= '
    ' . str_repeat(' ', $depth * 2) - . '' . strtr($curr_key, $_replace) . ' => ' - . smarty_modifier_debug_print_var($curr_val, ++$depth, $length); - $depth--; + . '' . strtr($curr_key, $_replace) . ' => ' + . smarty_modifier_debug_print_var($curr_val, ++$depth, $length); + $depth --; } break; @@ -42,9 +43,9 @@ function smarty_modifier_debug_print_var ($var, $depth = 0, $length = 40) $results = '' . get_class($var) . ' Object (' . count($object_vars) . ')'; foreach ($object_vars as $curr_key => $curr_val) { $results .= '
    ' . str_repeat(' ', $depth * 2) - . ' ->' . strtr($curr_key, $_replace) . ' = ' - . smarty_modifier_debug_print_var($curr_val, ++$depth, $length); - $depth--; + . ' ->' . strtr($curr_key, $_replace) . ' = ' + . smarty_modifier_debug_print_var($curr_val, ++$depth, $length); + $depth --; } break; diff --git a/onyx/modules/templates/smarty/plugins/modifier.escape.php b/onyx/modules/templates/smarty/plugins/modifier.escape.php index bc8ad42a..9fdb0702 100644 --- a/onyx/modules/templates/smarty/plugins/modifier.escape.php +++ b/onyx/modules/templates/smarty/plugins/modifier.escape.php @@ -2,23 +2,24 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifier */ /** * Smarty escape modifier plugin - * * Type: modifier
    * Name: escape
    * Purpose: escape string for output * - * @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual) + * @link http://www.smarty.net/docs/en/language.modifier.escape * @author Monte Ohrt + * * @param string $string input string * @param string $esc_type escape type * @param string $char_set character set, used for htmlspecialchars() or htmlentities() * @param boolean $double_encode encode already encoded entitites again, used for htmlspecialchars() or htmlentities() + * * @return string escaped input string */ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true) @@ -105,7 +106,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $ // Note that the UTF-8 encoded character ä will be represented as %c3%a4 $return = ''; $_length = strlen($string); - for ($x = 0; $x < $_length; $x++) { + for ($x = 0; $x < $_length; $x ++) { $return .= '%' . bin2hex($string[$x]); } @@ -124,7 +125,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $ } // no MBString fallback $_length = strlen($string); - for ($x = 0; $x < $_length; $x++) { + for ($x = 0; $x < $_length; $x ++) { $return .= '&#x' . bin2hex($string[$x]) . ';'; } @@ -143,7 +144,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $ } // no MBString fallback $_length = strlen($string); - for ($x = 0; $x < $_length; $x++) { + for ($x = 0; $x < $_length; $x ++) { $return .= '&#' . ord($string[$x]) . ';'; } @@ -179,7 +180,7 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $ } $_length = strlen($string); - for ($_i = 0; $_i < $_length; $_i++) { + for ($_i = 0; $_i < $_length; $_i ++) { $_ord = ord(substr($string, $_i, 1)); // non-standard char, escape it if ($_ord >= 126) { diff --git a/onyx/modules/templates/smarty/plugins/modifier.regex_replace.php b/onyx/modules/templates/smarty/plugins/modifier.regex_replace.php index a44afb5f..abb1ff54 100644 --- a/onyx/modules/templates/smarty/plugins/modifier.regex_replace.php +++ b/onyx/modules/templates/smarty/plugins/modifier.regex_replace.php @@ -2,23 +2,24 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifier */ /** * Smarty regex_replace modifier plugin - * * Type: modifier
    * Name: regex_replace
    * Purpose: regular expression search/replace * - * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php + * @link http://smarty.php.net/manual/en/language.modifier.regex.replace.php * regex_replace (Smarty online manual) - * @author Monte Ohrt - * @param string $string input string - * @param string|array $search regular expression(s) to search for - * @param string|array $replace string(s) that should be replaced + * @author Monte Ohrt + * + * @param string $string input string + * @param string|array $search regular expression(s) to search for + * @param string|array $replace string(s) that should be replaced + * * @return string */ function smarty_modifier_regex_replace($string, $search, $replace) @@ -36,6 +37,7 @@ function smarty_modifier_regex_replace($string, $search, $replace) /** * @param string $search string(s) that should be replaced + * * @return string * @ignore */ @@ -43,12 +45,12 @@ function _smarty_regex_replace_check($search) { // null-byte injection detection // anything behind the first null-byte is ignored - if (($pos = strpos($search,"\0")) !== false) { - $search = substr($search,0,$pos); + if (($pos = strpos($search, "\0")) !== false) { + $search = substr($search, 0, $pos); } // remove eval-modifier from $search if (preg_match('!([a-zA-Z\s]+)$!s', $search, $match) && (strpos($match[1], 'e') !== false)) { - $search = substr($search, 0, -strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]); + $search = substr($search, 0, - strlen($match[1])) . preg_replace('![e\s]+!', '', $match[1]); } return $search; diff --git a/onyx/modules/templates/smarty/plugins/modifier.replace.php b/onyx/modules/templates/smarty/plugins/modifier.replace.php index cf4f6459..aa5e8570 100644 --- a/onyx/modules/templates/smarty/plugins/modifier.replace.php +++ b/onyx/modules/templates/smarty/plugins/modifier.replace.php @@ -1,23 +1,25 @@ * Name: replace
    * Purpose: simple search/replace * - * @link http://smarty.php.net/manual/en/language.modifier.replace.php replace (Smarty online manual) + * @link http://smarty.php.net/manual/en/language.modifier.replace.php replace (Smarty online manual) * @author Monte Ohrt * @author Uwe Tews + * * @param string $string input string * @param string $search text to search for * @param string $replace replacement text + * * @return string */ function smarty_modifier_replace($string, $search, $replace) diff --git a/onyx/modules/templates/smarty/plugins/modifier.spacify.php b/onyx/modules/templates/smarty/plugins/modifier.spacify.php index 1a5f425a..e5c41ad8 100644 --- a/onyx/modules/templates/smarty/plugins/modifier.spacify.php +++ b/onyx/modules/templates/smarty/plugins/modifier.spacify.php @@ -1,25 +1,27 @@ * Name: spacify
    * Purpose: add spaces between characters in a string * - * @link http://smarty.php.net/manual/en/language.modifier.spacify.php spacify (Smarty online manual) + * @link http://smarty.php.net/manual/en/language.modifier.spacify.php spacify (Smarty online manual) * @author Monte Ohrt + * * @param string $string input string * @param string $spacify_char string to insert between characters. + * * @return string */ function smarty_modifier_spacify($string, $spacify_char = ' ') { // well… what about charsets besides latin and UTF-8? - return implode($spacify_char, preg_split('//' . Smarty::$_UTF8_MODIFIER, $string, -1, PREG_SPLIT_NO_EMPTY)); + return implode($spacify_char, preg_split('//' . Smarty::$_UTF8_MODIFIER, $string, - 1, PREG_SPLIT_NO_EMPTY)); } diff --git a/onyx/modules/templates/smarty/plugins/modifier.truncate.php b/onyx/modules/templates/smarty/plugins/modifier.truncate.php index e2810ed7..fbe62e82 100644 --- a/onyx/modules/templates/smarty/plugins/modifier.truncate.php +++ b/onyx/modules/templates/smarty/plugins/modifier.truncate.php @@ -2,32 +2,34 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifier */ /** * Smarty truncate modifier plugin - * * Type: modifier
    * Name: truncate
    * Purpose: Truncate a string to a certain length if necessary, * optionally splitting in the middle of a word, and * appending the $etc string or inserting $etc into the middle. * - * @link http://smarty.php.net/manual/en/language.modifier.truncate.php truncate (Smarty online manual) + * @link http://smarty.php.net/manual/en/language.modifier.truncate.php truncate (Smarty online manual) * @author Monte Ohrt + * * @param string $string input string * @param integer $length length of truncated text * @param string $etc end string * @param boolean $break_words truncate at word boundary * @param boolean $middle truncate in the middle of text + * * @return string truncated string */ function smarty_modifier_truncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false) { - if ($length == 0) + if ($length == 0) { return ''; + } if (Smarty::$_MBSTRING) { if (mb_strlen($string, Smarty::$_CHARSET) > $length) { diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.cat.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.cat.php index 5dff7474..db9d81fb 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.cat.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.cat.php @@ -2,13 +2,12 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty cat modifier plugin - * * Type: modifier
    * Name: cat
    * Date: Feb 24, 2003
    @@ -16,13 +15,15 @@ * Input: string to catenate
    * Example: {$var|cat:"foo"} * - * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat - * (Smarty online manual) + * @link http://smarty.php.net/manual/en/language.modifier.cat.php cat + * (Smarty online manual) * @author Uwe Tews + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_cat($params, $compiler) +function smarty_modifiercompiler_cat($params) { - return '('.implode(').(', $params).')'; + return '(' . implode(').(', $params) . ')'; } diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.count_characters.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.count_characters.php index 778d0385..f8463d80 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.count_characters.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.count_characters.php @@ -2,23 +2,24 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty count_characters modifier plugin - * * Type: modifier
    * Name: count_characteres
    * Purpose: count the number of characters in a text * - * @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online manual) * @author Uwe Tews + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_count_characters($params, $compiler) +function smarty_modifiercompiler_count_characters($params) { if (!isset($params[1]) || $params[1] != 'true') { return 'preg_match_all(\'/[^\s]/' . Smarty::$_UTF8_MODIFIER . '\',' . $params[0] . ', $tmp)'; diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.count_paragraphs.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.count_paragraphs.php index 581d291c..34f0bbb8 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.count_paragraphs.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.count_paragraphs.php @@ -2,24 +2,25 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty count_paragraphs modifier plugin - * * Type: modifier
    * Name: count_paragraphs
    * Purpose: count the number of paragraphs in a text * - * @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php + * @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php * count_paragraphs (Smarty online manual) - * @author Uwe Tews + * @author Uwe Tews + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_count_paragraphs($params, $compiler) +function smarty_modifiercompiler_count_paragraphs($params) { // count \r or \n characters return '(preg_match_all(\'#[\r\n]+#\', ' . $params[0] . ', $tmp)+1)'; diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.count_sentences.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.count_sentences.php index 5cb0f2ae..f1ec5600 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.count_sentences.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.count_sentences.php @@ -2,24 +2,25 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty count_sentences modifier plugin - * * Type: modifier
    * Name: count_sentences * Purpose: count the number of sentences in a text * - * @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php + * @link http://www.smarty.net/manual/en/language.modifier.count.paragraphs.php * count_sentences (Smarty online manual) - * @author Uwe Tews + * @author Uwe Tews + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_count_sentences($params, $compiler) +function smarty_modifiercompiler_count_sentences($params) { // find periods, question marks, exclamation marks with a word before but not after. return 'preg_match_all("#\w[\.\?\!](\W|$)#S' . Smarty::$_UTF8_MODIFIER . '", ' . $params[0] . ', $tmp)'; diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.count_words.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.count_words.php index 9146900d..8b4330f1 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.count_words.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.count_words.php @@ -2,23 +2,24 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty count_words modifier plugin - * * Type: modifier
    * Name: count_words
    * Purpose: count the number of words in a text * - * @link http://www.smarty.net/manual/en/language.modifier.count.words.php count_words (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.modifier.count.words.php count_words (Smarty online manual) * @author Uwe Tews + * * @param array $params parameters + * * @return string with compiled code -*/ -function smarty_modifiercompiler_count_words($params, $compiler) + */ +function smarty_modifiercompiler_count_words($params) { if (Smarty::$_MBSTRING) { // return 'preg_match_all(\'#[\w\pL]+#' . Smarty::$_UTF8_MODIFIER . '\', ' . $params[0] . ', $tmp)'; diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.default.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.default.php index 83b3f365..fe777623 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.default.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.default.php @@ -2,23 +2,24 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty default modifier plugin - * * Type: modifier
    * Name: default
    * Purpose: designate default value for empty variables * - * @link http://www.smarty.net/manual/en/language.modifier.default.php default (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.modifier.default.php default (Smarty online manual) * @author Uwe Tews + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_default ($params, $compiler) +function smarty_modifiercompiler_default($params) { $output = $params[0]; if (!isset($params[1])) { diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.escape.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.escape.php index 6c6a356a..7e848aae 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.escape.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.escape.php @@ -2,25 +2,27 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * @ignore */ -require_once( SMARTY_PLUGINS_DIR .'shared.literal_compiler_param.php' ); +require_once(SMARTY_PLUGINS_DIR . 'shared.literal_compiler_param.php'); /** * Smarty escape modifier plugin - * * Type: modifier
    * Name: escape
    * Purpose: escape string for output * - * @link http://www.smarty.net/docsv2/en/language.modifier.escape count_characters (Smarty online manual) + * @link http://www.smarty.net/docsv2/en/language.modifier.escape count_characters (Smarty online manual) * @author Rodney Rehm + * * @param array $params parameters + * @param $compiler + * * @return string with compiled code */ function smarty_modifiercompiler_escape($params, $compiler) @@ -43,13 +45,13 @@ function smarty_modifiercompiler_escape($params, $compiler) case 'html': if ($_double_encode) { return 'htmlspecialchars(' - . $params[0] .', ENT_QUOTES, ' - . var_export($char_set, true) . ', ' - . var_export($double_encode, true) . ')'; + . $params[0] . ', ENT_QUOTES, ' + . var_export($char_set, true) . ', ' + . var_export($double_encode, true) . ')'; } elseif ($double_encode) { return 'htmlspecialchars(' - . $params[0] .', ENT_QUOTES, ' - . var_export($char_set, true) . ')'; + . $params[0] . ', ENT_QUOTES, ' + . var_export($char_set, true) . ')'; } else { // fall back to modifier.escape.php } @@ -59,18 +61,18 @@ function smarty_modifiercompiler_escape($params, $compiler) if ($_double_encode) { // php >=5.2.3 - go native return 'mb_convert_encoding(htmlspecialchars(' - . $params[0] .', ENT_QUOTES, ' - . var_export($char_set, true) . ', ' - . var_export($double_encode, true) - . '), "HTML-ENTITIES", ' - . var_export($char_set, true) . ')'; + . $params[0] . ', ENT_QUOTES, ' + . var_export($char_set, true) . ', ' + . var_export($double_encode, true) + . '), "HTML-ENTITIES", ' + . var_export($char_set, true) . ')'; } elseif ($double_encode) { // php <5.2.3 - only handle double encoding return 'mb_convert_encoding(htmlspecialchars(' - . $params[0] .', ENT_QUOTES, ' - . var_export($char_set, true) - . '), "HTML-ENTITIES", ' - . var_export($char_set, true) . ')'; + . $params[0] . ', ENT_QUOTES, ' + . var_export($char_set, true) + . '), "HTML-ENTITIES", ' + . var_export($char_set, true) . ')'; } else { // fall back to modifier.escape.php } @@ -80,14 +82,14 @@ function smarty_modifiercompiler_escape($params, $compiler) if ($_double_encode) { // php >=5.2.3 - go native return 'htmlentities(' - . $params[0] .', ENT_QUOTES, ' - . var_export($char_set, true) . ', ' - . var_export($double_encode, true) . ')'; + . $params[0] . ', ENT_QUOTES, ' + . var_export($char_set, true) . ', ' + . var_export($double_encode, true) . ')'; } elseif ($double_encode) { // php <5.2.3 - only handle double encoding return 'htmlentities(' - . $params[0] .', ENT_QUOTES, ' - . var_export($char_set, true) . ')'; + . $params[0] . ', ENT_QUOTES, ' + . var_export($char_set, true) . ')'; } else { // fall back to modifier.escape.php } @@ -105,20 +107,20 @@ function smarty_modifiercompiler_escape($params, $compiler) case 'javascript': // escape quotes and backslashes, newlines, etc. return 'strtr(' . $params[0] . ', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", " "<\/" ))'; - } - } catch (SmartyException $e) { + } + catch (SmartyException $e) { // pass through to regular plugin fallback } // could not optimize |escape call, so fallback to regular plugin if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) { - $compiler->template->required_plugins['nocache']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR .'modifier.escape.php'; + $compiler->template->required_plugins['nocache']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'modifier.escape.php'; $compiler->template->required_plugins['nocache']['escape']['modifier']['function'] = 'smarty_modifier_escape'; } else { - $compiler->template->required_plugins['compiled']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR .'modifier.escape.php'; + $compiler->template->required_plugins['compiled']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'modifier.escape.php'; $compiler->template->required_plugins['compiled']['escape']['modifier']['function'] = 'smarty_modifier_escape'; } - return 'smarty_modifier_escape(' . join( ', ', $params ) . ')'; + return 'smarty_modifier_escape(' . join(', ', $params) . ')'; } diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.from_charset.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.from_charset.php index 1dfee367..dab43e9c 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.from_charset.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.from_charset.php @@ -2,22 +2,23 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty from_charset modifier plugin - * * Type: modifier
    * Name: from_charset
    * Purpose: convert character encoding from $charset to internal encoding * * @author Rodney Rehm + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_from_charset($params, $compiler) +function smarty_modifiercompiler_from_charset($params) { if (!Smarty::$_MBSTRING) { // FIXME: (rodneyrehm) shouldn't this throw an error? diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.indent.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.indent.php index 85bc6105..e3ca2082 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.indent.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.indent.php @@ -1,24 +1,26 @@ * Name: indent
    * Purpose: indent lines of text * - * @link http://www.smarty.net/manual/en/language.modifier.indent.php indent (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.modifier.indent.php indent (Smarty online manual) * @author Uwe Tews + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_indent($params, $compiler) +function smarty_modifiercompiler_indent($params) { if (!isset($params[1])) { $params[1] = 4; diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.lower.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.lower.php index b1a23186..1d255f37 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.lower.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.lower.php @@ -1,28 +1,30 @@ * Name: lower
    * Purpose: convert string to lowercase * - * @link http://www.smarty.net/manual/en/language.modifier.lower.php lower (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.modifier.lower.php lower (Smarty online manual) * @author Monte Ohrt * @author Uwe Tews + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_lower($params, $compiler) +function smarty_modifiercompiler_lower($params) { if (Smarty::$_MBSTRING) { - return 'mb_strtolower(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')' ; + return 'mb_strtolower(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')'; } // no MBString fallback return 'strtolower(' . $params[0] . ')'; diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.noprint.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.noprint.php index 71f6bfae..4906908b 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.noprint.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.noprint.php @@ -2,22 +2,20 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty noprint modifier plugin - * * Type: modifier
    * Name: noprint
    * Purpose: return an empty string * * @author Uwe Tews - * @param array $params parameters * @return string with compiled code */ -function smarty_modifiercompiler_noprint($params, $compiler) +function smarty_modifiercompiler_noprint() { return "''"; } diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.string_format.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.string_format.php index defbf6e2..71cdf281 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.string_format.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.string_format.php @@ -2,23 +2,24 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty string_format modifier plugin - * * Type: modifier
    * Name: string_format
    * Purpose: format strings via sprintf * - * @link http://www.smarty.net/manual/en/language.modifier.string.format.php string_format (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.modifier.string.format.php string_format (Smarty online manual) * @author Uwe Tews + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_string_format($params, $compiler) +function smarty_modifiercompiler_string_format($params) { return 'sprintf(' . $params[1] . ',' . $params[0] . ')'; } diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.strip.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.strip.php index 6c732e81..fcd6cbae 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.strip.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.strip.php @@ -2,13 +2,12 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty strip modifier plugin - * * Type: modifier
    * Name: strip
    * Purpose: Replace all repeated spaces, newlines, tabs @@ -16,13 +15,15 @@ * Example: {$var|strip} {$var|strip:" "}
    * Date: September 25th, 2002 * - * @link http://www.smarty.net/manual/en/language.modifier.strip.php strip (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.modifier.strip.php strip (Smarty online manual) * @author Uwe Tews + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_strip($params, $compiler) +function smarty_modifiercompiler_strip($params) { if (!isset($params[1])) { $params[1] = "' '"; diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.strip_tags.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.strip_tags.php index bc5eab26..3e6e1304 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.strip_tags.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.strip_tags.php @@ -2,26 +2,27 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty strip_tags modifier plugin - * * Type: modifier
    * Name: strip_tags
    * Purpose: strip html tags from text * - * @link http://www.smarty.net/manual/en/language.modifier.strip.tags.php strip_tags (Smarty online manual) + * @link http://www.smarty.net/manual/en/language.modifier.strip.tags.php strip_tags (Smarty online manual) * @author Uwe Tews + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_strip_tags($params, $compiler) +function smarty_modifiercompiler_strip_tags($params) { - if (!isset($params[1]) || $params[1] === true || trim($params[1],'"') == 'true') { - return "preg_replace('!<[^>]*?>!', ' ', {$params[0]})"; + if (!isset($params[1]) || $params[1] === true || trim($params[1], '"') == 'true') { + return "preg_replace('!<[^>]*?>!', ' ', {$params[0]})"; } else { return 'strip_tags(' . $params[0] . ')'; } diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.to_charset.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.to_charset.php index af75779a..9122d8bb 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.to_charset.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.to_charset.php @@ -2,22 +2,23 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty to_charset modifier plugin - * * Type: modifier
    * Name: to_charset
    * Purpose: convert character encoding from internal encoding to $charset * * @author Rodney Rehm + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_to_charset($params, $compiler) +function smarty_modifiercompiler_to_charset($params) { if (!Smarty::$_MBSTRING) { // FIXME: (rodneyrehm) shouldn't this throw an error? diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.unescape.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.unescape.php index 19474fcb..3b17ea2e 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.unescape.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.unescape.php @@ -2,22 +2,23 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty unescape modifier plugin - * * Type: modifier
    * Name: unescape
    * Purpose: unescape html entities * * @author Rodney Rehm + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_unescape($params, $compiler) +function smarty_modifiercompiler_unescape($params) { if (!isset($params[1])) { $params[1] = 'html'; diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.upper.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.upper.php index f10ed187..52ca4e8f 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.upper.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.upper.php @@ -2,26 +2,27 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty upper modifier plugin - * * Type: modifier
    * Name: lower
    * Purpose: convert string to uppercase * - * @link http://smarty.php.net/manual/en/language.modifier.upper.php lower (Smarty online manual) + * @link http://smarty.php.net/manual/en/language.modifier.upper.php lower (Smarty online manual) * @author Uwe Tews + * * @param array $params parameters + * * @return string with compiled code */ -function smarty_modifiercompiler_upper($params, $compiler) +function smarty_modifiercompiler_upper($params) { if (Smarty::$_MBSTRING) { - return 'mb_strtoupper(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')' ; + return 'mb_strtoupper(' . $params[0] . ', \'' . addslashes(Smarty::$_CHARSET) . '\')'; } // no MBString fallback return 'strtoupper(' . $params[0] . ')'; diff --git a/onyx/modules/templates/smarty/plugins/modifiercompiler.wordwrap.php b/onyx/modules/templates/smarty/plugins/modifiercompiler.wordwrap.php index 39312b41..2ad928ea 100644 --- a/onyx/modules/templates/smarty/plugins/modifiercompiler.wordwrap.php +++ b/onyx/modules/templates/smarty/plugins/modifiercompiler.wordwrap.php @@ -2,20 +2,22 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsModifierCompiler */ /** * Smarty wordwrap modifier plugin - * * Type: modifier
    * Name: wordwrap
    * Purpose: wrap a string of text at a given length * - * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php wordwrap (Smarty online manual) + * @link http://smarty.php.net/manual/en/language.modifier.wordwrap.php wordwrap (Smarty online manual) * @author Uwe Tews + * * @param array $params parameters + * @param $compiler + * * @return string with compiled code */ function smarty_modifiercompiler_wordwrap($params, $compiler) @@ -31,11 +33,11 @@ function smarty_modifiercompiler_wordwrap($params, $compiler) } $function = 'wordwrap'; if (Smarty::$_MBSTRING) { - if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) { - $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR .'shared.mb_wordwrap.php'; + if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) { + $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php'; $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap'; } else { - $compiler->template->required_plugins['compiled']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR .'shared.mb_wordwrap.php'; + $compiler->template->required_plugins['compiled']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR . 'shared.mb_wordwrap.php'; $compiler->template->required_plugins['compiled']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap'; } $function = 'smarty_mb_wordwrap'; diff --git a/onyx/modules/templates/smarty/plugins/outputfilter.trimwhitespace.php b/onyx/modules/templates/smarty/plugins/outputfilter.trimwhitespace.php index 9da7f3db..62ab4e77 100644 --- a/onyx/modules/templates/smarty/plugins/outputfilter.trimwhitespace.php +++ b/onyx/modules/templates/smarty/plugins/outputfilter.trimwhitespace.php @@ -2,22 +2,22 @@ /** * Smarty plugin * - * @package Smarty + * @package Smarty * @subpackage PluginsFilter */ /** * Smarty trimwhitespace outputfilter plugin - * * Trim unnecessary whitespace from HTML markup. * * @author Rodney Rehm - * @param string $source input string - * @param Smarty_Internal_Template $smarty Smarty object + * + * @param string $source input string + * * @return string filtered output - * @todo substr_replace() is not overloaded by mbstring.func_overload - so this function might fail! + * @todo substr_replace() is not overloaded by mbstring.func_overload - so this function might fail! */ -function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $smarty) +function smarty_outputfilter_trimwhitespace($source) { $store = array(); $_store = 0; @@ -35,13 +35,13 @@ function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $s $source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length); $_offset += $_length - strlen($replace); - $_store++; + $_store ++; } } // Strip all HTML-Comments // yes, even the ones in +{/block} diff --git a/onyx/tpl/bootstrap/admin/layout.tpl b/onyx/tpl/bootstrap/admin/layout.tpl index d56229cd..ca09d3f0 100644 --- a/onyx/tpl/bootstrap/admin/layout.tpl +++ b/onyx/tpl/bootstrap/admin/layout.tpl @@ -16,6 +16,7 @@ {/if} update_end(); + {block name=end2}{/block} {/block} {block name=body} From 3f15b7187eb00cad16704b590ca386c48780ed80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sun, 18 Jan 2015 11:50:13 +0100 Subject: [PATCH 0370/2686] Error pages are now copied at frontend start --- front/Dockerfile | 3 ++- front/nginx.conf | 2 +- synchro.sh | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/front/Dockerfile b/front/Dockerfile index 5ed4054a..8a0cf970 100644 --- a/front/Dockerfile +++ b/front/Dockerfile @@ -30,6 +30,7 @@ RUN ln -sf /var/www/fic-server/front/nginx.conf /etc/nginx/sites-enabled/default EXPOSE 80/tcp 443/tcp -CMD service nginx start && \ +CMD cp -r out/errors shared/ && \ + service nginx start && \ service php5-fpm start && \ /bin/bash diff --git a/front/nginx.conf b/front/nginx.conf index 76aa1a37..af60f533 100644 --- a/front/nginx.conf +++ b/front/nginx.conf @@ -58,7 +58,7 @@ server { location /errors { - root /var/www/fic-server/out/; + root /var/www/fic-server/shared; } location /challenge diff --git a/synchro.sh b/synchro.sh index 7c3c0680..f8b94cb4 100755 --- a/synchro.sh +++ b/synchro.sh @@ -24,10 +24,10 @@ fi # Synchronize HTML pages rsync -e "$SSH_OPTS" -av $OPTS out "$FRONTEND_HOSTNAME":~/ rsync -e "$SSH_OPTS" -avL $OPTS files "$FRONTEND_HOSTNAME":~/ -rsync -e "$SSH_OPTS" -av $OPTS front shared "$FRONTEND_HOSTNAME":~/ +rsync -e "$SSH_OPTS" -av front shared "$FRONTEND_HOSTNAME":~/ # Synchronize submissions rsync -e "$SSH_OPTS" -av "$FRONTEND_HOSTNAME":~/submission/ submission/ -ssh -o 'UserKnownHostsFile=/dev/null' -o 'StrictHostKeyChecking=no' -p 2242 -i .ssh/id_rsa "$FRONTEND_HOSTNAME" "rm -fv ~/submission/*" +$SSH_OPTS "$FRONTEND_HOSTNAME" "rm -fv ~/submission/*" exit $? From 2a9cac24f7eabbb49574daa575fa74a6bce66b7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sun, 18 Jan 2015 11:50:55 +0100 Subject: [PATCH 0371/2686] Lobby at challenge end --- TODO | 1 - htdocs/index.php | 11 ++++++++ onyx/tpl/bootstrap/rank.tpl | 20 ++++++++++++++ onyx/tpl/bootstrap/teams/end.tpl | 43 +++++++++++++++++++++++++++++++ onyx/tpl/bootstrap/teams/rank.tpl | 21 +-------------- 5 files changed, 75 insertions(+), 21 deletions(-) create mode 100644 onyx/tpl/bootstrap/rank.tpl create mode 100644 onyx/tpl/bootstrap/teams/end.tpl diff --git a/TODO b/TODO index 00507107..05fd0ea4 100644 --- a/TODO +++ b/TODO @@ -4,7 +4,6 @@ ** TODO trop de thèmes dans l'interface d'admin => menu ** TODO avoir la page avec le résumé * PHP -** TODO On peut encore soumettre après la fin... ** TODO les mauvaises pages sont generees (pas debug et non liens prod) ** TODO sur le frontend, en mode productoin, il va chercher les pages de debug ** TODO numéro des exercices diff --git a/htdocs/index.php b/htdocs/index.php index aa0de1ea..f034b421 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -150,6 +150,17 @@ else if ($n && $p[0] == SALT_USER) $page = "teams/lobby"; } + else if (time() > $VAR["end_challenge"]) + { + $TEAM = new Team($p[1]); + $template->assign("my_team", $TEAM); + $template->assign("themes", Theme::get_themes()); + $template->assign("rank", Team::get_top()); + + require("team/summary.php"); + $page = "teams/end"; + } + else { $TEAM = new Team($p[1]); diff --git a/onyx/tpl/bootstrap/rank.tpl b/onyx/tpl/bootstrap/rank.tpl new file mode 100644 index 00000000..bb571dfa --- /dev/null +++ b/onyx/tpl/bootstrap/rank.tpl @@ -0,0 +1,20 @@ + + + + + + + + + + + {foreach from=$rank item=t key=k} + id == $my_team->id} class="active" style="font-weight: bold"{/if}> + + + + + + {/foreach} + +
    #TeamSloganPoints
    {$t->get_rank()}{$t->get_name()}{$t->slogan}{$t->get_pts()}
    diff --git a/onyx/tpl/bootstrap/teams/end.tpl b/onyx/tpl/bootstrap/teams/end.tpl new file mode 100644 index 00000000..1b56b20f --- /dev/null +++ b/onyx/tpl/bootstrap/teams/end.tpl @@ -0,0 +1,43 @@ +{extends file="layout.tpl"} + +{block name=head} + +{block name=head2}{/block} +{/block} + +{block name=end} + + +{/block} + +{block name=content} + {include file="clock.tpl"} +
    +
    + Le challenge est terminé ! Vous avez résolu {$my_team->get_solved_exercices()|count} exercices, pour un total de {$my_team->get_pts()} points. Vous êtes {$my_team->get_rank()}e, bravo ! +
    + +
    +
    +

    Progression

    +
    +
    + {include file="summary.tpl"} +
    +
    + +
    +
    +

    Classement final

    +
    +
    + {include file="rank.tpl"} +
    +
    +
    +{/block} diff --git a/onyx/tpl/bootstrap/teams/rank.tpl b/onyx/tpl/bootstrap/teams/rank.tpl index b70c546d..5f5c30fc 100644 --- a/onyx/tpl/bootstrap/teams/rank.tpl +++ b/onyx/tpl/bootstrap/teams/rank.tpl @@ -1,24 +1,5 @@ {extends file="teams/layout.tpl"} {block name=content} - - - - - - - - - - - {foreach from=$rank item=t key=k} - id == $my_team->id} class="active" style="font-weight: bold"{/if}> - - - - - - {/foreach} - -
    #TeamSloganPoints
    {$t->get_rank()}{$t->get_name()}{$t->slogan}{$t->get_pts()}
    + {include file="rank.tpl"} {/block} From 90f47b2e9f2a9d5afd1d5252d0d459f2632c00f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sun, 18 Jan 2015 11:51:49 +0100 Subject: [PATCH 0372/2686] Don't SYNC when launching chrono, wait manual action --- onyx/include/admin/chrono.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/onyx/include/admin/chrono.php b/onyx/include/admin/chrono.php index 97cb9bc9..a2b319f1 100644 --- a/onyx/include/admin/chrono.php +++ b/onyx/include/admin/chrono.php @@ -7,8 +7,8 @@ if (count($p) > 2) switch($p[2]) { case "start": - file_put_contents($VAR["misc_dir"]."/shared/challenge_started", time() + (intval($_POST["time"]) - 240) * 60); - pipe_backend_scheduler("resetreset:HOME:all:SY"); + file_put_contents($VAR["misc_dir"]."/shared/challenge_started", time() + 40 + (intval($_POST["time"]) - 240) * 60); + pipe_backend_scheduler("resetreset:HOME:all"); break; case "init": From 8cdbf08482d785fda6091bb35c54353203aa8978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sun, 18 Jan 2015 12:09:29 +0100 Subject: [PATCH 0373/2686] Optimize backend Dockerfile to reduce building time --- Dockerfile | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1453b109..505b4c27 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,31 +28,13 @@ RUN apt-get -y update && \ RUN useradd -d /var/www/fic-server -M -N -g www-data synchro -# Copying files ####################################################### - -WORKDIR /var/www/fic-server - -COPY . /var/www/fic-server/ - -# Configure softwares ################################################# - -RUN dpkg -i /var/www/fic-server/libmcrypt-perl*.deb || \ - (echo "Please build perl-mcrypt first. Consult the given README!"; exit 1) && \ - rm /var/www/fic-server/libmcrypt-perl*.deb && \ - ln -sf /var/www/fic-server/nginx-server.conf /etc/nginx/sites-enabled/default && \ - ln -sf /var/www/fic-server/php-fpm.conf /etc/php5/fpm/pool.d/www.conf - -# Configure site ###################################################### - -RUN ln -sf /var/www/fic-server/onyx/config/sample.root.xml /var/www/fic-server/onyx/config/root.xml && \ - sed -i "s/challenge-public//" /var/www/fic-server/onyx/config/root.xml && \ - chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/templates/cache/ /var/www/fic-server/onyx/cache/templates/compile/ - # ENVIRONNEMENT ####################################################### EXPOSE 80/tcp 443/tcp VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submission","/var/www/fic-server/shared"] +WORKDIR /var/www/fic-server + ENTRYPOINT ["/var/www/fic-server/entrypoint.sh"] CMD service nginx start && \ @@ -61,3 +43,19 @@ CMD service nginx start && \ chown www-data ./shared/nginx-teams.conf && \ (./launch.sh &); \ /bin/bash + +# Copying files ####################################################### + +COPY . /var/www/fic-server/ + +# Configure softwares ################################################# + +RUN dpkg -i /var/www/fic-server/libmcrypt-perl*.deb || \ + (echo "Please build perl-mcrypt first. Consult the given README!"; exit 1) && \ + rm /var/www/fic-server/libmcrypt-perl*.deb && \ + ln -sf /var/www/fic-server/nginx-server.conf /etc/nginx/sites-enabled/default && \ + ln -sf /var/www/fic-server/php-fpm.conf /etc/php5/fpm/pool.d/www.conf && \ + \ + ln -sf /var/www/fic-server/onyx/config/sample.root.xml /var/www/fic-server/onyx/config/root.xml && \ + sed -i "s/challenge-public//" /var/www/fic-server/onyx/config/root.xml && \ + chmod 777 /var/www/fic-server/onyx/cache/ /var/www/fic-server/onyx/cache/templates/cache/ /var/www/fic-server/onyx/cache/templates/compile/ From 603f7bb72ee02f4d6f5c9c9209cceef85bc83a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sun, 18 Jan 2015 12:10:52 +0100 Subject: [PATCH 0374/2686] Fix timezone problem --- .../templates/smarty/plugins/modifier.date_format.php | 1 + .../templates/smarty/plugins/shared.make_timestamp.php | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/onyx/modules/templates/smarty/plugins/modifier.date_format.php b/onyx/modules/templates/smarty/plugins/modifier.date_format.php index 5ad7540b..a0cb2cab 100644 --- a/onyx/modules/templates/smarty/plugins/modifier.date_format.php +++ b/onyx/modules/templates/smarty/plugins/modifier.date_format.php @@ -43,6 +43,7 @@ function smarty_modifier_date_format($string, $format = null, $default_date = '' } else { return; } + $timestamp += 3600; if ($formatter == 'strftime' || ($formatter == 'auto' && strpos($format, '%') !== false)) { if (DS == '\\') { $_win_from = array('%D', '%h', '%n', '%r', '%R', '%t', '%T'); diff --git a/onyx/modules/templates/smarty/plugins/shared.make_timestamp.php b/onyx/modules/templates/smarty/plugins/shared.make_timestamp.php index 7c94e5f5..58bea326 100644 --- a/onyx/modules/templates/smarty/plugins/shared.make_timestamp.php +++ b/onyx/modules/templates/smarty/plugins/shared.make_timestamp.php @@ -20,7 +20,7 @@ function smarty_make_timestamp($string) { if (empty($string)) { // use "now": - return time(); + return localtime(); } elseif ($string instanceof DateTime) { return $string->getTimestamp(); } elseif (strlen($string) == 14 && ctype_digit($string)) { @@ -29,13 +29,13 @@ function smarty_make_timestamp($string) substr($string, 4, 2), substr($string, 6, 2), substr($string, 0, 4)); } elseif (is_numeric($string)) { // it is a numeric string, we handle it as timestamp - return (int) $string; + return localtime($string); } else { // strtotime should handle it $time = strtotime($string); if ($time == - 1 || $time === false) { // strtotime() was not able to parse $string, use "now": - return time(); + return localtime(); } return $time; From a848527d93592532a88358b7c984102521444711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sun, 18 Jan 2015 15:58:00 +0100 Subject: [PATCH 0375/2686] Give good rights to submission directory on frontend start --- front/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/front/Dockerfile b/front/Dockerfile index 8a0cf970..9044113d 100644 --- a/front/Dockerfile +++ b/front/Dockerfile @@ -31,6 +31,7 @@ RUN ln -sf /var/www/fic-server/front/nginx.conf /etc/nginx/sites-enabled/default EXPOSE 80/tcp 443/tcp CMD cp -r out/errors shared/ && \ + chown www-data submission/ && \ service nginx start && \ service php5-fpm start && \ /bin/bash From f7da5ed9933be49459084ae6336027d43ebf1fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sun, 18 Jan 2015 15:58:52 +0100 Subject: [PATCH 0376/2686] Fix deletion of submission in synchro.sh --- synchro.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/synchro.sh b/synchro.sh index f8b94cb4..495496a7 100755 --- a/synchro.sh +++ b/synchro.sh @@ -23,11 +23,11 @@ fi # Synchronize HTML pages rsync -e "$SSH_OPTS" -av $OPTS out "$FRONTEND_HOSTNAME":~/ -rsync -e "$SSH_OPTS" -avL $OPTS files "$FRONTEND_HOSTNAME":~/ rsync -e "$SSH_OPTS" -av front shared "$FRONTEND_HOSTNAME":~/ +rsync -e "$SSH_OPTS" -avL $OPTS files "$FRONTEND_HOSTNAME":~/ # Synchronize submissions rsync -e "$SSH_OPTS" -av "$FRONTEND_HOSTNAME":~/submission/ submission/ -$SSH_OPTS "$FRONTEND_HOSTNAME" "rm -fv ~/submission/*" +eval $SSH_OPTS "$FRONTEND_HOSTNAME" "rm -fv ~/submission/*" exit $? From 977cd67c8ba5ec90c27574e86101269e17eff410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sun, 18 Jan 2015 22:23:40 +0100 Subject: [PATCH 0377/2686] Add margins --- onyx/tpl/bootstrap/admin/home.tpl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/onyx/tpl/bootstrap/admin/home.tpl b/onyx/tpl/bootstrap/admin/home.tpl index 4e9ebbcb..5ece0731 100644 --- a/onyx/tpl/bootstrap/admin/home.tpl +++ b/onyx/tpl/bootstrap/admin/home.tpl @@ -97,17 +97,17 @@
    Complet Accueil - Pages d'erreurs
    + Pages d'erreurs

    Synchro légère - Vider la file d'attente
    + Vider la file d'attente

    Freeze - Unfreeze + Unfreeze

    - +
    From 05bc4c605c460180086e5c2fe44159f1c4e9beef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9munaire?= Date: Sun, 18 Jan 2015 22:23:53 +0100 Subject: [PATCH 0378/2686] Count solved exercices --- onyx/include/common/Team.class.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/onyx/include/common/Team.class.php b/onyx/include/common/Team.class.php index b299cf03..89830b7f 100644 --- a/onyx/include/common/Team.class.php +++ b/onyx/include/common/Team.class.php @@ -216,25 +216,25 @@ class Team function get_solved_exercices($id_theme=-1) { + $array = array(); + global $db; if ($id_theme != -1) - { - global $db; $ids = $db->query("SELECT `id_theme`, `id_exercice` FROM solved S LEFT OUTER JOIN exercices E ON S.id_exercice = E.id WHERE id_team =".$this->id." AND id_theme =".$id_theme); - - $array = array(); - $i = 0; - if ($ids) - { - foreach ($ids as $id) - $array[] = new Exercice($id['id_exercice']); - } - - return $array; + else + $ids = $db->query("SELECT `id_theme`, `id_exercice` + FROM solved S + LEFT OUTER JOIN exercices E ON S.id_exercice = E.id + WHERE id_team =".$this->id); + if ($ids) + { + foreach ($ids as $id) + $array[] = new Exercice($id['id_exercice']); } - return NULL; + + return $array; } // Static methods From 458060bc3b54da7bd85eec20fc432369d475a96e Mon Sep 17 00:00:00 2001 From: Nemunaire Date: Mon, 29 Dec 2014 01:34:18 +0100 Subject: [PATCH 0379/2686] Use team 0 to display solutions --- htdocs/css/main.css | 2 +- htdocs/index.php | 4 ++-- onyx/include/admin/generation.php | 2 +- onyx/include/team/summary.php | 1 + onyx/tpl/bootstrap/teams/exercice.tpl | 23 +++++++---------------- onyx/tpl/bootstrap/teams/summary.tpl | 13 +++++++++++++ 6 files changed, 25 insertions(+), 20 deletions(-) diff --git a/htdocs/css/main.css b/htdocs/css/main.css index 4a04e24d..c752d8b9 100644 --- a/htdocs/css/main.css +++ b/htdocs/css/main.css @@ -53,7 +53,7 @@ } samp { display: block; - overflow-x: scroll; + overflow-x: auto; text-overflow: ellipsis; } diff --git a/htdocs/index.php b/htdocs/index.php index f034b421..112709a6 100644 --- a/htdocs/index.php +++ b/htdocs/index.php @@ -140,7 +140,7 @@ else if ($n && $p[0] == SALT_USER) $page = "teams/list"; } - else if (empty($VAR["start_challenge"])) + else if (!empty($p[1]) && empty($VAR["start_challenge"])) { $TEAM = new Team($p[1]); $template->assign("my_team", $TEAM); @@ -150,7 +150,7 @@ else if ($n && $p[0] == SALT_USER) $page = "teams/lobby"; } - else if (time() > $VAR["end_challenge"]) + else if (!empty($p[1]) && time() > $VAR["end_challenge"]) { $TEAM = new Team($p[1]); $template->assign("my_team", $TEAM); diff --git a/onyx/include/admin/generation.php b/onyx/include/admin/generation.php index 85b4cc5b..0f63b4f9 100644 --- a/onyx/include/admin/generation.php +++ b/onyx/include/admin/generation.php @@ -39,7 +39,7 @@ if (count($p) > 2) break; case "team": - if (!empty($_POST["team"])) + if (isset($_POST["team"])) $ret = pipe_backend_scheduler("resetr:TEAM".intval($_POST["team"]).":SYNCS"); break; diff --git a/onyx/include/team/summary.php b/onyx/include/team/summary.php index 556a9298..2e1e36e6 100644 --- a/onyx/include/team/summary.php +++ b/onyx/include/team/summary.php @@ -19,5 +19,6 @@ if (!empty($themes)) $template->assign("themes", Theme::get_themes()); $template->assign("nbExoMax", Exercice::get_nb_exo_max()); $template->assign("percent", $percent); +$template->assign("rank", Team::get_top()); return "teams/summary"; diff --git a/onyx/tpl/bootstrap/teams/exercice.tpl b/onyx/tpl/bootstrap/teams/exercice.tpl index 662ff74b..875dae89 100644 --- a/onyx/tpl/bootstrap/teams/exercice.tpl +++ b/onyx/tpl/bootstrap/teams/exercice.tpl @@ -53,22 +53,13 @@
    {if empty($my_team->id)} - Vérifiez votre solution parmi les algorithmes suivants : - - - - - - - - {foreach from=$cur_exercice->keys item=key} - - - - - {/foreach} - -
    AlgorithmeHash
    {$key.format}
    {$key.value}
    + Vérifiez votre solution parmi les algorithmes suivants :

    +
    + {foreach from=$cur_exercice->keys item=key} +
    {$key.format}
    +
    {$key.value}
    + {/foreach} +
    {else if $cur_exercice->has_solved($my_team)} Résolu à {$cur_exercice->has_solved($my_team)|date_format:"%H:%M:%S"} :) {else} diff --git a/onyx/tpl/bootstrap/teams/summary.tpl b/onyx/tpl/bootstrap/teams/summary.tpl index cf025cba..78479668 100644 --- a/onyx/tpl/bootstrap/teams/summary.tpl +++ b/onyx/tpl/bootstrap/teams/summary.tpl @@ -1,6 +1,18 @@ {extends file="teams/layout.tpl"} {block name=content} +{if empty($my_team->id)} +
    +
    +

    Challenge forensic Épita 2015

    +
    +
    + Le challenge s'est déroulé le mardi 20 janvier 2015 lors du Forum International de la Cybercriminalité. Bravo à tous les participants !

    + Consultez la chaîne YouTube d'Épita pour visionner les vidéos de résolutions des exercices. +
    +
    +{include file="rank.tpl"} +{else} {if isset($percent)}
    @@ -17,4 +29,5 @@
    {/if} {include file="summary.tpl"} +{/if} {/block} From 21e4432fad1a5e59554dbc2540beb44b16d255f3 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 6 Jan 2016 19:30:57 +0100 Subject: [PATCH 0380/2686] Add frontend --- frontend/.gitignore | 1 + frontend/main.go | 33 ++++++++++++++++ frontend/submit.go | 91 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 frontend/.gitignore create mode 100644 frontend/main.go create mode 100644 frontend/submit.go diff --git a/frontend/.gitignore b/frontend/.gitignore new file mode 100644 index 00000000..1097e68b --- /dev/null +++ b/frontend/.gitignore @@ -0,0 +1 @@ +frontend diff --git a/frontend/main.go b/frontend/main.go new file mode 100644 index 00000000..2427f571 --- /dev/null +++ b/frontend/main.go @@ -0,0 +1,33 @@ +package main + +import ( + "flag" + "fmt" + "log" + "net/http" + "os" +) + +var SubmissionDir string + +func main() { + var bind = flag.String("bind", "0.0.0.0:8080", "Bind port/socket") + var prefix = flag.String("prefix", "", "Request path prefix to strip (from proxy)") + flag.StringVar(&SubmissionDir, "submission", "./submissions/", "Base directory where save submissions") + flag.Parse() + + log.Println("Creating submission directory...") + if _, err := os.Stat(SubmissionDir); os.IsNotExist(err) { + if err := os.MkdirAll(SubmissionDir, 0777); err != nil { + log.Fatal("Unable to create submission directory: ", err) + } + } + + log.Println("Registering handlers...") + http.Handle(fmt.Sprintf("%s/", *prefix), http.StripPrefix(*prefix, SubmissionHandler{})) + + log.Println(fmt.Sprintf("Ready, listening on %s", *bind)) + if err := http.ListenAndServe(*bind, nil); err != nil { + log.Fatal("Unable to listen and serve: ", err) + } +} diff --git a/frontend/submit.go b/frontend/submit.go new file mode 100644 index 00000000..2b66f644 --- /dev/null +++ b/frontend/submit.go @@ -0,0 +1,91 @@ +package main + +import ( + "fmt" + "log" + "net/http" + "os" + "path" + "strconv" + "strings" +) + +type SubmissionHandler struct{} + +func (SubmissionHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + log.Printf("Handling %s request from %s: %s [%s]\n", r.Method, r.RemoteAddr, r.URL.Path, r.UserAgent()) + + w.Header().Set("Content-Type", "application/json") + + + // Check request type and size + if r.Method != "POST" { + http.Error(w, "{errmsg:\"Bad request.\"}", http.StatusBadRequest) + return + } else if r.ContentLength < 0 || r.ContentLength > 255 { + http.Error(w, "{errmsg:\"Request too large or request size unknown\"}", http.StatusRequestEntityTooLarge) + return + } + + + // Extract URL arguments + var sURL = strings.Split(r.URL.Path, "/") + + if len(sURL) != 3 && len(sURL) != 4 { + http.Error(w, "{errmsg:\"Bad request.\"}", http.StatusBadRequest) + return + } + + // Parse arguments + if team, err := strconv.Atoi(sURL[1]); err != nil { + http.Error(w, "{errmsg:\"Bad request.\"}", http.StatusBadRequest) + return + } else if exercice, err := strconv.Atoi(sURL[2]); err != nil { + http.Error(w, "{errmsg:\"Bad request.\"}", http.StatusBadRequest) + return + } else { + if _, err := os.Stat(path.Join(SubmissionDir, fmt.Sprintf("%d", team))); os.IsNotExist(err) { + log.Println("Creating submission directory for", team) + if err := os.MkdirAll(path.Join(SubmissionDir, fmt.Sprintf("%d", team)), 0777); err != nil { + log.Println("Unable to create submission directory: ", err) + http.Error(w, "{errmsg:\"Internal server error. Please retry in few seconds.\"}", http.StatusInternalServerError) + return + } + } + + + // Previous submission not treated + if _, err := os.Stat(path.Join(SubmissionDir, fmt.Sprintf("%d", team), fmt.Sprintf("%d", exercice))); !os.IsNotExist(err) { + http.Error(w, "{errmsg:\"Calm-down. A solution is already being processed.\"}", http.StatusPaymentRequired) + return + } + + + // Read request body + var body []byte + if r.ContentLength > 0 { + tmp := make([]byte, 1024) + for { + n, err := r.Body.Read(tmp) + for j := 0; j < n; j++ { + body = append(body, tmp[j]) + } + if err != nil || n <= 0 { + break + } + } + } + + + // Store content in file + if file, err := os.Create(path.Join(SubmissionDir, fmt.Sprintf("%d", team), fmt.Sprintf("%d", exercice))); err != nil { + log.Println("Unable to open exercice file:", err) + http.Error(w, "{errmsg:\"Internal server error. Please retry in few seconds.\"}", http.StatusInternalServerError) + return + } else { + file.Write(body) + file.Close() + } + http.Error(w, "{errmsg:\"Submission accepted, please wait...\"}", http.StatusAccepted) + } +} From a5dc600f28b5ba8192e0184136f0ea094ad30a96 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 7 Jan 2016 18:27:53 +0100 Subject: [PATCH 0381/2686] Add API basis --- admin/api.go | 85 ++++++++++++++++++++++++++++++++++++++++++++ admin/api_version.go | 11 ++++++ admin/main.go | 27 ++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 admin/api.go create mode 100644 admin/api_version.go create mode 100644 admin/main.go diff --git a/admin/api.go b/admin/api.go new file mode 100644 index 00000000..349d5181 --- /dev/null +++ b/admin/api.go @@ -0,0 +1,85 @@ +package main + +import ( + "encoding/json" + "errors" + "fmt" + "log" + "net/http" + "strings" +) + +type DispatchFunction func([]string, []byte) (interface{}, error) + +var apiRouting = map[string]*(map[string]DispatchFunction){ + "version": &ApiVersionRouting, + //"images": &ApiImagesRouting, + //"users": &ApiUsersRouting, +} + +func ApiRouting(w http.ResponseWriter, r *http.Request) { + log.Printf("Handling %s request from %s: %s [%s]\n", r.Method, r.RemoteAddr, r.URL.Path, r.UserAgent()) + + // Extract URL arguments + var sURL = strings.Split(r.URL.Path, "/") + if sURL[len(sURL)-1] == "" && len(sURL) > 2 { + // Remove trailing / + sURL = sURL[:len(sURL)-1] + } + + w.Header().Set("Content-Type", "application/json") + + var ret interface{} + var err error = nil + + // Read the body + if r.ContentLength < 0 || r.ContentLength > 6553600 { + http.Error(w, fmt.Sprintf("{errmsg:\"Request too large or request size unknown\"}", err), http.StatusRequestEntityTooLarge) + return + } + var body []byte + if r.ContentLength > 0 { + tmp := make([]byte, 1024) + for { + n, err := r.Body.Read(tmp) + for j := 0; j < n; j++ { + body = append(body, tmp[j]) + } + if err != nil || n <= 0 { + break + } + } + } + + // Route request + if len(sURL) > 1 { + if h, ok := apiRouting[sURL[1]]; ok { + if f, ok := (*h)[r.Method]; ok { + ret, err = f(sURL[2:], body) + } else { + err = errors.New(fmt.Sprintf("Invalid action (%s) provided for %s.", r.Method, sURL[1])) + } + } + } else { + err = errors.New("No action provided.") + } + + // Format response + resStatus := http.StatusOK + if err != nil { + ret = map[string]string{"errmsg": err.Error()} + resStatus = http.StatusBadRequest + } + + if ret == nil { + ret = map[string]string{"errmsg": "Page not found"} + resStatus = http.StatusNotFound + } + + if j, err := json.Marshal(ret); err != nil { + http.Error(w, fmt.Sprintf("{errmsg:\"%q\"}", err), http.StatusInternalServerError) + } else { + w.WriteHeader(resStatus) + w.Write(j) + } +} diff --git a/admin/api_version.go b/admin/api_version.go new file mode 100644 index 00000000..9b4cbbfb --- /dev/null +++ b/admin/api_version.go @@ -0,0 +1,11 @@ +package main + +import () + +var ApiVersionRouting = map[string]DispatchFunction{ + "GET": showVersion, +} + +func showVersion(args []string, body []byte) (interface{}, error) { + return map[string]interface{}{"version": 0.1}, nil +} diff --git a/admin/main.go b/admin/main.go new file mode 100644 index 00000000..87b856fc --- /dev/null +++ b/admin/main.go @@ -0,0 +1,27 @@ +package main + +import ( + "flag" + "fmt" + "log" + "net/http" +) + +var SubmissionDir string +var BaseURL string + +func main() { + var bind = flag.String("bind", "0.0.0.0:8081", "Bind port/socket") + var _ = flag.String("db", "fic.db", "Path to the DB") + flag.StringVar(&BaseURL, "baseurl", "http://fic.srs.epita.fr/", "URL prepended to each URL") + flag.StringVar(&SubmissionDir, "submission", "./submissions/", "Base directory where save submissions") + flag.Parse() + + log.Println("Registering handlers...") + http.HandleFunc("/", ApiRouting) + + log.Println(fmt.Sprintf("Ready, listening on %s", *bind)) + if err := http.ListenAndServe(*bind, nil); err != nil { + log.Fatal("Unable to listen and serve: ", err) + } +} From abd5e2025ea4ce344668eadc39da20b90d7d9881 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 7 Jan 2016 18:28:16 +0100 Subject: [PATCH 0382/2686] Add DB creation from schema --- admin/.gitignore | 2 + admin/db.go | 109 +++++++++++++++++++++++++++++++++++++++++++++++ admin/main.go | 18 +++++++- 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 admin/.gitignore create mode 100644 admin/db.go diff --git a/admin/.gitignore b/admin/.gitignore new file mode 100644 index 00000000..6a514f21 --- /dev/null +++ b/admin/.gitignore @@ -0,0 +1,2 @@ +admin +fic.db diff --git a/admin/db.go b/admin/db.go new file mode 100644 index 00000000..0a8bc61e --- /dev/null +++ b/admin/db.go @@ -0,0 +1,109 @@ +package main + +import ( + "database/sql" + _ "github.com/mattn/go-sqlite3" +) + +var db *sql.DB + +func DBInit(path string) error { + var err error + if db, err = sql.Open("sqlite3", path); err != nil { + return err + } + + _, err = db.Exec(` +PRAGMA foreign_keys=ON; +`) + return err +} + +func DBCreate() error { + _, err := db.Exec(` +CREATE TABLE IF NOT EXISTS themes( + id_theme INTEGER NOT NULL PRIMARY KEY, + name TEXT NOT NULL +); +CREATE TABLE IF NOT EXISTS teams( + id_team INTEGER NOT NULL PRIMARY KEY, + name TEXT NOT NULL +); +CREATE TABLE IF NOT EXISTS team_certificates( + id_team INTEGER NOT NULL PRIMARY KEY, + revoked INTEGER NOT NULL, + FOREIGN KEY(id_team) REFERENCES teams(id_team) +); +CREATE TABLE IF NOT EXISTS team_members( + id_member INTEGER NOT NULL PRIMARY KEY, + id_team INTEGER, + firstname TEXT NOT NULL, + lastname TEXT NOT NULL, + nickname TEXT NOT NULL, + company TEXT NOT NULL, + FOREIGN KEY(id_team) REFERENCES teams(id_team) +); +CREATE TABLE IF NOT EXISTS exercices( + id_exercice INTEGER NOT NULL PRIMARY KEY, + id_theme INTEGER NOT NULL, + title TEXT NOT NULL, + statement TEXT NOT NULL, + hint TEXT NOT NULL, + depend INTEGER, + gain INTEGER NOT NULL, + video_uri TEXT NOT NULL, + FOREIGN KEY(id_theme) REFERENCES themes(id_theme), + FOREIGN KEY(depend) REFERENCES exercices(id_exercice) +); +CREATE TABLE IF NOT EXISTS exercice_files( + id_file INTEGER NOT NULL PRIMARY KEY, + path TEXT NOT NULL UNIQUE, + id_exercice INTEGER NOT NULL, + name TEXT NOT NULL, + sha1 BLOB NOT NULL, + FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice) +); +CREATE TABLE IF NOT EXISTS exercice_keys( + id_key INTEGER NOT NULL PRIMARY KEY, + id_exercice INTEGER NOT NULL, + type TEXT NOT NULL, + value BLOB NOT NULL, + FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice) +); +CREATE TABLE IF NOT EXISTS exercice_solved( + id_exercice INTEGER NOT NULL, + id_team INTEGER NOT NULL, + time TIMESTAMP NOT NULL, + FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice), + FOREIGN KEY(id_team) REFERENCES teams(id_team) +); +CREATE TABLE IF NOT EXISTS exercice_tries( + id_exercice INTEGER NOT NULL, + id_team INTEGER NOT NULL, + time TIMESTAMP NOT NULL, + FOREIGN KEY(id_exercice) REFERENCES exercices(id_exercice), + FOREIGN KEY(id_team) REFERENCES teams(id_team) +); +`) + return err +} + +func DBClose() error { + return db.Close() +} + +func DBPrepare(query string) (*sql.Stmt, error) { + return db.Prepare(query) +} + +func DBQuery(query string, args ...interface{}) (*sql.Rows, error) { + return db.Query(query, args...) +} + +func DBExec(query string, args ...interface{}) (sql.Result, error) { + return db.Exec(query, args...) +} + +func DBQueryRow(query string, args ...interface{}) *sql.Row { + return db.QueryRow(query, args...) +} diff --git a/admin/main.go b/admin/main.go index 87b856fc..1979ca64 100644 --- a/admin/main.go +++ b/admin/main.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "net/http" + "os" ) var SubmissionDir string @@ -12,11 +13,26 @@ var BaseURL string func main() { var bind = flag.String("bind", "0.0.0.0:8081", "Bind port/socket") - var _ = flag.String("db", "fic.db", "Path to the DB") + var dbfile = flag.String("db", "fic.db", "Path to the DB") flag.StringVar(&BaseURL, "baseurl", "http://fic.srs.epita.fr/", "URL prepended to each URL") flag.StringVar(&SubmissionDir, "submission", "./submissions/", "Base directory where save submissions") flag.Parse() + log.Println("Opening database...") + if err := DBInit(*dbfile); err != nil { + log.Fatal("Cannot open the database: ", err) + os.Exit(1) + + } + defer DBClose() + + log.Println("Creating database...") + if err := DBCreate(); err != nil { + log.Fatal("Cannot create database: ", err) + os.Exit(1) + + } + log.Println("Registering handlers...") http.HandleFunc("/", ApiRouting) From 6ec37b83ceb6917668543bcabf3042bb97d680f6 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 7 Jan 2016 18:43:02 +0100 Subject: [PATCH 0383/2686] Add DB objects --- admin/api.go | 4 +-- admin/exercice.go | 83 +++++++++++++++++++++++++++++++++++++++++++++ admin/file.go | 85 +++++++++++++++++++++++++++++++++++++++++++++++ admin/key.go | 69 ++++++++++++++++++++++++++++++++++++++ admin/member.go | 73 ++++++++++++++++++++++++++++++++++++++++ admin/team.go | 69 ++++++++++++++++++++++++++++++++++++++ admin/theme.go | 69 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 450 insertions(+), 2 deletions(-) create mode 100644 admin/exercice.go create mode 100644 admin/file.go create mode 100644 admin/key.go create mode 100644 admin/member.go create mode 100644 admin/team.go create mode 100644 admin/theme.go diff --git a/admin/api.go b/admin/api.go index 349d5181..0dd72256 100644 --- a/admin/api.go +++ b/admin/api.go @@ -13,8 +13,8 @@ type DispatchFunction func([]string, []byte) (interface{}, error) var apiRouting = map[string]*(map[string]DispatchFunction){ "version": &ApiVersionRouting, - //"images": &ApiImagesRouting, - //"users": &ApiUsersRouting, + //"themes": &ApiThemesRouting, + //"teams": &ApiTeamsRouting, } func ApiRouting(w http.ResponseWriter, r *http.Request) { diff --git a/admin/exercice.go b/admin/exercice.go new file mode 100644 index 00000000..988ec192 --- /dev/null +++ b/admin/exercice.go @@ -0,0 +1,83 @@ +package main + +import ( + "time" +) + +type Exercice struct { + id int64 + Title string + Statement string + Hint string + depend int64 + Gain int64 + VideoURI string +} + +func (t Theme) GetExercices() ([]Exercice, error) { + if rows, err := DBQuery("SELECT id_exercice, title, statement, hint, depend, gain, video_uri FROM teams WHERE id_theme = ?", t.id); err != nil { + return nil, err + } else { + defer rows.Close() + + var exos = make([]Exercice, 0) + for rows.Next() { + var e Exercice + if err := rows.Scan(&e.id, &e.Title, &e.Statement, &e.Hint, &e.depend, &e.Gain, &e.VideoURI); err != nil { + return nil, err + } + exos = append(exos, e) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return exos, nil + } +} + +func (t Theme) AddExercice(title string, statement string, hint string, depend *Exercice, gain int, videoURI string) (Exercice, error) { + if res, err := DBExec("INSERT INTO exercices (id_theme, title, statement, hint, depend, gain, video_uri) VALUES (?, ?, ?, ?, ?, ?, ?)", t.id, title, statement, hint, depend.id, gain, videoURI); err != nil { + return Exercice{}, err + } else if eid, err := res.LastInsertId(); err != nil { + return Exercice{}, err + } else { + return Exercice{eid, title, statement, hint, depend.id, int64(gain), videoURI}, nil + } +} + +func (e Exercice) Update() (int64, error) { + if res, err := DBExec("UPDATE exercices SET title = ?, statement = ?, hint = ?, depend = ?, gain = ?, video_uri = ? WHERE id_exercice = ?", e.Title, e.Statement, e.Hint, e.depend, e.Gain, e.VideoURI, e.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (e Exercice) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM exercices WHERE id_exercice = ?", e.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (e Exercice) NewTry(t Team) error { + if _, err := DBExec("INSERT INTO exercice_tries (id_exercice, id_team, time) VALUES (?, ?, ?)", e.id, t.id, time.Now()); err != nil { + return err + } else { + return nil + } +} + +func (e Exercice) Solved(t Team) error { + if _, err := DBExec("INSERT INTO exercice_solved (id_exercice, id_team, time) VALUES (?, ?, ?)", e.id, t.id, time.Now()); err != nil { + return err + } else { + return nil + } +} diff --git a/admin/file.go b/admin/file.go new file mode 100644 index 00000000..82728ef4 --- /dev/null +++ b/admin/file.go @@ -0,0 +1,85 @@ +package main + +import ( + "crypto/sha1" + "io" + "os" + "path" +) + +type EFile struct { + id int64 + Path string + id_exercice int64 + Name string + Checksum []byte +} + +func (e Exercice) GetFiles() ([]EFile, error) { + if rows, err := DBQuery("SELECT id_file, path, name, sha1 FROM exercice_files WHERE id_exercice = ?", e.id); err != nil { + return nil, err + } else { + defer rows.Close() + + var files = make([]EFile, 0) + for rows.Next() { + var f EFile + f.id_exercice = e.id + if err := rows.Scan(&f.id, &f.Path, &f.Name, &f.Checksum); err != nil { + return nil, err + } + files = append(files, f) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return files, nil + } +} + +func (e Exercice) ImportFile(filePath string) (EFile, error) { + if fd, err := os.Open(filePath); err != nil { + return EFile{}, err + } else { + defer fd.Close() + + hash := sha1.New() + if _, err := io.Copy(hash, fd); err != nil { + return EFile{}, err + } + + var result []byte + return e.AddFile(filePath, path.Base(filePath), hash.Sum(result)) + } +} + +func (e Exercice) AddFile(path string, name string, checksum []byte) (EFile, error) { + if res, err := DBExec("INSERT INTO exercice_files (id_exercice, path, name, sha1) VALUES (?, ?, ?, ?)", e.id, path, name, checksum); err != nil { + return EFile{}, err + } else if fid, err := res.LastInsertId(); err != nil { + return EFile{}, err + } else { + return EFile{fid, path, e.id, name, checksum}, nil + } +} + +func (f EFile) Update() (int64, error) { + if res, err := DBExec("UPDATE exercice_files SET id_exercice = ?, path = ?, name = ?, sha1 = ? WHERE id_file = ?", f.id_exercice, f.Path, f.Name, f.Checksum, f.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (f EFile) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM exercice_files WHERE id_file = ?", f.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} diff --git a/admin/key.go b/admin/key.go new file mode 100644 index 00000000..3052ddb7 --- /dev/null +++ b/admin/key.go @@ -0,0 +1,69 @@ +package main + +import ( + "crypto/sha512" +) + +type Key struct { + id int64 + id_exercice int64 + Type string + Value [64]byte +} + +func (e Exercice) GetKeys() ([]Key, error) { + if rows, err := DBQuery("SELECT id_key, type, value FROM exercice_keys WHERE id_exercice = ?", e.id); err != nil { + return nil, err + } else { + defer rows.Close() + + var keys = make([]Key, 0) + for rows.Next() { + var k Key + k.id_exercice = e.id + if err := rows.Scan(&k.id, &k.id_exercice, &k.Type, &k.Value); err != nil { + return nil, err + } + keys = append(keys, k) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return keys, nil + } +} + +func (e Exercice) AddRawKey(name string, raw_value string) (Key, error) { + return e.AddKey(name, sha512.Sum512([]byte(raw_value))) +} + +func (e Exercice) AddKey(name string, value [64]byte) (Key, error) { + if res, err := DBExec("INSERT INTO exercice_keys (id_exercice, type, value) VALUES (?, ?, ?)", e.id, name, value); err != nil { + return Key{}, err + } else if kid, err := res.LastInsertId(); err != nil { + return Key{}, err + } else { + return Key{kid, e.id, name, value}, nil + } +} + +func (k Key) Update() (int64, error) { + if res, err := DBExec("UPDATE exercice_keys SET id_exercice = ?, type = ?, value = ? WHERE id_key = ?", k.id_exercice, k.Type, k.Value, k.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (k Key) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM exercice_keys WHERE id_key = ?", k.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} diff --git a/admin/member.go b/admin/member.go new file mode 100644 index 00000000..5de67e41 --- /dev/null +++ b/admin/member.go @@ -0,0 +1,73 @@ +package main + +import () + +type Member struct { + id int64 + Firstname string + Lastname string + Nickname string + Company string +} + +func (t Team) GetMembers() ([]Member, error) { + if rows, err := DBQuery("SELECT id_member, firstname, lastname, nickname, company FROM team_members WHERE id_team = ?", t.id); err != nil { + return nil, err + } else { + defer rows.Close() + + var members = make([]Member, 0) + for rows.Next() { + var m Member + if err := rows.Scan(&m.id, &m.Firstname, &m.Lastname, &m.Nickname, &m.Company); err != nil { + return nil, err + } + members = append(members, m) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return members, nil + } +} + +func (t Team) AddMember(firstname string, lastname string, nickname string, company string) (Member, error) { + if res, err := DBExec("INSERT INTO team_members (id_team, firstname, lastname, nickname, company) VALUES (?, ?, ?, ?, ?)", t.id, firstname, lastname, nickname, company); err != nil { + return Member{}, err + } else if mid, err := res.LastInsertId(); err != nil { + return Member{}, err + } else { + return Member{mid, firstname, lastname, nickname, company}, nil + } +} + +func (t Team) GainMember(m Member) error { + if res, err := DBExec("UPDATE team_members SET id_team = ? WHERE id_member = ?", t.id, m.id); err != nil { + return err + } else if _, err := res.RowsAffected(); err != nil { + return err + } else { + return nil + } +} + +func (m Member) Update() (int64, error) { + if res, err := DBExec("UPDATE team_members SET firstname = ?, lastname = ?, nickname = ?, company = ? WHERE id_member = ?", m.Firstname, m.Lastname, m.Nickname, m.Company, m.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (m Member) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM team_members WHERE id_member = ?", m.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} diff --git a/admin/team.go b/admin/team.go new file mode 100644 index 00000000..4cc13a5b --- /dev/null +++ b/admin/team.go @@ -0,0 +1,69 @@ +package main + +import () + +type Team struct { + id int64 + Name string +} + +func GetTeams() ([]Team, error) { + if rows, err := DBQuery("SELECT id_team, name FROM teams"); err != nil { + return nil, err + } else { + defer rows.Close() + + var teams = make([]Team, 0) + for rows.Next() { + var t Team + if err := rows.Scan(&t.id, &t.Name); err != nil { + return nil, err + } + teams = append(teams, t) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return teams, nil + } +} + +func GetTeam(id int) (Team, error) { + var t Team + if err := DBQueryRow("SELECT id_team, name FROM teams WHERE id_team = ?", id).Scan(&t.id, &t.Name); err != nil { + return t, err + } + + return t, nil +} + +func CreateTeam(name string) (Team, error) { + if res, err := DBExec("INSERT INTO teams (name) VALUES (?)", name); err != nil { + return Team{}, err + } else if tid, err := res.LastInsertId(); err != nil { + return Team{}, err + } else { + return Team{tid, name}, nil + } +} + +func (t Team) Update() (int64, error) { + if res, err := DBExec("UPDATE teams SET name = ? WHERE id_team = ?", t.Name, t.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (t Team) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM teams WHERE id_teams = ?", t.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} diff --git a/admin/theme.go b/admin/theme.go new file mode 100644 index 00000000..dbe15a30 --- /dev/null +++ b/admin/theme.go @@ -0,0 +1,69 @@ +package main + +import () + +type Theme struct { + id int64 + Name string +} + +func GetThemes() ([]Theme, error) { + if rows, err := DBQuery("SELECT id_theme, name FROM themes"); err != nil { + return nil, err + } else { + defer rows.Close() + + var themes = make([]Theme, 0) + for rows.Next() { + var t Theme + if err := rows.Scan(&t.id, &t.Name); err != nil { + return nil, err + } + themes = append(themes, t) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return themes, nil + } +} + +func GetTheme(id int) (Theme, error) { + var t Theme + if err := DBQueryRow("SELECT id_theme, name FROM themes WHERE id_theme=?", id).Scan(&t.id, &t.Name); err != nil { + return t, err + } + + return t, nil +} + +func CreateTheme(name string) (Theme, error) { + if res, err := DBExec("INSERT INTO themes (name) VALUES (?)", name); err != nil { + return Theme{}, err + } else if tid, err := res.LastInsertId(); err != nil { + return Theme{}, err + } else { + return Theme{tid, name}, nil + } +} + +func (t Theme) Update() (int64, error) { + if res, err := DBExec("UPDATE themes SET name = ? WHERE id_team = ?", t.Name, t.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} + +func (t Theme) Delete() (int64, error) { + if res, err := DBExec("DELETE FROM themes WHERE id_theme = ?", t.id); err != nil { + return 0, err + } else if nb, err := res.RowsAffected(); err != nil { + return 0, err + } else { + return nb, err + } +} From 5a6bac928eef0efcb8375536bfaf0a04ad3e0a54 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 7 Jan 2016 20:08:48 +0100 Subject: [PATCH 0384/2686] Add team listing --- admin/api.go | 2 +- admin/api_team.go | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 admin/api_team.go diff --git a/admin/api.go b/admin/api.go index 0dd72256..647a883c 100644 --- a/admin/api.go +++ b/admin/api.go @@ -14,7 +14,7 @@ type DispatchFunction func([]string, []byte) (interface{}, error) var apiRouting = map[string]*(map[string]DispatchFunction){ "version": &ApiVersionRouting, //"themes": &ApiThemesRouting, - //"teams": &ApiTeamsRouting, + "teams": &ApiTeamsRouting, } func ApiRouting(w http.ResponseWriter, r *http.Request) { diff --git a/admin/api_team.go b/admin/api_team.go new file mode 100644 index 00000000..450d852a --- /dev/null +++ b/admin/api_team.go @@ -0,0 +1,27 @@ +package main + +import ( + "strconv" +) + +var ApiTeamsRouting = map[string]DispatchFunction{ + "GET": list, +} + +func list(args []string, body []byte) (interface{}, error) { + if len(args) == 1 { + // List given team + if tid, err := strconv.Atoi(string(args[0])); err != nil { + return nil, err + } else if team, err := GetTeam(tid); err != nil { + return nil, err + } else { + return team.GetMembers() + } + } else if len(args) == 0 { + // List all teams + return GetTeams() + } else { + return nil, nil + } +} From b958b01635d4fa1a8783041562aeccfc9144c10b Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 7 Jan 2016 20:32:24 +0100 Subject: [PATCH 0385/2686] Implement team creation --- admin/api_team.go | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/admin/api_team.go b/admin/api_team.go index 450d852a..63efa416 100644 --- a/admin/api_team.go +++ b/admin/api_team.go @@ -1,14 +1,16 @@ package main import ( + "encoding/json" "strconv" ) var ApiTeamsRouting = map[string]DispatchFunction{ - "GET": list, + "GET": listTeam, + "POST": creationTeam, } -func list(args []string, body []byte) (interface{}, error) { +func listTeam(args []string, body []byte) (interface{}, error) { if len(args) == 1 { // List given team if tid, err := strconv.Atoi(string(args[0])); err != nil { @@ -25,3 +27,34 @@ func list(args []string, body []byte) (interface{}, error) { return nil, nil } } + +func creationTeam(args []string, body []byte) (interface{}, error) { + if len(args) == 0 { + type UploadedMember struct { + Firstname string + Lastname string + Nickname string + Company string + } + + // Create a new team + var members []UploadedMember + if err := json.Unmarshal(body, &members); err != nil { + return nil, err + } + + if team, err := CreateTeam(""); err != nil { + return nil, err + } else { + for _, member := range members { + if _, err := team.AddMember(member.Firstname, member.Lastname, member.Nickname, member.Company); err != nil { + return nil, err + } + } + + return "Ok", nil + } + } else { + return nil,nil + } +} From 40f7d7a0be2ae1f80a9c45ac585c62ad1a76274f Mon Sep 17 00:00:00 2001 From: nemunaire Date: Thu, 7 Jan 2016 20:47:07 +0100 Subject: [PATCH 0386/2686] Add theme listing --- admin/api.go | 2 +- admin/api_theme.go | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 admin/api_theme.go diff --git a/admin/api.go b/admin/api.go index 647a883c..3e024278 100644 --- a/admin/api.go +++ b/admin/api.go @@ -13,7 +13,7 @@ type DispatchFunction func([]string, []byte) (interface{}, error) var apiRouting = map[string]*(map[string]DispatchFunction){ "version": &ApiVersionRouting, - //"themes": &ApiThemesRouting, + "themes": &ApiThemesRouting, "teams": &ApiTeamsRouting, } diff --git a/admin/api_theme.go b/admin/api_theme.go new file mode 100644 index 00000000..52d8d429 --- /dev/null +++ b/admin/api_theme.go @@ -0,0 +1,25 @@ +package main + +import ( + "strconv" +) + +var ApiThemesRouting = map[string]DispatchFunction{ + "GET": listTheme, +} + +func listTheme(args []string, body []byte) (interface{}, error) { + if len(args) == 1 { + // List given theme + if tid, err := strconv.Atoi(string(args[0])); err != nil { + return nil, err + } else { + return GetTheme(tid) + } + } else if len(args) == 0 { + // List all themes + return GetThemes() + } else { + return nil, nil + } +} From 8cf2a36fe10f7737a0d72ba6bcf17c385e731f31 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 13 Jan 2016 01:12:36 +0100 Subject: [PATCH 0387/2686] Implement team deletion --- admin/api_team.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/admin/api_team.go b/admin/api_team.go index 63efa416..89ec6c24 100644 --- a/admin/api_team.go +++ b/admin/api_team.go @@ -8,6 +8,7 @@ import ( var ApiTeamsRouting = map[string]DispatchFunction{ "GET": listTeam, "POST": creationTeam, + "DELETE": deletionTeam, } func listTeam(args []string, body []byte) (interface{}, error) { @@ -58,3 +59,17 @@ func creationTeam(args []string, body []byte) (interface{}, error) { return nil,nil } } + +func deletionTeam(args []string, body []byte) (interface{}, error) { + if len(args) == 1 { + if tid, err := strconv.Atoi(string(args[0])); err != nil { + return nil, err + } else if team, err := GetTeam(tid); err != nil { + return nil, err + } else { + return team.Delete() + } + } else { + return nil, nil + } +} From e89af34c5c21d738e25014983429f983cb89bcea Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 13 Jan 2016 01:20:21 +0100 Subject: [PATCH 0388/2686] Change internal variable representation vs JSON one --- admin/exercice.go | 30 +++++++++++++++--------------- admin/file.go | 24 ++++++++++++------------ admin/key.go | 22 +++++++++++----------- admin/member.go | 22 +++++++++++----------- admin/team.go | 12 ++++++------ admin/theme.go | 12 ++++++------ 6 files changed, 61 insertions(+), 61 deletions(-) diff --git a/admin/exercice.go b/admin/exercice.go index 988ec192..b7bb1f56 100644 --- a/admin/exercice.go +++ b/admin/exercice.go @@ -5,17 +5,17 @@ import ( ) type Exercice struct { - id int64 - Title string - Statement string - Hint string - depend int64 - Gain int64 - VideoURI string + Id int64 `json:"id"` + Title string `json:"title"` + Statement string `json:"statement"` + Hint string `json:"hint"` + Depend int64 `json:"depend"` + Gain int64 `json:"gain"` + VideoURI string `json:"videoURI"` } func (t Theme) GetExercices() ([]Exercice, error) { - if rows, err := DBQuery("SELECT id_exercice, title, statement, hint, depend, gain, video_uri FROM teams WHERE id_theme = ?", t.id); err != nil { + if rows, err := DBQuery("SELECT id_exercice, title, statement, hint, depend, gain, video_uri FROM teams WHERE id_theme = ?", t.Id); err != nil { return nil, err } else { defer rows.Close() @@ -23,7 +23,7 @@ func (t Theme) GetExercices() ([]Exercice, error) { var exos = make([]Exercice, 0) for rows.Next() { var e Exercice - if err := rows.Scan(&e.id, &e.Title, &e.Statement, &e.Hint, &e.depend, &e.Gain, &e.VideoURI); err != nil { + if err := rows.Scan(&e.Id, &e.Title, &e.Statement, &e.Hint, &e.Depend, &e.Gain, &e.VideoURI); err != nil { return nil, err } exos = append(exos, e) @@ -37,17 +37,17 @@ func (t Theme) GetExercices() ([]Exercice, error) { } func (t Theme) AddExercice(title string, statement string, hint string, depend *Exercice, gain int, videoURI string) (Exercice, error) { - if res, err := DBExec("INSERT INTO exercices (id_theme, title, statement, hint, depend, gain, video_uri) VALUES (?, ?, ?, ?, ?, ?, ?)", t.id, title, statement, hint, depend.id, gain, videoURI); err != nil { + if res, err := DBExec("INSERT INTO exercices (id_theme, title, statement, hint, depend, gain, video_uri) VALUES (?, ?, ?, ?, ?, ?, ?)", t.Id, title, statement, hint, depend.Id, gain, videoURI); err != nil { return Exercice{}, err } else if eid, err := res.LastInsertId(); err != nil { return Exercice{}, err } else { - return Exercice{eid, title, statement, hint, depend.id, int64(gain), videoURI}, nil + return Exercice{eid, title, statement, hint, depend.Id, int64(gain), videoURI}, nil } } func (e Exercice) Update() (int64, error) { - if res, err := DBExec("UPDATE exercices SET title = ?, statement = ?, hint = ?, depend = ?, gain = ?, video_uri = ? WHERE id_exercice = ?", e.Title, e.Statement, e.Hint, e.depend, e.Gain, e.VideoURI, e.id); err != nil { + if res, err := DBExec("UPDATE exercices SET title = ?, statement = ?, hint = ?, depend = ?, gain = ?, video_uri = ? WHERE id_exercice = ?", e.Title, e.Statement, e.Hint, e.Depend, e.Gain, e.VideoURI, e.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -57,7 +57,7 @@ func (e Exercice) Update() (int64, error) { } func (e Exercice) Delete() (int64, error) { - if res, err := DBExec("DELETE FROM exercices WHERE id_exercice = ?", e.id); err != nil { + if res, err := DBExec("DELETE FROM exercices WHERE id_exercice = ?", e.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -67,7 +67,7 @@ func (e Exercice) Delete() (int64, error) { } func (e Exercice) NewTry(t Team) error { - if _, err := DBExec("INSERT INTO exercice_tries (id_exercice, id_team, time) VALUES (?, ?, ?)", e.id, t.id, time.Now()); err != nil { + if _, err := DBExec("INSERT INTO exercice_tries (id_exercice, id_team, time) VALUES (?, ?, ?)", e.Id, t.Id, time.Now()); err != nil { return err } else { return nil @@ -75,7 +75,7 @@ func (e Exercice) NewTry(t Team) error { } func (e Exercice) Solved(t Team) error { - if _, err := DBExec("INSERT INTO exercice_solved (id_exercice, id_team, time) VALUES (?, ?, ?)", e.id, t.id, time.Now()); err != nil { + if _, err := DBExec("INSERT INTO exercice_solved (id_exercice, id_team, time) VALUES (?, ?, ?)", e.Id, t.Id, time.Now()); err != nil { return err } else { return nil diff --git a/admin/file.go b/admin/file.go index 82728ef4..b1255fda 100644 --- a/admin/file.go +++ b/admin/file.go @@ -8,15 +8,15 @@ import ( ) type EFile struct { - id int64 - Path string - id_exercice int64 - Name string - Checksum []byte + Id int64 `json:"id"` + Path string `json:"path"` + IdExercice int64 `json:"idExercice"` + Name string `json:"name"` + Checksum []byte `json:"checksum"` } func (e Exercice) GetFiles() ([]EFile, error) { - if rows, err := DBQuery("SELECT id_file, path, name, sha1 FROM exercice_files WHERE id_exercice = ?", e.id); err != nil { + if rows, err := DBQuery("SELECT id_file, path, name, sha1 FROM exercice_files WHERE id_exercice = ?", e.Id); err != nil { return nil, err } else { defer rows.Close() @@ -24,8 +24,8 @@ func (e Exercice) GetFiles() ([]EFile, error) { var files = make([]EFile, 0) for rows.Next() { var f EFile - f.id_exercice = e.id - if err := rows.Scan(&f.id, &f.Path, &f.Name, &f.Checksum); err != nil { + f.IdExercice = e.Id + if err := rows.Scan(&f.Id, &f.Path, &f.Name, &f.Checksum); err != nil { return nil, err } files = append(files, f) @@ -55,17 +55,17 @@ func (e Exercice) ImportFile(filePath string) (EFile, error) { } func (e Exercice) AddFile(path string, name string, checksum []byte) (EFile, error) { - if res, err := DBExec("INSERT INTO exercice_files (id_exercice, path, name, sha1) VALUES (?, ?, ?, ?)", e.id, path, name, checksum); err != nil { + if res, err := DBExec("INSERT INTO exercice_files (id_exercice, path, name, sha1) VALUES (?, ?, ?, ?)", e.Id, path, name, checksum); err != nil { return EFile{}, err } else if fid, err := res.LastInsertId(); err != nil { return EFile{}, err } else { - return EFile{fid, path, e.id, name, checksum}, nil + return EFile{fid, path, e.Id, name, checksum}, nil } } func (f EFile) Update() (int64, error) { - if res, err := DBExec("UPDATE exercice_files SET id_exercice = ?, path = ?, name = ?, sha1 = ? WHERE id_file = ?", f.id_exercice, f.Path, f.Name, f.Checksum, f.id); err != nil { + if res, err := DBExec("UPDATE exercice_files SET id_exercice = ?, path = ?, name = ?, sha1 = ? WHERE id_file = ?", f.IdExercice, f.Path, f.Name, f.Checksum, f.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -75,7 +75,7 @@ func (f EFile) Update() (int64, error) { } func (f EFile) Delete() (int64, error) { - if res, err := DBExec("DELETE FROM exercice_files WHERE id_file = ?", f.id); err != nil { + if res, err := DBExec("DELETE FROM exercice_files WHERE id_file = ?", f.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err diff --git a/admin/key.go b/admin/key.go index 3052ddb7..a39f2cf6 100644 --- a/admin/key.go +++ b/admin/key.go @@ -5,14 +5,14 @@ import ( ) type Key struct { - id int64 - id_exercice int64 - Type string - Value [64]byte + Id int64 `json:"id"` + IdExercice int64 `json:"idExercice"` + Type string `json:"type"` + Value [64]byte `json:"value"` } func (e Exercice) GetKeys() ([]Key, error) { - if rows, err := DBQuery("SELECT id_key, type, value FROM exercice_keys WHERE id_exercice = ?", e.id); err != nil { + if rows, err := DBQuery("SELECT id_key, type, value FROM exercice_keys WHERE id_exercice = ?", e.Id); err != nil { return nil, err } else { defer rows.Close() @@ -20,8 +20,8 @@ func (e Exercice) GetKeys() ([]Key, error) { var keys = make([]Key, 0) for rows.Next() { var k Key - k.id_exercice = e.id - if err := rows.Scan(&k.id, &k.id_exercice, &k.Type, &k.Value); err != nil { + k.IdExercice = e.Id + if err := rows.Scan(&k.Id, &k.IdExercice, &k.Type, &k.Value); err != nil { return nil, err } keys = append(keys, k) @@ -39,17 +39,17 @@ func (e Exercice) AddRawKey(name string, raw_value string) (Key, error) { } func (e Exercice) AddKey(name string, value [64]byte) (Key, error) { - if res, err := DBExec("INSERT INTO exercice_keys (id_exercice, type, value) VALUES (?, ?, ?)", e.id, name, value); err != nil { + if res, err := DBExec("INSERT INTO exercice_keys (id_exercice, type, value) VALUES (?, ?, ?)", e.Id, name, value); err != nil { return Key{}, err } else if kid, err := res.LastInsertId(); err != nil { return Key{}, err } else { - return Key{kid, e.id, name, value}, nil + return Key{kid, e.Id, name, value}, nil } } func (k Key) Update() (int64, error) { - if res, err := DBExec("UPDATE exercice_keys SET id_exercice = ?, type = ?, value = ? WHERE id_key = ?", k.id_exercice, k.Type, k.Value, k.id); err != nil { + if res, err := DBExec("UPDATE exercice_keys SET id_exercice = ?, type = ?, value = ? WHERE id_key = ?", k.IdExercice, k.Type, k.Value, k.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -59,7 +59,7 @@ func (k Key) Update() (int64, error) { } func (k Key) Delete() (int64, error) { - if res, err := DBExec("DELETE FROM exercice_keys WHERE id_key = ?", k.id); err != nil { + if res, err := DBExec("DELETE FROM exercice_keys WHERE id_key = ?", k.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err diff --git a/admin/member.go b/admin/member.go index 5de67e41..2e17d1d9 100644 --- a/admin/member.go +++ b/admin/member.go @@ -3,15 +3,15 @@ package main import () type Member struct { - id int64 - Firstname string - Lastname string - Nickname string - Company string + Id int64 `json:"id"` + Firstname string `json:"firstname"` + Lastname string `json:"lastname"` + Nickname string `json:"nickname"` + Company string `json:"company"` } func (t Team) GetMembers() ([]Member, error) { - if rows, err := DBQuery("SELECT id_member, firstname, lastname, nickname, company FROM team_members WHERE id_team = ?", t.id); err != nil { + if rows, err := DBQuery("SELECT id_member, firstname, lastname, nickname, company FROM team_members WHERE id_team = ?", t.Id); err != nil { return nil, err } else { defer rows.Close() @@ -19,7 +19,7 @@ func (t Team) GetMembers() ([]Member, error) { var members = make([]Member, 0) for rows.Next() { var m Member - if err := rows.Scan(&m.id, &m.Firstname, &m.Lastname, &m.Nickname, &m.Company); err != nil { + if err := rows.Scan(&m.Id, &m.Firstname, &m.Lastname, &m.Nickname, &m.Company); err != nil { return nil, err } members = append(members, m) @@ -33,7 +33,7 @@ func (t Team) GetMembers() ([]Member, error) { } func (t Team) AddMember(firstname string, lastname string, nickname string, company string) (Member, error) { - if res, err := DBExec("INSERT INTO team_members (id_team, firstname, lastname, nickname, company) VALUES (?, ?, ?, ?, ?)", t.id, firstname, lastname, nickname, company); err != nil { + if res, err := DBExec("INSERT INTO team_members (id_team, firstname, lastname, nickname, company) VALUES (?, ?, ?, ?, ?)", t.Id, firstname, lastname, nickname, company); err != nil { return Member{}, err } else if mid, err := res.LastInsertId(); err != nil { return Member{}, err @@ -43,7 +43,7 @@ func (t Team) AddMember(firstname string, lastname string, nickname string, comp } func (t Team) GainMember(m Member) error { - if res, err := DBExec("UPDATE team_members SET id_team = ? WHERE id_member = ?", t.id, m.id); err != nil { + if res, err := DBExec("UPDATE team_members SET id_team = ? WHERE id_member = ?", t.Id, m.Id); err != nil { return err } else if _, err := res.RowsAffected(); err != nil { return err @@ -53,7 +53,7 @@ func (t Team) GainMember(m Member) error { } func (m Member) Update() (int64, error) { - if res, err := DBExec("UPDATE team_members SET firstname = ?, lastname = ?, nickname = ?, company = ? WHERE id_member = ?", m.Firstname, m.Lastname, m.Nickname, m.Company, m.id); err != nil { + if res, err := DBExec("UPDATE team_members SET firstname = ?, lastname = ?, nickname = ?, company = ? WHERE id_member = ?", m.Firstname, m.Lastname, m.Nickname, m.Company, m.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -63,7 +63,7 @@ func (m Member) Update() (int64, error) { } func (m Member) Delete() (int64, error) { - if res, err := DBExec("DELETE FROM team_members WHERE id_member = ?", m.id); err != nil { + if res, err := DBExec("DELETE FROM team_members WHERE id_member = ?", m.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err diff --git a/admin/team.go b/admin/team.go index 4cc13a5b..f1a42f69 100644 --- a/admin/team.go +++ b/admin/team.go @@ -3,8 +3,8 @@ package main import () type Team struct { - id int64 - Name string + Id int64 `json:"id"` + Name string `json:"name"` } func GetTeams() ([]Team, error) { @@ -16,7 +16,7 @@ func GetTeams() ([]Team, error) { var teams = make([]Team, 0) for rows.Next() { var t Team - if err := rows.Scan(&t.id, &t.Name); err != nil { + if err := rows.Scan(&t.Id, &t.Name); err != nil { return nil, err } teams = append(teams, t) @@ -31,7 +31,7 @@ func GetTeams() ([]Team, error) { func GetTeam(id int) (Team, error) { var t Team - if err := DBQueryRow("SELECT id_team, name FROM teams WHERE id_team = ?", id).Scan(&t.id, &t.Name); err != nil { + if err := DBQueryRow("SELECT id_team, name FROM teams WHERE id_team = ?", id).Scan(&t.Id, &t.Name); err != nil { return t, err } @@ -49,7 +49,7 @@ func CreateTeam(name string) (Team, error) { } func (t Team) Update() (int64, error) { - if res, err := DBExec("UPDATE teams SET name = ? WHERE id_team = ?", t.Name, t.id); err != nil { + if res, err := DBExec("UPDATE teams SET name = ? WHERE id_team = ?", t.Name, t.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -59,7 +59,7 @@ func (t Team) Update() (int64, error) { } func (t Team) Delete() (int64, error) { - if res, err := DBExec("DELETE FROM teams WHERE id_teams = ?", t.id); err != nil { + if res, err := DBExec("DELETE FROM team_members WHERE id_team = ?; DELETE FROM teams WHERE id_team = ?", t.Id, t.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err diff --git a/admin/theme.go b/admin/theme.go index dbe15a30..5ca0b34e 100644 --- a/admin/theme.go +++ b/admin/theme.go @@ -3,8 +3,8 @@ package main import () type Theme struct { - id int64 - Name string + Id int64 `json:"id"` + Name string `json:"name"` } func GetThemes() ([]Theme, error) { @@ -16,7 +16,7 @@ func GetThemes() ([]Theme, error) { var themes = make([]Theme, 0) for rows.Next() { var t Theme - if err := rows.Scan(&t.id, &t.Name); err != nil { + if err := rows.Scan(&t.Id, &t.Name); err != nil { return nil, err } themes = append(themes, t) @@ -31,7 +31,7 @@ func GetThemes() ([]Theme, error) { func GetTheme(id int) (Theme, error) { var t Theme - if err := DBQueryRow("SELECT id_theme, name FROM themes WHERE id_theme=?", id).Scan(&t.id, &t.Name); err != nil { + if err := DBQueryRow("SELECT id_theme, name FROM themes WHERE id_theme=?", id).Scan(&t.Id, &t.Name); err != nil { return t, err } @@ -49,7 +49,7 @@ func CreateTheme(name string) (Theme, error) { } func (t Theme) Update() (int64, error) { - if res, err := DBExec("UPDATE themes SET name = ? WHERE id_team = ?", t.Name, t.id); err != nil { + if res, err := DBExec("UPDATE themes SET name = ? WHERE id_team = ?", t.Name, t.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err @@ -59,7 +59,7 @@ func (t Theme) Update() (int64, error) { } func (t Theme) Delete() (int64, error) { - if res, err := DBExec("DELETE FROM themes WHERE id_theme = ?", t.id); err != nil { + if res, err := DBExec("DELETE FROM themes WHERE id_theme = ?", t.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { return 0, err From d635420a9f69bb45dc23c3ba461890b9784b8db5 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 13 Jan 2016 01:22:01 +0100 Subject: [PATCH 0389/2686] Add static page routing, place API under /api/ --- admin/api.go | 22 ++++++++++++++-------- admin/main.go | 7 ++++++- admin/static.go | 9 +++++++++ 3 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 admin/static.go diff --git a/admin/api.go b/admin/api.go index 3e024278..8ee191f4 100644 --- a/admin/api.go +++ b/admin/api.go @@ -11,18 +11,24 @@ import ( type DispatchFunction func([]string, []byte) (interface{}, error) -var apiRouting = map[string]*(map[string]DispatchFunction){ +var apiRoutes = map[string]*(map[string]DispatchFunction){ "version": &ApiVersionRouting, "themes": &ApiThemesRouting, "teams": &ApiTeamsRouting, } -func ApiRouting(w http.ResponseWriter, r *http.Request) { +type apiRouting struct{} + +func ApiHandler() http.Handler { + return apiRouting{} +} + +func (a apiRouting) ServeHTTP(w http.ResponseWriter, r *http.Request) { log.Printf("Handling %s request from %s: %s [%s]\n", r.Method, r.RemoteAddr, r.URL.Path, r.UserAgent()) // Extract URL arguments - var sURL = strings.Split(r.URL.Path, "/") - if sURL[len(sURL)-1] == "" && len(sURL) > 2 { + var sURL = strings.Split(r.URL.Path, "/")[1:] + if len(sURL) > 1 && sURL[len(sURL)-1] == "" { // Remove trailing / sURL = sURL[:len(sURL)-1] } @@ -52,12 +58,12 @@ func ApiRouting(w http.ResponseWriter, r *http.Request) { } // Route request - if len(sURL) > 1 { - if h, ok := apiRouting[sURL[1]]; ok { + if len(sURL) > 0 { + if h, ok := apiRoutes[sURL[0]]; ok { if f, ok := (*h)[r.Method]; ok { - ret, err = f(sURL[2:], body) + ret, err = f(sURL[1:], body) } else { - err = errors.New(fmt.Sprintf("Invalid action (%s) provided for %s.", r.Method, sURL[1])) + err = errors.New(fmt.Sprintf("Invalid action (%s) provided for %s.", r.Method, sURL[0])) } } } else { diff --git a/admin/main.go b/admin/main.go index 1979ca64..6277cef4 100644 --- a/admin/main.go +++ b/admin/main.go @@ -34,7 +34,12 @@ func main() { } log.Println("Registering handlers...") - http.HandleFunc("/", ApiRouting) + mux := http.NewServeMux() + mux.Handle("/api/", http.StripPrefix("/api", ApiHandler())) + mux.HandleFunc("/teams", StaticRouting) + mux.HandleFunc("/themes", StaticRouting) + mux.Handle("/", http.FileServer(http.Dir("./static/"))) + http.HandleFunc("/", mux.ServeHTTP) log.Println(fmt.Sprintf("Ready, listening on %s", *bind)) if err := http.ListenAndServe(*bind, nil); err != nil { diff --git a/admin/static.go b/admin/static.go new file mode 100644 index 00000000..f82ab08b --- /dev/null +++ b/admin/static.go @@ -0,0 +1,9 @@ +package main + +import ( + "net/http" +) + +func StaticRouting(w http.ResponseWriter, r *http.Request) { + http.ServeFile(w, r, "./static/index.html") +} From 181953a9f03fd54c017c24b991693be3960a2a41 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Wed, 13 Jan 2016 01:22:54 +0100 Subject: [PATCH 0390/2686] Work on admin web interface --- admin/static/css/bootstrap.min.css | 6 + admin/static/css/slate.min.css | 11 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 +++++++++++++++++ .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes admin/static/index.html | 27 ++ admin/static/js/angular-resource.min.js | 14 + admin/static/js/angular-route.min.js | 15 + admin/static/js/angular.min.js | 295 ++++++++++++++++++ admin/static/js/app.js | 33 ++ admin/static/js/bootstrap.min.js | 7 + admin/static/js/jquery.min.js | 5 + admin/static/views/team-list.html | 17 + admin/static/views/team-new.html | 11 + 16 files changed, 729 insertions(+) create mode 100644 admin/static/css/bootstrap.min.css create mode 100644 admin/static/css/slate.min.css create mode 100644 admin/static/fonts/glyphicons-halflings-regular.eot create mode 100644 admin/static/fonts/glyphicons-halflings-regular.svg create mode 100644 admin/static/fonts/glyphicons-halflings-regular.ttf create mode 100644 admin/static/fonts/glyphicons-halflings-regular.woff create mode 100644 admin/static/fonts/glyphicons-halflings-regular.woff2 create mode 100644 admin/static/index.html create mode 100644 admin/static/js/angular-resource.min.js create mode 100644 admin/static/js/angular-route.min.js create mode 100644 admin/static/js/angular.min.js create mode 100644 admin/static/js/app.js create mode 100644 admin/static/js/bootstrap.min.js create mode 100644 admin/static/js/jquery.min.js create mode 100644 admin/static/views/team-list.html create mode 100644 admin/static/views/team-new.html diff --git a/admin/static/css/bootstrap.min.css b/admin/static/css/bootstrap.min.css new file mode 100644 index 00000000..4cf729e4 --- /dev/null +++ b/admin/static/css/bootstrap.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}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 silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!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:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-eur:before,.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"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-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}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;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}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;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}[role=button]{cursor:pointer}.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,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,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,.h5,.h6,h4,h5,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%}.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:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{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}dd,dt{line-height:1.42857143}dt{font-weight:700}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[data-original-title],abbr[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 ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer: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 .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}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%;font-weight:700;-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-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.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-md-1,.col-md-10,.col-md-11,.col-md-12,.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-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.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-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{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-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{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-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{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-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{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>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{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:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{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=checkbox]:focus,input[type=radio]: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:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{background-color:transparent;border:0}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],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-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],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}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;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{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{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 .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{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 .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{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~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{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{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;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.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{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{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled.focus,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled].focus,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled.focus,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled].focus,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled.focus,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled].focus,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{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.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled.focus,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled].focus,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{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.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled.focus,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled].focus,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{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.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled.focus,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled].focus,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{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=button].btn-block,input[type=reset].btn-block,input[type=submit].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-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{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:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{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 dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@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-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-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:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-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-left-radius:4px;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-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-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=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.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}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn: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:400;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=checkbox],.input-group-addon input[type=radio]{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-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){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:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{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:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{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:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.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:focus,.nav-tabs>li.active>a:hover{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:focus,.nav-tabs.nav-justified>.active>a:hover{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:focus,.nav-tabs.nav-justified>.active>a:hover{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:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.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:focus,.nav-tabs-justified>.active>a:hover{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:focus,.nav-tabs-justified>.active>a:hover{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-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{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-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{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:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;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 .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{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-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 .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.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{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;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}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{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:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{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:focus,.navbar-default .navbar-nav>.open>a:hover{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:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{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:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{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:focus,.navbar-inverse .navbar-nav>.open>a:hover{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:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{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:#337ab7;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:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:2;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:3;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{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;line-height:1.3333333}.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;line-height:1.5}.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:focus,.pager li>a:hover{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:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{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]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#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,.container-fluid .jumbotron{padding-right:15px;padding-left:15px;border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .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:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.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:700}.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:#337ab7;-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-bar-striped,.progress-striped .progress-bar{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-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#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{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{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}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{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>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>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,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.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 th:first-child,.panel>.table-responsive:first-child>.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 th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.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 th:last-child,.panel>.table-responsive:first-child>.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 th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.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 th:first-child,.panel>.table-responsive:last-child>.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 th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.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 th:last-child,.panel>.table-responsive:last-child>.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 th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.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>.list-group,.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:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.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 embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#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:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;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:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#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{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-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.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;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{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;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;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-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;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;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);line-break:auto}.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;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>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);background-color:rgba(0,0,0,0);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:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.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-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.modal-header:after,.modal-header:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.modal-header:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row: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}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.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.min.css.map */ \ No newline at end of file diff --git a/admin/static/css/slate.min.css b/admin/static/css/slate.min.css new file mode 100644 index 00000000..af7e2033 --- /dev/null +++ b/admin/static/css/slate.min.css @@ -0,0 +1,11 @@ +/*! + * bootswatch v3.3.6 + * Homepage: http://bootswatch.com + * Copyright 2012-2015 Thomas Park + * Licensed under MIT + * Based on Bootstrap +*//*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}@font-face{font-family:'Glyphicons Halflings';src:url('../fonts/glyphicons-halflings-regular.eot');src:url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'),url('../fonts/glyphicons-halflings-regular.woff') format('woff'),url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\002a"}.glyphicon-plus:before{content:"\002b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#c8c8c8;background-color:#272b30}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#ffffff;text-decoration:none}a:hover,a:focus{color:#ffffff;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{padding:4px;line-height:1.42857143;background-color:#1c1e22;border:1px solid #0c0d0e;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #1c1e22}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role="button"]{cursor:pointer}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;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:#7a8288}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%}mark,.mark{background-color:#f89406;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#7a8288}.text-primary{color:#7a8288}a.text-primary:hover,a.text-primary:focus{color:#62686d}.text-success{color:#ffffff}a.text-success:hover,a.text-success:focus{color:#e6e6e6}.text-info{color:#ffffff}a.text-info:hover,a.text-info:focus{color:#e6e6e6}.text-warning{color:#ffffff}a.text-warning:hover,a.text-warning:focus{color:#e6e6e6}.text-danger{color:#ffffff}a.text-danger:hover,a.text-danger:focus{color:#e6e6e6}.bg-primary{color:#fff;background-color:#7a8288}a.bg-primary:hover,a.bg-primary:focus{background-color:#62686d}.bg-success{background-color:#62c462}a.bg-success:hover,a.bg-success:focus{background-color:#42b142}.bg-info{background-color:#5bc0de}a.bg-info:hover,a.bg-info:focus{background-color:#31b0d5}.bg-warning{background-color:#f89406}a.bg-warning:hover,a.bg-warning:focus{background-color:#c67605}.bg-danger{background-color:#ee5f5b}a.bg-danger:hover,a.bg-danger:focus{background-color:#e9322d}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #1c1e22}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;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right: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;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #7a8288}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #7a8288}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:#7a8288}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #7a8288;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom: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:#ffffff;background-color:#333333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;word-break:break-all;word-wrap:break-word;color:#3a3f44;background-color:#f5f5f5;border:1px solid #cccccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0%}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0%}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0%}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0%}}table{background-color:#2e3338}caption{padding-top:8px;padding-bottom:8px;color:#7a8288;text-align:left}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 #1c1e22}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #1c1e22}.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 #1c1e22}.table .table{background-color:#272b30}.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 #1c1e22}.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 #1c1e22}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#353a41}.table-hover>tbody>tr:hover{background-color:#49515a}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#49515a}.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:#3e444c}.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:#62c462}.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:#4fbd4f}.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:#5bc0de}.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:#46b8da}.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:#f89406}.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:#df8505}.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:#ee5f5b}.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:#ec4844}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #1c1e22}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#c8c8c8;border:0;border-bottom:1px solid #1c1e22}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:9px;font-size:14px;line-height:1.42857143;color:#272b30}.form-control{display:block;width:100%;height:38px;padding:8px 12px;font-size:14px;line-height:1.42857143;color:#272b30;background-color:#ffffff;background-image:none;border:1px solid #cccccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control::-moz-placeholder{color:#7a8288;opacity:1}.form-control:-ms-input-placeholder{color:#7a8288}.form-control::-webkit-input-placeholder{color:#7a8288}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#999999;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:38px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm,.input-group-sm input[type="date"],.input-group-sm input[type="time"],.input-group-sm input[type="datetime-local"],.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg,.input-group-lg input[type="date"],.input-group-lg input[type="time"],.input-group-lg input[type="datetime-local"],.input-group-lg input[type="month"]{line-height:54px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:9px;padding-bottom:9px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm{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}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:54px;line-height:54px}textarea.input-lg,select[multiple].input-lg{height:auto}.form-group-lg .form-control{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:54px;line-height:54px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:54px;min-height:38px;padding:15px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:47.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:38px;height:38px;line-height:38px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:54px;height:54px;line-height:54px}.input-sm+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.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,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#ffffff}.has-success .form-control{border-color:#ffffff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.has-success .input-group-addon{color:#ffffff;border-color:#ffffff;background-color:#62c462}.has-success .form-control-feedback{color:#ffffff}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#ffffff}.has-warning .form-control{border-color:#ffffff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.has-warning .input-group-addon{color:#ffffff;border-color:#ffffff;background-color:#f89406}.has-warning .form-control-feedback{color:#ffffff}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#ffffff}.has-error .form-control{border-color:#ffffff;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#e6e6e6;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #fff}.has-error .input-group-addon{color:#ffffff;border-color:#ffffff;background-color:#ee5f5b}.has-error .form-control-feedback{color:#ffffff}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#ffffff}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:9px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:29px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:9px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:15px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:8px 12px;font-size:14px;line-height:1.42857143;border-radius:4px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#ffffff;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#ffffff;background-color:#3a3f44;border-color:#3a3f44}.btn-default:focus,.btn-default.focus{color:#ffffff;background-color:#232628;border-color:#000000}.btn-default:hover{color:#ffffff;background-color:#232628;border-color:#1e2023}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#ffffff;background-color:#232628;border-color:#1e2023}.btn-default:active:hover,.btn-default.active:hover,.open>.dropdown-toggle.btn-default:hover,.btn-default:active:focus,.btn-default.active:focus,.open>.dropdown-toggle.btn-default:focus,.btn-default:active.focus,.btn-default.active.focus,.open>.dropdown-toggle.btn-default.focus{color:#ffffff;background-color:#121415;border-color:#000000}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus{background-color:#3a3f44;border-color:#3a3f44}.btn-default .badge{color:#3a3f44;background-color:#ffffff}.btn-primary{color:#ffffff;background-color:#7a8288;border-color:#7a8288}.btn-primary:focus,.btn-primary.focus{color:#ffffff;background-color:#62686d;border-color:#3e4245}.btn-primary:hover{color:#ffffff;background-color:#62686d;border-color:#5d6368}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#ffffff;background-color:#62686d;border-color:#5d6368}.btn-primary:active:hover,.btn-primary.active:hover,.open>.dropdown-toggle.btn-primary:hover,.btn-primary:active:focus,.btn-primary.active:focus,.open>.dropdown-toggle.btn-primary:focus,.btn-primary:active.focus,.btn-primary.active.focus,.open>.dropdown-toggle.btn-primary.focus{color:#ffffff;background-color:#51565a;border-color:#3e4245}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus{background-color:#7a8288;border-color:#7a8288}.btn-primary .badge{color:#7a8288;background-color:#ffffff}.btn-success{color:#ffffff;background-color:#62c462;border-color:#62c462}.btn-success:focus,.btn-success.focus{color:#ffffff;background-color:#42b142;border-color:#2d792d}.btn-success:hover{color:#ffffff;background-color:#42b142;border-color:#40a940}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#ffffff;background-color:#42b142;border-color:#40a940}.btn-success:active:hover,.btn-success.active:hover,.open>.dropdown-toggle.btn-success:hover,.btn-success:active:focus,.btn-success.active:focus,.open>.dropdown-toggle.btn-success:focus,.btn-success:active.focus,.btn-success.active.focus,.open>.dropdown-toggle.btn-success.focus{color:#ffffff;background-color:#399739;border-color:#2d792d}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus{background-color:#62c462;border-color:#62c462}.btn-success .badge{color:#62c462;background-color:#ffffff}.btn-info{color:#ffffff;background-color:#5bc0de;border-color:#5bc0de}.btn-info:focus,.btn-info.focus{color:#ffffff;background-color:#31b0d5;border-color:#1f7e9a}.btn-info:hover{color:#ffffff;background-color:#31b0d5;border-color:#2aabd2}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#ffffff;background-color:#31b0d5;border-color:#2aabd2}.btn-info:active:hover,.btn-info.active:hover,.open>.dropdown-toggle.btn-info:hover,.btn-info:active:focus,.btn-info.active:focus,.open>.dropdown-toggle.btn-info:focus,.btn-info:active.focus,.btn-info.active.focus,.open>.dropdown-toggle.btn-info.focus{color:#ffffff;background-color:#269abc;border-color:#1f7e9a}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus{background-color:#5bc0de;border-color:#5bc0de}.btn-info .badge{color:#5bc0de;background-color:#ffffff}.btn-warning{color:#ffffff;background-color:#f89406;border-color:#f89406}.btn-warning:focus,.btn-warning.focus{color:#ffffff;background-color:#c67605;border-color:#7c4a03}.btn-warning:hover{color:#ffffff;background-color:#c67605;border-color:#bc7005}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#ffffff;background-color:#c67605;border-color:#bc7005}.btn-warning:active:hover,.btn-warning.active:hover,.open>.dropdown-toggle.btn-warning:hover,.btn-warning:active:focus,.btn-warning.active:focus,.open>.dropdown-toggle.btn-warning:focus,.btn-warning:active.focus,.btn-warning.active.focus,.open>.dropdown-toggle.btn-warning.focus{color:#ffffff;background-color:#a36104;border-color:#7c4a03}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus{background-color:#f89406;border-color:#f89406}.btn-warning .badge{color:#f89406;background-color:#ffffff}.btn-danger{color:#ffffff;background-color:#ee5f5b;border-color:#ee5f5b}.btn-danger:focus,.btn-danger.focus{color:#ffffff;background-color:#e9322d;border-color:#b71713}.btn-danger:hover{color:#ffffff;background-color:#e9322d;border-color:#e82924}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#ffffff;background-color:#e9322d;border-color:#e82924}.btn-danger:active:hover,.btn-danger.active:hover,.open>.dropdown-toggle.btn-danger:hover,.btn-danger:active:focus,.btn-danger.active:focus,.open>.dropdown-toggle.btn-danger:focus,.btn-danger:active.focus,.btn-danger.active.focus,.open>.dropdown-toggle.btn-danger.focus{color:#ffffff;background-color:#dc1c17;border-color:#b71713}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus{background-color:#ee5f5b;border-color:#ee5f5b}.btn-danger .badge{color:#ee5f5b;background-color:#ffffff}.btn-link{color:#ffffff;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#ffffff;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:#7a8288;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:14px 16px;font-size:18px;line-height:1.3333333;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 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:0.35s;-o-transition-duration:0.35s;transition-duration:0.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid \9;border-right:4px solid transparent;border-left:4px solid transparent}.dropup,.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:14px;text-align:left;background-color:#3a3f44;border:1px solid #272b30;border:1px solid rgba(0,0,0,0.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#272b30}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.42857143;color:#c8c8c8;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#ffffff;background-color:#272b30}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#272b30}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#7a8288}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#7a8288;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px dashed;border-bottom:4px solid \9;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-right-radius:0;border-top-left-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:54px;padding:14px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:54px;line-height:54px}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:8px 12px;font-size:14px;font-weight:normal;line-height:1;color:#272b30;text-align:center;background-color:#999999;border:1px solid #cccccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:14px 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-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#3e444c}.nav>li.disabled>a{color:#7a8288}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#7a8288;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#3e444c;border-color:#ffffff}.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 #1c1e22}.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:#1c1e22 #1c1e22 #1c1e22}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#ffffff;background-color:#3e444c;border:1px solid #1c1e22;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #1c1e22}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #1c1e22;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:#272b30}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#ffffff;background-color:transparent}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #1c1e22}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #1c1e22;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:#272b30}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height: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{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:15px 15px;font-size:18px;line-height:20px;height:50px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:8px;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-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:6px;margin-bottom:6px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-right-radius:4px;border-top-left-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:6px;margin-bottom:6px}.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-left:15px;margin-right:15px}}@media (min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#3a3f44;border-color:#2b2e32}.navbar-default .navbar-brand{color:#c8c8c8}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#ffffff;background-color:none}.navbar-default .navbar-text{color:#c8c8c8}.navbar-default .navbar-nav>li>a{color:#c8c8c8}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#ffffff;background-color:#272b2e}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#ffffff;background-color:#272b2e}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#272b2e}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#272b2e}.navbar-default .navbar-toggle .icon-bar{background-color:#c8c8c8}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#2b2e32}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#272b2e;color:#ffffff}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#c8c8c8}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:#272b2e}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:#272b2e}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#cccccc;background-color:transparent}}.navbar-default .navbar-link{color:#c8c8c8}.navbar-default .navbar-link:hover{color:#ffffff}.navbar-default .btn-link{color:#c8c8c8}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#ffffff}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#cccccc}.navbar-inverse{background-color:#7a8288;border-color:#62686d}.navbar-inverse .navbar-brand{color:#cccccc}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#ffffff;background-color:none}.navbar-inverse .navbar-text{color:#cccccc}.navbar-inverse .navbar-nav>li>a{color:#cccccc}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#ffffff;background-color:#5d6368}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#ffffff;background-color:#5d6368}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#5d6368}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#5d6368}.navbar-inverse .navbar-toggle .icon-bar{background-color:#ffffff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#697075}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#5d6368;color:#ffffff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#62686d}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#62686d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#cccccc}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:#5d6368}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:#5d6368}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#cccccc;background-color:transparent}}.navbar-inverse .navbar-link{color:#cccccc}.navbar-inverse .navbar-link:hover{color:#ffffff}.navbar-inverse .btn-link{color:#cccccc}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#ffffff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#cccccc}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:transparent;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#cccccc}.breadcrumb>.active{color:#7a8288}.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:8px 12px;line-height:1.42857143;text-decoration:none;color:#ffffff;background-color:#3a3f44;border:1px solid rgba(0,0,0,0.6);margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:4px;border-top-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:4px;border-top-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{z-index:2;color:#ffffff;background-color:transparent;border-color:rgba(0,0,0,0.6)}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:3;color:#ffffff;background-color:#232628;border-color:rgba(0,0,0,0.6);cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#7a8288;background-color:#ffffff;border-color:rgba(0,0,0,0.6);cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:14px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:6px;border-top-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:6px;border-top-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:20px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#3a3f44;border:1px solid rgba(0,0,0,0.6);border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:transparent}.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:#7a8288;background-color:#3a3f44;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#ffffff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#3a3f44}.label-default[href]:hover,.label-default[href]:focus{background-color:#232628}.label-primary{background-color:#7a8288}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#62686d}.label-success{background-color:#62c462}.label-success[href]:hover,.label-success[href]:focus{background-color:#42b142}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f89406}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#c67605}.label-danger{background-color:#ee5f5b}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#e9322d}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:bold;color:#ffffff;line-height:1;vertical-align:middle;white-space:nowrap;text-align:center;background-color:#7a8288;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge,.btn-group-xs>.btn .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#ffffff;background-color:#7a8288}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#1c1e22}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#050506}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px;padding-left:15px;padding-right:15px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#1c1e22;border:1px solid #0c0d0e;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#ffffff}.thumbnail .caption{padding:9px;color:#c8c8c8}.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{background-color:#62c462;border-color:#62bd4f;color:#ffffff}.alert-success hr{border-top-color:#55b142}.alert-success .alert-link{color:#e6e6e6}.alert-info{background-color:#5bc0de;border-color:#3dced8;color:#ffffff}.alert-info hr{border-top-color:#2ac7d2}.alert-info .alert-link{color:#e6e6e6}.alert-warning{background-color:#f89406;border-color:#e96506;color:#ffffff}.alert-warning hr{border-top-color:#d05a05}.alert-warning .alert-link{color:#e6e6e6}.alert-danger{background-color:#ee5f5b;border-color:#ed4d63;color:#ffffff}.alert-danger hr{border-top-color:#ea364f}.alert-danger .alert-link{color:#e6e6e6}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#1c1e22;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:20px;color:#ffffff;text-align:center;background-color:#7a8288;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#62c462}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#f89406}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-danger{background-color:#ee5f5b}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{zoom:1;overflow:hidden}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#32383e;border:1px solid rgba(0,0,0,0.6)}.list-group-item:first-child{border-top-right-radius:4px;border-top-left-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#c8c8c8}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#ffffff}a.list-group-item:hover,button.list-group-item:hover,a.list-group-item:focus,button.list-group-item:focus{text-decoration:none;color:#c8c8c8;background-color:#3e444c}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#999999;color:#7a8288;cursor:not-allowed}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#7a8288}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#ffffff;background-color:#3e444c;border-color:rgba(0,0,0,0.6)}.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:#a2aab4}.list-group-item-success{color:#ffffff;background-color:#62c462}a.list-group-item-success,button.list-group-item-success{color:#ffffff}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,button.list-group-item-success:hover,a.list-group-item-success:focus,button.list-group-item-success:focus{color:#ffffff;background-color:#4fbd4f}a.list-group-item-success.active,button.list-group-item-success.active,a.list-group-item-success.active:hover,button.list-group-item-success.active:hover,a.list-group-item-success.active:focus,button.list-group-item-success.active:focus{color:#fff;background-color:#ffffff;border-color:#ffffff}.list-group-item-info{color:#ffffff;background-color:#5bc0de}a.list-group-item-info,button.list-group-item-info{color:#ffffff}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,button.list-group-item-info:hover,a.list-group-item-info:focus,button.list-group-item-info:focus{color:#ffffff;background-color:#46b8da}a.list-group-item-info.active,button.list-group-item-info.active,a.list-group-item-info.active:hover,button.list-group-item-info.active:hover,a.list-group-item-info.active:focus,button.list-group-item-info.active:focus{color:#fff;background-color:#ffffff;border-color:#ffffff}.list-group-item-warning{color:#ffffff;background-color:#f89406}a.list-group-item-warning,button.list-group-item-warning{color:#ffffff}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,button.list-group-item-warning:hover,a.list-group-item-warning:focus,button.list-group-item-warning:focus{color:#ffffff;background-color:#df8505}a.list-group-item-warning.active,button.list-group-item-warning.active,a.list-group-item-warning.active:hover,button.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus,button.list-group-item-warning.active:focus{color:#fff;background-color:#ffffff;border-color:#ffffff}.list-group-item-danger{color:#ffffff;background-color:#ee5f5b}a.list-group-item-danger,button.list-group-item-danger{color:#ffffff}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,button.list-group-item-danger:hover,a.list-group-item-danger:focus,button.list-group-item-danger:focus{color:#ffffff;background-color:#ec4844}a.list-group-item-danger.active,button.list-group-item-danger.active,a.list-group-item-danger.active:hover,button.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus,button.list-group-item-danger.active:focus{color:#fff;background-color:#ffffff;border-color:#ffffff}.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:#2e3338;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:3px;border-top-left-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a,.panel-title>small,.panel-title>.small,.panel-title>small>a,.panel-title>.small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#3e444c;border-top:1px solid rgba(0,0,0,0.6);border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:3px;border-top-left-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-right-radius:0;border-top-left-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-left-radius:3px;border-bottom-right-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #1c1e22}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom: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,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid rgba(0,0,0,0.6)}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid rgba(0,0,0,0.6)}.panel-default{border-color:rgba(0,0,0,0.6)}.panel-default>.panel-heading{color:#c8c8c8;background-color:#3e444c;border-color:rgba(0,0,0,0.6)}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)}.panel-default>.panel-heading .badge{color:#3e444c;background-color:#c8c8c8}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)}.panel-primary{border-color:rgba(0,0,0,0.6)}.panel-primary>.panel-heading{color:#ffffff;background-color:#7a8288;border-color:rgba(0,0,0,0.6)}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)}.panel-primary>.panel-heading .badge{color:#7a8288;background-color:#ffffff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)}.panel-success{border-color:rgba(0,0,0,0.6)}.panel-success>.panel-heading{color:#ffffff;background-color:#62c462;border-color:rgba(0,0,0,0.6)}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)}.panel-success>.panel-heading .badge{color:#62c462;background-color:#ffffff}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)}.panel-info{border-color:rgba(0,0,0,0.6)}.panel-info>.panel-heading{color:#ffffff;background-color:#5bc0de;border-color:rgba(0,0,0,0.6)}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)}.panel-info>.panel-heading .badge{color:#5bc0de;background-color:#ffffff}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)}.panel-warning{border-color:rgba(0,0,0,0.6)}.panel-warning>.panel-heading{color:#ffffff;background-color:#f89406;border-color:rgba(0,0,0,0.6)}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)}.panel-warning>.panel-heading .badge{color:#f89406;background-color:#ffffff}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)}.panel-danger{border-color:rgba(0,0,0,0.6)}.panel-danger>.panel-heading{color:#ffffff;background-color:#ee5f5b;border-color:rgba(0,0,0,0.6)}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:rgba(0,0,0,0.6)}.panel-danger>.panel-heading .badge{color:#ee5f5b;background-color:#ffffff}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:rgba(0,0,0,0.6)}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;left:0;bottom:0;height:100%;width:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#1c1e22;border:1px solid #0c0d0e;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:bold;line-height:1;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#2e3338;border:1px solid #999999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid #1c1e22}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:20px}.modal-footer{padding:20px;text-align:right;border-top:1px solid #1c1e22}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:12px;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:0.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;background-color:#000000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000000}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-style:normal;font-weight:normal;letter-spacing:normal;line-break:auto;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;white-space:normal;word-break:normal;word-spacing:normal;word-wrap:normal;font-size:14px;background-color:#2e3338;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999999;border:1px solid rgba(0,0,0,0.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:14px;background-color:#2e3338;border-bottom:1px solid #22262a;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#666666;border-top-color:rgba(0,0,0,0.25);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#2e3338}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:#666666;border-right-color:rgba(0,0,0,0.25)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#2e3338}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#666666;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#2e3338}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#666666;border-left-color:rgba(0,0,0,0.25)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#2e3338;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:0.5;filter:alpha(opacity=50);font-size:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6);background-color:rgba(0,0,0,0)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0.0001)));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.0001)), to(rgba(0,0,0,0.5)));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;margin-top:-10px;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;line-height:1;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #ffffff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#ffffff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-10px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-10px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-header:before,.modal-header:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-header:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table !important}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table !important}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table !important}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table !important}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table !important}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}.navbar{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none;border:1px solid rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3)}.navbar-inverse{background-image:-webkit-linear-gradient(#8a9196, #7a8288 60%, #70787d);background-image:-o-linear-gradient(#8a9196, #7a8288 60%, #70787d);background-image:-webkit-gradient(linear, left top, left bottom, from(#8a9196), color-stop(60%, #7a8288), to(#70787d));background-image:linear-gradient(#8a9196, #7a8288 60%, #70787d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff8a9196', endColorstr='#ff70787d', GradientType=0);-webkit-filter:none;filter:none}.navbar-inverse .badge{background-color:#5d6368}.navbar-nav>li>a{border-right:1px solid rgba(0,0,0,0.2);border-left:1px solid rgba(255,255,255,0.1)}.navbar-nav>li>a:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none;border-left-color:transparent}.navbar .nav .open>a{border-color:transparent}.navbar-nav>li.active>a{border-left-color:transparent}.navbar-form{margin-left:5px;margin-right:5px}.btn,.btn:hover{border-color:rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3)}.btn-default{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none}.btn-default:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none}.btn-primary{background-image:-webkit-linear-gradient(#8a9196, #7a8288 60%, #70787d);background-image:-o-linear-gradient(#8a9196, #7a8288 60%, #70787d);background-image:-webkit-gradient(linear, left top, left bottom, from(#8a9196), color-stop(60%, #7a8288), to(#70787d));background-image:linear-gradient(#8a9196, #7a8288 60%, #70787d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff8a9196', endColorstr='#ff70787d', GradientType=0);-webkit-filter:none;filter:none}.btn-primary:hover{background-image:-webkit-linear-gradient(#404448, #4e5458 40%, #585e62);background-image:-o-linear-gradient(#404448, #4e5458 40%, #585e62);background-image:-webkit-gradient(linear, left top, left bottom, from(#404448), color-stop(40%, #4e5458), to(#585e62));background-image:linear-gradient(#404448, #4e5458 40%, #585e62);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff404448', endColorstr='#ff585e62', GradientType=0);-webkit-filter:none;filter:none}.btn-success{background-image:-webkit-linear-gradient(#78cc78, #62c462 60%, #53be53);background-image:-o-linear-gradient(#78cc78, #62c462 60%, #53be53);background-image:-webkit-gradient(linear, left top, left bottom, from(#78cc78), color-stop(60%, #62c462), to(#53be53));background-image:linear-gradient(#78cc78, #62c462 60%, #53be53);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff78cc78', endColorstr='#ff53be53', GradientType=0);-webkit-filter:none;filter:none}.btn-success:hover{background-image:-webkit-linear-gradient(#2f7d2f, #379337 40%, #3da23d);background-image:-o-linear-gradient(#2f7d2f, #379337 40%, #3da23d);background-image:-webkit-gradient(linear, left top, left bottom, from(#2f7d2f), color-stop(40%, #379337), to(#3da23d));background-image:linear-gradient(#2f7d2f, #379337 40%, #3da23d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff2f7d2f', endColorstr='#ff3da23d', GradientType=0);-webkit-filter:none;filter:none}.btn-info{background-image:-webkit-linear-gradient(#74cae3, #5bc0de 60%, #4ab9db);background-image:-o-linear-gradient(#74cae3, #5bc0de 60%, #4ab9db);background-image:-webkit-gradient(linear, left top, left bottom, from(#74cae3), color-stop(60%, #5bc0de), to(#4ab9db));background-image:linear-gradient(#74cae3, #5bc0de 60%, #4ab9db);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff74cae3', endColorstr='#ff4ab9db', GradientType=0);-webkit-filter:none;filter:none}.btn-info:hover{background-image:-webkit-linear-gradient(#20829f, #2596b8 40%, #28a4c9);background-image:-o-linear-gradient(#20829f, #2596b8 40%, #28a4c9);background-image:-webkit-gradient(linear, left top, left bottom, from(#20829f), color-stop(40%, #2596b8), to(#28a4c9));background-image:linear-gradient(#20829f, #2596b8 40%, #28a4c9);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff20829f', endColorstr='#ff28a4c9', GradientType=0);-webkit-filter:none;filter:none}.btn-warning{background-image:-webkit-linear-gradient(#faa123, #f89406 60%, #e48806);background-image:-o-linear-gradient(#faa123, #f89406 60%, #e48806);background-image:-webkit-gradient(linear, left top, left bottom, from(#faa123), color-stop(60%, #f89406), to(#e48806));background-image:linear-gradient(#faa123, #f89406 60%, #e48806);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffaa123', endColorstr='#ffe48806', GradientType=0);-webkit-filter:none;filter:none}.btn-warning:hover{background-image:-webkit-linear-gradient(#804d03, #9e5f04 40%, #b26a04);background-image:-o-linear-gradient(#804d03, #9e5f04 40%, #b26a04);background-image:-webkit-gradient(linear, left top, left bottom, from(#804d03), color-stop(40%, #9e5f04), to(#b26a04));background-image:linear-gradient(#804d03, #9e5f04 40%, #b26a04);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff804d03', endColorstr='#ffb26a04', GradientType=0);-webkit-filter:none;filter:none}.btn-danger{background-image:-webkit-linear-gradient(#f17a77, #ee5f5b 60%, #ec4d49);background-image:-o-linear-gradient(#f17a77, #ee5f5b 60%, #ec4d49);background-image:-webkit-gradient(linear, left top, left bottom, from(#f17a77), color-stop(60%, #ee5f5b), to(#ec4d49));background-image:linear-gradient(#f17a77, #ee5f5b 60%, #ec4d49);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff17a77', endColorstr='#ffec4d49', GradientType=0);-webkit-filter:none;filter:none}.btn-danger:hover{background-image:-webkit-linear-gradient(#bb1813, #d71c16 40%, #e7201a);background-image:-o-linear-gradient(#bb1813, #d71c16 40%, #e7201a);background-image:-webkit-gradient(linear, left top, left bottom, from(#bb1813), color-stop(40%, #d71c16), to(#e7201a));background-image:linear-gradient(#bb1813, #d71c16 40%, #e7201a);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffbb1813', endColorstr='#ffe7201a', GradientType=0);-webkit-filter:none;filter:none}.btn-link,.btn-link:hover{border-color:transparent}h1,h2,h3,h4,h5,h6{text-shadow:-1px -1px 0 rgba(0,0,0,0.3)}.text-primary,.text-primary:hover{color:#7a8288}.text-success,.text-success:hover{color:#62c462}.text-danger,.text-danger:hover{color:#ee5f5b}.text-warning,.text-warning:hover{color:#f89406}.text-info,.text-info:hover{color:#5bc0de}.table .success,.table .warning,.table .danger,.table .info{color:#fff}.table-bordered tbody tr.success td,.table-bordered tbody tr.warning td,.table-bordered tbody tr.danger td,.table-bordered tbody tr.success:hover td,.table-bordered tbody tr.warning:hover td,.table-bordered tbody tr.danger:hover td{border-color:#1c1e22}.table-responsive>.table{background-color:#2e3338}input,textarea{color:#272b30}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label,.has-warning .form-control-feedback{color:#f89406}.has-warning .form-control,.has-warning .form-control:focus{border-color:#f89406}.has-warning .input-group-addon{background-color:#272b30;border:none}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label,.has-error .form-control-feedback{color:#ee5f5b}.has-error .form-control,.has-error .form-control:focus{border-color:#ee5f5b}.has-error .input-group-addon{background-color:#272b30;border:none}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label,.has-success .form-control-feedback{color:#62c462}.has-success .form-control,.has-success .form-control:focus{border-color:#62c462}.has-success .input-group-addon{background-color:#272b30;border:none}legend{color:#fff}.input-group-addon{border-color:rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3);background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none;color:#ffffff}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{border-color:rgba(0,0,0,0.6)}.nav-pills>li>a{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none;border:1px solid rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3)}.nav-pills>li>a:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none;border:1px solid rgba(0,0,0,0.6)}.nav-pills>li.active>a,.nav-pills>li.active>a:hover{background-color:none;background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none;border:1px solid rgba(0,0,0,0.6)}.nav-pills>li.disabled>a,.nav-pills>li.disabled>a:hover{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none}.pagination>li>a,.pagination>li>span{text-shadow:1px 1px 1px rgba(0,0,0,0.3);background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none}.pagination>li>a:hover,.pagination>li>span:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none}.pagination>li.active>a,.pagination>li.active>span{background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none}.pagination>li.disabled>a,.pagination>li.disabled>a:hover,.pagination>li.disabled>span,.pagination>li.disabled>span:hover{background-color:transparent;background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none}.pager>li>a{background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none;text-shadow:1px 1px 1px rgba(0,0,0,0.3)}.pager>li>a:hover{background-image:-webkit-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-o-linear-gradient(#020202, #101112 40%, #191b1d);background-image:-webkit-gradient(linear, left top, left bottom, from(#020202), color-stop(40%, #101112), to(#191b1d));background-image:linear-gradient(#020202, #101112 40%, #191b1d);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff020202', endColorstr='#ff191b1d', GradientType=0);-webkit-filter:none;filter:none}.pager>li.disabled>a,.pager>li.disabled>a:hover{background-color:transparent;background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none}.breadcrumb{border:1px solid rgba(0,0,0,0.6);text-shadow:1px 1px 1px rgba(0,0,0,0.3);background-image:-webkit-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-o-linear-gradient(#484e55, #3a3f44 60%, #313539);background-image:-webkit-gradient(linear, left top, left bottom, from(#484e55), color-stop(60%, #3a3f44), to(#313539));background-image:linear-gradient(#484e55, #3a3f44 60%, #313539);background-repeat:no-repeat;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff484e55', endColorstr='#ff313539', GradientType=0);-webkit-filter:none;filter:none}.alert .alert-link,.alert a{color:#fff;text-decoration:underline}.alert .close{color:#000000;text-decoration:none}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#0c0d0e}a.list-group-item.active,a.list-group-item.active:hover,a.list-group-item.active:focus{border-color:rgba(0,0,0,0.6)}a.list-group-item-success.active{background-color:#62c462}a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{background-color:#4fbd4f}a.list-group-item-warning.active{background-color:#f89406}a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{background-color:#df8505}a.list-group-item-danger.active{background-color:#ee5f5b}a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{background-color:#ec4844}.jumbotron{border:1px solid rgba(0,0,0,0.6)}.panel-primary .panel-heading,.panel-success .panel-heading,.panel-danger .panel-heading,.panel-warning .panel-heading,.panel-info .panel-heading{border-color:#000} \ No newline at end of file diff --git a/admin/static/fonts/glyphicons-halflings-regular.eot b/admin/static/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000000000000000000000000000000000000..b93a4953fff68df523aa7656497ee339d6026d64 GIT binary patch literal 20127 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/admin/static/fonts/glyphicons-halflings-regular.ttf b/admin/static/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1413fc609ab6f21774de0cb7e01360095584f65b GIT binary patch literal 45404 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 G`u_lkUM?>H literal 0 HcmV?d00001 diff --git a/admin/static/fonts/glyphicons-halflings-regular.woff2 b/admin/static/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..64539b54c3751a6d9adb44c8e3a45ba5a73b77f0 GIT binary patch literal 18028 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 literal 0 HcmV?d00001 diff --git a/admin/static/index.html b/admin/static/index.html new file mode 100644 index 00000000..96ef0a41 --- /dev/null +++ b/admin/static/index.html @@ -0,0 +1,27 @@ + + + + + Challenge Forensic FIC 2016 - Administration + + + + +
    + +
    +
    +
    +
    + + + + + + + + + diff --git a/admin/static/js/angular-resource.min.js b/admin/static/js/angular-resource.min.js new file mode 100644 index 00000000..c3fb7aab --- /dev/null +++ b/admin/static/js/angular-resource.min.js @@ -0,0 +1,14 @@ +/* + AngularJS v1.4.8 + (c) 2010-2015 Google, Inc. http://angularjs.org + License: MIT +*/ +(function(I,f,C){'use strict';function D(t,e){e=e||{};f.forEach(e,function(f,k){delete e[k]});for(var k in t)!t.hasOwnProperty(k)||"$"===k.charAt(0)&&"$"===k.charAt(1)||(e[k]=t[k]);return e}var y=f.$$minErr("$resource"),B=/^(\.[a-zA-Z_$@][0-9a-zA-Z_$@]*)+$/;f.module("ngResource",["ng"]).provider("$resource",function(){var t=/^https?:\/\/[^\/]*/,e=this;this.defaults={stripTrailingSlashes:!0,actions:{get:{method:"GET"},save:{method:"POST"},query:{method:"GET",isArray:!0},remove:{method:"DELETE"},"delete":{method:"DELETE"}}}; +this.$get=["$http","$q",function(k,F){function w(f,g){this.template=f;this.defaults=r({},e.defaults,g);this.urlParams={}}function z(l,g,s,h){function c(a,q){var c={};q=r({},g,q);u(q,function(b,q){x(b)&&(b=b());var m;if(b&&b.charAt&&"@"==b.charAt(0)){m=a;var d=b.substr(1);if(null==d||""===d||"hasOwnProperty"===d||!B.test("."+d))throw y("badmember",d);for(var d=d.split("."),n=0,g=d.length;n").append(a).html();try{return a[0].nodeType===Na?F(d):d.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/,function(a,b){return"<"+F(b)})}catch(c){return F(d)}}function wc(a){try{return decodeURIComponent(a)}catch(b){}} +function xc(a){var b={};n((a||"").split("&"),function(a){var c,e,f;a&&(e=a=a.replace(/\+/g,"%20"),c=a.indexOf("="),-1!==c&&(e=a.substring(0,c),f=a.substring(c+1)),e=wc(e),y(e)&&(f=y(f)?wc(f):!0,qa.call(b,e)?I(b[e])?b[e].push(f):b[e]=[b[e],f]:b[e]=f))});return b}function Qb(a){var b=[];n(a,function(a,c){I(a)?n(a,function(a){b.push(ja(c,!0)+(!0===a?"":"="+ja(a,!0)))}):b.push(ja(c,!0)+(!0===a?"":"="+ja(a,!0)))});return b.length?b.join("&"):""}function ob(a){return ja(a,!0).replace(/%26/gi,"&").replace(/%3D/gi, +"=").replace(/%2B/gi,"+")}function ja(a,b){return encodeURIComponent(a).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%3B/gi,";").replace(/%20/g,b?"%20":"+")}function Yd(a,b){var d,c,e=Oa.length;for(c=0;c/,">"));}b=b||[];b.unshift(["$provide",function(b){b.value("$rootElement",a)}]);d.debugInfoEnabled&&b.push(["$compileProvider",function(a){a.debugInfoEnabled(!0)}]);b.unshift("ng");c=eb(b,d.strictDi);c.invoke(["$rootScope", +"$rootElement","$compile","$injector",function(a,b,c,d){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},e=/^NG_ENABLE_DEBUG_INFO!/,f=/^NG_DEFER_BOOTSTRAP!/;S&&e.test(S.name)&&(d.debugInfoEnabled=!0,S.name=S.name.replace(e,""));if(S&&!f.test(S.name))return c();S.name=S.name.replace(f,"");fa.resumeBootstrap=function(a){n(a,function(a){b.push(a)});return c()};z(fa.resumeDeferredBootstrap)&&fa.resumeDeferredBootstrap()}function $d(){S.name="NG_ENABLE_DEBUG_INFO!"+S.name;S.location.reload()} +function ae(a){a=fa.element(a).injector();if(!a)throw Aa("test");return a.get("$$testability")}function zc(a,b){b=b||"_";return a.replace(be,function(a,c){return(c?b:"")+a.toLowerCase()})}function ce(){var a;if(!Ac){var b=pb();(oa=q(b)?S.jQuery:b?S[b]:u)&&oa.fn.on?(B=oa,M(oa.fn,{scope:Pa.scope,isolateScope:Pa.isolateScope,controller:Pa.controller,injector:Pa.injector,inheritedData:Pa.inheritedData}),a=oa.cleanData,oa.cleanData=function(b){var c;if(Rb)Rb=!1;else for(var e=0,f;null!=(f=b[e]);e++)(c= +oa._data(f,"events"))&&c.$destroy&&oa(f).triggerHandler("$destroy");a(b)}):B=N;fa.element=B;Ac=!0}}function qb(a,b,d){if(!a)throw Aa("areq",b||"?",d||"required");return a}function Qa(a,b,d){d&&I(a)&&(a=a[a.length-1]);qb(z(a),b,"not a function, got "+(a&&"object"===typeof a?a.constructor.name||"Object":typeof a));return a}function Ra(a,b){if("hasOwnProperty"===a)throw Aa("badname",b);}function Bc(a,b,d){if(!b)return a;b=b.split(".");for(var c,e=a,f=b.length,g=0;g")+c[2];for(c=c[0];c--;)d=d.lastChild;f=cb(f,d.childNodes);d=e.firstChild;d.textContent=""}else f.push(b.createTextNode(a));e.textContent="";e.innerHTML="";n(f,function(a){e.appendChild(a)});return e}function N(a){if(a instanceof N)return a;var b;E(a)&&(a=U(a), +b=!0);if(!(this instanceof N)){if(b&&"<"!=a.charAt(0))throw Ub("nosel");return new N(a)}if(b){b=X;var d;a=(d=Ef.exec(a))?[b.createElement(d[1])]:(d=Lc(a,b))?d.childNodes:[]}Mc(this,a)}function Vb(a){return a.cloneNode(!0)}function ub(a,b){b||vb(a);if(a.querySelectorAll)for(var d=a.querySelectorAll("*"),c=0,e=d.length;cl&&this.remove(t.key);return b}},get:function(a){if(l").parent()[0])});var f=O(a,b,a,c,d,e);K.$$addScopeClass(a);var g=null;return function(b,c,d){qb(b,"scope");e&&e.needsNewScope&&(b=b.$parent.$new());d=d||{};var h=d.parentBoundTranscludeFn,k=d.transcludeControllers;d=d.futureParentElement;h&&h.$$boundTransclude&&(h=h.$$boundTransclude);g||(g=(d= +d&&d[0])?"foreignobject"!==ta(d)&&d.toString().match(/SVG/)?"svg":"html":"html");d="html"!==g?B(Yb(g,B("
    ").append(a).html())):c?Pa.clone.call(a):a;if(k)for(var l in k)d.data("$"+l+"Controller",k[l].instance);K.$$addScopeInfo(d,b);c&&c(d,b);f&&f(b,d,d,h);return d}}function O(a,b,c,d,e,f){function g(a,c,d,e){var f,k,l,m,t,w,D;if(p)for(D=Array(c.length),m=0;mq.priority)break;if(P=q.scope)q.templateUrl||(H(P)?(Ua("new/isolated scope",O||R,q,Z),O=q):Ua("new/isolated scope",O,q,Z)),R=R||q;x=q.name;!q.templateUrl&&q.controller&&(P=q.controller,T=T||$(),Ua("'"+x+"' controller",T[x],q,Z),T[x]=q);if(P=q.transclude)ga=!0,q.$$tlb||(Ua("transclusion",n,q,Z),n=q),"element"==P?(aa=!0,A=q.priority,P=Z,Z=d.$$element=B(X.createComment(" "+x+": "+d[x]+" ")),b=Z[0],Y(f,ra.call(P,0), +b),Ia=K(P,e,A,g&&g.name,{nonTlbTranscludeDirective:n})):(P=B(Vb(b)).contents(),Z.empty(),Ia=K(P,e,u,u,{needsNewScope:q.$$isolateScope||q.$$newScope}));if(q.template)if(L=!0,Ua("template",J,q,Z),J=q,P=z(q.template)?q.template(Z,d):q.template,P=ja(P),q.replace){g=q;P=Tb.test(P)?Xc(Yb(q.templateNamespace,U(P))):[];b=P[0];if(1!=P.length||1!==b.nodeType)throw ha("tplrt",x,"");Y(f,Z,b);P={$attr:{}};var Wc=V(b,[],P),W=a.splice(F+1,a.length-(F+1));(O||R)&&y(Wc,O,R);a=a.concat(Wc).concat(W);S(d,P);M=a.length}else Z.html(P); +if(q.templateUrl)L=!0,Ua("template",J,q,Z),J=q,q.replace&&(g=q),D=Of(a.splice(F,a.length-F),Z,d,f,ga&&Ia,h,l,{controllerDirectives:T,newScopeDirective:R!==q&&R,newIsolateScopeDirective:O,templateDirective:J,nonTlbTranscludeDirective:n}),M=a.length;else if(q.compile)try{G=q.compile(Z,d,Ia),z(G)?t(null,G,N,Q):G&&t(G.pre,G.post,N,Q)}catch(da){c(da,ua(Z))}q.terminal&&(D.terminal=!0,A=Math.max(A,q.priority))}D.scope=R&&!0===R.scope;D.transcludeOnThisElement=ga;D.templateOnThisElement=L;D.transclude=Ia; +m.hasElementTranscludeDirective=aa;return D}function y(a,b,c){for(var d=0,e=a.length;dm.priority)&&-1!=m.restrict.indexOf(f)&&(k&&(m=Ob(m,{$$start:k,$$end:l})),b.push(m),h=m)}catch(D){c(D)}}return h}function G(b){if(e.hasOwnProperty(b))for(var c=a.get(b+"Directive"),d=0,f=c.length;d"+b+"";return c.childNodes[0].childNodes;default:return b}}function Q(a,b){if("srcdoc"==b)return L.HTML;var c=ta(a);if("xlinkHref"==b||"form"==c&&"action"==b||"img"!=c&&("src"==b||"ngSrc"==b))return L.RESOURCE_URL}function W(a,c,d,e,f){var g=Q(a,e);f=h[e]||f;var k=b(d,!0,g,f);if(k){if("multiple"===e&&"select"===ta(a))throw ha("selmulti",ua(a));c.push({priority:100,compile:function(){return{pre:function(a,c,h){c=h.$$observers||(h.$$observers=$());if(l.test(e))throw ha("nodomevents"); +var m=h[e];m!==d&&(k=m&&b(m,!0,g,f),d=m);k&&(h[e]=k(a),(c[e]||(c[e]=[])).$$inter=!0,(h.$$observers&&h.$$observers[e].$$scope||a).$watch(k,function(a,b){"class"===e&&a!=b?h.$updateClass(a,b):h.$set(e,a)}))}}}})}}function Y(a,b,c){var d=b[0],e=b.length,f=d.parentNode,g,h;if(a)for(g=0,h=a.length;g=b)return a;for(;b--;)8===a[b].nodeType&&Pf.call(a,b,1);return a}function Xe(){var a={},b=!1;this.register=function(b,c){Ra(b,"controller");H(b)?M(a,b):a[b]=c};this.allowGlobals=function(){b=!0};this.$get=["$injector","$window",function(d,c){function e(a,b,c,d){if(!a||!H(a.$scope))throw G("$controller")("noscp", +d,b);a.$scope[b]=c}return function(f,g,h,k){var l,m,r;h=!0===h;k&&E(k)&&(r=k);if(E(f)){k=f.match(Uc);if(!k)throw Qf("ctrlfmt",f);m=k[1];r=r||k[3];f=a.hasOwnProperty(m)?a[m]:Bc(g.$scope,m,!0)||(b?Bc(c,m,!0):u);Qa(f,m,!0)}if(h)return h=(I(f)?f[f.length-1]:f).prototype,l=Object.create(h||null),r&&e(g,r,l,m||f.name),M(function(){var a=d.invoke(f,l,g,m);a!==l&&(H(a)||z(a))&&(l=a,r&&e(g,r,l,m||f.name));return l},{instance:l,identifier:r});l=d.instantiate(f,g,m);r&&e(g,r,l,m||f.name);return l}}]}function Ye(){this.$get= +["$window",function(a){return B(a.document)}]}function Ze(){this.$get=["$log",function(a){return function(b,d){a.error.apply(a,arguments)}}]}function Zb(a){return H(a)?da(a)?a.toISOString():db(a):a}function df(){this.$get=function(){return function(a){if(!a)return"";var b=[];oc(a,function(a,c){null===a||q(a)||(I(a)?n(a,function(a,d){b.push(ja(c)+"="+ja(Zb(a)))}):b.push(ja(c)+"="+ja(Zb(a))))});return b.join("&")}}}function ef(){this.$get=function(){return function(a){function b(a,e,f){null===a||q(a)|| +(I(a)?n(a,function(a,c){b(a,e+"["+(H(a)?c:"")+"]")}):H(a)&&!da(a)?oc(a,function(a,c){b(a,e+(f?"":"[")+c+(f?"":"]"))}):d.push(ja(e)+"="+ja(Zb(a))))}if(!a)return"";var d=[];b(a,"",!0);return d.join("&")}}}function $b(a,b){if(E(a)){var d=a.replace(Rf,"").trim();if(d){var c=b("Content-Type");(c=c&&0===c.indexOf($c))||(c=(c=d.match(Sf))&&Tf[c[0]].test(d));c&&(a=uc(d))}}return a}function ad(a){var b=$(),d;E(a)?n(a.split("\n"),function(a){d=a.indexOf(":");var e=F(U(a.substr(0,d)));a=U(a.substr(d+1));e&& +(b[e]=b[e]?b[e]+", "+a:a)}):H(a)&&n(a,function(a,d){var f=F(d),g=U(a);f&&(b[f]=b[f]?b[f]+", "+g:g)});return b}function bd(a){var b;return function(d){b||(b=ad(a));return d?(d=b[F(d)],void 0===d&&(d=null),d):b}}function cd(a,b,d,c){if(z(c))return c(a,b,d);n(c,function(c){a=c(a,b,d)});return a}function cf(){var a=this.defaults={transformResponse:[$b],transformRequest:[function(a){return H(a)&&"[object File]"!==sa.call(a)&&"[object Blob]"!==sa.call(a)&&"[object FormData]"!==sa.call(a)?db(a):a}],headers:{common:{Accept:"application/json, text/plain, */*"}, +post:ia(ac),put:ia(ac),patch:ia(ac)},xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",paramSerializer:"$httpParamSerializer"},b=!1;this.useApplyAsync=function(a){return y(a)?(b=!!a,this):b};var d=!0;this.useLegacyPromiseExtensions=function(a){return y(a)?(d=!!a,this):d};var c=this.interceptors=[];this.$get=["$httpBackend","$$cookieReader","$cacheFactory","$rootScope","$q","$injector",function(e,f,g,h,k,l){function m(b){function c(a){var b=M({},a);b.data=cd(a.data,a.headers,a.status,f.transformResponse); +a=a.status;return 200<=a&&300>a?b:k.reject(b)}function e(a,b){var c,d={};n(a,function(a,e){z(a)?(c=a(b),null!=c&&(d[e]=c)):d[e]=a});return d}if(!fa.isObject(b))throw G("$http")("badreq",b);var f=M({method:"get",transformRequest:a.transformRequest,transformResponse:a.transformResponse,paramSerializer:a.paramSerializer},b);f.headers=function(b){var c=a.headers,d=M({},b.headers),f,g,h,c=M({},c.common,c[F(b.method)]);a:for(f in c){g=F(f);for(h in d)if(F(h)===g)continue a;d[f]=c[f]}return e(d,ia(b))}(b); +f.method=sb(f.method);f.paramSerializer=E(f.paramSerializer)?l.get(f.paramSerializer):f.paramSerializer;var g=[function(b){var d=b.headers,e=cd(b.data,bd(d),u,b.transformRequest);q(e)&&n(d,function(a,b){"content-type"===F(b)&&delete d[b]});q(b.withCredentials)&&!q(a.withCredentials)&&(b.withCredentials=a.withCredentials);return r(b,e).then(c,c)},u],h=k.when(f);for(n(v,function(a){(a.request||a.requestError)&&g.unshift(a.request,a.requestError);(a.response||a.responseError)&&g.push(a.response,a.responseError)});g.length;){b= +g.shift();var m=g.shift(),h=h.then(b,m)}d?(h.success=function(a){Qa(a,"fn");h.then(function(b){a(b.data,b.status,b.headers,f)});return h},h.error=function(a){Qa(a,"fn");h.then(null,function(b){a(b.data,b.status,b.headers,f)});return h}):(h.success=dd("success"),h.error=dd("error"));return h}function r(c,d){function g(a,c,d,e){function f(){l(c,a,d,e)}J&&(200<=a&&300>a?J.put(R,[a,c,ad(d),e]):J.remove(R));b?h.$applyAsync(f):(f(),h.$$phase||h.$apply())}function l(a,b,d,e){b=-1<=b?b:0;(200<=b&&300>b?n.resolve: +n.reject)({data:a,status:b,headers:bd(d),config:c,statusText:e})}function r(a){l(a.data,a.status,ia(a.headers()),a.statusText)}function v(){var a=m.pendingRequests.indexOf(c);-1!==a&&m.pendingRequests.splice(a,1)}var n=k.defer(),D=n.promise,J,K,O=c.headers,R=t(c.url,c.paramSerializer(c.params));m.pendingRequests.push(c);D.then(v,v);!c.cache&&!a.cache||!1===c.cache||"GET"!==c.method&&"JSONP"!==c.method||(J=H(c.cache)?c.cache:H(a.cache)?a.cache:A);J&&(K=J.get(R),y(K)?K&&z(K.then)?K.then(r,r):I(K)?l(K[1], +K[0],ia(K[2]),K[3]):l(K,200,{},"OK"):J.put(R,D));q(K)&&((K=ed(c.url)?f()[c.xsrfCookieName||a.xsrfCookieName]:u)&&(O[c.xsrfHeaderName||a.xsrfHeaderName]=K),e(c.method,R,d,g,O,c.timeout,c.withCredentials,c.responseType));return D}function t(a,b){0=k&&(p.resolve(v),A(C.$$intervalId),delete f[C.$$intervalId]);n||a.$apply()},h);f[C.$$intervalId]=p;return C}var f={};e.cancel=function(a){return a&&a.$$intervalId in f?(f[a.$$intervalId].reject("canceled"),b.clearInterval(a.$$intervalId),delete f[a.$$intervalId],!0):!1};return e}]}function bc(a){a=a.split("/");for(var b=a.length;b--;)a[b]=ob(a[b]);return a.join("/")}function fd(a,b){var d=wa(a);b.$$protocol=d.protocol;b.$$host=d.hostname;b.$$port=ea(d.port)||Vf[d.protocol]|| +null}function gd(a,b){var d="/"!==a.charAt(0);d&&(a="/"+a);var c=wa(a);b.$$path=decodeURIComponent(d&&"/"===c.pathname.charAt(0)?c.pathname.substring(1):c.pathname);b.$$search=xc(c.search);b.$$hash=decodeURIComponent(c.hash);b.$$path&&"/"!=b.$$path.charAt(0)&&(b.$$path="/"+b.$$path)}function pa(a,b){if(0===b.indexOf(a))return b.substr(a.length)}function Fa(a){var b=a.indexOf("#");return-1==b?a:a.substr(0,b)}function ib(a){return a.replace(/(#.+)|#$/,"$1")}function cc(a,b,d){this.$$html5=!0;d=d||""; +fd(a,this);this.$$parse=function(a){var d=pa(b,a);if(!E(d))throw Db("ipthprfx",a,b);gd(d,this);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Qb(this.$$search),d=this.$$hash?"#"+ob(this.$$hash):"";this.$$url=bc(this.$$path)+(a?"?"+a:"")+d;this.$$absUrl=b+this.$$url.substr(1)};this.$$parseLinkUrl=function(c,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;y(f=pa(a,c))?(g=f,g=y(f=pa(d,f))?b+(pa("/",f)||f):a+g):y(f=pa(b,c))?g=b+f:b==c+"/"&&(g=b);g&&this.$$parse(g); +return!!g}}function dc(a,b,d){fd(a,this);this.$$parse=function(c){var e=pa(a,c)||pa(b,c),f;q(e)||"#"!==e.charAt(0)?this.$$html5?f=e:(f="",q(e)&&(a=c,this.replace())):(f=pa(d,e),q(f)&&(f=e));gd(f,this);c=this.$$path;var e=a,g=/^\/[A-Z]:(\/.*)/;0===f.indexOf(e)&&(f=f.replace(e,""));g.exec(f)||(c=(f=g.exec(c))?f[1]:c);this.$$path=c;this.$$compose()};this.$$compose=function(){var b=Qb(this.$$search),e=this.$$hash?"#"+ob(this.$$hash):"";this.$$url=bc(this.$$path)+(b?"?"+b:"")+e;this.$$absUrl=a+(this.$$url? +d+this.$$url:"")};this.$$parseLinkUrl=function(b,d){return Fa(a)==Fa(b)?(this.$$parse(b),!0):!1}}function hd(a,b,d){this.$$html5=!0;dc.apply(this,arguments);this.$$parseLinkUrl=function(c,e){if(e&&"#"===e[0])return this.hash(e.slice(1)),!0;var f,g;a==Fa(c)?f=c:(g=pa(b,c))?f=a+d+g:b===c+"/"&&(f=b);f&&this.$$parse(f);return!!f};this.$$compose=function(){var b=Qb(this.$$search),e=this.$$hash?"#"+ob(this.$$hash):"";this.$$url=bc(this.$$path)+(b?"?"+b:"")+e;this.$$absUrl=a+d+this.$$url}}function Eb(a){return function(){return this[a]}} +function id(a,b){return function(d){if(q(d))return this[a];this[a]=b(d);this.$$compose();return this}}function hf(){var a="",b={enabled:!1,requireBase:!0,rewriteLinks:!0};this.hashPrefix=function(b){return y(b)?(a=b,this):a};this.html5Mode=function(a){return $a(a)?(b.enabled=a,this):H(a)?($a(a.enabled)&&(b.enabled=a.enabled),$a(a.requireBase)&&(b.requireBase=a.requireBase),$a(a.rewriteLinks)&&(b.rewriteLinks=a.rewriteLinks),this):b};this.$get=["$rootScope","$browser","$sniffer","$rootElement","$window", +function(d,c,e,f,g){function h(a,b,d){var e=l.url(),f=l.$$state;try{c.url(a,b,d),l.$$state=c.state()}catch(g){throw l.url(e),l.$$state=f,g;}}function k(a,b){d.$broadcast("$locationChangeSuccess",l.absUrl(),a,l.$$state,b)}var l,m;m=c.baseHref();var r=c.url(),t;if(b.enabled){if(!m&&b.requireBase)throw Db("nobase");t=r.substring(0,r.indexOf("/",r.indexOf("//")+2))+(m||"/");m=e.history?cc:hd}else t=Fa(r),m=dc;var A=t.substr(0,Fa(t).lastIndexOf("/")+1);l=new m(t,A,"#"+a);l.$$parseLinkUrl(r,r);l.$$state= +c.state();var v=/^\s*(javascript|mailto):/i;f.on("click",function(a){if(b.rewriteLinks&&!a.ctrlKey&&!a.metaKey&&!a.shiftKey&&2!=a.which&&2!=a.button){for(var e=B(a.target);"a"!==ta(e[0]);)if(e[0]===f[0]||!(e=e.parent())[0])return;var h=e.prop("href"),k=e.attr("href")||e.attr("xlink:href");H(h)&&"[object SVGAnimatedString]"===h.toString()&&(h=wa(h.animVal).href);v.test(h)||!h||e.attr("target")||a.isDefaultPrevented()||!l.$$parseLinkUrl(h,k)||(a.preventDefault(),l.absUrl()!=c.url()&&(d.$apply(),g.angular["ff-684208-preventDefault"]= +!0))}});ib(l.absUrl())!=ib(r)&&c.url(l.absUrl(),!0);var n=!0;c.onUrlChange(function(a,b){q(pa(A,a))?g.location.href=a:(d.$evalAsync(function(){var c=l.absUrl(),e=l.$$state,f;a=ib(a);l.$$parse(a);l.$$state=b;f=d.$broadcast("$locationChangeStart",a,c,b,e).defaultPrevented;l.absUrl()===a&&(f?(l.$$parse(c),l.$$state=e,h(c,!1,e)):(n=!1,k(c,e)))}),d.$$phase||d.$digest())});d.$watch(function(){var a=ib(c.url()),b=ib(l.absUrl()),f=c.state(),g=l.$$replace,m=a!==b||l.$$html5&&e.history&&f!==l.$$state;if(n|| +m)n=!1,d.$evalAsync(function(){var b=l.absUrl(),c=d.$broadcast("$locationChangeStart",b,a,l.$$state,f).defaultPrevented;l.absUrl()===b&&(c?(l.$$parse(a),l.$$state=f):(m&&h(b,g,f===l.$$state?null:l.$$state),k(a,f)))});l.$$replace=!1});return l}]}function jf(){var a=!0,b=this;this.debugEnabled=function(b){return y(b)?(a=b,this):a};this.$get=["$window",function(d){function c(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack:a.stack:a.sourceURL&& +(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=d.console||{},e=b[a]||b.log||x;a=!1;try{a=!!e.apply}catch(k){}return a?function(){var a=[];n(arguments,function(b){a.push(c(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){a&&c.apply(b,arguments)}}()}}]}function Va(a,b){if("__defineGetter__"===a||"__defineSetter__"===a||"__lookupGetter__"===a||"__lookupSetter__"=== +a||"__proto__"===a)throw ba("isecfld",b);return a}function jd(a,b){a+="";if(!E(a))throw ba("iseccst",b);return a}function xa(a,b){if(a){if(a.constructor===a)throw ba("isecfn",b);if(a.window===a)throw ba("isecwindow",b);if(a.children&&(a.nodeName||a.prop&&a.attr&&a.find))throw ba("isecdom",b);if(a===Object)throw ba("isecobj",b);}return a}function kd(a,b){if(a){if(a.constructor===a)throw ba("isecfn",b);if(a===Wf||a===Xf||a===Yf)throw ba("isecff",b);}}function ld(a,b){if(a&&(a===(0).constructor||a=== +(!1).constructor||a==="".constructor||a==={}.constructor||a===[].constructor||a===Function.constructor))throw ba("isecaf",b);}function Zf(a,b){return"undefined"!==typeof a?a:b}function md(a,b){return"undefined"===typeof a?b:"undefined"===typeof b?a:a+b}function W(a,b){var d,c;switch(a.type){case s.Program:d=!0;n(a.body,function(a){W(a.expression,b);d=d&&a.expression.constant});a.constant=d;break;case s.Literal:a.constant=!0;a.toWatch=[];break;case s.UnaryExpression:W(a.argument,b);a.constant=a.argument.constant; +a.toWatch=a.argument.toWatch;break;case s.BinaryExpression:W(a.left,b);W(a.right,b);a.constant=a.left.constant&&a.right.constant;a.toWatch=a.left.toWatch.concat(a.right.toWatch);break;case s.LogicalExpression:W(a.left,b);W(a.right,b);a.constant=a.left.constant&&a.right.constant;a.toWatch=a.constant?[]:[a];break;case s.ConditionalExpression:W(a.test,b);W(a.alternate,b);W(a.consequent,b);a.constant=a.test.constant&&a.alternate.constant&&a.consequent.constant;a.toWatch=a.constant?[]:[a];break;case s.Identifier:a.constant= +!1;a.toWatch=[a];break;case s.MemberExpression:W(a.object,b);a.computed&&W(a.property,b);a.constant=a.object.constant&&(!a.computed||a.property.constant);a.toWatch=[a];break;case s.CallExpression:d=a.filter?!b(a.callee.name).$stateful:!1;c=[];n(a.arguments,function(a){W(a,b);d=d&&a.constant;a.constant||c.push.apply(c,a.toWatch)});a.constant=d;a.toWatch=a.filter&&!b(a.callee.name).$stateful?c:[a];break;case s.AssignmentExpression:W(a.left,b);W(a.right,b);a.constant=a.left.constant&&a.right.constant; +a.toWatch=[a];break;case s.ArrayExpression:d=!0;c=[];n(a.elements,function(a){W(a,b);d=d&&a.constant;a.constant||c.push.apply(c,a.toWatch)});a.constant=d;a.toWatch=c;break;case s.ObjectExpression:d=!0;c=[];n(a.properties,function(a){W(a.value,b);d=d&&a.value.constant;a.value.constant||c.push.apply(c,a.value.toWatch)});a.constant=d;a.toWatch=c;break;case s.ThisExpression:a.constant=!1,a.toWatch=[]}}function nd(a){if(1==a.length){a=a[0].expression;var b=a.toWatch;return 1!==b.length?b:b[0]!==a?b:u}} +function od(a){return a.type===s.Identifier||a.type===s.MemberExpression}function pd(a){if(1===a.body.length&&od(a.body[0].expression))return{type:s.AssignmentExpression,left:a.body[0].expression,right:{type:s.NGValueParameter},operator:"="}}function qd(a){return 0===a.body.length||1===a.body.length&&(a.body[0].expression.type===s.Literal||a.body[0].expression.type===s.ArrayExpression||a.body[0].expression.type===s.ObjectExpression)}function rd(a,b){this.astBuilder=a;this.$filter=b}function sd(a, +b){this.astBuilder=a;this.$filter=b}function Fb(a){return"constructor"==a}function ec(a){return z(a.valueOf)?a.valueOf():$f.call(a)}function kf(){var a=$(),b=$();this.$get=["$filter",function(d){function c(a,b){return null==a||null==b?a===b:"object"===typeof a&&(a=ec(a),"object"===typeof a)?!1:a===b||a!==a&&b!==b}function e(a,b,d,e,f){var g=e.inputs,h;if(1===g.length){var k=c,g=g[0];return a.$watch(function(a){var b=g(a);c(b,k)||(h=e(a,u,u,[b]),k=b&&ec(b));return h},b,d,f)}for(var l=[],m=[],r=0,n= +g.length;r=this.promise.$$state.status&&d&&d.length&&a(function(){for(var a,e,f=0,g=d.length;fa)for(b in l++,f)qa.call(e,b)||(n--,delete f[b])}else f!==e&&(f=e,l++);return l}}c.$stateful=!0;var d=this,e,f,g,k=1n&&(v=4-n,q[v]||(q[v]=[]),q[v].push({msg:z(a.exp)?"fn: "+(a.exp.name||a.exp.toString()):a.exp,newVal:f,oldVal:h}));else if(a===c){r=!1;break a}}catch(y){g(y)}if(!(l=A.$$watchersCount&&A.$$childHead||A!==this&&A.$$nextSibling))for(;A!==this&&!(l=A.$$nextSibling);)A=A.$parent}while(A=l);if((r||u.length)&&!n--)throw w.$$phase=null,d("infdig", +b,q);}while(r||u.length);for(w.$$phase=null;L.length;)try{L.shift()()}catch(x){g(x)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;this===w&&k.$$applicationDestroyed();A(this,-this.$$watchersCount);for(var b in this.$$listenerCount)v(this,this.$$listenerCount[b],b);a&&a.$$childHead==this&&(a.$$childHead=this.$$nextSibling);a&&a.$$childTail==this&&(a.$$childTail=this.$$prevSibling);this.$$prevSibling&&(this.$$prevSibling.$$nextSibling= +this.$$nextSibling);this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling);this.$destroy=this.$digest=this.$apply=this.$evalAsync=this.$applyAsync=x;this.$on=this.$watch=this.$watchGroup=function(){return x};this.$$listeners={};this.$$nextSibling=null;m(this)}},$eval:function(a,b){return h(a)(this,b)},$evalAsync:function(a,b){w.$$phase||u.length||k.defer(function(){u.length&&w.$digest()});u.push({scope:this,expression:a,locals:b})},$$postDigest:function(a){L.push(a)},$apply:function(a){try{t("$apply"); +try{return this.$eval(a)}finally{w.$$phase=null}}catch(b){g(b)}finally{try{w.$digest()}catch(c){throw g(c),c;}}},$applyAsync:function(a){function b(){c.$eval(a)}var c=this;a&&aa.push(b);C()},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent);var e=this;return function(){var d=c.indexOf(b);-1!==d&&(c[d]=null,v(e,1,a))}},$emit:function(a,b){var c=[],d,e=this,f=!1,h= +{name:a,targetScope:e,stopPropagation:function(){f=!0},preventDefault:function(){h.defaultPrevented=!0},defaultPrevented:!1},k=cb([h],arguments,1),l,m;do{d=e.$$listeners[a]||c;h.currentScope=e;l=0;for(m=d.length;lHa)throw ya("iequirks");var c=ia(la);c.isEnabled=function(){return a};c.trustAs=d.trustAs;c.getTrusted=d.getTrusted;c.valueOf=d.valueOf;a||(c.trustAs=c.getTrusted=function(a,b){return b},c.valueOf=Ya);c.parseAs=function(a,d){var e=b(d);return e.literal&&e.constant?e:b(d,function(b){return c.getTrusted(a,b)})};var e=c.parseAs,f=c.getTrusted,g=c.trustAs;n(la,function(a, +b){var d=F(b);c[fb("parse_as_"+d)]=function(b){return e(a,b)};c[fb("get_trusted_"+d)]=function(b){return f(a,b)};c[fb("trust_as_"+d)]=function(b){return g(a,b)}});return c}]}function qf(){this.$get=["$window","$document",function(a,b){var d={},c=ea((/android (\d+)/.exec(F((a.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((a.navigator||{}).userAgent),f=b[0]||{},g,h=/^(Moz|webkit|ms)(?=[A-Z])/,k=f.body&&f.body.style,l=!1,m=!1;if(k){for(var r in k)if(l=h.exec(r)){g=l[0];g=g.substr(0,1).toUpperCase()+ +g.substr(1);break}g||(g="WebkitOpacity"in k&&"webkit");l=!!("transition"in k||g+"Transition"in k);m=!!("animation"in k||g+"Animation"in k);!c||l&&m||(l=E(k.webkitTransition),m=E(k.webkitAnimation))}return{history:!(!a.history||!a.history.pushState||4>c||e),hasEvent:function(a){if("input"===a&&11>=Ha)return!1;if(q(d[a])){var b=f.createElement("div");d[a]="on"+a in b}return d[a]},csp:Ba(),vendorPrefix:g,transitions:l,animations:m,android:c}}]}function sf(){this.$get=["$templateCache","$http","$q","$sce", +function(a,b,d,c){function e(f,g){e.totalPendingRequests++;E(f)&&a.get(f)||(f=c.getTrustedResourceUrl(f));var h=b.defaults&&b.defaults.transformResponse;I(h)?h=h.filter(function(a){return a!==$b}):h===$b&&(h=null);return b.get(f,{cache:a,transformResponse:h})["finally"](function(){e.totalPendingRequests--}).then(function(b){a.put(f,b.data);return b.data},function(a){if(!g)throw ha("tpload",f,a.status,a.statusText);return d.reject(a)})}e.totalPendingRequests=0;return e}]}function tf(){this.$get=["$rootScope", +"$browser","$location",function(a,b,d){return{findBindings:function(a,b,d){a=a.getElementsByClassName("ng-binding");var g=[];n(a,function(a){var c=fa.element(a).data("$binding");c&&n(c,function(c){d?(new RegExp("(^|\\s)"+ud(b)+"(\\s|\\||$)")).test(c)&&g.push(a):-1!=c.indexOf(b)&&g.push(a)})});return g},findModels:function(a,b,d){for(var g=["ng-","data-ng-","ng\\:"],h=0;ha;a=Math.abs(a);var g=Infinity===a;if(!g&&!isFinite(a))return"";var h=a+"",k="",l=!1,m=[];g&&(k="\u221e");if(!g&&-1!==h.indexOf("e")){var r=h.match(/([\d\.]+)e(-?)(\d+)/);r&&"-"==r[2]&&r[3]>e+1?a=0:(k=h,l=!0)}if(g||l)0a&&(k=a.toFixed(e),a=parseFloat(k),k=k.replace(ic,c));else{g=(h.split(ic)[1]||"").length; +q(e)&&(e=Math.min(Math.max(b.minFrac,g),b.maxFrac));a=+(Math.round(+(a.toString()+"e"+e)).toString()+"e"+-e);var g=(""+a).split(ic),h=g[0],g=g[1]||"",r=0,t=b.lgSize,n=b.gSize;if(h.length>=t+n)for(r=h.length-t,l=0;la&&(c="-",a=-a);for(a=""+a;a.length-d)e+=d;0===e&&-12==d&&(e=12);return Gb(e,b,c)}}function Hb(a,b){return function(d,c){var e=d["get"+a](),f=sb(b?"SHORT"+a:a);return c[f][e]}}function Dd(a){var b=(new Date(a,0,1)).getDay();return new Date(a,0,(4>=b?5:12)-b)}function Ed(a){return function(b){var d=Dd(b.getFullYear());b=+new Date(b.getFullYear(),b.getMonth(),b.getDate()+(4-b.getDay()))- ++d;b=1+Math.round(b/6048E5);return Gb(b,a)}}function jc(a,b){return 0>=a.getFullYear()?b.ERAS[0]:b.ERAS[1]}function zd(a){function b(a){var b;if(b=a.match(d)){a=new Date(0);var f=0,g=0,h=b[8]?a.setUTCFullYear:a.setFullYear,k=b[8]?a.setUTCHours:a.setHours;b[9]&&(f=ea(b[9]+b[10]),g=ea(b[9]+b[11]));h.call(a,ea(b[1]),ea(b[2])-1,ea(b[3]));f=ea(b[4]||0)-f;g=ea(b[5]||0)-g;h=ea(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));k.call(a,f,g,h,b)}return a}var d=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/; +return function(c,d,f){var g="",h=[],k,l;d=d||"mediumDate";d=a.DATETIME_FORMATS[d]||d;E(c)&&(c=hg.test(c)?ea(c):b(c));Q(c)&&(c=new Date(c));if(!da(c)||!isFinite(c.getTime()))return c;for(;d;)(l=ig.exec(d))?(h=cb(h,l,1),d=h.pop()):(h.push(d),d=null);var m=c.getTimezoneOffset();f&&(m=vc(f,c.getTimezoneOffset()),c=Pb(c,f,!0));n(h,function(b){k=jg[b];g+=k?k(c,a.DATETIME_FORMATS,m):b.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function cg(){return function(a,b){q(b)&&(b=2);return db(a,b)}}function dg(){return function(a, +b,d){b=Infinity===Math.abs(Number(b))?Number(b):ea(b);if(isNaN(b))return a;Q(a)&&(a=a.toString());if(!I(a)&&!E(a))return a;d=!d||isNaN(d)?0:ea(d);d=0>d?Math.max(0,a.length+d):d;return 0<=b?a.slice(d,d+b):0===d?a.slice(b,a.length):a.slice(Math.max(0,d+b),d)}}function Bd(a){function b(b,d){d=d?-1:1;return b.map(function(b){var c=1,h=Ya;if(z(b))h=b;else if(E(b)){if("+"==b.charAt(0)||"-"==b.charAt(0))c="-"==b.charAt(0)?-1:1,b=b.substring(1);if(""!==b&&(h=a(b),h.constant))var k=h(),h=function(a){return a[k]}}return{get:h, +descending:c*d}})}function d(a){switch(typeof a){case "number":case "boolean":case "string":return!0;default:return!1}}return function(a,e,f){if(!za(a))return a;I(e)||(e=[e]);0===e.length&&(e=["+"]);var g=b(e,f);g.push({get:function(){return{}},descending:f?-1:1});a=Array.prototype.map.call(a,function(a,b){return{value:a,predicateValues:g.map(function(c){var e=c.get(a);c=typeof e;if(null===e)c="string",e="null";else if("string"===c)e=e.toLowerCase();else if("object"===c)a:{if("function"===typeof e.valueOf&& +(e=e.valueOf(),d(e)))break a;if(qc(e)&&(e=e.toString(),d(e)))break a;e=b}return{value:e,type:c}})}});a.sort(function(a,b){for(var c=0,d=0,e=g.length;db||37<=b&&40>=b||m(a,this,this.value)});if(e.hasEvent("paste"))b.on("paste cut", +m)}b.on("change",k);c.$render=function(){var a=c.$isEmpty(c.$viewValue)?"":c.$viewValue;b.val()!==a&&b.val(a)}}function Kb(a,b){return function(d,c){var e,f;if(da(d))return d;if(E(d)){'"'==d.charAt(0)&&'"'==d.charAt(d.length-1)&&(d=d.substring(1,d.length-1));if(kg.test(d))return new Date(d);a.lastIndex=0;if(e=a.exec(d))return e.shift(),f=c?{yyyy:c.getFullYear(),MM:c.getMonth()+1,dd:c.getDate(),HH:c.getHours(),mm:c.getMinutes(),ss:c.getSeconds(),sss:c.getMilliseconds()/1E3}:{yyyy:1970,MM:1,dd:1,HH:0, +mm:0,ss:0,sss:0},n(e,function(a,c){c=s};g.$observe("min",function(a){s=n(a);h.$validate()})}if(y(g.max)||g.ngMax){var p;h.$validators.max=function(a){return!r(a)||q(p)||d(a)<=p};g.$observe("max",function(a){p=n(a);h.$validate()})}}}function Hd(a,b,d,c){(c.$$hasNativeValidators=H(b[0].validity))&&c.$parsers.push(function(a){var c=b.prop("validity")||{}; +return c.badInput&&!c.typeMismatch?u:a})}function Id(a,b,d,c,e){if(y(c)){a=a(c);if(!a.constant)throw lb("constexpr",d,c);return a(b)}return e}function lc(a,b){a="ngClass"+a;return["$animate",function(d){function c(a,b){var c=[],d=0;a:for(;d(?:<\/\1>|)$/,Tb=/<|&#?\w+;/, +Cf=/<([\w:-]+)/,Df=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,ka={option:[1,'"],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ka.optgroup=ka.option;ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead;ka.th=ka.td;var Kf=Node.prototype.contains||function(a){return!!(this.compareDocumentPosition(a)& +16)},Pa=N.prototype={ready:function(a){function b(){d||(d=!0,a())}var d=!1;"complete"===X.readyState?setTimeout(b):(this.on("DOMContentLoaded",b),N(S).on("load",b))},toString:function(){var a=[];n(this,function(b){a.push(""+b)});return"["+a.join(", ")+"]"},eq:function(a){return 0<=a?B(this[a]):B(this[this.length+a])},length:0,push:mg,sort:[].sort,splice:[].splice},Cb={};n("multiple selected checked disabled readOnly required open".split(" "),function(a){Cb[F(a)]=a});var Rc={};n("input select option textarea button form details".split(" "), +function(a){Rc[a]=!0});var Zc={ngMinlength:"minlength",ngMaxlength:"maxlength",ngMin:"min",ngMax:"max",ngPattern:"pattern"};n({data:Wb,removeData:vb,hasData:function(a){for(var b in gb[a.ng339])return!0;return!1}},function(a,b){N[b]=a});n({data:Wb,inheritedData:Bb,scope:function(a){return B.data(a,"$scope")||Bb(a.parentNode||a,["$isolateScope","$scope"])},isolateScope:function(a){return B.data(a,"$isolateScope")||B.data(a,"$isolateScopeNoTemplate")},controller:Oc,injector:function(a){return Bb(a, +"$injector")},removeAttr:function(a,b){a.removeAttribute(b)},hasClass:yb,css:function(a,b,d){b=fb(b);if(y(d))a.style[b]=d;else return a.style[b]},attr:function(a,b,d){var c=a.nodeType;if(c!==Na&&2!==c&&8!==c)if(c=F(b),Cb[c])if(y(d))d?(a[b]=!0,a.setAttribute(b,c)):(a[b]=!1,a.removeAttribute(c));else return a[b]||(a.attributes.getNamedItem(b)||x).specified?c:u;else if(y(d))a.setAttribute(b,d);else if(a.getAttribute)return a=a.getAttribute(b,2),null===a?u:a},prop:function(a,b,d){if(y(d))a[b]=d;else return a[b]}, +text:function(){function a(a,d){if(q(d)){var c=a.nodeType;return 1===c||c===Na?a.textContent:""}a.textContent=d}a.$dv="";return a}(),val:function(a,b){if(q(b)){if(a.multiple&&"select"===ta(a)){var d=[];n(a.options,function(a){a.selected&&d.push(a.value||a.text)});return 0===d.length?null:d}return a.value}a.value=b},html:function(a,b){if(q(b))return a.innerHTML;ub(a,!0);a.innerHTML=b},empty:Pc},function(a,b){N.prototype[b]=function(b,c){var e,f,g=this.length;if(a!==Pc&&q(2==a.length&&a!==yb&&a!==Oc? +b:c)){if(H(b)){for(e=0;e <= >= && || ! = |".split(" "),function(a){Lb[a]=!0});var sg={n:"\n",f:"\f",r:"\r", +t:"\t",v:"\v","'":"'",'"':'"'},fc=function(a){this.options=a};fc.prototype={constructor:fc,lex:function(a){this.text=a;this.index=0;for(this.tokens=[];this.index=a&&"string"===typeof a},isWhitespace:function(a){return" "===a||"\r"===a|| +"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,b,d){d=d||this.index;b=y(b)?"s "+b+"-"+this.index+" ["+this.text.substring(b,d)+"]":" "+d;throw ba("lexerr",a,b,this.text);},readNumber:function(){for(var a="",b=this.index;this.index","<=",">=");)a={type:s.BinaryExpression,operator:b.text,left:a,right:this.additive()};return a},additive:function(){for(var a=this.multiplicative(),b;b=this.expect("+","-");)a={type:s.BinaryExpression,operator:b.text,left:a,right:this.multiplicative()};return a},multiplicative:function(){for(var a=this.unary(),b;b=this.expect("*","/","%");)a={type:s.BinaryExpression,operator:b.text, +left:a,right:this.unary()};return a},unary:function(){var a;return(a=this.expect("+","-","!"))?{type:s.UnaryExpression,operator:a.text,prefix:!0,argument:this.unary()}:this.primary()},primary:function(){var a;this.expect("(")?(a=this.filterChain(),this.consume(")")):this.expect("[")?a=this.arrayDeclaration():this.expect("{")?a=this.object():this.constants.hasOwnProperty(this.peek().text)?a=bb(this.constants[this.consume().text]):this.peek().identifier?a=this.identifier():this.peek().constant?a=this.constant(): +this.throwError("not a primary expression",this.peek());for(var b;b=this.expect("(","[",".");)"("===b.text?(a={type:s.CallExpression,callee:a,arguments:this.parseArguments()},this.consume(")")):"["===b.text?(a={type:s.MemberExpression,object:a,property:this.expression(),computed:!0},this.consume("]")):"."===b.text?a={type:s.MemberExpression,object:a,property:this.identifier(),computed:!1}:this.throwError("IMPOSSIBLE");return a},filter:function(a){a=[a];for(var b={type:s.CallExpression,callee:this.identifier(), +arguments:a,filter:!0};this.expect(":");)a.push(this.expression());return b},parseArguments:function(){var a=[];if(")"!==this.peekToken().text){do a.push(this.expression());while(this.expect(","))}return a},identifier:function(){var a=this.consume();a.identifier||this.throwError("is not a valid identifier",a);return{type:s.Identifier,name:a.text}},constant:function(){return{type:s.Literal,value:this.consume().value}},arrayDeclaration:function(){var a=[];if("]"!==this.peekToken().text){do{if(this.peek("]"))break; +a.push(this.expression())}while(this.expect(","))}this.consume("]");return{type:s.ArrayExpression,elements:a}},object:function(){var a=[],b;if("}"!==this.peekToken().text){do{if(this.peek("}"))break;b={type:s.Property,kind:"init"};this.peek().constant?b.key=this.constant():this.peek().identifier?b.key=this.identifier():this.throwError("invalid key",this.peek());this.consume(":");b.value=this.expression();a.push(b)}while(this.expect(","))}this.consume("}");return{type:s.ObjectExpression,properties:a}}, +throwError:function(a,b){throw ba("syntax",b.text,a,b.index+1,this.text,this.text.substring(b.index));},consume:function(a){if(0===this.tokens.length)throw ba("ueoe",this.text);var b=this.expect(a);b||this.throwError("is unexpected, expecting ["+a+"]",this.peek());return b},peekToken:function(){if(0===this.tokens.length)throw ba("ueoe",this.text);return this.tokens[0]},peek:function(a,b,d,c){return this.peekAhead(0,a,b,d,c)},peekAhead:function(a,b,d,c,e){if(this.tokens.length>a){a=this.tokens[a]; +var f=a.text;if(f===b||f===d||f===c||f===e||!(b||d||c||e))return a}return!1},expect:function(a,b,d,c){return(a=this.peek(a,b,d,c))?(this.tokens.shift(),a):!1},constants:{"true":{type:s.Literal,value:!0},"false":{type:s.Literal,value:!1},"null":{type:s.Literal,value:null},undefined:{type:s.Literal,value:u},"this":{type:s.ThisExpression}}};rd.prototype={compile:function(a,b){var d=this,c=this.astBuilder.ast(a);this.state={nextId:0,filters:{},expensiveChecks:b,fn:{vars:[],body:[],own:{}},assign:{vars:[], +body:[],own:{}},inputs:[]};W(c,d.$filter);var e="",f;this.stage="assign";if(f=pd(c))this.state.computing="assign",e=this.nextId(),this.recurse(f,e),this.return_(e),e="fn.assign="+this.generateFunction("assign","s,v,l");f=nd(c.body);d.stage="inputs";n(f,function(a,b){var c="fn"+b;d.state[c]={vars:[],body:[],own:{}};d.state.computing=c;var e=d.nextId();d.recurse(a,e);d.return_(e);d.state.inputs.push(c);a.watchId=b});this.state.computing="fn";this.stage="main";this.recurse(c);e='"'+this.USE+" "+this.STRICT+ +'";\n'+this.filterPrefix()+"var fn="+this.generateFunction("fn","s,l,a,i")+e+this.watchFns()+"return fn;";e=(new Function("$filter","ensureSafeMemberName","ensureSafeObject","ensureSafeFunction","getStringValue","ensureSafeAssignContext","ifDefined","plus","text",e))(this.$filter,Va,xa,kd,jd,ld,Zf,md,a);this.state=this.stage=u;e.literal=qd(c);e.constant=c.constant;return e},USE:"use",STRICT:"strict",watchFns:function(){var a=[],b=this.state.inputs,d=this;n(b,function(b){a.push("var "+b+"="+d.generateFunction(b, +"s"))});b.length&&a.push("fn.inputs=["+b.join(",")+"];");return a.join("")},generateFunction:function(a,b){return"function("+b+"){"+this.varsPrefix(a)+this.body(a)+"};"},filterPrefix:function(){var a=[],b=this;n(this.state.filters,function(d,c){a.push(d+"=$filter("+b.escape(c)+")")});return a.length?"var "+a.join(",")+";":""},varsPrefix:function(a){return this.state[a].vars.length?"var "+this.state[a].vars.join(",")+";":""},body:function(a){return this.state[a].body.join("")},recurse:function(a,b, +d,c,e,f){var g,h,k=this,l,m;c=c||x;if(!f&&y(a.watchId))b=b||this.nextId(),this.if_("i",this.lazyAssign(b,this.computedMember("i",a.watchId)),this.lazyRecurse(a,b,d,c,e,!0));else switch(a.type){case s.Program:n(a.body,function(b,c){k.recurse(b.expression,u,u,function(a){h=a});c!==a.body.length-1?k.current().body.push(h,";"):k.return_(h)});break;case s.Literal:m=this.escape(a.value);this.assign(b,m);c(m);break;case s.UnaryExpression:this.recurse(a.argument,u,u,function(a){h=a});m=a.operator+"("+this.ifDefined(h, +0)+")";this.assign(b,m);c(m);break;case s.BinaryExpression:this.recurse(a.left,u,u,function(a){g=a});this.recurse(a.right,u,u,function(a){h=a});m="+"===a.operator?this.plus(g,h):"-"===a.operator?this.ifDefined(g,0)+a.operator+this.ifDefined(h,0):"("+g+")"+a.operator+"("+h+")";this.assign(b,m);c(m);break;case s.LogicalExpression:b=b||this.nextId();k.recurse(a.left,b);k.if_("&&"===a.operator?b:k.not(b),k.lazyRecurse(a.right,b));c(b);break;case s.ConditionalExpression:b=b||this.nextId();k.recurse(a.test, +b);k.if_(b,k.lazyRecurse(a.alternate,b),k.lazyRecurse(a.consequent,b));c(b);break;case s.Identifier:b=b||this.nextId();d&&(d.context="inputs"===k.stage?"s":this.assign(this.nextId(),this.getHasOwnProperty("l",a.name)+"?l:s"),d.computed=!1,d.name=a.name);Va(a.name);k.if_("inputs"===k.stage||k.not(k.getHasOwnProperty("l",a.name)),function(){k.if_("inputs"===k.stage||"s",function(){e&&1!==e&&k.if_(k.not(k.nonComputedMember("s",a.name)),k.lazyAssign(k.nonComputedMember("s",a.name),"{}"));k.assign(b,k.nonComputedMember("s", +a.name))})},b&&k.lazyAssign(b,k.nonComputedMember("l",a.name)));(k.state.expensiveChecks||Fb(a.name))&&k.addEnsureSafeObject(b);c(b);break;case s.MemberExpression:g=d&&(d.context=this.nextId())||this.nextId();b=b||this.nextId();k.recurse(a.object,g,u,function(){k.if_(k.notNull(g),function(){if(a.computed)h=k.nextId(),k.recurse(a.property,h),k.getStringValue(h),k.addEnsureSafeMemberName(h),e&&1!==e&&k.if_(k.not(k.computedMember(g,h)),k.lazyAssign(k.computedMember(g,h),"{}")),m=k.ensureSafeObject(k.computedMember(g, +h)),k.assign(b,m),d&&(d.computed=!0,d.name=h);else{Va(a.property.name);e&&1!==e&&k.if_(k.not(k.nonComputedMember(g,a.property.name)),k.lazyAssign(k.nonComputedMember(g,a.property.name),"{}"));m=k.nonComputedMember(g,a.property.name);if(k.state.expensiveChecks||Fb(a.property.name))m=k.ensureSafeObject(m);k.assign(b,m);d&&(d.computed=!1,d.name=a.property.name)}},function(){k.assign(b,"undefined")});c(b)},!!e);break;case s.CallExpression:b=b||this.nextId();a.filter?(h=k.filter(a.callee.name),l=[],n(a.arguments, +function(a){var b=k.nextId();k.recurse(a,b);l.push(b)}),m=h+"("+l.join(",")+")",k.assign(b,m),c(b)):(h=k.nextId(),g={},l=[],k.recurse(a.callee,h,g,function(){k.if_(k.notNull(h),function(){k.addEnsureSafeFunction(h);n(a.arguments,function(a){k.recurse(a,k.nextId(),u,function(a){l.push(k.ensureSafeObject(a))})});g.name?(k.state.expensiveChecks||k.addEnsureSafeObject(g.context),m=k.member(g.context,g.name,g.computed)+"("+l.join(",")+")"):m=h+"("+l.join(",")+")";m=k.ensureSafeObject(m);k.assign(b,m)}, +function(){k.assign(b,"undefined")});c(b)}));break;case s.AssignmentExpression:h=this.nextId();g={};if(!od(a.left))throw ba("lval");this.recurse(a.left,u,g,function(){k.if_(k.notNull(g.context),function(){k.recurse(a.right,h);k.addEnsureSafeObject(k.member(g.context,g.name,g.computed));k.addEnsureSafeAssignContext(g.context);m=k.member(g.context,g.name,g.computed)+a.operator+h;k.assign(b,m);c(b||m)})},1);break;case s.ArrayExpression:l=[];n(a.elements,function(a){k.recurse(a,k.nextId(),u,function(a){l.push(a)})}); +m="["+l.join(",")+"]";this.assign(b,m);c(m);break;case s.ObjectExpression:l=[];n(a.properties,function(a){k.recurse(a.value,k.nextId(),u,function(b){l.push(k.escape(a.key.type===s.Identifier?a.key.name:""+a.key.value)+":"+b)})});m="{"+l.join(",")+"}";this.assign(b,m);c(m);break;case s.ThisExpression:this.assign(b,"s");c("s");break;case s.NGValueParameter:this.assign(b,"v"),c("v")}},getHasOwnProperty:function(a,b){var d=a+"."+b,c=this.current().own;c.hasOwnProperty(d)||(c[d]=this.nextId(!1,a+"&&("+ +this.escape(b)+" in "+a+")"));return c[d]},assign:function(a,b){if(a)return this.current().body.push(a,"=",b,";"),a},filter:function(a){this.state.filters.hasOwnProperty(a)||(this.state.filters[a]=this.nextId(!0));return this.state.filters[a]},ifDefined:function(a,b){return"ifDefined("+a+","+this.escape(b)+")"},plus:function(a,b){return"plus("+a+","+b+")"},return_:function(a){this.current().body.push("return ",a,";")},if_:function(a,b,d){if(!0===a)b();else{var c=this.current().body;c.push("if(",a, +"){");b();c.push("}");d&&(c.push("else{"),d(),c.push("}"))}},not:function(a){return"!("+a+")"},notNull:function(a){return a+"!=null"},nonComputedMember:function(a,b){return a+"."+b},computedMember:function(a,b){return a+"["+b+"]"},member:function(a,b,d){return d?this.computedMember(a,b):this.nonComputedMember(a,b)},addEnsureSafeObject:function(a){this.current().body.push(this.ensureSafeObject(a),";")},addEnsureSafeMemberName:function(a){this.current().body.push(this.ensureSafeMemberName(a),";")}, +addEnsureSafeFunction:function(a){this.current().body.push(this.ensureSafeFunction(a),";")},addEnsureSafeAssignContext:function(a){this.current().body.push(this.ensureSafeAssignContext(a),";")},ensureSafeObject:function(a){return"ensureSafeObject("+a+",text)"},ensureSafeMemberName:function(a){return"ensureSafeMemberName("+a+",text)"},ensureSafeFunction:function(a){return"ensureSafeFunction("+a+",text)"},getStringValue:function(a){this.assign(a,"getStringValue("+a+",text)")},ensureSafeAssignContext:function(a){return"ensureSafeAssignContext("+ +a+",text)"},lazyRecurse:function(a,b,d,c,e,f){var g=this;return function(){g.recurse(a,b,d,c,e,f)}},lazyAssign:function(a,b){var d=this;return function(){d.assign(a,b)}},stringEscapeRegex:/[^ a-zA-Z0-9]/g,stringEscapeFn:function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)},escape:function(a){if(E(a))return"'"+a.replace(this.stringEscapeRegex,this.stringEscapeFn)+"'";if(Q(a))return a.toString();if(!0===a)return"true";if(!1===a)return"false";if(null===a)return"null";if("undefined"=== +typeof a)return"undefined";throw ba("esc");},nextId:function(a,b){var d="v"+this.state.nextId++;a||this.current().vars.push(d+(b?"="+b:""));return d},current:function(){return this.state[this.state.computing]}};sd.prototype={compile:function(a,b){var d=this,c=this.astBuilder.ast(a);this.expression=a;this.expensiveChecks=b;W(c,d.$filter);var e,f;if(e=pd(c))f=this.recurse(e);e=nd(c.body);var g;e&&(g=[],n(e,function(a,b){var c=d.recurse(a);a.input=c;g.push(c);a.watchId=b}));var h=[];n(c.body,function(a){h.push(d.recurse(a.expression))}); +e=0===c.body.length?function(){}:1===c.body.length?h[0]:function(a,b){var c;n(h,function(d){c=d(a,b)});return c};f&&(e.assign=function(a,b,c){return f(a,c,b)});g&&(e.inputs=g);e.literal=qd(c);e.constant=c.constant;return e},recurse:function(a,b,d){var c,e,f=this,g;if(a.input)return this.inputs(a.input,a.watchId);switch(a.type){case s.Literal:return this.value(a.value,b);case s.UnaryExpression:return e=this.recurse(a.argument),this["unary"+a.operator](e,b);case s.BinaryExpression:return c=this.recurse(a.left), +e=this.recurse(a.right),this["binary"+a.operator](c,e,b);case s.LogicalExpression:return c=this.recurse(a.left),e=this.recurse(a.right),this["binary"+a.operator](c,e,b);case s.ConditionalExpression:return this["ternary?:"](this.recurse(a.test),this.recurse(a.alternate),this.recurse(a.consequent),b);case s.Identifier:return Va(a.name,f.expression),f.identifier(a.name,f.expensiveChecks||Fb(a.name),b,d,f.expression);case s.MemberExpression:return c=this.recurse(a.object,!1,!!d),a.computed||(Va(a.property.name, +f.expression),e=a.property.name),a.computed&&(e=this.recurse(a.property)),a.computed?this.computedMember(c,e,b,d,f.expression):this.nonComputedMember(c,e,f.expensiveChecks,b,d,f.expression);case s.CallExpression:return g=[],n(a.arguments,function(a){g.push(f.recurse(a))}),a.filter&&(e=this.$filter(a.callee.name)),a.filter||(e=this.recurse(a.callee,!0)),a.filter?function(a,c,d,f){for(var r=[],n=0;n":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)>b(c,e,f,g);return d?{value:c}:c}},"binary<=":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)<=b(c,e,f,g);return d?{value:c}:c}},"binary>=":function(a,b,d){return function(c, +e,f,g){c=a(c,e,f,g)>=b(c,e,f,g);return d?{value:c}:c}},"binary&&":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)&&b(c,e,f,g);return d?{value:c}:c}},"binary||":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)||b(c,e,f,g);return d?{value:c}:c}},"ternary?:":function(a,b,d,c){return function(e,f,g,h){e=a(e,f,g,h)?b(e,f,g,h):d(e,f,g,h);return c?{value:e}:e}},value:function(a,b){return function(){return b?{context:u,name:u,value:a}:a}},identifier:function(a,b,d,c,e){return function(f,g,h,k){f= +g&&a in g?g:f;c&&1!==c&&f&&!f[a]&&(f[a]={});g=f?f[a]:u;b&&xa(g,e);return d?{context:f,name:a,value:g}:g}},computedMember:function(a,b,d,c,e){return function(f,g,h,k){var l=a(f,g,h,k),m,n;null!=l&&(m=b(f,g,h,k),m=jd(m),Va(m,e),c&&1!==c&&l&&!l[m]&&(l[m]={}),n=l[m],xa(n,e));return d?{context:l,name:m,value:n}:n}},nonComputedMember:function(a,b,d,c,e,f){return function(g,h,k,l){g=a(g,h,k,l);e&&1!==e&&g&&!g[b]&&(g[b]={});h=null!=g?g[b]:u;(d||Fb(b))&&xa(h,f);return c?{context:g,name:b,value:h}:h}},inputs:function(a, +b){return function(d,c,e,f){return f?f[b]:a(d,c,e)}}};var gc=function(a,b,d){this.lexer=a;this.$filter=b;this.options=d;this.ast=new s(this.lexer);this.astCompiler=d.csp?new sd(this.ast,b):new rd(this.ast,b)};gc.prototype={constructor:gc,parse:function(a){return this.astCompiler.compile(a,this.options.expensiveChecks)}};$();$();var $f=Object.prototype.valueOf,ya=G("$sce"),la={HTML:"html",CSS:"css",URL:"url",RESOURCE_URL:"resourceUrl",JS:"js"},ha=G("$compile"),Y=X.createElement("a"),wd=wa(S.location.href); +xd.$inject=["$document"];Jc.$inject=["$provide"];yd.$inject=["$locale"];Ad.$inject=["$locale"];var ic=".",jg={yyyy:ca("FullYear",4),yy:ca("FullYear",2,0,!0),y:ca("FullYear",1),MMMM:Hb("Month"),MMM:Hb("Month",!0),MM:ca("Month",2,1),M:ca("Month",1,1),dd:ca("Date",2),d:ca("Date",1),HH:ca("Hours",2),H:ca("Hours",1),hh:ca("Hours",2,-12),h:ca("Hours",1,-12),mm:ca("Minutes",2),m:ca("Minutes",1),ss:ca("Seconds",2),s:ca("Seconds",1),sss:ca("Milliseconds",3),EEEE:Hb("Day"),EEE:Hb("Day",!0),a:function(a,b){return 12> +a.getHours()?b.AMPMS[0]:b.AMPMS[1]},Z:function(a,b,d){a=-1*d;return a=(0<=a?"+":"")+(Gb(Math[0=a.getFullYear()?b.ERANAMES[0]:b.ERANAMES[1]}},ig=/((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,hg=/^\-?\d+$/;zd.$inject=["$locale"];var eg=na(F),fg=na(sb);Bd.$inject=["$parse"];var he=na({restrict:"E",compile:function(a,b){if(!b.href&&!b.xlinkHref)return function(a, +b){if("a"===b[0].nodeName.toLowerCase()){var e="[object SVGAnimatedString]"===sa.call(b.prop("href"))?"xlink:href":"href";b.on("click",function(a){b.attr(e)||a.preventDefault()})}}}}),tb={};n(Cb,function(a,b){function d(a,d,e){a.$watch(e[c],function(a){e.$set(b,!!a)})}if("multiple"!=a){var c=va("ng-"+b),e=d;"checked"===a&&(e=function(a,b,e){e.ngModel!==e[c]&&d(a,b,e)});tb[c]=function(){return{restrict:"A",priority:100,link:e}}}});n(Zc,function(a,b){tb[b]=function(){return{priority:100,link:function(a, +c,e){if("ngPattern"===b&&"/"==e.ngPattern.charAt(0)&&(c=e.ngPattern.match(lg))){e.$set("ngPattern",new RegExp(c[1],c[2]));return}a.$watch(e[b],function(a){e.$set(b,a)})}}}});n(["src","srcset","href"],function(a){var b=va("ng-"+a);tb[b]=function(){return{priority:99,link:function(d,c,e){var f=a,g=a;"href"===a&&"[object SVGAnimatedString]"===sa.call(c.prop("href"))&&(g="xlinkHref",e.$attr[g]="xlink:href",f=null);e.$observe(b,function(b){b?(e.$set(g,b),Ha&&f&&c.prop(f,e[g])):"href"===a&&e.$set(g,null)})}}}}); +var Ib={$addControl:x,$$renameControl:function(a,b){a.$name=b},$removeControl:x,$setValidity:x,$setDirty:x,$setPristine:x,$setSubmitted:x};Fd.$inject=["$element","$attrs","$scope","$animate","$interpolate"];var Nd=function(a){return["$timeout","$parse",function(b,d){function c(a){return""===a?d('this[""]').assign:d(a).assign||x}return{name:"form",restrict:a?"EAC":"E",require:["form","^^?form"],controller:Fd,compile:function(d,f){d.addClass(Wa).addClass(mb);var g=f.name?"name":a&&f.ngForm?"ngForm": +!1;return{pre:function(a,d,e,f){var n=f[0];if(!("action"in e)){var q=function(b){a.$apply(function(){n.$commitViewValue();n.$setSubmitted()});b.preventDefault()};d[0].addEventListener("submit",q,!1);d.on("$destroy",function(){b(function(){d[0].removeEventListener("submit",q,!1)},0,!1)})}(f[1]||n.$$parentForm).$addControl(n);var s=g?c(n.$name):x;g&&(s(a,n),e.$observe(g,function(b){n.$name!==b&&(s(a,u),n.$$parentForm.$$renameControl(n,b),s=c(n.$name),s(a,n))}));d.on("$destroy",function(){n.$$parentForm.$removeControl(n); +s(a,u);M(n,Ib)})}}}}}]},ie=Nd(),ve=Nd(!0),kg=/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/,tg=/^[A-Za-z][A-Za-z\d.+-]*:\/*(?:\w+(?::\w+)?@)?[^\s/]+(?::\d+)?(?:\/[\w#!:.?+=&%@\-/]*)?$/,ug=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,vg=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/,Od=/^(\d{4})-(\d{2})-(\d{2})$/,Pd=/^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/,mc=/^(\d{4})-W(\d\d)$/,Qd=/^(\d{4})-(\d\d)$/, +Rd=/^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/,Sd={text:function(a,b,d,c,e,f){jb(a,b,d,c,e,f);kc(c)},date:kb("date",Od,Kb(Od,["yyyy","MM","dd"]),"yyyy-MM-dd"),"datetime-local":kb("datetimelocal",Pd,Kb(Pd,"yyyy MM dd HH mm ss sss".split(" ")),"yyyy-MM-ddTHH:mm:ss.sss"),time:kb("time",Rd,Kb(Rd,["HH","mm","ss","sss"]),"HH:mm:ss.sss"),week:kb("week",mc,function(a,b){if(da(a))return a;if(E(a)){mc.lastIndex=0;var d=mc.exec(a);if(d){var c=+d[1],e=+d[2],f=d=0,g=0,h=0,k=Dd(c),e=7*(e-1);b&&(d=b.getHours(),f= +b.getMinutes(),g=b.getSeconds(),h=b.getMilliseconds());return new Date(c,0,k.getDate()+e,d,f,g,h)}}return NaN},"yyyy-Www"),month:kb("month",Qd,Kb(Qd,["yyyy","MM"]),"yyyy-MM"),number:function(a,b,d,c,e,f){Hd(a,b,d,c);jb(a,b,d,c,e,f);c.$$parserName="number";c.$parsers.push(function(a){return c.$isEmpty(a)?null:vg.test(a)?parseFloat(a):u});c.$formatters.push(function(a){if(!c.$isEmpty(a)){if(!Q(a))throw lb("numfmt",a);a=a.toString()}return a});if(y(d.min)||d.ngMin){var g;c.$validators.min=function(a){return c.$isEmpty(a)|| +q(g)||a>=g};d.$observe("min",function(a){y(a)&&!Q(a)&&(a=parseFloat(a,10));g=Q(a)&&!isNaN(a)?a:u;c.$validate()})}if(y(d.max)||d.ngMax){var h;c.$validators.max=function(a){return c.$isEmpty(a)||q(h)||a<=h};d.$observe("max",function(a){y(a)&&!Q(a)&&(a=parseFloat(a,10));h=Q(a)&&!isNaN(a)?a:u;c.$validate()})}},url:function(a,b,d,c,e,f){jb(a,b,d,c,e,f);kc(c);c.$$parserName="url";c.$validators.url=function(a,b){var d=a||b;return c.$isEmpty(d)||tg.test(d)}},email:function(a,b,d,c,e,f){jb(a,b,d,c,e,f);kc(c); +c.$$parserName="email";c.$validators.email=function(a,b){var d=a||b;return c.$isEmpty(d)||ug.test(d)}},radio:function(a,b,d,c){q(d.name)&&b.attr("name",++nb);b.on("click",function(a){b[0].checked&&c.$setViewValue(d.value,a&&a.type)});c.$render=function(){b[0].checked=d.value==c.$viewValue};d.$observe("value",c.$render)},checkbox:function(a,b,d,c,e,f,g,h){var k=Id(h,a,"ngTrueValue",d.ngTrueValue,!0),l=Id(h,a,"ngFalseValue",d.ngFalseValue,!1);b.on("click",function(a){c.$setViewValue(b[0].checked,a&& +a.type)});c.$render=function(){b[0].checked=c.$viewValue};c.$isEmpty=function(a){return!1===a};c.$formatters.push(function(a){return ma(a,k)});c.$parsers.push(function(a){return a?k:l})},hidden:x,button:x,submit:x,reset:x,file:x},Dc=["$browser","$sniffer","$filter","$parse",function(a,b,d,c){return{restrict:"E",require:["?ngModel"],link:{pre:function(e,f,g,h){h[0]&&(Sd[F(g.type)]||Sd.text)(e,f,g,h[0],b,a,d,c)}}}}],wg=/^(true|false|\d+)$/,Ne=function(){return{restrict:"A",priority:100,compile:function(a, +b){return wg.test(b.ngValue)?function(a,b,e){e.$set("value",a.$eval(e.ngValue))}:function(a,b,e){a.$watch(e.ngValue,function(a){e.$set("value",a)})}}}},ne=["$compile",function(a){return{restrict:"AC",compile:function(b){a.$$addBindingClass(b);return function(b,c,e){a.$$addBindingInfo(c,e.ngBind);c=c[0];b.$watch(e.ngBind,function(a){c.textContent=q(a)?"":a})}}}}],pe=["$interpolate","$compile",function(a,b){return{compile:function(d){b.$$addBindingClass(d);return function(c,d,f){c=a(d.attr(f.$attr.ngBindTemplate)); +b.$$addBindingInfo(d,c.expressions);d=d[0];f.$observe("ngBindTemplate",function(a){d.textContent=q(a)?"":a})}}}}],oe=["$sce","$parse","$compile",function(a,b,d){return{restrict:"A",compile:function(c,e){var f=b(e.ngBindHtml),g=b(e.ngBindHtml,function(a){return(a||"").toString()});d.$$addBindingClass(c);return function(b,c,e){d.$$addBindingInfo(c,e.ngBindHtml);b.$watch(g,function(){c.html(a.getTrustedHtml(f(b))||"")})}}}}],Me=na({restrict:"A",require:"ngModel",link:function(a,b,d,c){c.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}), +qe=lc("",!0),se=lc("Odd",0),re=lc("Even",1),te=La({compile:function(a,b){b.$set("ngCloak",u);a.removeClass("ng-cloak")}}),ue=[function(){return{restrict:"A",scope:!0,controller:"@",priority:500}}],Ic={},xg={blur:!0,focus:!0};n("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var b=va("ng-"+a);Ic[b]=["$parse","$rootScope",function(d,c){return{restrict:"A",compile:function(e,f){var g= +d(f[b],null,!0);return function(b,d){d.on(a,function(d){var e=function(){g(b,{$event:d})};xg[a]&&c.$$phase?b.$evalAsync(e):b.$apply(e)})}}}}]});var xe=["$animate",function(a){return{multiElement:!0,transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(b,d,c,e,f){var g,h,k;b.$watch(c.ngIf,function(b){b?h||f(function(b,e){h=e;b[b.length++]=X.createComment(" end ngIf: "+c.ngIf+" ");g={clone:b};a.enter(b,d.parent(),d)}):(k&&(k.remove(),k=null),h&&(h.$destroy(),h=null),g&&(k= +rb(g.clone),a.leave(k).then(function(){k=null}),g=null))})}}}],ye=["$templateRequest","$anchorScroll","$animate",function(a,b,d){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:fa.noop,compile:function(c,e){var f=e.ngInclude||e.src,g=e.onload||"",h=e.autoscroll;return function(c,e,m,n,q){var s=0,v,u,p,C=function(){u&&(u.remove(),u=null);v&&(v.$destroy(),v=null);p&&(d.leave(p).then(function(){u=null}),u=p,p=null)};c.$watch(f,function(f){var m=function(){!y(h)||h&&!c.$eval(h)|| +b()},u=++s;f?(a(f,!0).then(function(a){if(u===s){var b=c.$new();n.template=a;a=q(b,function(a){C();d.enter(a,null,e).then(m)});v=b;p=a;v.$emit("$includeContentLoaded",f);c.$eval(g)}},function(){u===s&&(C(),c.$emit("$includeContentError",f))}),c.$emit("$includeContentRequested",f)):(C(),n.template=null)})}}}}],Pe=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(b,d,c,e){/SVG/.test(d[0].toString())?(d.empty(),a(Lc(e.template,X).childNodes)(b,function(a){d.append(a)}, +{futureParentElement:d})):(d.html(e.template),a(d.contents())(b))}}}],ze=La({priority:450,compile:function(){return{pre:function(a,b,d){a.$eval(d.ngInit)}}}}),Le=function(){return{restrict:"A",priority:100,require:"ngModel",link:function(a,b,d,c){var e=b.attr(d.$attr.ngList)||", ",f="false"!==d.ngTrim,g=f?U(e):e;c.$parsers.push(function(a){if(!q(a)){var b=[];a&&n(a.split(g),function(a){a&&b.push(f?U(a):a)});return b}});c.$formatters.push(function(a){return I(a)?a.join(e):u});c.$isEmpty=function(a){return!a|| +!a.length}}}},mb="ng-valid",Jd="ng-invalid",Wa="ng-pristine",Jb="ng-dirty",Ld="ng-pending",lb=G("ngModel"),yg=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate","$timeout","$rootScope","$q","$interpolate",function(a,b,d,c,e,f,g,h,k,l){this.$modelValue=this.$viewValue=Number.NaN;this.$$rawModelValue=u;this.$validators={};this.$asyncValidators={};this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$untouched=!0;this.$touched=!1;this.$pristine=!0;this.$dirty=!1; +this.$valid=!0;this.$invalid=!1;this.$error={};this.$$success={};this.$pending=u;this.$name=l(d.name||"",!1)(a);this.$$parentForm=Ib;var m=e(d.ngModel),r=m.assign,t=m,s=r,v=null,B,p=this;this.$$setOptions=function(a){if((p.$options=a)&&a.getterSetter){var b=e(d.ngModel+"()"),f=e(d.ngModel+"($$$p)");t=function(a){var c=m(a);z(c)&&(c=b(a));return c};s=function(a,b){z(m(a))?f(a,{$$$p:p.$modelValue}):r(a,p.$modelValue)}}else if(!m.assign)throw lb("nonassign",d.ngModel,ua(c));};this.$render=x;this.$isEmpty= +function(a){return q(a)||""===a||null===a||a!==a};var C=0;Gd({ctrl:this,$element:c,set:function(a,b){a[b]=!0},unset:function(a,b){delete a[b]},$animate:f});this.$setPristine=function(){p.$dirty=!1;p.$pristine=!0;f.removeClass(c,Jb);f.addClass(c,Wa)};this.$setDirty=function(){p.$dirty=!0;p.$pristine=!1;f.removeClass(c,Wa);f.addClass(c,Jb);p.$$parentForm.$setDirty()};this.$setUntouched=function(){p.$touched=!1;p.$untouched=!0;f.setClass(c,"ng-untouched","ng-touched")};this.$setTouched=function(){p.$touched= +!0;p.$untouched=!1;f.setClass(c,"ng-touched","ng-untouched")};this.$rollbackViewValue=function(){g.cancel(v);p.$viewValue=p.$$lastCommittedViewValue;p.$render()};this.$validate=function(){if(!Q(p.$modelValue)||!isNaN(p.$modelValue)){var a=p.$$rawModelValue,b=p.$valid,c=p.$modelValue,d=p.$options&&p.$options.allowInvalid;p.$$runValidators(a,p.$$lastCommittedViewValue,function(e){d||b===e||(p.$modelValue=e?a:u,p.$modelValue!==c&&p.$$writeModelToScope())})}};this.$$runValidators=function(a,b,c){function d(){var c= +!0;n(p.$validators,function(d,e){var g=d(a,b);c=c&&g;f(e,g)});return c?!0:(n(p.$asyncValidators,function(a,b){f(b,null)}),!1)}function e(){var c=[],d=!0;n(p.$asyncValidators,function(e,g){var h=e(a,b);if(!h||!z(h.then))throw lb("$asyncValidators",h);f(g,u);c.push(h.then(function(){f(g,!0)},function(a){d=!1;f(g,!1)}))});c.length?k.all(c).then(function(){g(d)},x):g(!0)}function f(a,b){h===C&&p.$setValidity(a,b)}function g(a){h===C&&c(a)}C++;var h=C;(function(){var a=p.$$parserName||"parse";if(q(B))f(a, +null);else return B||(n(p.$validators,function(a,b){f(b,null)}),n(p.$asyncValidators,function(a,b){f(b,null)})),f(a,B),B;return!0})()?d()?e():g(!1):g(!1)};this.$commitViewValue=function(){var a=p.$viewValue;g.cancel(v);if(p.$$lastCommittedViewValue!==a||""===a&&p.$$hasNativeValidators)p.$$lastCommittedViewValue=a,p.$pristine&&this.$setDirty(),this.$$parseAndValidate()};this.$$parseAndValidate=function(){var b=p.$$lastCommittedViewValue;if(B=q(b)?u:!0)for(var c=0;ce||c.$isEmpty(b)||b.length<=e}}}}},Gc=function(){return{restrict:"A",require:"?ngModel",link:function(a,b,d,c){if(c){var e=0;d.$observe("minlength",function(a){e=ea(a)||0;c.$validate()});c.$validators.minlength=function(a,b){return c.$isEmpty(b)||b.length>=e}}}}};S.angular.bootstrap? +console.log("WARNING: Tried to load angular more than once."):(ce(),ee(fa),fa.module("ngLocale",[],["$provide",function(a){function b(a){a+="";var b=a.indexOf(".");return-1==b?0:a.length-b-1}a.value("$locale",{DATETIME_FORMATS:{AMPMS:["AM","PM"],DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),ERANAMES:["Before Christ","Anno Domini"],ERAS:["BC","AD"],FIRSTDAYOFWEEK:6,MONTH:"January February March April May June July August September October November December".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "), +SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),WEEKENDRANGE:[5,6],fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",medium:"MMM d, y h:mm:ss a",mediumDate:"MMM d, y",mediumTime:"h:mm:ss a","short":"M/d/yy h:mm a",shortDate:"M/d/yy",shortTime:"h:mm a"},NUMBER_FORMATS:{CURRENCY_SYM:"$",DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{gSize:3,lgSize:3,maxFrac:3,minFrac:0,minInt:1,negPre:"-",negSuf:"",posPre:"",posSuf:""},{gSize:3,lgSize:3,maxFrac:2,minFrac:2,minInt:1,negPre:"-\u00a4", +negSuf:"",posPre:"\u00a4",posSuf:""}]},id:"en-us",pluralCat:function(a,c){var e=a|0,f=c;u===f&&(f=Math.min(b(a),3));Math.pow(10,f);return 1==e&&0==f?"one":"other"}})}]),B(X).ready(function(){Zd(X,yc)}))})(window,document);!window.angular.$$csp().noInlineStyle&&window.angular.element(document.head).prepend(''); +//# sourceMappingURL=angular.min.js.map diff --git a/admin/static/js/app.js b/admin/static/js/app.js new file mode 100644 index 00000000..5853e29b --- /dev/null +++ b/admin/static/js/app.js @@ -0,0 +1,33 @@ +angular.module("FICApp", ["ngRoute", "ngResource"]) + .config(function($routeProvider, $locationProvider) { + $routeProvider + .when("/teams", { + controller: "TeamsListController", + templateUrl: "views/team-list.html" + }) + .when("/teams/new", { + controller: "TeamNewController", + templateUrl: "views/team-new.html" + }); + $locationProvider.html5Mode(true); + }) + .run(function($rootScope) { + $rootScope.message = "Hello Angular!"; + }); + +angular.module("FICApp") + .factory("Team", function($resource) { + return $resource("/api/teams/:id", { id: '@id' }, { + 'update': { method: "PATCH" } + }) + }); + +angular.module("FICApp") + .controller("TeamsListController", function($scope, Team, $location) { + $scope.teams = Team.query(); + $scope.fields = ["id", "name"]; + + $scope.show = function(id) { + $location.url("/teams/" + id); + }; + }); diff --git a/admin/static/js/bootstrap.min.js b/admin/static/js/bootstrap.min.js new file mode 100644 index 00000000..e79c0651 --- /dev/null +++ b/admin/static/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.6 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.6",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.6",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/admin/static/js/jquery.min.js b/admin/static/js/jquery.min.js new file mode 100644 index 00000000..6c60672f --- /dev/null +++ b/admin/static/js/jquery.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.12.0 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; +return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="
    a",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:l.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?""!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.rnamespace||a.rnamespace.test(g.namespace))&&(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n(" From 5e74b3f7ce98b217dd487aa8a056b80cdc4562c5 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 13 Oct 2016 19:52:13 +0200 Subject: [PATCH 0493/2686] [admin] Can retrieves tries rate --- admin/api_team.go | 4 ++++ libfic/team.go | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/admin/api_team.go b/admin/api_team.go index da32dee4..3c9f449f 100644 --- a/admin/api_team.go +++ b/admin/api_team.go @@ -85,6 +85,8 @@ func listTeam(args []string, body []byte) (interface{}, error) { return fic.MyJSONTeam(team, true) } else if args[1] == "wait.json" { return fic.MyJSONTeam(team, false) + } else if args[1] == "tries" { + return fic.GetTries(team, nil) } else if team != nil && args[1] == "members" { return team.GetMembers() } else if args[1] == "certificate" && team != nil { @@ -95,6 +97,8 @@ func listTeam(args []string, body []byte) (interface{}, error) { } else if len(args) == 1 { if args[0] == "teams.json" { return fic.ExportTeams() + } else if args[0] == "tries" { + return fic.GetTries(nil, nil) } else if args[0] == "nginx" { return nginxGenTeam() } else if args[0] == "binding" { diff --git a/libfic/team.go b/libfic/team.go index 10d67b72..4be647a4 100644 --- a/libfic/team.go +++ b/libfic/team.go @@ -1,6 +1,7 @@ package fic import ( + "database/sql" "fmt" "time" ) @@ -152,6 +153,61 @@ func (t Team) HasAccess(e Exercice) bool { } } +func NbTry(t *Team, e Exercice) int { + var cnt *int + + if t != nil { + DBQueryRow("SELECT COUNT(*) FROM exercice_tries WHERE id_team = ? AND id_exercice = ?", t.Id, e.Id).Scan(&cnt) + } else { + DBQueryRow("SELECT COUNT(*) FROM exercice_tries WHERE id_exercice = ?", e.Id).Scan(&cnt) + } + + if cnt == nil { + return 0 + } else { + return *cnt + } +} + +func GetTries(t *Team, e *Exercice) ([]time.Time, error) { + var rows *sql.Rows + var err error + + if t == nil { + if e == nil { + rows, err = DBQuery("SELECT time FROM exercice_tries ORDER BY time ASC") + } else { + rows, err = DBQuery("SELECT time FROM exercice_tries WHERE id_exercice = ? ORDER BY time ASC", e.Id) + } + } else { + if e == nil { + rows, err = DBQuery("SELECT time FROM exercice_tries WHERE id_team = ? ORDER BY time ASC", t.Id) + } else { + rows, err = DBQuery("SELECT time FROM exercice_tries WHERE id_team = ? AND id_exercice = ? ORDER BY time ASC", t.Id, e.Id) + } + } + + if err != nil { + return nil, err + } else { + defer rows.Close() + + times := make([]time.Time, 0) + for rows.Next() { + var tm time.Time + if err := rows.Scan(&tm); err != nil { + return nil, err + } + times = append(times, tm) + } + if err := rows.Err(); err != nil { + return nil, err + } + + return times, nil + } +} + func (t Team) HasSolved(e Exercice) (bool, time.Time, int64) { var nb *int64 var tm *time.Time From 017adfb2b15d60a50dcf11102146d1a43e0f8476 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 13 Oct 2016 19:52:40 +0200 Subject: [PATCH 0494/2686] [admin] statistic generation --- admin/api_team.go | 6 +++ libfic/team.go | 102 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/admin/api_team.go b/admin/api_team.go index 3c9f449f..a5ba9a7a 100644 --- a/admin/api_team.go +++ b/admin/api_team.go @@ -85,6 +85,12 @@ func listTeam(args []string, body []byte) (interface{}, error) { return fic.MyJSONTeam(team, true) } else if args[1] == "wait.json" { return fic.MyJSONTeam(team, false) + } else if args[1] == "stats.json" { + if team != nil { + return team.GetStats() + } else { + return fic.GetTeamsStats(nil) + } } else if args[1] == "tries" { return fic.GetTries(team, nil) } else if team != nil && args[1] == "members" { diff --git a/libfic/team.go b/libfic/team.go index 4be647a4..5db84293 100644 --- a/libfic/team.go +++ b/libfic/team.go @@ -226,6 +226,108 @@ func (t Team) HasSolved(e Exercice) (bool, time.Time, int64) { } } +func IsSolved(e Exercice) (int, time.Time) { + var nb *int + var tm *time.Time + if DBQueryRow("SELECT COUNT(id_exercice), MIN(time) FROM exercice_solved WHERE id_exercice = ?", e.Id).Scan(&nb, &tm); nb == nil || tm == nil { + return 0, time.Time{} + } else { + return *nb, *tm + } +} + +type statLine struct { + Tip string `json:"tip"` + Total int `json:"total"` + Solved int `json:"solved"` + Tried int `json:"tried"` + Tries int `json:"tries"` +} + +type teamStats struct { + Levels []statLine `json:"levels"` + Themes []statLine `json:"themes"` +} + +func (s *teamStats) GetLevel(level int) *statLine { + level -= 1 + + for len(s.Levels) <= level { + s.Levels = append(s.Levels, statLine{ + fmt.Sprintf("Level %d", (len(s.Levels) + 1)), + 0, + 0, + 0, + 0, + }) + } + + return &s.Levels[level] +} + +func (t Team) GetStats() (interface{}, error) { + return GetTeamsStats(&t) +} + +func GetTeamsStats(t *Team) (interface{}, error) { + stat := teamStats{} + + if themes, err := GetThemes(); err != nil { + return nil, err + } else { + for _, theme := range themes { + total := 0 + solved := 0 + tried := 0 + tries := 0 + + if exercices, err := theme.GetExercices(); err != nil { + return nil, err + } else { + for _, exercice := range exercices { + var lvl int + if lvl, err = exercice.GetLevel(); err != nil { + return nil, err + } + sLvl := stat.GetLevel(lvl) + + total += 1 + sLvl.Total += 1 + + if t != nil { + if b, _, _ := t.HasSolved(exercice); b { + solved += 1 + sLvl.Solved += 1 + } + } else { + if n, _ := IsSolved(exercice); n > 0 { + solved += 1 + sLvl.Solved += 1 + } + } + + try := NbTry(t, exercice) + if try > 0 { + tried += 1 + tries += try + sLvl.Tried += 1 + sLvl.Tries += try + } + } + } + + stat.Themes = append(stat.Themes, statLine{ + theme.Name, + total, + solved, + tried, + tries, + }) + } + + return stat, nil + } +} type exportedTeam struct { Name string `json:"name"` From 347f317dd9431eb13d2feb11d03b3eead829bd25 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 13 Oct 2016 19:52:54 +0200 Subject: [PATCH 0495/2686] [admin] Improve interface --- admin/static/img/epita.png | Bin 0 -> 39967 bytes admin/static/img/fic.png | Bin 0 -> 40107 bytes admin/static/img/srs.png | Bin 0 -> 29880 bytes admin/static/index.html | 33 +++- admin/static/js/app.js | 338 ++++++++++++++++++++++++++++++++++- admin/static/views/home.html | 9 + admin/static/views/team.html | 54 ++++++ 7 files changed, 421 insertions(+), 13 deletions(-) create mode 100644 admin/static/img/epita.png create mode 100644 admin/static/img/fic.png create mode 100644 admin/static/img/srs.png create mode 100644 admin/static/views/home.html create mode 100644 admin/static/views/team.html diff --git a/admin/static/img/epita.png b/admin/static/img/epita.png new file mode 100644 index 0000000000000000000000000000000000000000..e89f7181dc2b749a4d27d616d0a570e9006f765e GIT binary patch literal 39967 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 literal 0 HcmV?d00001 diff --git a/admin/static/img/fic.png b/admin/static/img/fic.png new file mode 100644 index 0000000000000000000000000000000000000000..7956bd4db0fab2c34246cc7658fb3dd0c95b47b5 GIT binary patch literal 40107 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 D5^Cq@ literal 0 HcmV?d00001 diff --git a/admin/static/img/srs.png b/admin/static/img/srs.png new file mode 100644 index 0000000000000000000000000000000000000000..82294f52864d2244b12f89e20d2cc5e6d5a76aa8 GIT binary patch literal 29880 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 DAqC!t literal 0 HcmV?d00001 diff --git a/admin/static/index.html b/admin/static/index.html index e2142455..c409ffa9 100644 --- a/admin/static/index.html +++ b/admin/static/index.html @@ -2,15 +2,40 @@ - Challenge Forensic FIC 2016 - Administration + Challenge Forensic - Administration + -
    -
    ","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};ka.optgroup=ka.option;ka.tbody=ka.tfoot=ka.colgroup=ka.caption=ka.thead;ka.th=ka.td;var Kf=Node.prototype.contains||function(a){return!!(this.compareDocumentPosition(a)& -16)},Pa=N.prototype={ready:function(a){function b(){d||(d=!0,a())}var d=!1;"complete"===X.readyState?setTimeout(b):(this.on("DOMContentLoaded",b),N(S).on("load",b))},toString:function(){var a=[];n(this,function(b){a.push(""+b)});return"["+a.join(", ")+"]"},eq:function(a){return 0<=a?B(this[a]):B(this[this.length+a])},length:0,push:mg,sort:[].sort,splice:[].splice},Cb={};n("multiple selected checked disabled readOnly required open".split(" "),function(a){Cb[F(a)]=a});var Rc={};n("input select option textarea button form details".split(" "), -function(a){Rc[a]=!0});var Zc={ngMinlength:"minlength",ngMaxlength:"maxlength",ngMin:"min",ngMax:"max",ngPattern:"pattern"};n({data:Wb,removeData:vb,hasData:function(a){for(var b in gb[a.ng339])return!0;return!1}},function(a,b){N[b]=a});n({data:Wb,inheritedData:Bb,scope:function(a){return B.data(a,"$scope")||Bb(a.parentNode||a,["$isolateScope","$scope"])},isolateScope:function(a){return B.data(a,"$isolateScope")||B.data(a,"$isolateScopeNoTemplate")},controller:Oc,injector:function(a){return Bb(a, -"$injector")},removeAttr:function(a,b){a.removeAttribute(b)},hasClass:yb,css:function(a,b,d){b=fb(b);if(y(d))a.style[b]=d;else return a.style[b]},attr:function(a,b,d){var c=a.nodeType;if(c!==Na&&2!==c&&8!==c)if(c=F(b),Cb[c])if(y(d))d?(a[b]=!0,a.setAttribute(b,c)):(a[b]=!1,a.removeAttribute(c));else return a[b]||(a.attributes.getNamedItem(b)||x).specified?c:u;else if(y(d))a.setAttribute(b,d);else if(a.getAttribute)return a=a.getAttribute(b,2),null===a?u:a},prop:function(a,b,d){if(y(d))a[b]=d;else return a[b]}, -text:function(){function a(a,d){if(q(d)){var c=a.nodeType;return 1===c||c===Na?a.textContent:""}a.textContent=d}a.$dv="";return a}(),val:function(a,b){if(q(b)){if(a.multiple&&"select"===ta(a)){var d=[];n(a.options,function(a){a.selected&&d.push(a.value||a.text)});return 0===d.length?null:d}return a.value}a.value=b},html:function(a,b){if(q(b))return a.innerHTML;ub(a,!0);a.innerHTML=b},empty:Pc},function(a,b){N.prototype[b]=function(b,c){var e,f,g=this.length;if(a!==Pc&&q(2==a.length&&a!==yb&&a!==Oc? -b:c)){if(H(b)){for(e=0;e <= >= && || ! = |".split(" "),function(a){Lb[a]=!0});var sg={n:"\n",f:"\f",r:"\r", -t:"\t",v:"\v","'":"'",'"':'"'},fc=function(a){this.options=a};fc.prototype={constructor:fc,lex:function(a){this.text=a;this.index=0;for(this.tokens=[];this.index=a&&"string"===typeof a},isWhitespace:function(a){return" "===a||"\r"===a|| -"\t"===a||"\n"===a||"\v"===a||"\u00a0"===a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,b,d){d=d||this.index;b=y(b)?"s "+b+"-"+this.index+" ["+this.text.substring(b,d)+"]":" "+d;throw ba("lexerr",a,b,this.text);},readNumber:function(){for(var a="",b=this.index;this.index","<=",">=");)a={type:s.BinaryExpression,operator:b.text,left:a,right:this.additive()};return a},additive:function(){for(var a=this.multiplicative(),b;b=this.expect("+","-");)a={type:s.BinaryExpression,operator:b.text,left:a,right:this.multiplicative()};return a},multiplicative:function(){for(var a=this.unary(),b;b=this.expect("*","/","%");)a={type:s.BinaryExpression,operator:b.text, -left:a,right:this.unary()};return a},unary:function(){var a;return(a=this.expect("+","-","!"))?{type:s.UnaryExpression,operator:a.text,prefix:!0,argument:this.unary()}:this.primary()},primary:function(){var a;this.expect("(")?(a=this.filterChain(),this.consume(")")):this.expect("[")?a=this.arrayDeclaration():this.expect("{")?a=this.object():this.constants.hasOwnProperty(this.peek().text)?a=bb(this.constants[this.consume().text]):this.peek().identifier?a=this.identifier():this.peek().constant?a=this.constant(): -this.throwError("not a primary expression",this.peek());for(var b;b=this.expect("(","[",".");)"("===b.text?(a={type:s.CallExpression,callee:a,arguments:this.parseArguments()},this.consume(")")):"["===b.text?(a={type:s.MemberExpression,object:a,property:this.expression(),computed:!0},this.consume("]")):"."===b.text?a={type:s.MemberExpression,object:a,property:this.identifier(),computed:!1}:this.throwError("IMPOSSIBLE");return a},filter:function(a){a=[a];for(var b={type:s.CallExpression,callee:this.identifier(), -arguments:a,filter:!0};this.expect(":");)a.push(this.expression());return b},parseArguments:function(){var a=[];if(")"!==this.peekToken().text){do a.push(this.expression());while(this.expect(","))}return a},identifier:function(){var a=this.consume();a.identifier||this.throwError("is not a valid identifier",a);return{type:s.Identifier,name:a.text}},constant:function(){return{type:s.Literal,value:this.consume().value}},arrayDeclaration:function(){var a=[];if("]"!==this.peekToken().text){do{if(this.peek("]"))break; -a.push(this.expression())}while(this.expect(","))}this.consume("]");return{type:s.ArrayExpression,elements:a}},object:function(){var a=[],b;if("}"!==this.peekToken().text){do{if(this.peek("}"))break;b={type:s.Property,kind:"init"};this.peek().constant?b.key=this.constant():this.peek().identifier?b.key=this.identifier():this.throwError("invalid key",this.peek());this.consume(":");b.value=this.expression();a.push(b)}while(this.expect(","))}this.consume("}");return{type:s.ObjectExpression,properties:a}}, -throwError:function(a,b){throw ba("syntax",b.text,a,b.index+1,this.text,this.text.substring(b.index));},consume:function(a){if(0===this.tokens.length)throw ba("ueoe",this.text);var b=this.expect(a);b||this.throwError("is unexpected, expecting ["+a+"]",this.peek());return b},peekToken:function(){if(0===this.tokens.length)throw ba("ueoe",this.text);return this.tokens[0]},peek:function(a,b,d,c){return this.peekAhead(0,a,b,d,c)},peekAhead:function(a,b,d,c,e){if(this.tokens.length>a){a=this.tokens[a]; -var f=a.text;if(f===b||f===d||f===c||f===e||!(b||d||c||e))return a}return!1},expect:function(a,b,d,c){return(a=this.peek(a,b,d,c))?(this.tokens.shift(),a):!1},constants:{"true":{type:s.Literal,value:!0},"false":{type:s.Literal,value:!1},"null":{type:s.Literal,value:null},undefined:{type:s.Literal,value:u},"this":{type:s.ThisExpression}}};rd.prototype={compile:function(a,b){var d=this,c=this.astBuilder.ast(a);this.state={nextId:0,filters:{},expensiveChecks:b,fn:{vars:[],body:[],own:{}},assign:{vars:[], -body:[],own:{}},inputs:[]};W(c,d.$filter);var e="",f;this.stage="assign";if(f=pd(c))this.state.computing="assign",e=this.nextId(),this.recurse(f,e),this.return_(e),e="fn.assign="+this.generateFunction("assign","s,v,l");f=nd(c.body);d.stage="inputs";n(f,function(a,b){var c="fn"+b;d.state[c]={vars:[],body:[],own:{}};d.state.computing=c;var e=d.nextId();d.recurse(a,e);d.return_(e);d.state.inputs.push(c);a.watchId=b});this.state.computing="fn";this.stage="main";this.recurse(c);e='"'+this.USE+" "+this.STRICT+ -'";\n'+this.filterPrefix()+"var fn="+this.generateFunction("fn","s,l,a,i")+e+this.watchFns()+"return fn;";e=(new Function("$filter","ensureSafeMemberName","ensureSafeObject","ensureSafeFunction","getStringValue","ensureSafeAssignContext","ifDefined","plus","text",e))(this.$filter,Va,xa,kd,jd,ld,Zf,md,a);this.state=this.stage=u;e.literal=qd(c);e.constant=c.constant;return e},USE:"use",STRICT:"strict",watchFns:function(){var a=[],b=this.state.inputs,d=this;n(b,function(b){a.push("var "+b+"="+d.generateFunction(b, -"s"))});b.length&&a.push("fn.inputs=["+b.join(",")+"];");return a.join("")},generateFunction:function(a,b){return"function("+b+"){"+this.varsPrefix(a)+this.body(a)+"};"},filterPrefix:function(){var a=[],b=this;n(this.state.filters,function(d,c){a.push(d+"=$filter("+b.escape(c)+")")});return a.length?"var "+a.join(",")+";":""},varsPrefix:function(a){return this.state[a].vars.length?"var "+this.state[a].vars.join(",")+";":""},body:function(a){return this.state[a].body.join("")},recurse:function(a,b, -d,c,e,f){var g,h,k=this,l,m;c=c||x;if(!f&&y(a.watchId))b=b||this.nextId(),this.if_("i",this.lazyAssign(b,this.computedMember("i",a.watchId)),this.lazyRecurse(a,b,d,c,e,!0));else switch(a.type){case s.Program:n(a.body,function(b,c){k.recurse(b.expression,u,u,function(a){h=a});c!==a.body.length-1?k.current().body.push(h,";"):k.return_(h)});break;case s.Literal:m=this.escape(a.value);this.assign(b,m);c(m);break;case s.UnaryExpression:this.recurse(a.argument,u,u,function(a){h=a});m=a.operator+"("+this.ifDefined(h, -0)+")";this.assign(b,m);c(m);break;case s.BinaryExpression:this.recurse(a.left,u,u,function(a){g=a});this.recurse(a.right,u,u,function(a){h=a});m="+"===a.operator?this.plus(g,h):"-"===a.operator?this.ifDefined(g,0)+a.operator+this.ifDefined(h,0):"("+g+")"+a.operator+"("+h+")";this.assign(b,m);c(m);break;case s.LogicalExpression:b=b||this.nextId();k.recurse(a.left,b);k.if_("&&"===a.operator?b:k.not(b),k.lazyRecurse(a.right,b));c(b);break;case s.ConditionalExpression:b=b||this.nextId();k.recurse(a.test, -b);k.if_(b,k.lazyRecurse(a.alternate,b),k.lazyRecurse(a.consequent,b));c(b);break;case s.Identifier:b=b||this.nextId();d&&(d.context="inputs"===k.stage?"s":this.assign(this.nextId(),this.getHasOwnProperty("l",a.name)+"?l:s"),d.computed=!1,d.name=a.name);Va(a.name);k.if_("inputs"===k.stage||k.not(k.getHasOwnProperty("l",a.name)),function(){k.if_("inputs"===k.stage||"s",function(){e&&1!==e&&k.if_(k.not(k.nonComputedMember("s",a.name)),k.lazyAssign(k.nonComputedMember("s",a.name),"{}"));k.assign(b,k.nonComputedMember("s", -a.name))})},b&&k.lazyAssign(b,k.nonComputedMember("l",a.name)));(k.state.expensiveChecks||Fb(a.name))&&k.addEnsureSafeObject(b);c(b);break;case s.MemberExpression:g=d&&(d.context=this.nextId())||this.nextId();b=b||this.nextId();k.recurse(a.object,g,u,function(){k.if_(k.notNull(g),function(){if(a.computed)h=k.nextId(),k.recurse(a.property,h),k.getStringValue(h),k.addEnsureSafeMemberName(h),e&&1!==e&&k.if_(k.not(k.computedMember(g,h)),k.lazyAssign(k.computedMember(g,h),"{}")),m=k.ensureSafeObject(k.computedMember(g, -h)),k.assign(b,m),d&&(d.computed=!0,d.name=h);else{Va(a.property.name);e&&1!==e&&k.if_(k.not(k.nonComputedMember(g,a.property.name)),k.lazyAssign(k.nonComputedMember(g,a.property.name),"{}"));m=k.nonComputedMember(g,a.property.name);if(k.state.expensiveChecks||Fb(a.property.name))m=k.ensureSafeObject(m);k.assign(b,m);d&&(d.computed=!1,d.name=a.property.name)}},function(){k.assign(b,"undefined")});c(b)},!!e);break;case s.CallExpression:b=b||this.nextId();a.filter?(h=k.filter(a.callee.name),l=[],n(a.arguments, -function(a){var b=k.nextId();k.recurse(a,b);l.push(b)}),m=h+"("+l.join(",")+")",k.assign(b,m),c(b)):(h=k.nextId(),g={},l=[],k.recurse(a.callee,h,g,function(){k.if_(k.notNull(h),function(){k.addEnsureSafeFunction(h);n(a.arguments,function(a){k.recurse(a,k.nextId(),u,function(a){l.push(k.ensureSafeObject(a))})});g.name?(k.state.expensiveChecks||k.addEnsureSafeObject(g.context),m=k.member(g.context,g.name,g.computed)+"("+l.join(",")+")"):m=h+"("+l.join(",")+")";m=k.ensureSafeObject(m);k.assign(b,m)}, -function(){k.assign(b,"undefined")});c(b)}));break;case s.AssignmentExpression:h=this.nextId();g={};if(!od(a.left))throw ba("lval");this.recurse(a.left,u,g,function(){k.if_(k.notNull(g.context),function(){k.recurse(a.right,h);k.addEnsureSafeObject(k.member(g.context,g.name,g.computed));k.addEnsureSafeAssignContext(g.context);m=k.member(g.context,g.name,g.computed)+a.operator+h;k.assign(b,m);c(b||m)})},1);break;case s.ArrayExpression:l=[];n(a.elements,function(a){k.recurse(a,k.nextId(),u,function(a){l.push(a)})}); -m="["+l.join(",")+"]";this.assign(b,m);c(m);break;case s.ObjectExpression:l=[];n(a.properties,function(a){k.recurse(a.value,k.nextId(),u,function(b){l.push(k.escape(a.key.type===s.Identifier?a.key.name:""+a.key.value)+":"+b)})});m="{"+l.join(",")+"}";this.assign(b,m);c(m);break;case s.ThisExpression:this.assign(b,"s");c("s");break;case s.NGValueParameter:this.assign(b,"v"),c("v")}},getHasOwnProperty:function(a,b){var d=a+"."+b,c=this.current().own;c.hasOwnProperty(d)||(c[d]=this.nextId(!1,a+"&&("+ -this.escape(b)+" in "+a+")"));return c[d]},assign:function(a,b){if(a)return this.current().body.push(a,"=",b,";"),a},filter:function(a){this.state.filters.hasOwnProperty(a)||(this.state.filters[a]=this.nextId(!0));return this.state.filters[a]},ifDefined:function(a,b){return"ifDefined("+a+","+this.escape(b)+")"},plus:function(a,b){return"plus("+a+","+b+")"},return_:function(a){this.current().body.push("return ",a,";")},if_:function(a,b,d){if(!0===a)b();else{var c=this.current().body;c.push("if(",a, -"){");b();c.push("}");d&&(c.push("else{"),d(),c.push("}"))}},not:function(a){return"!("+a+")"},notNull:function(a){return a+"!=null"},nonComputedMember:function(a,b){return a+"."+b},computedMember:function(a,b){return a+"["+b+"]"},member:function(a,b,d){return d?this.computedMember(a,b):this.nonComputedMember(a,b)},addEnsureSafeObject:function(a){this.current().body.push(this.ensureSafeObject(a),";")},addEnsureSafeMemberName:function(a){this.current().body.push(this.ensureSafeMemberName(a),";")}, -addEnsureSafeFunction:function(a){this.current().body.push(this.ensureSafeFunction(a),";")},addEnsureSafeAssignContext:function(a){this.current().body.push(this.ensureSafeAssignContext(a),";")},ensureSafeObject:function(a){return"ensureSafeObject("+a+",text)"},ensureSafeMemberName:function(a){return"ensureSafeMemberName("+a+",text)"},ensureSafeFunction:function(a){return"ensureSafeFunction("+a+",text)"},getStringValue:function(a){this.assign(a,"getStringValue("+a+",text)")},ensureSafeAssignContext:function(a){return"ensureSafeAssignContext("+ -a+",text)"},lazyRecurse:function(a,b,d,c,e,f){var g=this;return function(){g.recurse(a,b,d,c,e,f)}},lazyAssign:function(a,b){var d=this;return function(){d.assign(a,b)}},stringEscapeRegex:/[^ a-zA-Z0-9]/g,stringEscapeFn:function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)},escape:function(a){if(E(a))return"'"+a.replace(this.stringEscapeRegex,this.stringEscapeFn)+"'";if(Q(a))return a.toString();if(!0===a)return"true";if(!1===a)return"false";if(null===a)return"null";if("undefined"=== -typeof a)return"undefined";throw ba("esc");},nextId:function(a,b){var d="v"+this.state.nextId++;a||this.current().vars.push(d+(b?"="+b:""));return d},current:function(){return this.state[this.state.computing]}};sd.prototype={compile:function(a,b){var d=this,c=this.astBuilder.ast(a);this.expression=a;this.expensiveChecks=b;W(c,d.$filter);var e,f;if(e=pd(c))f=this.recurse(e);e=nd(c.body);var g;e&&(g=[],n(e,function(a,b){var c=d.recurse(a);a.input=c;g.push(c);a.watchId=b}));var h=[];n(c.body,function(a){h.push(d.recurse(a.expression))}); -e=0===c.body.length?function(){}:1===c.body.length?h[0]:function(a,b){var c;n(h,function(d){c=d(a,b)});return c};f&&(e.assign=function(a,b,c){return f(a,c,b)});g&&(e.inputs=g);e.literal=qd(c);e.constant=c.constant;return e},recurse:function(a,b,d){var c,e,f=this,g;if(a.input)return this.inputs(a.input,a.watchId);switch(a.type){case s.Literal:return this.value(a.value,b);case s.UnaryExpression:return e=this.recurse(a.argument),this["unary"+a.operator](e,b);case s.BinaryExpression:return c=this.recurse(a.left), -e=this.recurse(a.right),this["binary"+a.operator](c,e,b);case s.LogicalExpression:return c=this.recurse(a.left),e=this.recurse(a.right),this["binary"+a.operator](c,e,b);case s.ConditionalExpression:return this["ternary?:"](this.recurse(a.test),this.recurse(a.alternate),this.recurse(a.consequent),b);case s.Identifier:return Va(a.name,f.expression),f.identifier(a.name,f.expensiveChecks||Fb(a.name),b,d,f.expression);case s.MemberExpression:return c=this.recurse(a.object,!1,!!d),a.computed||(Va(a.property.name, -f.expression),e=a.property.name),a.computed&&(e=this.recurse(a.property)),a.computed?this.computedMember(c,e,b,d,f.expression):this.nonComputedMember(c,e,f.expensiveChecks,b,d,f.expression);case s.CallExpression:return g=[],n(a.arguments,function(a){g.push(f.recurse(a))}),a.filter&&(e=this.$filter(a.callee.name)),a.filter||(e=this.recurse(a.callee,!0)),a.filter?function(a,c,d,f){for(var r=[],n=0;n":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)>b(c,e,f,g);return d?{value:c}:c}},"binary<=":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)<=b(c,e,f,g);return d?{value:c}:c}},"binary>=":function(a,b,d){return function(c, -e,f,g){c=a(c,e,f,g)>=b(c,e,f,g);return d?{value:c}:c}},"binary&&":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)&&b(c,e,f,g);return d?{value:c}:c}},"binary||":function(a,b,d){return function(c,e,f,g){c=a(c,e,f,g)||b(c,e,f,g);return d?{value:c}:c}},"ternary?:":function(a,b,d,c){return function(e,f,g,h){e=a(e,f,g,h)?b(e,f,g,h):d(e,f,g,h);return c?{value:e}:e}},value:function(a,b){return function(){return b?{context:u,name:u,value:a}:a}},identifier:function(a,b,d,c,e){return function(f,g,h,k){f= -g&&a in g?g:f;c&&1!==c&&f&&!f[a]&&(f[a]={});g=f?f[a]:u;b&&xa(g,e);return d?{context:f,name:a,value:g}:g}},computedMember:function(a,b,d,c,e){return function(f,g,h,k){var l=a(f,g,h,k),m,n;null!=l&&(m=b(f,g,h,k),m=jd(m),Va(m,e),c&&1!==c&&l&&!l[m]&&(l[m]={}),n=l[m],xa(n,e));return d?{context:l,name:m,value:n}:n}},nonComputedMember:function(a,b,d,c,e,f){return function(g,h,k,l){g=a(g,h,k,l);e&&1!==e&&g&&!g[b]&&(g[b]={});h=null!=g?g[b]:u;(d||Fb(b))&&xa(h,f);return c?{context:g,name:b,value:h}:h}},inputs:function(a, -b){return function(d,c,e,f){return f?f[b]:a(d,c,e)}}};var gc=function(a,b,d){this.lexer=a;this.$filter=b;this.options=d;this.ast=new s(this.lexer);this.astCompiler=d.csp?new sd(this.ast,b):new rd(this.ast,b)};gc.prototype={constructor:gc,parse:function(a){return this.astCompiler.compile(a,this.options.expensiveChecks)}};$();$();var $f=Object.prototype.valueOf,ya=G("$sce"),la={HTML:"html",CSS:"css",URL:"url",RESOURCE_URL:"resourceUrl",JS:"js"},ha=G("$compile"),Y=X.createElement("a"),wd=wa(S.location.href); -xd.$inject=["$document"];Jc.$inject=["$provide"];yd.$inject=["$locale"];Ad.$inject=["$locale"];var ic=".",jg={yyyy:ca("FullYear",4),yy:ca("FullYear",2,0,!0),y:ca("FullYear",1),MMMM:Hb("Month"),MMM:Hb("Month",!0),MM:ca("Month",2,1),M:ca("Month",1,1),dd:ca("Date",2),d:ca("Date",1),HH:ca("Hours",2),H:ca("Hours",1),hh:ca("Hours",2,-12),h:ca("Hours",1,-12),mm:ca("Minutes",2),m:ca("Minutes",1),ss:ca("Seconds",2),s:ca("Seconds",1),sss:ca("Milliseconds",3),EEEE:Hb("Day"),EEE:Hb("Day",!0),a:function(a,b){return 12> -a.getHours()?b.AMPMS[0]:b.AMPMS[1]},Z:function(a,b,d){a=-1*d;return a=(0<=a?"+":"")+(Gb(Math[0=a.getFullYear()?b.ERANAMES[0]:b.ERANAMES[1]}},ig=/((?:[^yMdHhmsaZEwG']+)|(?:'(?:[^']|'')*')|(?:E+|y+|M+|d+|H+|h+|m+|s+|a|Z|G+|w+))(.*)/,hg=/^\-?\d+$/;zd.$inject=["$locale"];var eg=na(F),fg=na(sb);Bd.$inject=["$parse"];var he=na({restrict:"E",compile:function(a,b){if(!b.href&&!b.xlinkHref)return function(a, -b){if("a"===b[0].nodeName.toLowerCase()){var e="[object SVGAnimatedString]"===sa.call(b.prop("href"))?"xlink:href":"href";b.on("click",function(a){b.attr(e)||a.preventDefault()})}}}}),tb={};n(Cb,function(a,b){function d(a,d,e){a.$watch(e[c],function(a){e.$set(b,!!a)})}if("multiple"!=a){var c=va("ng-"+b),e=d;"checked"===a&&(e=function(a,b,e){e.ngModel!==e[c]&&d(a,b,e)});tb[c]=function(){return{restrict:"A",priority:100,link:e}}}});n(Zc,function(a,b){tb[b]=function(){return{priority:100,link:function(a, -c,e){if("ngPattern"===b&&"/"==e.ngPattern.charAt(0)&&(c=e.ngPattern.match(lg))){e.$set("ngPattern",new RegExp(c[1],c[2]));return}a.$watch(e[b],function(a){e.$set(b,a)})}}}});n(["src","srcset","href"],function(a){var b=va("ng-"+a);tb[b]=function(){return{priority:99,link:function(d,c,e){var f=a,g=a;"href"===a&&"[object SVGAnimatedString]"===sa.call(c.prop("href"))&&(g="xlinkHref",e.$attr[g]="xlink:href",f=null);e.$observe(b,function(b){b?(e.$set(g,b),Ha&&f&&c.prop(f,e[g])):"href"===a&&e.$set(g,null)})}}}}); -var Ib={$addControl:x,$$renameControl:function(a,b){a.$name=b},$removeControl:x,$setValidity:x,$setDirty:x,$setPristine:x,$setSubmitted:x};Fd.$inject=["$element","$attrs","$scope","$animate","$interpolate"];var Nd=function(a){return["$timeout","$parse",function(b,d){function c(a){return""===a?d('this[""]').assign:d(a).assign||x}return{name:"form",restrict:a?"EAC":"E",require:["form","^^?form"],controller:Fd,compile:function(d,f){d.addClass(Wa).addClass(mb);var g=f.name?"name":a&&f.ngForm?"ngForm": -!1;return{pre:function(a,d,e,f){var n=f[0];if(!("action"in e)){var q=function(b){a.$apply(function(){n.$commitViewValue();n.$setSubmitted()});b.preventDefault()};d[0].addEventListener("submit",q,!1);d.on("$destroy",function(){b(function(){d[0].removeEventListener("submit",q,!1)},0,!1)})}(f[1]||n.$$parentForm).$addControl(n);var s=g?c(n.$name):x;g&&(s(a,n),e.$observe(g,function(b){n.$name!==b&&(s(a,u),n.$$parentForm.$$renameControl(n,b),s=c(n.$name),s(a,n))}));d.on("$destroy",function(){n.$$parentForm.$removeControl(n); -s(a,u);M(n,Ib)})}}}}}]},ie=Nd(),ve=Nd(!0),kg=/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/,tg=/^[A-Za-z][A-Za-z\d.+-]*:\/*(?:\w+(?::\w+)?@)?[^\s/]+(?::\d+)?(?:\/[\w#!:.?+=&%@\-/]*)?$/,ug=/^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,vg=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))([eE][+-]?\d+)?\s*$/,Od=/^(\d{4})-(\d{2})-(\d{2})$/,Pd=/^(\d{4})-(\d\d)-(\d\d)T(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/,mc=/^(\d{4})-W(\d\d)$/,Qd=/^(\d{4})-(\d\d)$/, -Rd=/^(\d\d):(\d\d)(?::(\d\d)(\.\d{1,3})?)?$/,Sd={text:function(a,b,d,c,e,f){jb(a,b,d,c,e,f);kc(c)},date:kb("date",Od,Kb(Od,["yyyy","MM","dd"]),"yyyy-MM-dd"),"datetime-local":kb("datetimelocal",Pd,Kb(Pd,"yyyy MM dd HH mm ss sss".split(" ")),"yyyy-MM-ddTHH:mm:ss.sss"),time:kb("time",Rd,Kb(Rd,["HH","mm","ss","sss"]),"HH:mm:ss.sss"),week:kb("week",mc,function(a,b){if(da(a))return a;if(E(a)){mc.lastIndex=0;var d=mc.exec(a);if(d){var c=+d[1],e=+d[2],f=d=0,g=0,h=0,k=Dd(c),e=7*(e-1);b&&(d=b.getHours(),f= -b.getMinutes(),g=b.getSeconds(),h=b.getMilliseconds());return new Date(c,0,k.getDate()+e,d,f,g,h)}}return NaN},"yyyy-Www"),month:kb("month",Qd,Kb(Qd,["yyyy","MM"]),"yyyy-MM"),number:function(a,b,d,c,e,f){Hd(a,b,d,c);jb(a,b,d,c,e,f);c.$$parserName="number";c.$parsers.push(function(a){return c.$isEmpty(a)?null:vg.test(a)?parseFloat(a):u});c.$formatters.push(function(a){if(!c.$isEmpty(a)){if(!Q(a))throw lb("numfmt",a);a=a.toString()}return a});if(y(d.min)||d.ngMin){var g;c.$validators.min=function(a){return c.$isEmpty(a)|| -q(g)||a>=g};d.$observe("min",function(a){y(a)&&!Q(a)&&(a=parseFloat(a,10));g=Q(a)&&!isNaN(a)?a:u;c.$validate()})}if(y(d.max)||d.ngMax){var h;c.$validators.max=function(a){return c.$isEmpty(a)||q(h)||a<=h};d.$observe("max",function(a){y(a)&&!Q(a)&&(a=parseFloat(a,10));h=Q(a)&&!isNaN(a)?a:u;c.$validate()})}},url:function(a,b,d,c,e,f){jb(a,b,d,c,e,f);kc(c);c.$$parserName="url";c.$validators.url=function(a,b){var d=a||b;return c.$isEmpty(d)||tg.test(d)}},email:function(a,b,d,c,e,f){jb(a,b,d,c,e,f);kc(c); -c.$$parserName="email";c.$validators.email=function(a,b){var d=a||b;return c.$isEmpty(d)||ug.test(d)}},radio:function(a,b,d,c){q(d.name)&&b.attr("name",++nb);b.on("click",function(a){b[0].checked&&c.$setViewValue(d.value,a&&a.type)});c.$render=function(){b[0].checked=d.value==c.$viewValue};d.$observe("value",c.$render)},checkbox:function(a,b,d,c,e,f,g,h){var k=Id(h,a,"ngTrueValue",d.ngTrueValue,!0),l=Id(h,a,"ngFalseValue",d.ngFalseValue,!1);b.on("click",function(a){c.$setViewValue(b[0].checked,a&& -a.type)});c.$render=function(){b[0].checked=c.$viewValue};c.$isEmpty=function(a){return!1===a};c.$formatters.push(function(a){return ma(a,k)});c.$parsers.push(function(a){return a?k:l})},hidden:x,button:x,submit:x,reset:x,file:x},Dc=["$browser","$sniffer","$filter","$parse",function(a,b,d,c){return{restrict:"E",require:["?ngModel"],link:{pre:function(e,f,g,h){h[0]&&(Sd[F(g.type)]||Sd.text)(e,f,g,h[0],b,a,d,c)}}}}],wg=/^(true|false|\d+)$/,Ne=function(){return{restrict:"A",priority:100,compile:function(a, -b){return wg.test(b.ngValue)?function(a,b,e){e.$set("value",a.$eval(e.ngValue))}:function(a,b,e){a.$watch(e.ngValue,function(a){e.$set("value",a)})}}}},ne=["$compile",function(a){return{restrict:"AC",compile:function(b){a.$$addBindingClass(b);return function(b,c,e){a.$$addBindingInfo(c,e.ngBind);c=c[0];b.$watch(e.ngBind,function(a){c.textContent=q(a)?"":a})}}}}],pe=["$interpolate","$compile",function(a,b){return{compile:function(d){b.$$addBindingClass(d);return function(c,d,f){c=a(d.attr(f.$attr.ngBindTemplate)); -b.$$addBindingInfo(d,c.expressions);d=d[0];f.$observe("ngBindTemplate",function(a){d.textContent=q(a)?"":a})}}}}],oe=["$sce","$parse","$compile",function(a,b,d){return{restrict:"A",compile:function(c,e){var f=b(e.ngBindHtml),g=b(e.ngBindHtml,function(a){return(a||"").toString()});d.$$addBindingClass(c);return function(b,c,e){d.$$addBindingInfo(c,e.ngBindHtml);b.$watch(g,function(){c.html(a.getTrustedHtml(f(b))||"")})}}}}],Me=na({restrict:"A",require:"ngModel",link:function(a,b,d,c){c.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}), -qe=lc("",!0),se=lc("Odd",0),re=lc("Even",1),te=La({compile:function(a,b){b.$set("ngCloak",u);a.removeClass("ng-cloak")}}),ue=[function(){return{restrict:"A",scope:!0,controller:"@",priority:500}}],Ic={},xg={blur:!0,focus:!0};n("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var b=va("ng-"+a);Ic[b]=["$parse","$rootScope",function(d,c){return{restrict:"A",compile:function(e,f){var g= -d(f[b],null,!0);return function(b,d){d.on(a,function(d){var e=function(){g(b,{$event:d})};xg[a]&&c.$$phase?b.$evalAsync(e):b.$apply(e)})}}}}]});var xe=["$animate",function(a){return{multiElement:!0,transclude:"element",priority:600,terminal:!0,restrict:"A",$$tlb:!0,link:function(b,d,c,e,f){var g,h,k;b.$watch(c.ngIf,function(b){b?h||f(function(b,e){h=e;b[b.length++]=X.createComment(" end ngIf: "+c.ngIf+" ");g={clone:b};a.enter(b,d.parent(),d)}):(k&&(k.remove(),k=null),h&&(h.$destroy(),h=null),g&&(k= -rb(g.clone),a.leave(k).then(function(){k=null}),g=null))})}}}],ye=["$templateRequest","$anchorScroll","$animate",function(a,b,d){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:fa.noop,compile:function(c,e){var f=e.ngInclude||e.src,g=e.onload||"",h=e.autoscroll;return function(c,e,m,n,q){var s=0,v,u,p,C=function(){u&&(u.remove(),u=null);v&&(v.$destroy(),v=null);p&&(d.leave(p).then(function(){u=null}),u=p,p=null)};c.$watch(f,function(f){var m=function(){!y(h)||h&&!c.$eval(h)|| -b()},u=++s;f?(a(f,!0).then(function(a){if(u===s){var b=c.$new();n.template=a;a=q(b,function(a){C();d.enter(a,null,e).then(m)});v=b;p=a;v.$emit("$includeContentLoaded",f);c.$eval(g)}},function(){u===s&&(C(),c.$emit("$includeContentError",f))}),c.$emit("$includeContentRequested",f)):(C(),n.template=null)})}}}}],Pe=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(b,d,c,e){/SVG/.test(d[0].toString())?(d.empty(),a(Lc(e.template,X).childNodes)(b,function(a){d.append(a)}, -{futureParentElement:d})):(d.html(e.template),a(d.contents())(b))}}}],ze=La({priority:450,compile:function(){return{pre:function(a,b,d){a.$eval(d.ngInit)}}}}),Le=function(){return{restrict:"A",priority:100,require:"ngModel",link:function(a,b,d,c){var e=b.attr(d.$attr.ngList)||", ",f="false"!==d.ngTrim,g=f?U(e):e;c.$parsers.push(function(a){if(!q(a)){var b=[];a&&n(a.split(g),function(a){a&&b.push(f?U(a):a)});return b}});c.$formatters.push(function(a){return I(a)?a.join(e):u});c.$isEmpty=function(a){return!a|| -!a.length}}}},mb="ng-valid",Jd="ng-invalid",Wa="ng-pristine",Jb="ng-dirty",Ld="ng-pending",lb=G("ngModel"),yg=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate","$timeout","$rootScope","$q","$interpolate",function(a,b,d,c,e,f,g,h,k,l){this.$modelValue=this.$viewValue=Number.NaN;this.$$rawModelValue=u;this.$validators={};this.$asyncValidators={};this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$untouched=!0;this.$touched=!1;this.$pristine=!0;this.$dirty=!1; -this.$valid=!0;this.$invalid=!1;this.$error={};this.$$success={};this.$pending=u;this.$name=l(d.name||"",!1)(a);this.$$parentForm=Ib;var m=e(d.ngModel),r=m.assign,t=m,s=r,v=null,B,p=this;this.$$setOptions=function(a){if((p.$options=a)&&a.getterSetter){var b=e(d.ngModel+"()"),f=e(d.ngModel+"($$$p)");t=function(a){var c=m(a);z(c)&&(c=b(a));return c};s=function(a,b){z(m(a))?f(a,{$$$p:p.$modelValue}):r(a,p.$modelValue)}}else if(!m.assign)throw lb("nonassign",d.ngModel,ua(c));};this.$render=x;this.$isEmpty= -function(a){return q(a)||""===a||null===a||a!==a};var C=0;Gd({ctrl:this,$element:c,set:function(a,b){a[b]=!0},unset:function(a,b){delete a[b]},$animate:f});this.$setPristine=function(){p.$dirty=!1;p.$pristine=!0;f.removeClass(c,Jb);f.addClass(c,Wa)};this.$setDirty=function(){p.$dirty=!0;p.$pristine=!1;f.removeClass(c,Wa);f.addClass(c,Jb);p.$$parentForm.$setDirty()};this.$setUntouched=function(){p.$touched=!1;p.$untouched=!0;f.setClass(c,"ng-untouched","ng-touched")};this.$setTouched=function(){p.$touched= -!0;p.$untouched=!1;f.setClass(c,"ng-touched","ng-untouched")};this.$rollbackViewValue=function(){g.cancel(v);p.$viewValue=p.$$lastCommittedViewValue;p.$render()};this.$validate=function(){if(!Q(p.$modelValue)||!isNaN(p.$modelValue)){var a=p.$$rawModelValue,b=p.$valid,c=p.$modelValue,d=p.$options&&p.$options.allowInvalid;p.$$runValidators(a,p.$$lastCommittedViewValue,function(e){d||b===e||(p.$modelValue=e?a:u,p.$modelValue!==c&&p.$$writeModelToScope())})}};this.$$runValidators=function(a,b,c){function d(){var c= -!0;n(p.$validators,function(d,e){var g=d(a,b);c=c&&g;f(e,g)});return c?!0:(n(p.$asyncValidators,function(a,b){f(b,null)}),!1)}function e(){var c=[],d=!0;n(p.$asyncValidators,function(e,g){var h=e(a,b);if(!h||!z(h.then))throw lb("$asyncValidators",h);f(g,u);c.push(h.then(function(){f(g,!0)},function(a){d=!1;f(g,!1)}))});c.length?k.all(c).then(function(){g(d)},x):g(!0)}function f(a,b){h===C&&p.$setValidity(a,b)}function g(a){h===C&&c(a)}C++;var h=C;(function(){var a=p.$$parserName||"parse";if(q(B))f(a, -null);else return B||(n(p.$validators,function(a,b){f(b,null)}),n(p.$asyncValidators,function(a,b){f(b,null)})),f(a,B),B;return!0})()?d()?e():g(!1):g(!1)};this.$commitViewValue=function(){var a=p.$viewValue;g.cancel(v);if(p.$$lastCommittedViewValue!==a||""===a&&p.$$hasNativeValidators)p.$$lastCommittedViewValue=a,p.$pristine&&this.$setDirty(),this.$$parseAndValidate()};this.$$parseAndValidate=function(){var b=p.$$lastCommittedViewValue;if(B=q(b)?u:!0)for(var c=0;ce||c.$isEmpty(b)||b.length<=e}}}}},Gc=function(){return{restrict:"A",require:"?ngModel",link:function(a,b,d,c){if(c){var e=0;d.$observe("minlength",function(a){e=ea(a)||0;c.$validate()});c.$validators.minlength=function(a,b){return c.$isEmpty(b)||b.length>=e}}}}};S.angular.bootstrap? -console.log("WARNING: Tried to load angular more than once."):(ce(),ee(fa),fa.module("ngLocale",[],["$provide",function(a){function b(a){a+="";var b=a.indexOf(".");return-1==b?0:a.length-b-1}a.value("$locale",{DATETIME_FORMATS:{AMPMS:["AM","PM"],DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),ERANAMES:["Before Christ","Anno Domini"],ERAS:["BC","AD"],FIRSTDAYOFWEEK:6,MONTH:"January February March April May June July August September October November December".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "), -SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),WEEKENDRANGE:[5,6],fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",medium:"MMM d, y h:mm:ss a",mediumDate:"MMM d, y",mediumTime:"h:mm:ss a","short":"M/d/yy h:mm a",shortDate:"M/d/yy",shortTime:"h:mm a"},NUMBER_FORMATS:{CURRENCY_SYM:"$",DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{gSize:3,lgSize:3,maxFrac:3,minFrac:0,minInt:1,negPre:"-",negSuf:"",posPre:"",posSuf:""},{gSize:3,lgSize:3,maxFrac:2,minFrac:2,minInt:1,negPre:"-\u00a4", -negSuf:"",posPre:"\u00a4",posSuf:""}]},id:"en-us",pluralCat:function(a,c){var e=a|0,f=c;u===f&&(f=Math.min(b(a),3));Math.pow(10,f);return 1==e&&0==f?"one":"other"}})}]),B(X).ready(function(){Zd(X,yc)}))})(window,document);!window.angular.$$csp().noInlineStyle&&window.angular.element(document.head).prepend(''); -//# sourceMappingURL=angular.min.js.map diff --git a/admin/static/js/angular.min.js b/admin/static/js/angular.min.js new file mode 120000 index 00000000..86b88964 --- /dev/null +++ b/admin/static/js/angular.min.js @@ -0,0 +1 @@ +../../../frontend/static/js/angular.min.js \ No newline at end of file diff --git a/admin/static/js/bootstrap.min.js b/admin/static/js/bootstrap.min.js deleted file mode 100644 index e79c0651..00000000 --- a/admin/static/js/bootstrap.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v3.3.6 (http://getbootstrap.com) - * Copyright 2011-2015 Twitter, Inc. - * Licensed under the MIT license - */ -if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>2)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.6",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.6",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.6",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.6",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.6",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.6",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.6",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.6",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/admin/static/js/bootstrap.min.js b/admin/static/js/bootstrap.min.js new file mode 120000 index 00000000..d074c9db --- /dev/null +++ b/admin/static/js/bootstrap.min.js @@ -0,0 +1 @@ +../../../frontend/static/js/bootstrap.min.js \ No newline at end of file diff --git a/admin/static/js/jquery.min.js b/admin/static/js/jquery.min.js deleted file mode 100644 index 6c60672f..00000000 --- a/admin/static/js/jquery.min.js +++ /dev/null @@ -1,5 +0,0 @@ -/*! jQuery v1.12.0 | (c) jQuery Foundation | jquery.org/license */ -!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; -return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthh;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="
    a",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,""],legend:[1,"
    ","
    "],area:[1,"",""],param:[1,"",""],thead:[1,"","
    "],tr:[2,"","
    "],col:[2,"","
    "],td:[3,"","
    "],_default:l.htmlSerialize?[0,"",""]:[1,"X
    ","
    "]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?""!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.rnamespace||a.rnamespace.test(g.namespace))&&(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n(" +
    + +
    From 8c2e8a19d1e43e5ff93eaa427d0803d37dd6d45a Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 5 Jan 2017 02:18:31 +0100 Subject: [PATCH 0548/2686] front: use ng-pluralize --- frontend/static/index.html | 6 +++--- frontend/static/views/theme.html | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/frontend/static/index.html b/frontend/static/index.html index 01de3f90..84c638b4 100644 --- a/frontend/static/index.html +++ b/frontend/static/index.html @@ -83,8 +83,8 @@
    - {{ teams[my.team_id].rank }}e sur {{ teams_count }} – - {{ my.score }} points + {{ teams[my.team_id].rank }} sur {{ teams_count }} – +
    @@ -97,7 +97,7 @@
    diff --git a/frontend/static/views/theme.html b/frontend/static/views/theme.html index ebaf8c8c..792cf571 100644 --- a/frontend/static/views/theme.html +++ b/frontend/static/views/theme.html @@ -8,8 +8,8 @@

      -
    • Gain : {{ themes[current_theme].exercices[current_exercice].gain }} points +50% happy hour +50% first blood
    • -
    • Résolu par : {{ themes[current_theme].exercices[current_exercice].solved }} équipes
    • +
    • Gain : +50% happy hour +50% first blood
    • +
    • Résolu par : .
    @@ -37,7 +37,7 @@

    {{ hint.title }}

    -

    Cet indice vous coûtera {{ hint.cost }}% des points de l'exercice

    +

    Débloquer cet indice vous coûtera .

    @@ -47,7 +47,7 @@
    Soumettre une solution
      -
    • {{ my.exercices[current_exercice].solved_number }} tentative(s) effectuée(s). Dernière solution envoyée à {{ my.exercices[current_exercice].solved_time | date:"mediumTime" }}.
    • +
    • . Dernière solution envoyée à {{ my.exercices[current_exercice].solved_time | date:"mediumTime" }}.
    • Votre solution a bien été envoyée !{{ sberr }} {{ message }}
    @@ -69,7 +69,7 @@
    Challenge réussi !
    - Vous êtes la {{ my.exercices[current_exercice].solved_number }}e équipe à avoir résolu ce challenge à {{ my.exercices[current_exercice].solved_time | date:"mediumTime" }}. Vous avez marqué {{ themes[current_theme].exercices[current_exercice].gain }} points ! + Vous êtes la {{ my.exercices[current_exercice].solved_number }} équipe à avoir résolu ce challenge à {{ my.exercices[current_exercice].solved_time | date:"mediumTime" }}. Vous avez marqué !
    From b772a227057508723fcc50983f0b6ca14d1592c5 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Thu, 5 Jan 2017 02:21:32 +0100 Subject: [PATCH 0549/2686] Hints can something else than text --- admin/api/exercice.go | 30 +++++++++++++++++++++++---- admin/api/file.go | 12 +++-------- admin/fill_exercices.sh | 35 ++++++++++++++++++++++++-------- frontend/static/views/theme.html | 4 +++- libfic/file.go | 3 +-- libfic/hint.go | 10 +++++++++ 6 files changed, 69 insertions(+), 25 deletions(-) diff --git a/admin/api/exercice.go b/admin/api/exercice.go index e00772e7..309a0d71 100644 --- a/admin/api/exercice.go +++ b/admin/api/exercice.go @@ -3,6 +3,7 @@ package api import ( "encoding/json" "errors" + "strings" "srs.epita.fr/fic-server/libfic" @@ -119,17 +120,29 @@ func createExerciceKey(exercice fic.Exercice, body []byte) (interface{}, error) return exercice.AddRawKey(uk.Type, uk.Key) } +type uploadedHint struct { + Title string + Content string + Cost int64 + Path string +} + func createExerciceHint(exercice fic.Exercice, body []byte) (interface{}, error) { - var uh fic.EHint + var uh uploadedHint if err := json.Unmarshal(body, &uh); err != nil { return nil, err } - if len(uh.Content) == 0 { + if len(uh.Content) != 0 { + return exercice.AddHint(uh.Title, uh.Content, uh.Cost) + } else if len(uh.Path) != 0 { + return importFile(uploadedFile{Path: uh.Path}, + func(filePath string, origin string, digest []byte) (interface{}, error) { + return exercice.AddHint(uh.Title, "$FILES" + strings.TrimPrefix(filePath, fic.FilesDir), uh.Cost) + }) + } else { return nil, errors.New("Hint's content not filled") } - - return exercice.AddHint(uh.Title, uh.Content, uh.Cost) } func showExerciceHint(hint fic.EHint, body []byte) (interface{}, error) { @@ -189,6 +202,15 @@ func deleteExerciceKey(key fic.Key, _ fic.Exercice, _ []byte) (interface{}, erro } +func createExerciceFile(exercice fic.Exercice, body []byte) (interface{}, error) { + var uf uploadedFile + if err := json.Unmarshal(body, &uf); err != nil { + return nil, err + } + + return importFile(uf, exercice.ImportFile) +} + func showExerciceFile(file fic.EFile, body []byte) (interface{}, error) { return file, nil } diff --git a/admin/api/file.go b/admin/api/file.go index e8667107..66d8dc46 100644 --- a/admin/api/file.go +++ b/admin/api/file.go @@ -5,7 +5,6 @@ import ( "crypto/sha512" "encoding/base32" "encoding/hex" - "encoding/json" "errors" "fmt" "log" @@ -29,12 +28,7 @@ type uploadedFile struct { Parts []string } -func createExerciceFile(exercice fic.Exercice, body []byte) (interface{}, error) { - var uf uploadedFile - if err := json.Unmarshal(body, &uf); err != nil { - return nil, err - } - +func importFile(uf uploadedFile, next func(string, string, []byte) (interface{}, error)) (interface{}, error) { var hash [sha512.Size]byte var logStr string var fromURI string @@ -80,7 +74,7 @@ func createExerciceFile(exercice fic.Exercice, body []byte) (interface{}, error) pathname := path.Join(fic.FilesDir, strings.ToLower(base32.StdEncoding.EncodeToString(hash[:])), path.Base(fromURI)) // Remove the file if it exists - if _, err := os.Stat(pathname); os.IsExist(err) && !RapidImport { + if _, err := os.Stat(pathname); !os.IsNotExist(err) && !RapidImport { if err := os.Remove(pathname); err != nil { return nil, err } @@ -98,7 +92,7 @@ func createExerciceFile(exercice fic.Exercice, body []byte) (interface{}, error) if digest, err := hex.DecodeString(uf.Digest); err != nil { return nil, err } else { - return exercice.ImportFile(pathname, fromURI, digest) + return next(pathname, fromURI, digest) } } diff --git a/admin/fill_exercices.sh b/admin/fill_exercices.sh index 149fad64..b57756b6 100755 --- a/admin/fill_exercices.sh +++ b/admin/fill_exercices.sh @@ -59,8 +59,12 @@ new_hint() { TITLE=`echo "$3" | sed 's/"/\\\\"/g'` CONTENT=`echo "$4" | sed 's/"/\\\\"/g' | sed ':a;N;$!ba;s/\n/
    /g'` COST="$5" + URI="$6" - curl -f -s -d "{\"title\": \"$TITLE\", \"content\": \"$CONTENT\", \"cost\": $COST}" "${BASEURL}/api/themes/$THEME/exercices/$EXERCICE/hints" | + [ -n "${CONTENT}" ] && CONTENT=", \"content\": \"${CONTENT}\"" + [ -n "${URI}" ] && URI=", \"path\": \"${BASEFILE}${URI}\"" + + curl -f -s -d "{\"title\": \"$TITLE\"$CONTENT$URI, \"cost\": $COST}" "${BASEURL}/api/themes/$THEME/exercices/$EXERCICE/hints" | grep -Eo '"id":[0-9]+,' | grep -Eo "[0-9]+" } @@ -191,15 +195,28 @@ do # Hints - EXO_HINT=$(get_file "${THM_BASEURI}${EXO_BASEURI}/hint.txt") - if [ -n "$EXO_HINT" ]; then - HINT_ID=`new_hint "${THEME_ID}" "${EXO_ID}" "Astuce #1" "${EXO_HINT}" "${HINT_COST}"` - if [ -z "$HINT_ID" ]; then - echo -e "\e[31;01m!!! An error occured during hint import!\e[00m (title=Astuce #1;content=${EXO_HINT};cost=${HINT_COST})" - else - echo -e "\e[32m>>> New hint added:\e[00m $HINT_ID - Astuce #1" + HINTS=$(get_dir "${THM_BASEURI}${EXO_BASEURI}/hints/" | sed -E 's#(.*)#hints/\1#') + [ -z "${HINTS}" ] && HINTS=$(get_dir "${THM_BASEURI}${EXO_BASEURI}/" | grep ^hint.) + [ -z "${HINTS}" ] && HINTS="hint.txt" + HINT_COUNT=1 + echo "${HINTS}" | while read HINT + do + EXO_HINT=$(get_file "${THM_BASEURI}${EXO_BASEURI}/${HINT}") + if [ -n "$EXO_HINT" ]; then + if echo "${EXO_HINT}" | file --mime-type -b - | grep text/ && [ $(echo "${EXO_HINT}" | wc -l) -lt 25 ]; then + HINT_ID=`new_hint "${THEME_ID}" "${EXO_ID}" "Astuce #${HINT_COUNT}" "${EXO_HINT}" "${HINT_COST}"` + else + HINT_ID=`new_hint "${THEME_ID}" "${EXO_ID}" "Astuce #${HINT_COUNT}" "" "${HINT_COST}" "${THM_BASEURI}${EXO_BASEURI}/${HINT}"` + fi + + if [ -z "$HINT_ID" ]; then + echo -e "\e[31;01m!!! An error occured during hint import!\e[00m (title=Astuce #${HINT_COUNT};content=${EXO_HINT};cost=${HINT_COST})" + else + echo -e "\e[32m>>> New hint added:\e[00m $HINT_ID - Astuce #${HINT_COUNT}" + fi fi - fi + HINT_COUNT=$(($HINT_COUNT + 1)) + done # Files: splited diff --git a/frontend/static/views/theme.html b/frontend/static/views/theme.html index 792cf571..af62f802 100644 --- a/frontend/static/views/theme.html +++ b/frontend/static/views/theme.html @@ -35,8 +35,10 @@
    + Télécharger

    {{ hint.title }}

    -

    +

    +

    Utilisez le bouton pour télécharger l'indice.

    Débloquer cet indice vous coûtera .

    diff --git a/libfic/file.go b/libfic/file.go index 5b3e74ed..658f7a22 100644 --- a/libfic/file.go +++ b/libfic/file.go @@ -69,7 +69,7 @@ func (e Exercice) GetFiles() ([]EFile, error) { } } -func (e Exercice) ImportFile(filePath string, origin string, digest []byte) (EFile, error) { +func (e Exercice) ImportFile(filePath string, origin string, digest []byte) (interface{}, error) { if digest == nil && !OptionalDigest { return EFile{}, errors.New("No digest given.") } else if fi, err := os.Stat(filePath); err != nil { @@ -84,7 +84,6 @@ func (e Exercice) ImportFile(filePath string, origin string, digest []byte) (EFi if _, err := io.Copy(hash, reader); err != nil { return EFile{}, err } - result := hash.Sum(nil) if len(digest) != len(result) { diff --git a/libfic/hint.go b/libfic/hint.go index 123d4a02..6dab02b6 100644 --- a/libfic/hint.go +++ b/libfic/hint.go @@ -1,6 +1,8 @@ package fic import ( + "path" + "strings" ) type EHint struct { @@ -11,11 +13,18 @@ type EHint struct { Cost int64 `json:"cost"` } +func treatHintContent(content *string) { + if strings.HasPrefix(*content, "$FILES") { + *content = "$FILES" + path.Join(FilesDir, strings.TrimPrefix(*content, "$FILES")) + } +} + func GetHint(id int64) (EHint, error) { var h EHint if err := DBQueryRow("SELECT id_hint, id_exercice, title, content, cost FROM exercice_hints WHERE id_hint = ?", id).Scan(&h.Id, &h.IdExercice, &h.Title, &h.Content, &h.Cost); err != nil { return h, err } + treatHintContent(&h.Content) return h, nil } @@ -33,6 +42,7 @@ func (e Exercice) GetHints() ([]EHint, error) { if err := rows.Scan(&h.Id, &h.Title, &h.Content, &h.Cost); err != nil { return nil, err } + treatHintContent(&h.Content) hints = append(hints, h) } if err := rows.Err(); err != nil { From 21e4b04c193dcfa0abdba95932d90c00febafdbc Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sat, 14 Jan 2017 15:03:25 +0100 Subject: [PATCH 0550/2686] frontend: dedicate a field in JSON to file hint --- frontend/static/views/theme.html | 20 +++++++++----------- libfic/hint.go | 22 ++++++++++++---------- libfic/team_my.go | 14 +++++++------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/frontend/static/views/theme.html b/frontend/static/views/theme.html index af62f802..d0c8974e 100644 --- a/frontend/static/views/theme.html +++ b/frontend/static/views/theme.html @@ -30,18 +30,16 @@
    Indices
    - +

    +

    Cliquez ici pour télécharger l'indice.

    +

    Débloquer cet indice vous coûtera .

    +
    +
    diff --git a/libfic/hint.go b/libfic/hint.go index 6dab02b6..a47b3501 100644 --- a/libfic/hint.go +++ b/libfic/hint.go @@ -6,16 +6,18 @@ import ( ) type EHint struct { - Id int64 `json:"id"` - IdExercice int64 `json:"idExercice"` - Title string `json:"title"` + Id int64 `json:"id"` + IdExercice int64 `json:"idExercice"` + Title string `json:"title"` Content string `json:"content"` - Cost int64 `json:"cost"` + File string `json:"file"` + Cost int64 `json:"cost"` } -func treatHintContent(content *string) { - if strings.HasPrefix(*content, "$FILES") { - *content = "$FILES" + path.Join(FilesDir, strings.TrimPrefix(*content, "$FILES")) +func treatHintContent(h *EHint) { + if strings.HasPrefix(h.Content, "$FILES") { + h.File = path.Join(FilesDir, strings.TrimPrefix(h.Content, "$FILES")) + h.Content = "" } } @@ -24,7 +26,7 @@ func GetHint(id int64) (EHint, error) { if err := DBQueryRow("SELECT id_hint, id_exercice, title, content, cost FROM exercice_hints WHERE id_hint = ?", id).Scan(&h.Id, &h.IdExercice, &h.Title, &h.Content, &h.Cost); err != nil { return h, err } - treatHintContent(&h.Content) + treatHintContent(&h) return h, nil } @@ -42,7 +44,7 @@ func (e Exercice) GetHints() ([]EHint, error) { if err := rows.Scan(&h.Id, &h.Title, &h.Content, &h.Cost); err != nil { return nil, err } - treatHintContent(&h.Content) + treatHintContent(&h) hints = append(hints, h) } if err := rows.Err(); err != nil { @@ -59,7 +61,7 @@ func (e Exercice) AddHint(title string, content string, cost int64) (EHint, erro } else if hid, err := res.LastInsertId(); err != nil { return EHint{}, err } else { - return EHint{hid, e.Id, title, content, cost}, nil + return EHint{hid, e.Id, title, content, "", cost}, nil } } diff --git a/libfic/team_my.go b/libfic/team_my.go index 6e5404e9..242d0bb0 100644 --- a/libfic/team_my.go +++ b/libfic/team_my.go @@ -14,11 +14,11 @@ type myTeamFile struct { Size int64 `json:"size"` } type myTeamHint struct { - HintId int64 `json:"id"` - Title string `json:"title"` - Content string `json:"content"` - Cost int64 `json:"cost"` - Unlocked bool `json:"unlocked"` + HintId int64 `json:"id"` + Title string `json:"title"` + Content *string `json:"content"` + File *string `json:"file"` + Cost int64 `json:"cost"` } type myTeamExercice struct { ThemeId int `json:"theme_id"` @@ -99,9 +99,9 @@ func MyJSONTeam(t *Team, started bool) (interface{}, error) { } else { for _, h := range hints { if t == nil || t.HasHint(h) { - exercice.Hints = append(exercice.Hints, myTeamHint{h.Id, h.Title, h.Content, h.Cost, true}) + exercice.Hints = append(exercice.Hints, myTeamHint{h.Id, h.Title, &h.Content, &h.File, h.Cost}) } else { - exercice.Hints = append(exercice.Hints, myTeamHint{h.Id, h.Title, "", h.Cost, false}) + exercice.Hints = append(exercice.Hints, myTeamHint{h.Id, h.Title, nil, nil, h.Cost}) } } } From 78ce24f3f720eb465dba7d943ea488ff4d6b5634 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 15 Jan 2017 23:56:28 +0100 Subject: [PATCH 0551/2686] fixup! fixup! WIP esthetic changes --- frontend/static/css/fic.css | 1 - frontend/static/index.html | 4 +-- frontend/static/js/challenge.js | 5 ++-- frontend/static/public.html | 50 ++++++++++++++++++-------------- frontend/static/views/theme.html | 8 ++--- 5 files changed, 37 insertions(+), 31 deletions(-) diff --git a/frontend/static/css/fic.css b/frontend/static/css/fic.css index 2f9a7d81..081f0c84 100644 --- a/frontend/static/css/fic.css +++ b/frontend/static/css/fic.css @@ -15,7 +15,6 @@ body { } .navbar #clock { font-size: 70px; - text-align: center; } .point, .expired { transition: color text-shadow 1s; diff --git a/frontend/static/index.html b/frontend/static/index.html index 84c638b4..964d927a 100644 --- a/frontend/static/index.html +++ b/frontend/static/index.html @@ -46,7 +46,7 @@ Epita
    -
    +
    {{ time.hours | time }} : {{ time.minutes | time }} @@ -107,7 +107,7 @@
    diff --git a/frontend/static/js/challenge.js b/frontend/static/js/challenge.js index 6b5d21ee..2dbad794 100644 --- a/frontend/static/js/challenge.js +++ b/frontend/static/js/challenge.js @@ -30,14 +30,12 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"]) }); $locationProvider.html5Mode(true); }) - .run(function($rootScope, $timeout) { + .run(function($rootScope, $interval) { $rootScope.current_theme = 0; $rootScope.current_exercice = 0; $rootScope.time = {}; function updTime() { - $timeout.cancel($rootScope.cbm); - $rootScope.cbm = $timeout(updTime, 1000); if (sessionStorage.userService) { var time = angular.fromJson(sessionStorage.userService); var srv_cur = (Date.now() + (time.cu * 1000 - time.he)) / 1000; @@ -68,6 +66,7 @@ angular.module("FICApp", ["ngRoute", "ngSanitize"]) } } updTime(); + $interval(updTime, 1000); }) .controller("DataController", function($sce, $scope, $http, $rootScope, $timeout) { var actMenu = function() { diff --git a/frontend/static/public.html b/frontend/static/public.html index f3c5411f..b805d76c 100644 --- a/frontend/static/public.html +++ b/frontend/static/public.html @@ -20,7 +20,7 @@ - + -
    +
    +
    - - - - - - + + - - - - + + + + + + + + + + + + + + + +
    Niveau 1Niveau 2Niveau 3Niveau 4Niveau 5
    {{ th.name }}
    {{ themes[th].name }}{{ ex.solved }}{{ ex.tried }}
    Niveau {{ lvl }} + + {{ exercice.solved }} + {{ exercice.tried }} + +
    {{ team.rank }}ere
    {{ team.name }}
    + {{ mystats.themes[tid].solved }}/{{ mystats.themes[tid].total }} + ({{ mystats.themes[tid].tries }}) +
    + Résolus + Total résolus
    + Tentatives +
    + {{ mystats.themes[tid].solved }}
    + {{ mystats.themes[tid].tries }} +
    +
    - +
    +
    @@ -171,31 +156,139 @@ - - - + + +
    PlaceScore
    {{ r.rank }}ere
    {{ r.rank }}ere {{ r.name }} {{ r.score }}
    - -
    +
    +
    -
    +
    -
    +
    +
    {{ e.since | since }}
    - - Epita - + + +
    @@ -209,5 +302,10 @@ + From 416ad65c875229760c71043153181d0b48ef5a5b Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 20 Jan 2017 19:18:43 +0100 Subject: [PATCH 0565/2686] admin: add public interface management --- admin/api/public.go | 80 ++++++++++++++++++++ admin/index.go | 1 + admin/static.go | 3 + admin/static/index.html | 1 + admin/static/js/app.js | 80 ++++++++++++++++++++ admin/static/views/public.html | 129 +++++++++++++++++++++++++++++++++ 6 files changed, 294 insertions(+) create mode 100644 admin/api/public.go create mode 100644 admin/static/views/public.html diff --git a/admin/api/public.go b/admin/api/public.go new file mode 100644 index 00000000..ceccf230 --- /dev/null +++ b/admin/api/public.go @@ -0,0 +1,80 @@ +package api + +import ( + "encoding/json" + "os" + "path" + + "github.com/julienschmidt/httprouter" +) + +func init() { + router.GET("/api/public.json", apiHandler(getPublic)) + router.DELETE("/api/public.json", apiHandler(deletePublic)) + router.PUT("/api/public.json", apiHandler(savePublic)) +} + +type FICPublicScene struct { + Type string `json:"type"` + Params map[string]interface{} `json:"params"` +} + +func readPublic(path string) ([]FICPublicScene, error) { + var s []FICPublicScene + if fd, err := os.Open(path); err != nil { + return s, err + } else { + defer fd.Close() + jdec := json.NewDecoder(fd) + + if err := jdec.Decode(&s); err != nil { + return s, err + } + + return s, nil + } +} + +func savePublicTo(path string, s []FICPublicScene) error { + if fd, err := os.Create(path); err != nil { + return err + } else { + defer fd.Close() + jenc := json.NewEncoder(fd) + + if err := jenc.Encode(s); err != nil { + return err + } + + return nil + } +} + +func getPublic(_ httprouter.Params, body []byte) (interface{}, error) { + if _, err := os.Stat(path.Join(TeamsDir, "_public", "public.json")); !os.IsNotExist(err) { + return readPublic(path.Join(TeamsDir, "_public", "public.json")) + } else { + return []FICPublicScene{}, nil + } +} + +func deletePublic(_ httprouter.Params, body []byte) (interface{}, error) { + if err := savePublicTo(path.Join(TeamsDir, "_public", "public.json"), []FICPublicScene{}); err != nil { + return nil, err + } else { + return []FICPublicScene{}, err + } +} + +func savePublic(_ httprouter.Params, body []byte) (interface{}, error) { + var scenes []FICPublicScene + if err := json.Unmarshal(body, &scenes); err != nil { + return nil, err + } + + if err := savePublicTo(path.Join(TeamsDir, "_public", "public.json"), scenes); err != nil { + return nil, err + } else { + return scenes, err + } +} diff --git a/admin/index.go b/admin/index.go index 85c7448c..7e1270f2 100644 --- a/admin/index.go +++ b/admin/index.go @@ -23,6 +23,7 @@ const indextpl = `
  • Équipes
  • Thèmes
  • Exercices
  • +
  • Public
  • Événements
  • Paramètres
  • diff --git a/admin/static.go b/admin/static.go index ba2bebf5..9d1bb918 100644 --- a/admin/static.go +++ b/admin/static.go @@ -19,6 +19,9 @@ func init() { api.Router().GET("/events/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { http.ServeFile(w, r, path.Join(StaticDir, "index.html")) }) + api.Router().GET("/public", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + http.ServeFile(w, r, path.Join(StaticDir, "index.html")) + }) api.Router().GET("/settings/*_", func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { http.ServeFile(w, r, path.Join(StaticDir, "index.html")) }) diff --git a/admin/static/index.html b/admin/static/index.html index dcbd3374..631dd44a 100644 --- a/admin/static/index.html +++ b/admin/static/index.html @@ -21,6 +21,7 @@
  • Équipes
  • Thèmes
  • Exercices
  • +
  • Public
  • Événements
  • Paramètres
  • diff --git a/admin/static/js/app.js b/admin/static/js/app.js index 64a77597..458e49f8 100644 --- a/admin/static/js/app.js +++ b/admin/static/js/app.js @@ -37,6 +37,10 @@ angular.module("FICApp", ["ngRoute", "ngResource", "ngSanitize"]) controller: "TeamNewController", templateUrl: "views/team-new.html" }) + .when("/public", { + controller: "PublicController", + templateUrl: "views/public.html" + }) .when("/events", { controller: "EventsListController", templateUrl: "views/event-list.html" @@ -65,6 +69,11 @@ angular.module("FICApp") 'update': {method: 'PUT'}, }) }) + .factory("Scene", function($resource) { + return $resource("/api/public.json", null, { + 'update': {method: 'PUT'}, + }) + }) .factory("Team", function($resource) { return $resource("/api/teams/:teamId", { teamId: '@id' }, { 'update': {method: 'PUT'}, @@ -228,6 +237,77 @@ angular.module("FICApp") } }) + .controller("PublicController", function($scope, Scene, Theme, Teams, Exercice) { + $scope.scenes = Scene.query(); + $scope.themes = Theme.query(); + $scope.teams = Teams.get(); + + $scope.types = { + "welcome": "Messages de bienvenue", + "message": "Message", + "panel": "Boîte", + "exercice": "Exercice", + "table": "Tableau", + "rank": "Classement", + }; + $scope.welcome_types = { + "init": "Accueil des équipes", + "public": "Accueil du public", + "countdown": "Compte à rebours lancement", + }; + $scope.panel_types = { + "panel-default": "Default", + "panel-info": "Info", + "panel-success": "Success", + "panel-warning": "Warning", + "panel-danger": "Danger", + }; + $scope.rank_types = { + "general": "Classement général", + }; + $scope.table_types = { + "levels": "Niveaux d'exercices", + "teams": "Équipes", + }; + $scope.exercices = Exercice.query(); + + $scope.clearScene = function() { + Scene.delete(function() { + $scope.scenes = []; + }); + }; + $scope.saveScenes = function() { + Scene.update($scope.scenes); + }; + $scope.addScene = function() { + $scope.scenes.push({params: {}}); + }; + $scope.delScene = function(s) { + angular.forEach($scope.scenes, function(scene, k) { + if (scene == s) + $scope.scenes.splice(k, 1); + }); + }; + $scope.upScene = function(s) { + angular.forEach($scope.scenes, function(scene, k) { + if (scene == s && k > 0) { + $scope.scenes.splice(k, 1); + $scope.scenes.splice(k - 1, 0, scene); + } + }); + }; + $scope.downScene = function(s) { + var move = true; + angular.forEach($scope.scenes, function(scene, k) { + if (move && scene == s) { + $scope.scenes.splice(k, 1); + $scope.scenes.splice(k + 1, 0, scene); + move = false; + } + }); + }; + }) + .controller("EventsListController", function($scope, Event, $location) { $scope.events = Event.query(); $scope.fields = ["id", "kind", "txt", "time"]; diff --git a/admin/static/views/public.html b/admin/static/views/public.html new file mode 100644 index 00000000..435d30bd --- /dev/null +++ b/admin/static/views/public.html @@ -0,0 +1,129 @@ +
    +

    Interface publique Vider la scène Ajouter un élément +

    + +
    +
    +
    +
    + +
    +
    +
    + Up + Down +
    + +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    + +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +
    +
    From 544bbb745c7289fd8fe367d8861fe011651e7608 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 20 Jan 2017 20:52:31 +0100 Subject: [PATCH 0566/2686] admin: new route /members/ --- admin/api/team.go | 22 ++++++++++++++++++++++ libfic/member.go | 9 +++++++++ 2 files changed, 31 insertions(+) diff --git a/admin/api/team.go b/admin/api/team.go index 828ff18b..5ae6ddee 100644 --- a/admin/api/team.go +++ b/admin/api/team.go @@ -3,6 +3,7 @@ package api import ( "encoding/json" "fmt" + "strconv" "strings" "srs.epita.fr/fic-server/libfic" @@ -62,6 +63,9 @@ func init() { router.GET("/api/teams/:tid/name", apiHandler(teamHandler( func(team fic.Team, _ []byte) (interface{}, error) { return team.InitialName, nil }))) + + router.GET("/api/members/:mid/team", apiHandler(dispMemberTeam)) + router.GET("/api/members/:mid/team/name", apiHandler(dispMemberTeamName)) } func nginxGenMember() (string, error) { @@ -149,3 +153,21 @@ func addTeamMember(team fic.Team, body []byte) (interface{}, error) { return team.GetMembers() } + +func dispMemberTeam(ps httprouter.Params, body []byte) (interface{}, error) { + if mid, err := strconv.Atoi(string(ps.ByName("mid"))); err != nil { + return fic.Team{}, err + } else { + return fic.GetMember(mid) + } +} + +func dispMemberTeamName(ps httprouter.Params, body []byte) (interface{}, error) { + if mid, err := strconv.Atoi(string(ps.ByName("mid"))); err != nil { + return nil, err + } else if team, err := fic.GetMember(mid); err != nil { + return nil, err + } else { + return team.InitialName, nil + } +} diff --git a/libfic/member.go b/libfic/member.go index 7dad3c4c..0b4ce660 100644 --- a/libfic/member.go +++ b/libfic/member.go @@ -10,6 +10,15 @@ type Member struct { Company string `json:"company"` } +func GetMember(cnt int) (Team, error) { + var t Team + if err := DBQueryRow("SELECT T.id_team, T.initial_name, T.name, T.color FROM team_members M RIGHT OUTER JOIN teams T ON T.id_team = M.id_team LIMIT ?, 1", cnt - 1).Scan(&t.Id, &t.InitialName, &t.Name, &t.Color); err != nil { + return t, err + } + + return t, nil +} + func (t Team) GetMembers() ([]Member, error) { if rows, err := DBQuery("SELECT id_member, firstname, lastname, nickname, company FROM team_members WHERE id_team = ?", t.Id); err != nil { return nil, err From 318bc4bc4d616907f164ae6f198d8760515ee7c5 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 20 Jan 2017 20:53:32 +0100 Subject: [PATCH 0567/2686] Update openssl settings --- admin/pki/openssl.cnf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/pki/openssl.cnf b/admin/pki/openssl.cnf index 495674f9..1848365b 100644 --- a/admin/pki/openssl.cnf +++ b/admin/pki/openssl.cnf @@ -101,7 +101,7 @@ emailAddress = optional #################################################################### [ req ] -default_bits = 2048 +default_bits = 4096 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes From 17f51f5e7b45821d0f59135b05b39cf4a410c1d5 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 24 Jan 2017 02:14:28 +0100 Subject: [PATCH 0568/2686] admin: can force page regeneration --- admin/api/settings.go | 2 +- admin/static/js/app.js | 4 ++++ admin/static/views/settings.html | 4 +++- backend/main.go | 6 +++++- settings/settings.go | 1 + 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/admin/api/settings.go b/admin/api/settings.go index 31bc7446..40afef56 100644 --- a/admin/api/settings.go +++ b/admin/api/settings.go @@ -22,7 +22,7 @@ func getSettings(_ httprouter.Params, body []byte) (interface{}, error) { if settings.ExistsSettings(path.Join(TeamsDir, settings.SettingsFile)) { return settings.ReadSettings(path.Join(TeamsDir, settings.SettingsFile)) } else { - return settings.FICSettings{time.Unix(0,0), time.Unix(0,0), fic.FirstBlood, fic.SubmissionCostBase, false, false, false, true, true}, nil + return settings.FICSettings{time.Unix(0,0), time.Unix(0,0), time.Unix(0,0), fic.FirstBlood, fic.SubmissionCostBase, false, false, false, true, true}, nil } } diff --git a/admin/static/js/app.js b/admin/static/js/app.js index 458e49f8..34366490 100644 --- a/admin/static/js/app.js +++ b/admin/static/js/app.js @@ -228,6 +228,10 @@ angular.module("FICApp") $location.url("/"); }); } + $scope.regenerate = function() { + this.config.generation = (new Date()).toISOString(); + $scope.saveSettings(); + } $scope.launchChallenge = function() { var ts = Date.now() - Date.now() % 60000; var d = new Date(ts + 120000); diff --git a/admin/static/views/settings.html b/admin/static/views/settings.html index fe15a1dc..97aebc06 100644 --- a/admin/static/views/settings.html +++ b/admin/static/views/settings.html @@ -1,7 +1,9 @@ -

    Paramètres

    +

    Paramètres Regénérer les fichiers statiques

    + +
    diff --git a/backend/main.go b/backend/main.go index b0d660ee..6b458107 100644 --- a/backend/main.go +++ b/backend/main.go @@ -43,8 +43,12 @@ func watchsubdir(watcher *fsnotify.Watcher, pathname string) error { } } +var lastRegeneration time.Time + func reloadSettings(config settings.FICSettings) { - if fic.PartialValidation != config.PartialValidation || fic.UnlockedChallenges != !config.EnableExerciceDepend || fic.FirstBlood != config.FirstBlood || fic.SubmissionCostBase != config.SubmissionCostBase { + if lastRegeneration != config.Generation || fic.PartialValidation != config.PartialValidation || fic.UnlockedChallenges != !config.EnableExerciceDepend || fic.FirstBlood != config.FirstBlood || fic.SubmissionCostBase != config.SubmissionCostBase { + lastRegeneration = config.Generation + fic.PartialValidation = config.PartialValidation fic.UnlockedChallenges = !config.EnableExerciceDepend diff --git a/settings/settings.go b/settings/settings.go index 6775c03c..d327663c 100644 --- a/settings/settings.go +++ b/settings/settings.go @@ -15,6 +15,7 @@ const SettingsFile = "settings.json" type FICSettings struct { Start time.Time `json:"start"` End time.Time `json:"end"` + Generation time.Time `json:"generation"` FirstBlood float64 `json:"firstBlood"` SubmissionCostBase float64 `json:"submissionCostBase"` From 4fe641a9f5183a028a39b02cb2893293bac15fa5 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 24 Jan 2017 02:17:21 +0100 Subject: [PATCH 0569/2686] change the way themes are stored in stats --- admin/static/js/app.js | 6 +++++- libfic/team_stats.go | 13 ++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/admin/static/js/app.js b/admin/static/js/app.js index 34366490..34d64d68 100644 --- a/admin/static/js/app.js +++ b/admin/static/js/app.js @@ -480,7 +480,11 @@ angular.module("FICApp") $scope.teamstats = TeamStats.get({ teamId: $routeParams.teamId }); $scope.teamstats.$promise.then(function(res) { solvedByLevelPie("#pieLevels", res.levels); - solvedByThemesPie("#pieThemes", res.themes); + var themes = []; + angular.forEach(res.themes, function(theme, tid) { + themes.push(theme); + }) + solvedByThemesPie("#pieThemes", themes); }); }) .controller("TeamExercicesController", function($scope, Teams, Themes, TeamMy, Exercice, $routeParams) { diff --git a/libfic/team_stats.go b/libfic/team_stats.go index a9ef4112..300dbe7b 100644 --- a/libfic/team_stats.go +++ b/libfic/team_stats.go @@ -13,8 +13,8 @@ type statLine struct { } type teamStats struct { - Levels []statLine `json:"levels"` - Themes []statLine `json:"themes"` + Levels []statLine `json:"levels"` + Themes map[int64]statLine `json:"themes"` } func (s *teamStats) GetLevel(level int) *statLine { @@ -38,7 +38,10 @@ func (t Team) GetStats() (interface{}, error) { } func GetTeamsStats(t *Team) (interface{}, error) { - stat := teamStats{} + stat := teamStats{ + []statLine{}, + map[int64]statLine{}, + } if themes, err := GetThemes(); err != nil { return nil, err @@ -84,13 +87,13 @@ func GetTeamsStats(t *Team) (interface{}, error) { } } - stat.Themes = append(stat.Themes, statLine{ + stat.Themes[theme.Id] = statLine{ theme.Name, total, solved, tried, tries, - }) + } } return stat, nil From cab95b79856b3a03586fbb56fb167151b415493b Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 24 Jan 2017 02:18:05 +0100 Subject: [PATCH 0570/2686] libfic: new function to retrieve exercices from a hint --- libfic/hint.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libfic/hint.go b/libfic/hint.go index a47b3501..d329c692 100644 --- a/libfic/hint.go +++ b/libfic/hint.go @@ -84,3 +84,12 @@ func (h EHint) Delete() (int64, error) { return nb, err } } + +func (h EHint) GetExercice() (Exercice, error) { + var eid int64 + if err := DBQueryRow("SELECT id_exercice FROM exercice_hints WHERE id_hint = ?", h.Id).Scan(&eid); err != nil { + return Exercice{}, err + } + + return GetExercice(eid) +} From cb1fe0847b1f9ad99496bf8e643aeceefddb0a82 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 24 Jan 2017 02:19:49 +0100 Subject: [PATCH 0571/2686] frontend: move file (on the same partition) instead of open, write, close the final file --- frontend/main.go | 6 ++++-- frontend/save.go | 46 +++++++++++++++++----------------------------- 2 files changed, 21 insertions(+), 31 deletions(-) diff --git a/frontend/main.go b/frontend/main.go index 30c6cb31..3c939ef4 100644 --- a/frontend/main.go +++ b/frontend/main.go @@ -17,6 +17,7 @@ const startedFile = "started" var TeamsDir string var SubmissionDir string +var TmpSubmissionDir string var touchTimer *time.Timer = nil @@ -70,10 +71,11 @@ func main() { log.SetPrefix("[frontend] ") SubmissionDir = path.Clean(SubmissionDir) + TmpSubmissionDir = path.Join(SubmissionDir, ".tmp") log.Println("Creating submission directory...") - if _, err := os.Stat(SubmissionDir); os.IsNotExist(err) { - if err := os.MkdirAll(SubmissionDir, 0777); err != nil { + if _, err := os.Stat(TmpSubmissionDir); os.IsNotExist(err) { + if err := os.MkdirAll(TmpSubmissionDir, 0777); err != nil { log.Fatal("Unable to create submission directory: ", err) } } diff --git a/frontend/save.go b/frontend/save.go index 8e87cbc4..bb2009b9 100644 --- a/frontend/save.go +++ b/frontend/save.go @@ -1,6 +1,7 @@ package main import ( + "bufio" "io/ioutil" "log" "net/http" @@ -42,40 +43,27 @@ func saveFile(dirname string, filename string, r *http.Request) error { } } - var f *os.File + // Write content to temp file + tmpfile, err := ioutil.TempFile(TmpSubmissionDir, "") + if err != nil { + return err + } + + writer := bufio.NewWriter(tmpfile) + reader := bufio.NewReader(r.Body) + if _, err := reader.WriteTo(writer); err != nil { + return err + } + writer.Flush() + tmpfile.Close() if filename == "" { - if fd, err := ioutil.TempFile(dirname, ""); err != nil { - return err - } else { - defer f.Close() - f = fd - } - } else { - if fd, err := os.Create(path.Join(dirname, filename)); err != nil { - return err - } else { - defer f.Close() - f = fd - } + filename = path.Base(tmpfile.Name()) } - // Read request body - var body []byte - if r.ContentLength > 0 { - tmp := make([]byte, 1024) - for { - n, err := r.Body.Read(tmp) - for j := 0; j < n; j++ { - body = append(body, tmp[j]) - } - if err != nil || n <= 0 { - break - } - } + if err := os.Rename(tmpfile.Name(), path.Join(dirname, filename)); err != nil { + log.Println("[ERROR] Unable to move file: ", err) } - f.Write(body) - return nil } From c1c84ba3d1b31c4d8f6a1db814ca16166ee8fe59 Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 24 Jan 2017 02:20:20 +0100 Subject: [PATCH 0572/2686] backend: generate an event when a team open an hint --- backend/hint.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/backend/hint.go b/backend/hint.go index 17124f5b..2a074a31 100644 --- a/backend/hint.go +++ b/backend/hint.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "fmt" "log" "io/ioutil" "os" @@ -28,6 +29,17 @@ func treatOpeningHint(pathname string, team fic.Team) { } else if err := team.OpenHint(hint); err != nil { log.Println("[ERR]", err) } else { + // Write event + if exercice, err := hint.GetExercice(); err != nil { + log.Println("[WRN]", err) + } else if lvl, err := exercice.GetLevel(); err != nil { + log.Println("[WRN]", err) + } else if theme, err := exercice.GetTheme(); err != nil { + log.Println("[WRN]", err) + } else if _, err := fic.NewEvent(fmt.Sprintf("L'équipe %s a dévoilé un indice pour le %de challenge %s !", team.Name, lvl, theme.Name), "alert-info"); err != nil { + log.Println("[WRN] Unable to create event:", err) + } + genTeamMyFile(team) if err := os.Remove(pathname); err != nil { log.Println("[ERR]", err) From da0e7facfddaf5380d56e09bad33f250ecd5bb8a Mon Sep 17 00:00:00 2001 From: nemunaire Date: Tue, 24 Jan 2017 02:21:21 +0100 Subject: [PATCH 0573/2686] frontend: improve 401 page thank to initial guide --- frontend/static/css/fic.css | 32 ++++++++ frontend/static/welcome.html | 137 ++++++++++++++++++++++++++++++----- 2 files changed, 151 insertions(+), 18 deletions(-) diff --git a/frontend/static/css/fic.css b/frontend/static/css/fic.css index 0c186d5f..14d20d4f 100644 --- a/frontend/static/css/fic.css +++ b/frontend/static/css/fic.css @@ -1,10 +1,42 @@ +@font-face { + font-family: "Linux Biolinum"; + src: url('../fonts/LinBiolinum_R.woff') format('woff'); +} +@font-face { + font-family: "Linux Biolinum"; + src: url('../fonts/LinBiolinum_RB.woff') format('woff'); + font-weight: bold; +} +@font-face { + font-family: "Linux Biolinum"; + src: url('../fonts/LinBiolinum_RI.woff') format('woff'); + font-style: italic; +} + +[ng-cloak] { + display:none !important; +} + body { overflow-y: scroll; } +.beautiful { + font-family: "Linux Biolinum",Helvetica,Arial,sans-serif; +} +.beautiful ol { + font-size: 133%; +} +.beautiful ol ol { + font-size: 90%; +} + .text-bold { font-weight: bolder; } +.text-indent p { + text-indent: 1em; +} .navbar { margin-bottom: 0; diff --git a/frontend/static/welcome.html b/frontend/static/welcome.html index 20ccbbe1..8455c639 100644 --- a/frontend/static/welcome.html +++ b/frontend/static/welcome.html @@ -1,5 +1,5 @@ - + Challenge Forensic @@ -18,22 +18,22 @@ - +

    -
    +
    {{ team.id }}
    -
    +
    - +

    -
    +
    diff --git a/admin/static/views/team-new.html b/admin/static/views/team-new.html deleted file mode 100644 index 8f1f14ee..00000000 --- a/admin/static/views/team-new.html +++ /dev/null @@ -1,11 +0,0 @@ -

    New team

    - -
    - -
    -
    - -
    -
    - -
    From 4a97b065203784da2a55bf22951a50d791beabca Mon Sep 17 00:00:00 2001 From: nemunaire Date: Sat, 4 Nov 2017 15:15:54 +0100 Subject: [PATCH 0599/2686] Set SQL_MODES, waiting https://jira.mariadb.org/browse/MDEV-10426 to be solved --- libfic/db.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libfic/db.go b/libfic/db.go index a08dfc00..e10967ea 100644 --- a/libfic/db.go +++ b/libfic/db.go @@ -38,6 +38,9 @@ func DBInit(dsn string) error { if db, err = sql.Open("mysql", dsn + "?parseTime=true&foreign_key_checks=1"); err != nil { return err } + if _, err := db.Exec(`SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';`); err != nil { + return err + } return nil } From 510e25e3515649d6b4c2b4fdee6ed90a120a3fad Mon Sep 17 00:00:00 2001 From: nemunaire Date: Fri, 10 Nov 2017 20:23:08 +0100 Subject: [PATCH 0600/2686] frontend: fix timer location --- frontend/static/public.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/static/public.html b/frontend/static/public.html index 8833201d..4040831f 100644 --- a/frontend/static/public.html +++ b/frontend/static/public.html @@ -179,8 +179,8 @@
    -