From 051575fa642c2a373d6c9b0fe60458f94f65f6b8 Mon Sep 17 00:00:00 2001 From: FramaJosephK <josephk@framasoft.org> Date: Tue, 21 Oct 2014 01:31:26 +0200 Subject: [PATCH] The big one --- admin/index.php | 10 +- adminstuds.php | 316 ++- app/classes/Framadate/Utils.php | 7 +- app/inc/i18n.php | 10 +- apropos.php | 279 --- bandeaux.php | 26 +- choix_autre.php | 104 +- choix_date.php | 79 +- contacts.php | 144 -- creation_sondage.php | 26 +- css/bootstrap-accessibility.css | 64 - css/datepicker3.css | 67 +- css/frama.css | 450 ++++ css/style.css | 145 +- exportcsv.php | 45 +- images/classic.png | Bin 12630 -> 23737 bytes images/date.png | Bin 15920 -> 23500 bytes images/logo-framadate.png | Bin 4783 -> 2580 bytes index.php | 61 +- infos_sondage.php | 16 +- js/bootstrap-accessibility.js | 406 ---- js/bootstrap-accessibility.min.js | 4 - js/bootstrap-datepicker.js | 3292 +++++++++++++++-------------- js/core.js | 172 +- locale/fr_FR/LC_MESSAGES/Studs.mo | Bin 16587 -> 18559 bytes locale/fr_FR/LC_MESSAGES/Studs.po | 278 ++- studs.php | 151 +- 27 files changed, 3067 insertions(+), 3085 deletions(-) delete mode 100644 apropos.php delete mode 100644 contacts.php delete mode 100644 css/bootstrap-accessibility.css create mode 100644 css/frama.css delete mode 100644 js/bootstrap-accessibility.js delete mode 100644 js/bootstrap-accessibility.min.js diff --git a/admin/index.php b/admin/index.php index 4c5ebf7d..e1abb1ef 100644 --- a/admin/index.php +++ b/admin/index.php @@ -60,7 +60,9 @@ while($dsondage = $sondage->FetchNextObject(false)) { $sondage=$connect->Execute("select * from sondage WHERE date_fin > DATE_SUB(now(), INTERVAL 3 MONTH) ORDER BY date_fin ASC"); $nbsondages=$sondage->RecordCount(); -echo '<p>' . $nbsondages. ' ' . _("polls in the database at this time") .'</p>'."\n"; +$btn_logs = (is_readable('logs_studs.txt')) ? '<a role="button" class="btn btn-default btn-xs pull-right" href="'.str_replace('/admin','', Utils::get_server_name()).'admin/logs_studs.txt">'. _("Logs") .'</a>' : ''; + +echo '<p>' . $nbsondages. ' ' . _("polls in the database at this time") . $btn_logs .'</p>'."\n"; // tableau qui affiche tous les sondages de la base echo '<table class="table table-bordered"> @@ -101,9 +103,9 @@ while($dsondage = $sondage->FetchNextObject(false)) { } echo ' <td>'.$nbuser.'</td> - <td><a href="' . Utils::getUrlSondage($dsondage->id_sondage) . '" class="btn btn-link" title="'. _("See the poll") .'"><span class="glyphicon glyphicon-eye-open"></span></a></td> - <td><a href="' . Utils::getUrlSondage($dsondage->id_sondage_admin, true) . '" class="btn btn-link" title="'. _("Change the poll") .'"><span class="glyphicon glyphicon-pencil"></span></a></td> - <td><button type="submit" name="supprimersondage'.$dsondage->id_sondage.'" value="'. _("Remove the poll") .'" class="btn btn-link" title="'. _("Remove the poll") .'"><span class="glyphicon glyphicon-trash text-danger"></span></td> + <td><a href="' . Utils::getUrlSondage($dsondage->id_sondage) . '" class="btn btn-link" title="'. _("See the poll") .'"><span class="glyphicon glyphicon-eye-open"></span><span class="sr-only">' . _("See the poll") . '</span></a></td> + <td><a href="' . Utils::getUrlSondage($dsondage->id_sondage_admin, true) . '" class="btn btn-link" title="'. _("Change the poll") .'"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">' . _("Change the poll") . '</span></a></td> + <td><button type="submit" name="supprimersondage'.$dsondage->id_sondage.'" value="'. _("Remove the poll") .'" class="btn btn-link" title="'. _("Remove the poll") .'"><span class="glyphicon glyphicon-trash text-danger"></span><span class="sr-only">' . _("Remove the poll") . '</span></td> </tr>'."\n"; $i++; } diff --git a/adminstuds.php b/adminstuds.php index fc2ffebd..67759b81 100644 --- a/adminstuds.php +++ b/adminstuds.php @@ -76,26 +76,36 @@ if (!$sondage || $sondage->RecordCount() != 1){ $dsujet=$sujets->FetchObject(false); $dsondage=$sondage->FetchObject(false); +// Send email (only once during the session) to alert admin of the change he made +$email_admin = $dsondage->mail_admin; +function send_mail_admin() { + global $email_admin; + global $numsondageadmin; + + if(!isset($_SESSION["mail_admin_sent"])) { + Utils::sendEmail( $email_admin, + _("[ADMINISTRATOR] New settings for your poll") . ' ' . stripslashes( $dsondage->titre ), + _("You have changed the settings of your poll. \nYou can modify this poll with this link") . + " :\n\n" . Utils::getUrlSondage($numsondageadmin, true) . "\n\n" . + _("Thanks for your confidence.") . "\n" . NOMAPPLICATION + ); + $_SESSION["mail_admin_sent"]=true; + } +} //si la valeur du nouveau titre est valide et que le bouton est activé -$adresseadmin = $dsondage->mail_admin; - if (isset($_POST["boutonnouveautitre"])) { if (Utils::issetAndNoEmpty('nouveautitre') === false) { $err |= TITLE_EMPTY; } else { - //modification de la base SQL avec le nouveau titre + //Update SQL database with new title $nouveautitre = htmlentities(html_entity_decode($_POST['nouveautitre'], ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8'); $sql = 'UPDATE sondage SET titre = '.$connect->Param('nouveautitre').' WHERE id_sondage = '.$connect->Param('numsondage'); $sql = $connect->Prepare($sql); - //envoi du mail pour prevenir l'admin de sondage + //Email sent to the admin if ($connect->Execute($sql, array($nouveautitre, $numsondage))) { - Utils::sendEmail( $adresseadmin, - _("[ADMINISTRATOR] New title for your poll") . ' ' . NOMAPPLICATION, - _("You have changed the title of your poll. \nYou can modify this poll with this link") . - " :\n\n" . Utils::getUrlSondage($numsondageadmin, true) . "\n\n" . - _("Thanks for your confidence.") . "\n" . NOMAPPLICATION ); + send_mail_admin(); } } } @@ -107,17 +117,13 @@ if (isset($_POST["boutonnouveauxcommentaires"])) { } else { $commentaires = htmlentities(html_entity_decode($_POST['nouveauxcommentaires'], ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8'); - //modification de la base SQL avec les nouveaux commentaires + //Update SQL database with new description $sql = 'UPDATE sondage SET commentaires = '.$connect->Param('commentaires').' WHERE id_sondage = '.$connect->Param('numsondage'); $sql = $connect->Prepare($sql); + //Email sent to the admin if ($connect->Execute($sql, array($commentaires, $numsondage))) { - //envoi du mail pour prevenir l'admin de sondage - Utils::sendEmail( $adresseadmin, - _("[ADMINISTRATOR] New description of your poll") . ' ' . NOMAPPLICATION, - _("You have changed the description of your poll. \nYou can modify this poll with this link") . - " :\n\n" . Utils::getUrlSondage($numsondageadmin, true) . " \n\n" . - _("Thanks for your confidence.") . "\n" . NOMAPPLICATION ); + send_mail_admin(); } } } @@ -129,21 +135,38 @@ if (isset($_POST["boutonnouvelleadresse"])) { } else { $nouvelleadresse = htmlentities(html_entity_decode($_POST['nouvelleadresse'], ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8'); - //modification de la base SQL avec la nouvelle adresse + //Update SQL database with new email $sql = 'UPDATE sondage SET mail_admin = '.$connect->Param('nouvelleadresse').' WHERE id_sondage = '.$connect->Param('numsondage'); $sql = $connect->Prepare($sql); + //Email sent to the admin if ($connect->Execute($sql, array($nouvelleadresse, $numsondage))) { - //envoi du mail pour prevenir l'admin de sondage - Utils::sendEmail( $_POST['nouvelleadresse'], - _("[ADMINISTRATOR] New email address for your poll") . ' ' . NOMAPPLICATION, - _("You have changed your email address in your poll. \nYou can modify this poll with this link") . - " :\n\n" . Utils::getUrlSondage($numsondageadmin, true) . "\n\n" . - _("Thanks for your confidence.") . "\n" . NOMAPPLICATION ); + send_mail_admin(); } } } +//New poll rules +if (isset($_POST["btn_poll_rules"])) { + echo '<!-- '; print_r($_POST); echo ' -->'; + if($_POST['poll_rules'] == '+') { + $new_poll_rules = substr($dsondage->format, 0, 1).'+'; + } elseif($_POST['poll_rules'] == '-') { + $new_poll_rules = substr($dsondage->format, 0, 1).'-'; + } else { + $new_poll_rules = substr($dsondage->format, 0, 1); + } + + //Update SQL database with new rules + $sql = 'UPDATE sondage SET format = '.$connect->Param('new_poll_rules').' WHERE id_sondage = '.$connect->Param('numsondage'); + $sql = $connect->Prepare($sql); + + //Email sent to the admin + if ($connect->Execute($sql, array($new_poll_rules, $numsondage))) { + send_mail_admin(); + } +} + // reload $dsujet=$sujets->FetchObject(false); $dsondage=$sondage->FetchObject(false); @@ -161,7 +184,7 @@ if (isset($_POST["ajoutsujet"])) { <form name="formulaire" class="form-horizontal" action="' . Utils::getUrlSondage($numsondageadmin, true) . '" method="POST"> <h2>' . _("Column's adding") . '</h2>'."\n"; - if ($dsondage->format=="A"||$dsondage->format=="A+"){ + if (substr($dsondage->format, 0, 1)=="A"){ echo ' <div class="form-group"> <label for="nouvellecolonne" class="col-md-6">' . _("Add a column") .' :</label> @@ -224,6 +247,20 @@ if (isset($_POST["suppressionsondage"])) { die(); } +// Remove all the comments +if (isset($_POST["removecomments"])) { + $sql = 'DELETE FROM comments WHERE id_sondage='.$connect->Param('numsondage'); + $sql = $connect->Prepare($sql); + $cleaning = $connect->Execute($sql, array($numsondage)); +} + +// Remove all the votes +if (isset($_POST["removevotes"])) { + $sql = 'DELETE FROM user_studs WHERE id_sondage='.$connect->Param('numsondage'); + $sql = $connect->Prepare($sql); + $cleaning = $connect->Execute($sql, array($numsondage)); +} + //action si bouton confirmation de suppression est activé if (isset($_POST["confirmesuppression"])) { $nbuser=$user_studs->RecordCount(); @@ -233,13 +270,8 @@ if (isset($_POST["confirmesuppression"])) { // on ecrit dans le fichier de logs la suppression du sondage error_log($date . " SUPPRESSION: $dsondage->id_sondage\t$dsondage->format\t$dsondage->nom_admin\t$dsondage->mail_admin\n", 3, 'admin/logs_studs.txt'); - //envoi du mail a l'administrateur du sondage - Utils::sendEmail( $adresseadmin, - _("[ADMINISTRATOR] Removing of your poll") . ' ' . NOMAPPLICATION, - _("You have removed your poll. \nYou can make new polls with this link") . - " :\n\n" . Utils::get_server_name() . "index.php \n\n" . - _("Thanks for your confidence.") . "\n" . NOMAPPLICATION ); - + // Email sent + send_mail_admin(); //affichage de l'ecran de confirmation de suppression de sondage Utils::print_header(_("Your poll has been removed!")); @@ -347,7 +379,7 @@ if (isset($_POST["boutonp"])) { //action quand on ajoute une colonne au format AUTRE -if (isset($_POST["ajoutercolonne"]) && Utils::issetAndNoEmpty('nouvellecolonne') && ($dsondage->format == "A" || $dsondage->format == "A+")) { +if (isset($_POST["ajoutercolonne"]) && Utils::issetAndNoEmpty('nouvellecolonne') && (substr($dsondage->format, 0, 1) == "A" )) { $nouveauxsujets=$dsujet->sujet; //on rajoute la valeur a la fin de tous les sujets deja entrés @@ -359,16 +391,13 @@ if (isset($_POST["ajoutercolonne"]) && Utils::issetAndNoEmpty('nouvellecolonne') $sql = 'UPDATE sujet_studs SET sujet = '.$connect->Param('nouveauxsujets').' WHERE id_sondage = '.$connect->Param('numsondage'); $sql = $connect->Prepare($sql); if ($connect->Execute($sql, array($nouveauxsujets, $numsondage))) { - //envoi d'un mail pour prévenir l'administrateur du changement - Utils::sendEmail( "$adresseadmin", "" . _("[ADMINISTRATOR] New column for your poll").NOMAPPLICATION, "" . - _("You have added a new column in your poll. \nYou can inform the voters of this change with this link") . - " : \n\n" . Utils::getUrlSondage($numsondage) . " \n\n " . _("Thanks for your confidence.") . "\n".NOMAPPLICATION ); + send_mail_admin(); } } //action quand on ajoute une colonne au format DATE -if (isset($_POST["ajoutercolonne"]) && ($dsondage->format == "D" || $dsondage->format == "D+")) { +if (isset($_POST["ajoutercolonne"]) && (substr($dsondage->format, 0, 1) == "D")) { $nouveauxsujets=$dsujet->sujet; if (isset($_POST["newdate"]) && $_POST["newdate"] != "vide") { @@ -446,13 +475,8 @@ if (isset($_POST["ajoutercolonne"]) && ($dsondage->format == "D" || $dsondage->f } } - //envoi d'un mail pour prévenir l'administrateur du changement - $adresseadmin = $dsondage->mail_admin; - - Utils::sendEmail( $adresseadmin, - _("[ADMINISTRATOR] New column for your poll"), - _("You have added a new column in your poll. \nYou can inform the voters of this change with this link"). - " : \n\n" . Utils::getUrlSondage($numsondage) . " \n\n " . _("Thanks for your confidence.") . "\n".NOMAPPLICATION ); + //Email sent to the admin + send_mail_admin(); } else { $erreur_ajout_date="yes"; @@ -644,6 +668,20 @@ $title = (isset($_POST["boutonnouveautitre"]) && Utils::issetAndNoEmpty('nouveau $description = (isset($_POST["nouveauxcommentaires"])) ? stripslashes(htmlentities(html_entity_decode($_POST['nouveauxcommentaires'], ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8')) : stripslashes( $dsondage->commentaires ); $email_admin = (isset($_POST["boutonnouvelleadresse"]) && Utils::issetAndNoEmpty('nouvelleadresse')) ? htmlentities(html_entity_decode($_POST['nouvelleadresse'], ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8') : stripslashes( $dsondage->mail_admin ); +//Poll format (locked A-/D-, open A/D, editable A+/D+) +$poll_rules = (isset($_POST["poll_rules"]) && Utils::issetAndNoEmpty('btn_poll_rules')) ? $_POST["poll_rules"] : substr($dsondage->format, 1, 1); +$poll_rules_opt1 = '';$poll_rules_opt2 = '';$poll_rules_opt3 = ''; +if($poll_rules == '+') { + $poll_rules_text = '<span class="glyphicon glyphicon-edit"></span> '. _("Votes are editable"); + $poll_rules_opt3 = 'selected'; +} elseif($poll_rules == '-') { + $poll_rules_text = '<span class="glyphicon glyphicon-lock"></span> '. _("Votes and comments are locked"); + $poll_rules_opt1 = 'selected'; +} else { + $poll_rules_text = '<span class="glyphicon glyphicon-check"></span> '. _("Votes and comments are open"); + $poll_rules_opt2 = 'selected'; +} + if ($errors!='') { Utils::print_header(_("Error!")); bandeau_titre(_("Error!")); @@ -668,8 +706,8 @@ echo ' <div class="input-group"> <input type="text" class="form-control" id="newtitle" name="nouveautitre" size="40" value="'.$title.'" /> <span class="input-group-btn"> - <button type="submit" class="btn btn-success" name="boutonnouveautitre" value="1" title="'. _('Save the new title') .'"><span class="glyphicon glyphicon-ok"></span></button> - <button class="btn btn-link btn-cancel" title="'. _('Cancel the title edit') .'"><span class="glyphicon glyphicon-remove"></span></button> + <button type="submit" class="btn btn-success" name="boutonnouveautitre" value="1" title="'. _('Save the new title') .'"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">' . _('Save') . '</span></button> + <button class="btn btn-link btn-cancel" title="'. _('Cancel the title edit') .'"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">' . _('Cancel') . '</span></button> </span> </div> </div> @@ -678,7 +716,15 @@ echo ' <div class="btn-group pull-right"> <button onclick="javascript:print(); return false;" class="btn btn-default"><span class="glyphicon glyphicon-print"></span> ' . _('Print') . '</button> <button onclick="window.location.href=\'' . Utils::get_server_name() . 'exportcsv.php?numsondage=' . $numsondage . '\';return false;" class="btn btn-default"><span class="glyphicon glyphicon-download-alt"></span> ' . _('Export to CSV') . '</button> - <button type="submit" id="suppressionsondage" name="suppressionsondage" value="" class="btn btn-danger" title="'. _("Remove the poll") .'"><span class="glyphicon glyphicon-trash"></span></button> + <button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown"> + <span class="glyphicon glyphicon-trash"></span> <span class="sr-only">' . _("Remove") . '</span> <span class="caret"></span> + </button> + <ul class="dropdown-menu" role="menu"> + <li><button class="btn btn-link" type="submit" name="removevotes">' . _('Remove all the votes') . '</button></li> + <li><button class="btn btn-link" type="submit" name="removecomments">' . _('Remove all the comments') . '</button></li> + <li class="divider" role="presentation"></li> + <li><button class="btn btn-link" type="submit" id="suppressionsondage" name="suppressionsondage" value="" >'. _("Remove the poll") .'</button></li> + </ul> </div> </div> </div> @@ -696,8 +742,8 @@ echo ' <div class="input-group"> <input type="text" class="form-control" id="newemail" name="nouvelleadresse" size="40" value="'.$email_admin.'" /> <span class="input-group-btn"> - <button type="submit" name="boutonnouvelleadresse" value="1" class="btn btn-success" title="'. _('Save the adress email') .'"><span class="glyphicon glyphicon-ok"></span></button> - <button class="btn btn-link btn-cancel" title="'. _('Cancel the adress email edit') .'"><span class="glyphicon glyphicon-remove"></span></button> + <button type="submit" name="boutonnouvelleadresse" value="1" class="btn btn-success" title="'. _('Save the adress email') .'"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">' . _('Save') . '</span></button> + <button class="btn btn-link btn-cancel" title="'. _('Cancel the adress email edit') .'"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">' . _('Cancel') . '</span></button> </span> </div> </div> @@ -724,10 +770,31 @@ echo ' <input class="form-control" id="admin-link" type="text" readonly="readonly" value="' . Utils::getUrlSondage($numsondageadmin, true) . '" /> </div> <div class="form-group col-md-2"> - <label>'. _("Expiration's date") .'</label> + <h3 class="control-label">'. _("Expiration's date") .'</h3> <p>'.date("d/m/Y",strtotime($dsondage->date_fin)).'</p> </div> </div> + <div class="row"> + <div class="col-md-5 col-md-offset-7" > + <div id="poll-rules-form"> + <p class="pull-right">'.$poll_rules_text.'<button class="btn btn-link btn-sm btn-edit" title="'. _('Edit the poll rules') .'"><span class="glyphicon glyphicon-pencil"></span><span class="sr-only">' . _('Edit') . '</span></button></p> + <div class="hidden js-poll-rules"> + <label class="sr-only" for="newrules">'. _("Poll rules") .'</label> + <div class="input-group"> + <select class="form-control" id="newrules" name="poll_rules"> + <option value="-" '.$poll_rules_opt1.'>'. _("Votes and comments are locked") .'</option> + <option value="0" '.$poll_rules_opt2.'>'. _("Votes and comments are open") .'</option> + <option value="+" '.$poll_rules_opt3.'>'. _("Votes are editable") .'</option> + </select> + <span class="input-group-btn"> + <button type="submit" name="btn_poll_rules" value="1" class="btn btn-success" title="'. _('Save the new rules') .'"><span class="glyphicon glyphicon-ok"></span><span class="sr-only">' . _('Save') . '</span></button> + <button class="btn btn-link btn-cancel" title="'. _('Cancel the rules edit') .'"><span class="glyphicon glyphicon-remove"></span><span class="sr-only">' . _('Cancel') . '</span></button> + </span> + </div> + </div> + </div> + </div> + </div> </div> </form>'."\n"; // .jumbotron @@ -751,7 +818,7 @@ $td_headers = array(); // for a11y, headers="M1 D4 H5" on each td $radio_title = array(); // date for // Dates poll -if ($dsondage->format=="D"||$dsondage->format=="D+") { +if (substr($dsondage->format, 0, 1)=="D") { $tr_months = '<tr><th role="presentation"></th>'; $tr_days = '<tr><th role="presentation"></th>'; @@ -797,7 +864,7 @@ if ($dsondage->format=="D"||$dsondage->format=="D+") { $hour = substr($current, strpos($current, '@')-count($current)+2); if ($hour != "") { - $tr_hours .= '<th class="bg-info'.$rbd.'" id="H'.$i.'">'.$hour.'</th>'; + $tr_hours .= '<th class="bg-info'.$rbd.'" id="H'.$i.'" title="'.$hour.'">'.$hour.'</th>'; $radio_title[$i] .= ' - '.$hour; $td_headers[$i] .= ' H'.$i; } else { @@ -808,7 +875,7 @@ if ($dsondage->format=="D"||$dsondage->format=="D+") { } // Remove col - $tr_add_remove_col .= (count($toutsujet) > 2 ) ? '<td headers="'.$td_headers[$i].'"><button type="submit" name="effacecolonne'.$i.'" class="btn btn-link btn-sm" title="' . _('Remove the column') . ' ' .$radio_title[$i]. '"><span class="glyphicon glyphicon-remove text-danger"></span></button></td>' : '<td role="presentation"></td>'; + $tr_add_remove_col .= (count($toutsujet) > 2 ) ? '<td headers="'.$td_headers[$i].'"><button type="submit" name="effacecolonne'.$i.'" class="btn btn-link btn-sm" title="' . _('Remove the column') . ' ' .$radio_title[$i]. '"><span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">'. _("Remove") .'</span></button></td>' : '<td role="presentation"></td>'; } @@ -819,7 +886,7 @@ if ($dsondage->format=="D"||$dsondage->format=="D+") { $tr_hours .= '<th></th></tr>'; // Add col - $tr_add_remove_col .= '<td><button type="submit" name="ajoutsujet" class="btn btn-link btn-sm" title="'. _('Add a column') . '"><span class="glyphicon glyphicon-plus text-success"></span></button></td></tr>'; + $tr_add_remove_col .= '<td><button type="submit" name="ajoutsujet" class="btn btn-link btn-sm" title="'. _('Add a column') . '"><span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _("Add a column") .'</span></button></td></tr>'; $thead = "\n".$tr_add_remove_col."\n".$tr_months."\n".$tr_days."\n".$tr_hours."\n"; @@ -834,18 +901,42 @@ if ($dsondage->format=="D"||$dsondage->format=="D+") { $td_headers[$i]='';$radio_title[$i]=''; // init before concatenate // Subjects - $tr_subjects .= '<th class="bg-info" id="S'.preg_replace("/[^a-zA-Z0-9]_+/", "", stripslashes($toutsujet[$i])).'">'.stripslashes($toutsujet[$i]).'</th>'; + preg_match_all('/\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)/',$toutsujet[$i],$md_a_img); // Markdown [](href) + preg_match_all('/!\[(.*?)\]\((.*?)\)/',$toutsujet[$i],$md_img); // Markdown  + preg_match_all('/\[(.*?)\]\((.*?)\)/',$toutsujet[$i],$md_a); // Markdown [text](href) + if (isset($md_a_img[2][0]) && $md_a_img[2][0]!='' && isset($md_a_img[3][0]) && $md_a_img[3][0]!='') { // [](href) + + $th_subject_text = (isset($md_a_img[1][0]) && $md_a_img[1][0]!='') ? stripslashes($md_a_img[1][0]) : _("Choice") .' '.($i+1); + $th_subject_html = '<a href="'.$md_a_img[3][0].'"><img src="'.$md_a_img[2][0].'" class="img-responsive" alt="'.$th_subject_text.'" /></a>'; + + } elseif (isset($md_img[2][0]) && $md_img[2][0]!='') { //  + + $th_subject_text = (isset($md_img[1][0]) && $md_img[1][0]!='') ? stripslashes($md_img[1][0]) : _("Choice") .' '.($i+1); + $th_subject_html = '<img src="'.$md_img[2][0].'" class="img-responsive" alt="'.$th_subject_text.'" />'; + + } elseif (isset($md_a[2][0]) && $md_a[2][0]!='') { // [text](href) + + $th_subject_text = (isset($md_a[1][0]) && $md_a[1][0]!='') ? stripslashes($md_a[1][0]) : _("Choice") .' '.($i+1); + $th_subject_html = '<a href="'.$md_a[2][0].'">'.$th_subject_text.'</a>'; + + } else { // text only + + $th_subject_text = stripslashes($toutsujet[$i]); + $th_subject_html = $th_subject_text; + + } + $tr_subjects .= '<th class="bg-info" id="S'.$i.'" title="'.$th_subject_text.'">'.$th_subject_html.'</th>'; $border[$i] = false; - $td_headers[$i] .= stripslashes($toutsujet[$i]); - $radio_title[$i] .= stripslashes($toutsujet[$i]); + $td_headers[$i] .= 'S'.$i; + $radio_title[$i] .= $th_subject_text; // Remove col - $tr_add_remove_col .= '<td headers="'.$td_headers[$i].'"><button type="submit" name="effacecolonne'.$i.'" class="btn btn-link btn-sm" title="' . _('Remove the column') . ' '. $radio_title[$i] .'"><span class="glyphicon glyphicon-remove text-danger"></span></button></td>'; + $tr_add_remove_col .= '<td headers="'.$td_headers[$i].'"><button type="submit" name="effacecolonne'.$i.'" class="btn btn-link btn-sm" title="' . _('Remove the column') . ' '. $radio_title[$i] .'"><span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">' . _('Remove') .'</span></button></td>'; } // Add col - $tr_add_remove_col .= '<td><button type="submit" name="ajoutsujet" class="btn btn-link btn-sm" title="'. _('Add a column') . '"><span class="glyphicon glyphicon-plus text-success"></span></button></td></tr>'; + $tr_add_remove_col .= '<td><button type="submit" name="ajoutsujet" class="btn btn-link btn-sm" title="'. _('Add a column') . '"><span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _("Add a column") .'</span></button></td></tr>'; $thead = $tr_add_remove_col.$tr_subjects.'<th></th></tr>'; } @@ -859,10 +950,23 @@ echo ' ' . _(' remove a column or a line with ') . '<span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">' . _('Remove') . '</span> ' . _('and add a new column with '). '<span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _('Add a column') . '</span></p> <p>' . _('Finally, you can change the informations of this poll like the title, the comments or your email address.') . '</p> + <p><b>' . _('Legend:'). '</b> <span class="glyphicon glyphicon-ok"></span> =' . _('Yes') . ', <b>(<span class="glyphicon glyphicon-ok"></span>)</b> = ' . _('Ifneedbe') . ', <span class="glyphicon glyphicon-ban-circle"></span> = ' . _('No') . '</span></p> + </div> + + <div class="hidden row scroll-buttons" aria-hidden="true"> + <div class="btn-group pull-right"> + <button class="btn btn-sm btn-link scroll-left" title="' . _('Scroll to the left') . '"> + <span class="glyphicon glyphicon-chevron-left"></span> + </button> + <button class="btn btn-sm btn-link scroll-right" title="' . _('Scroll to the right') . '"> + <span class="glyphicon glyphicon-chevron-right"></span> + </button> + </div> </div> + <div id="tableContainer" class="tableContainer"> <table class="results"> - <caption>'._('Votes of the poll ').$title.'</caption> + <caption class="sr-only">'._('Votes of the poll ').$title.'</caption> <thead>'. $thead . '</thead> <tbody>'; @@ -953,8 +1057,15 @@ while ($data = $user_studs->FetchNextObject(false)) { //a la fin de chaque ligne se trouve les boutons modifier if (!$testligneamodifier=="true") { - echo '<td><button type="submit" class="btn btn-link btn-sm" name="modifierligne'.$compteur.'" title="'. _('Edit the line:') .' '.stripslashes($nombase).'"> - <span class="glyphicon glyphicon-pencil"></span></button><button type="submit" name="effaceligne'.$compteur.'" title="'. _('Remove the line:') .' '.stripslashes($nombase).'" class="btn btn-link btn-sm"><span class="glyphicon glyphicon-remove text-danger"></span></button></td>'."\n"; + echo ' + <td> + <button type="submit" class="btn btn-link btn-sm" name="modifierligne'.$compteur.'" title="'. _('Edit the line:') .' '.stripslashes($nombase).'"> + <span class="glyphicon glyphicon-pencil"></span><span class="sr-only">' . _('Edit') . '</span> + </button> + <button type="submit" name="effaceligne'.$compteur.'" title="'. _('Remove the line:') .' '.stripslashes($nombase).'" class="btn btn-link btn-sm"> + <span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">' . _('Remove') . '</span> + </button> + </td>'."\n"; } //demande de confirmation pour modification de ligne @@ -1015,86 +1126,74 @@ if (!$testligneamodifier=="true") { // Addition and Best choice //affichage de la ligne contenant les sommes de chaque colonne -$tr_addition = '<tr><td>'. _("Addition") .'</td>'; -$tr_bestchoice = '<tr><td></td>'; -$meilleurecolonne = 0; - -for ($i = 0; $i < $nbcolonnes; $i++) { - if (isset($somme[$i]) && $somme[$i] > 0 ) { - if (isset($somme[$i]) && $somme[$i] > $meilleurecolonne){ - $meilleurecolonne = $somme[$i]; - } - $tr_addition .= '<td>'.$somme[$i].'</td>'; - } else { - $tr_addition .= '<td></td>'; - } -} -$tr_addition .= '<td></td></tr>'; - -//recuperation des valeurs des sujets et adaptation pour affichage -$toutsujet = explode(",", $dsujet->sujet); - +$tr_addition = '<tr id="addition"><td>'. _("Addition") .'</td>'; +$meilleurecolonne = max($somme); $compteursujet = 0; $meilleursujet = '<ul style="list-style:none">'; for ($i = 0; $i < $nbcolonnes; $i++) { + if (isset($somme[$i]) && $somme[$i] > 0 ) { + if (in_array($i, array_keys($somme, max($somme)))){ - if (isset($somme[$i]) && $somme[$i] > 0 && $somme[$i] == $meilleurecolonne){ - $tr_bestchoice .= '<td><span class="glyphicon glyphicon-star text-warning"></span></td>'; + $tr_addition .= '<td><span class="glyphicon glyphicon-star text-warning"></span><span>'.$somme[$i].'</span></td>'; - if ($dsondage->format == "D" || $dsondage->format == "D+") { - $meilleursujetexport = $toutsujet[$i]; + $meilleursujet.= '<li><b>'.$radio_title[$i].'</b></li>'; + $compteursujet++; - if (strpos($toutsujet[$i], '@') !== false) { - $toutsujetdate = explode("@", $toutsujet[$i]); - $meilleursujet .= '<li><b>'.strftime(_("%A, den %e. %B %Y"),$toutsujetdate[0]). ' - ' . $toutsujetdate[1].'</b></li>'; - } else { - $meilleursujet .= '<li><b>'.strftime(_("%A, den %e. %B %Y"),$toutsujet[$i]).'</b></li>'; - } } else { - $meilleursujet.= '<li><b>'.$toutsujet[$i].'</b></li>'; + $tr_addition .= '<td>'.$somme[$i].'</td>'; } - $compteursujet++; - } else { - $tr_bestchoice .= '<td></td>'; + $tr_addition .= '<td></td>'; } } -$tr_bestchoice .= '<td></td></tr>'; +$tr_addition .= '<td></td></tr>'; + +//recuperation des valeurs des sujets et adaptation pour affichage +$toutsujet = explode(",", $dsujet->sujet); $meilleursujet = str_replace("°", "'", $meilleursujet).'</ul>'; $vote_str = ($meilleurecolonne > 1) ? $vote_str = _('votes') : _('vote'); // Print Addition and Best choice -echo $tr_addition."\n".$tr_bestchoice.' +echo $tr_addition.' </tbody> </table> - <div class="col-sm-4 col-sm-offset-4"><p>'."\n"; + </div> + <div class="row">'."\n"; if ($compteursujet == 1) { - echo '<span class="glyphicon glyphicon-star text-warning"></span> ' . _("The best choice at this time is:") . '</p>' . $meilleursujet . '<p>' . _("with") . ' <b>' . $meilleurecolonne . '</b> ' . $vote_str . ".\n"; + echo ' + <div class="col-sm-6 col-sm-offset-3 alert alert-success"> + <p><span class="glyphicon glyphicon-star text-warning"></span> ' . _("The best choice at this time is:") . '</p> + ' . $meilleursujet . ' + <p>' . _("with") . ' <b>' . $meilleurecolonne . '</b> ' . $vote_str . '.</p> + </div>'."\n"; } elseif ($compteursujet > 1) { - echo '<span class="glyphicon glyphicon-star text-warning"></span> ' . _("The bests choices at this time are:") . '</p>' . $meilleursujet . '<p>' . _("with") . ' <b>' . $meilleurecolonne . '</b> ' . $vote_str . ".\n"; + echo ' + <div class="col-sm-6 col-sm-offset-3 alert alert-success"> + <p><span class="glyphicon glyphicon-star text-warning"></span> ' . _("The bests choices at this time are:") . '</p> + ' . $meilleursujet . ' + <p>' . _("with") . ' <b>' . $meilleurecolonne . '</b> ' . $vote_str . '.</p> + </div>'."\n"; } echo ' - </p></div> </div> - <hr /> -<form name="formulaire4" action="#bas" method="POST">'."\n"; +<form name="formulaire4" action="#" method="POST">'."\n"; // Commments $sql = 'SELECT * FROM comments WHERE id_sondage='.$connect->Param('numsondage').' ORDER BY id_comment'; $sql = $connect->Prepare($sql); $comment_user = $connect->Execute($sql, array($numsondage)); if ($comment_user->RecordCount() != 0) { - echo '<div class="row"><h3>' . _("Comments of polled people") . '</h3>'."\n"; + echo '<div><h3>' . _("Comments of polled people") . '</h3>'."\n"; $i = 0; while ( $dcomment=$comment_user->FetchNextObject(false)) { echo ' <div class="comment"> - <button type="submit" name="suppressioncomment'.$i.'" class="btn btn-link" title="' . _('Remove the comment') . '"><span class="glyphicon glyphicon-remove text-danger"></span></button> + <button type="submit" name="suppressioncomment'.$i.'" class="btn btn-link" title="' . _('Remove the comment') . '"><span class="glyphicon glyphicon-remove text-danger"></span><span class="sr-only">' . _('Remove') . '</span></button> <b>'.stripslashes($dcomment->usercomment). ' :</b> <span class="comment">' . stripslashes(nl2br($dcomment->comment)) . '</span> </div>'; @@ -1103,7 +1202,7 @@ if ($comment_user->RecordCount() != 0) { echo '</div>'; } echo ' - <div class="row hidden-print alert alert-info"> + <div class="hidden-print alert alert-info"> <div class="col-md-6 col-md-offset-3"> <fieldset id="add-comment"><legend>' . _("Add a comment in the poll") . '</legend> <div class="form-group"> @@ -1116,9 +1215,8 @@ echo ' <p class="text-center"><input type="submit" name="ajoutcomment" value="'. _("Send the comment") .'" class="btn btn-success"></p> </fieldset> </div> + <div class="clearfix"></div> </div> -</form> - -<a id="bas"></a>'; +</form>'; bandeau_pied(); diff --git a/app/classes/Framadate/Utils.php b/app/classes/Framadate/Utils.php index 3b7ce544..99f6d8df 100644 --- a/app/classes/Framadate/Utils.php +++ b/app/classes/Framadate/Utils.php @@ -90,6 +90,7 @@ class Utils <link rel="stylesheet" href="' . self::get_server_name() . 'css/bootstrap-accessibility.css"> <link rel="stylesheet" href="' . self::get_server_name() . 'css/datepicker3.css"> <link rel="stylesheet" href="' . self::get_server_name() . 'css/style.css"> + <link rel="stylesheet" href="' . self::get_server_name() . 'css/frama.css"> <link rel="stylesheet" href="' . self::get_server_name() . 'css/print.css" media="print"> <script type="text/javascript" src="' . self::get_server_name() . 'js/jquery-1.11.1.min.js"></script> <script type="text/javascript" src="' . self::get_server_name() . 'js/bootstrap.min.js"></script> @@ -104,7 +105,7 @@ class Utils echo ' </head> <body> - <div class="container">'; + <div class="container ombre">'; } @@ -161,7 +162,7 @@ class Utils $replyTo = $headers; $headers = ''; // on reinitialise $headers } else { - $replyTo = ADRESSEEMAILREPONSEAUTO; + $replyTo = ADRESSEMAILREPONSEAUTO; } $from = sprintf( "From: %s%s <%s>\n", $encoded_app, $folding, ADRESSEMAILADMIN); @@ -176,7 +177,7 @@ class Utils $headers .= "Content-Type: text/plain; charset=UTF-8\n"; $headers .= "Content-Transfer-Encoding: 8bit"; - $body = html_entity_decode($body, ENT_QUOTES, 'UTF-8'); + $body = html_entity_decode($body, ENT_QUOTES, 'UTF-8')._("\n--\n\n« La route est longue, mais la voie est libre… »\nFramasoft ne vit que par vos dons (déductibles des impôts).\nMerci d'avance pour votre soutien http://soutenir.framasoft.org."); mail($to, $subject, $body, $headers, $param); } diff --git a/app/inc/i18n.php b/app/inc/i18n.php index 20290c37..f5cff48d 100644 --- a/app/inc/i18n.php +++ b/app/inc/i18n.php @@ -23,7 +23,15 @@ if (isset($_POST['lang']) && is_string($_POST['lang']) && in_array($_POST['lang' } elseif ( isset($_COOKIE['lang']) && is_string($_COOKIE['lang']) && in_array($_COOKIE['lang'], array_keys($ALLOWED_LANGUAGES)) ) { $mlocale = $_COOKIE['lang'] ; } else { - $mlocale = LANGUE ; + + $mlocale = LANGUE; + // Replace config language by browser language if possible + foreach ($ALLOWED_LANGUAGES as $k => $v ) { + if (substr($k,0,2)==substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)) { + $mlocale = $k; + } + } + } $locale = $mlocale . '.utf8'; diff --git a/apropos.php b/apropos.php deleted file mode 100644 index e7fd1d97..00000000 --- a/apropos.php +++ /dev/null @@ -1,279 +0,0 @@ -<?php -/** - * This software is governed by the CeCILL-B license. If a copy of this license - * is not distributed with this file, you can obtain one at - * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt - * - * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ - * Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft) - * - * ============================= - * - * Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence - * ne se trouve pas avec ce fichier vous pouvez l'obtenir sur - * http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt - * - * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ - * Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft) - */ -namespace Framadate; - -session_start(); - -include_once __DIR__ . '/app/inc/init.php'; - -if (file_exists('bandeaux_local.php')) { - include_once('bandeaux_local.php'); -} else { - include_once('bandeaux.php'); -} - -//affichage de la page -Utils::print_header( _("About") ); -bandeau_titre(_("About")); - -echo <<<mentions -<ul> - <li><a href="#faq">Questions fréquentes</a></li> - <ul> - <li><a href="#framadate">Qu'est-ce que Framadate -?</a></li> - <li><a href="#studs">Quelles différences entre -Framadate et STUdS ?</a></li> - <li><a href="#doodle">Quelles différences entre -Framadate et Doodle ?</a></li> - <li><a href="#longevite">Mon sondage -restera-t-il longtemps en ligne ?</a></li> - </ul> - <li><a href="#mentions">Mentions légales</a></li> - <li><a href="#credits">Crédits</a></li> - <li><a href="#licence">Licence</a></li> -</ul> -<hr style="width: 100%; height: 2px;"> -<h1><a name="faq"></a>Questions fréquentes</h1> -<h3><a name="framadate"></a>Qu'est-ce que -Framadate ?</h3> -Framadate est un service en ligne permettant de planifier un -rendez-vous rapidement et simplement. Aucune inscription préalable -n'est nécessaire.<br /> -Framadate est un service du<a href="http://framasoft.org"> -réseau Framasoft</a>, mis en place par<a - href="http://fr.wikipedia.org/wiki/Framasoft"> l'association -Framasoft</a>.<br /> -<h3><a name="studs"></a>Quelles différences -entre Framadate et STUdS ! ?</h3> -Framadate est un service basé sur le logiciel libre <a - href="https://github.com/leblanc-simon/OpenSondage">OpenSondage</a>. -OpenSondage est lui-même basé sur le logiciel <a - href="http://studs.u-strasbg.fr">STUdS !</a> développé -par l'Université de Strasbourg. <br /> -Après avoir testé STUdS, nous avons décidé d'apporter de nombreuses -modifications, notamment ergonomiques, au code source existant. -L'ensemble de ces modifications ne pouvaient entrer dans le cadre -d'utilisation d'un logiciel déjà en production dans une université et -aurait été (fort logiquement) rejetté de la branche principale de -développement. C'est pourquoi nous avons préferer "<a - href="http://fr.wikipedia.org/wiki/Fork_%28d%C3%A9veloppement_logiciel%29">forker</a>" -STUdS pour créer OpenSondage.<br /> -<h3><a name="doodle"></a>Quelles différences -entre Framadate et <a href="http://doodle.com">Doodle</a> -?</h3> -Aujourd'hui, le danger pour le logiciel libre -ne provient plus de Microsoft ou d'Adobe et de leurs logiciels qu'on -installe sans avoir le code source, mais des applications web "dans les -nuages" proposés comme services par des entreprises.<br /> -<br /> -Cela pour au moins 4 raisons :<br /> -1- <span style="font-weight: bold;">sécurité</span> -: aucune garantie ne peut vous être apportée quand au fait les données -soient correctement sauvegardées et protégées, ni que le<br /> -code source "officiel" soit réellement celui que vous utilisez en ligne.<br /> -2- <span style="font-weight: bold;">fiabilité/perennité</span> -: le service peut tomber en panne, et rien ne garanti que la -société Doodle sera toujours là demain et maintiendra le site<br /> -3- <span style="font-weight: bold;">propriété des données</span> -: beaucoup d'entreprises s'autoproclament co-détentrices de vos -contenus "clouds" (ex: Facebook impose une clause de partage des droits -sur vos contenus, vos données, vos photos)<br /> -4-<span style="font-weight: bold;"> vie privée</span> -: une entreprise - comme Doodle - doit gagner de l'argent (et il n'y a -aucun mal à cela). Mais si elle est en difficulté financière, elle peut -décider de changer ses conditions d'utilisation et vendre vos données à -des tiers (alors que Framasoft, asso loi 1901 d'intérêt général, n'aura -jamais d'intérêt à le faire).<br /> -<br /> -A cela s'ajoute le problème, plus éthique, de la publicité.<br /> -<br /> -Les problèmes 1 et 2 concernent aussi Framadate.org : rien ne garanti -la sécurité et la fiabilité du service (d'autant plus que les -administrateurs systèmes de Framasoft sont bénévoles).<br /> -<br /> -Par contre :<br /> -- les problemes 3 et 4 ne sont pas d'actualité avec Framadate, exploité -par une association loi 1901<br /> -- et surtout, Framadate fait partie d'un projet plus global -(Framatools) qui vise justement à sensibiliser le grand public à la -problématique du "cloud". Cela peut sembler paradoxal, mais bien que -proposant le service Framadate.org, nous allons surtout encourager les -organisations à installer leur propre instance du logiciel afin de -maitriser totalement leurs données.<br /> -<br /> -Bref, oui Framadate est inspiré de Doodle.com, et oui Doodle est un -excellent service. Mais Doodle reste une "boite noire" pour -l'utilisateur final qui va sur doodle.com. Framadate.org essaie de -répondre, modestement, à cette problématique en montrant que des -alternatives libres existent et qu'on peut les installer "chez soi".<br /> -<h3><a name="longevite"></a>Mon sondage -restera-t-il longtemps en ligne ?</h3> -Le service Framadate est proposée gratuitement par l'association -Framasoft.<br /> -Framasoft -s'engage à maintenir le service "aussi longtemps que possible", mais ne -peut fournir aucune garantie de date. Si cela ne vous convient pas, -nous vous -encourageons sincèrement à installer vous-même Framadate et à maintenir -vous-même votre propre service. -<hr style="width: 100%; height: 2px;"> -<h1><a name="mentions"></a>Mentions légales<br /> -</h1> -<h2>Éditeur et Responsable de la publication</h2> -<p>Editeur : Association Framasoft (cf "Hébergement")</p> -<p>Responsable de la publication : Christophe Masutti</p> -<p>Vous pouvez rentrer en contact avec l'Editeur et le -Responsable de la publication en passant par la page "<a - href="http://contact.framasoft.org">contact</a>".</p> -<p>Les propos tenus sur ce site ne représentent que et uniquement -l’opinion de leur auteur, et n’engagent pas l'association Framasoft, -les sociétés, entreprises ou collectifs auxquels il contribue ou dont -il peut être associé ou employé.</p> -<h2>Hébergement</h2> -<p>Ce site est hébergé par Framasoft, 10 bis rue Jangot 69007 Lyon, France. -Cet hébergeur possède à ce jour les éléments d’identification -personnelle concernant l'Éditeur (voir <a - href="http://www.framasoft.net/article4736.html">http://www.framasoft.net/article4736.html</a>).</p> -<h2>Données personnelles</h2> -<p>Les données personnelles collectées par Framadate sont -uniquement destinées à un usage interne. En aucun cas ces données ne -seront cédées ou vendues à des tiers. -Conformément à l’article 39 de la loi du 6 janvier 1978 relative à -l’informatique, aux fichiers et aux libertés, vous avez un droit -d’accès, de modification et d’opposition sur vos données personnelles -enregistrées par le blog. -Dans ce cas, utilisez le formulaire de contact.</p> -<h2>Conditions de modération/suppression de sondages</h2> -<p>Les sondages de Framadate bénéficient d'une URL aléatoire, -mais publique. Si vous souhaitez supprimer un sondage, utilisez -l'adresse d'aministration fournie à la création. Vous pouvez -exceptionnellement demander la suppression d'un sondage en utilisant la -page de contact.</p> -<h2>Notification des contenus litigieux</h2> -<p>Conformément à l’article 6 I 5° LCEN, la connaissance des -contenus litigieux est présumée acquise par L’Éditeur lorsqu’il lui est -notifié, par lettre recommandée avec accusé de réception adressée au -siège social de L’Éditeur, la totalité des éléments suivants (i) la -date de la notification ; (ii) si le notifiant est une -personne physique : ses nom, prénoms, profession, domicile, -nationalité, date et lieu de naissance ; si le notifiant est -une personne morale : sa forme, sa dénomination, son siège -social et l’organe qui la représente légalement ; (iii) les -nom et domicile du destinataire ou, s’il s’agit d’une personne morale, -sa dénomination et son siège social ; (iv) la description des -faits litigieux et leur localisation précise ; (v) les motifs -pour lesquels le contenu doit être retiré, comprenant la mention des -dispositions légales et des justifications de faits ; (vi) la -copie de la correspondance adressée à l’auteur ou à l’éditeur des -informations ou activités litigieuses demandant leur interruption, leur -retrait ou leur modification, ou la justification de ce que l’auteur ou -l’éditeur n’a pu être contacté.</p> -<p>A défaut d’envoi de la totalité de ces éléments, la -notification ne sera pas prise en compte par L’Éditeur et ce dernier ne -pourra en conséquence être présumé informé d’un contenu litigieux.</p> -<p>L’Éditeur se réserve le droit d’engager des poursuites à -l’encontre de toute personne ayant usé abusivement du droit réservé par -l’article 6 I 4° LCEN. L’Éditeur vous rappelle que toute personne qui -aurait présenté un contenu ou une activité comme étant illicite dans le -but d’en obtenir le retrait ou d’en faire cesser la diffusion alors -qu’elle a connaissance du caractère inexact de cette information, est -susceptible d’encourir une peine d’un an d’emprisonnement et de 15.000 -€uros d’amende.</p> -<h2>Licences, droits de reproduction</h2> -<p>L'application Framadate, basé sur le logiciel OpenSondage, -lui-même basé sur STUdS, est publiée sous licence libre <a - href="http://www.cecill.info/licences.fr.html">CeCILL-B</a>. -Les contenus (sondages) sont publiés sous licence Creative Commons -BY-SA. Cela signifie que si l'adresse de votre sondage est connue d'un -individu, vous autorisez cette personne à utiliser, partager, modifier -votre sondage. Si vous souhaitez des sondages 100% privés et avec votre -propre licence, installez votre propre logiciel de sondage et -n'utilisez pas Framadate.org.</p> -<hr style="width: 100%; height: 2px;"> -<h2><a name="credits"></a>Crédits</h2> -<b>Application d'origine</b><br /> -<br /> -L'application Framadate est une instance du logiciel <b><a - href="http://studs.u-strasbg.fr">STUdS !</a></b> -développé à l'Université de Strasbourg depuis 2008.<br /> -<br /> -Pour les besoins de Framadate, STUdS a fait l'objet d'un fork par -l'équipe Framasoft. Les sources sont disponibles sur le Github <a - href="https://github.com/leblanc-simon/OpenSondage">OpenSondage</a>.<br /> -<br /> -<b>Technologies utilisées</b><br /> -<br /> -- <a href="http://www.php.net/">PHP</a><br /> -- <a href="http://www.postgresql.org/">MySQL</a><br /> -- <a href="http://www.apache.org/">Apache</a><br /> -- <a href="http://subversion.tigris.org/">Subversion</a><br /> -- <a href="http://www.kigkonsult.se/iCalcreator/">iCalcreator</a><br /> -- <a href="http://www.fpdf.org/">FPDF</a><br /> -- Icônes : <a href="http://deleket.deviantart.com/">Deleket</a>, -<a href="http://pixel-mixer.com">PixelMixer</a> et <a - href="http://dryicons.com">DryIcons</a><br /> -<br /> -<b>Compatibilités des navigateurs</b><br /> -<br /> -- <a href="http://www.mozilla.com/firefox/">Firefox</a><br /> -- <a href="http://www.opera.com/">Opéra</a><br /> -- <a href="http://www.konqueror.org/">Konqueror</a><br /> -- <a href="http://www.jikos.cz/%7Emikulas/links/">Links</a><br /> -- <a href="http://www.apple.com/fr/safari/">Safari</a><br /> -- <a href="http://www.mozilla.com/firefox/">IE</a><br /> -<br /> -<b>Validations des pages</b><br /> -<br /> -- Toutes les pages disposent de la validation HTML 4.01 Strict du W3C. <br /> -- La CSS dispose de la validation CSS 2.1 du W3C. -<p><img src="http://www.w3.org/Icons/valid-html401-blue" - alt="Valid HTML 4.01 Strict" height="31" width="88"><img - style="border: 0pt none ; width: 88px; height: 31px;" - src="http://jigsaw.w3.org/css-validator/images/vcss-blue" - alt="CSS Valide !"> -</p> -<b>Propositions améliorations de Framadate</b><br /> -<br /> -Si quelque chose venait à vous manquer, vous pouvez nous en faire part -via le <a href="http://contact.framasoft.org">formulaire en ligne</a>. -<br /> -Les dernières améliorations de Framadate sont visibles dans le fichier <a - href="CHANGELOG">CHANGELOG</a>.<br /> -<br /> -<b>Remerciements</b><br /> -<br /> -<b><a href="http://studs.u-strasbg.fr">STUdS !</a></b> : -Pour leurs contributions techniques ou ergonomiques : Guy, Christophe, -Julien, Pierre, Romaric, Matthieu, Catherine, Christine, Olivier, -Emmanuel et Florence <br /> -<a style="font-weight: bold;" - href="https://github.com/leblanc-simon/OpenSondage">Framadate</a> -: Simon Leblanc (développement principal), Pierre-Yves Gosset -(développement, graphisme), la communauté Framasoft.<br /> -<br /> -<h2><b><a name="licence"></a>Licence</b></h2> -Framadate est placé, comme <b><a - href="http://studs.u-strasbg.fr">STUdS !</a>,</b> -sous la licence logicielle libre <a - href="http://www.cecill.info/licences.fr.html">CeCILL-B</a>.<br /> -<br /> -mentions; - -bandeau_pied(); diff --git a/bandeaux.php b/bandeaux.php index 167e7ae8..40694ffd 100644 --- a/bandeaux.php +++ b/bandeaux.php @@ -26,8 +26,8 @@ function bandeau_titre($titre) $img = ( IMAGE_TITRE ) ? '<img src="'. Utils::get_server_name(). IMAGE_TITRE. '" title="'._("Home").' - '.NOMAPPLICATION.'" alt="'.NOMAPPLICATION.'">' : ''; echo ' <header role="banner"> - <form method="post" action=""> - <div class="input-group input-group-sm pull-right col-md-2"> + <form method="post" action="#"> + <div class="input-group input-group-sm pull-right col-md-2 col-xs-4"> <select name="lang" class="form-control" title="'. _("Select the language") .'" >' . liste_lang() . '</select> <span class="input-group-btn"> <button type="submit" class="btn btn-default btn-sm" title="'. _("Change the language") .'">OK</button> @@ -36,8 +36,9 @@ function bandeau_titre($titre) </form> <h1><a href="'.str_replace('/admin','', Utils::get_server_name()).'" title="'._("Home").' - '.NOMAPPLICATION.'">'.$img.'</a></h1> <p class="lead"><i>'. $titre .'</i></p> + <hr class="trait" /> </header> - <main>'; + <main role="main">'; } function liste_lang() @@ -61,25 +62,6 @@ function bandeau_pied($admin=false) { echo ' </main> - <footer> - <hr /> - <ul class="list-inline">'; - if($admin) { - echo ' - <li><a class="btn btn-default btn-xs" href="'.str_replace('/admin','', Utils::get_server_name()).'">'. _("Home") .'</a></li>'; - if (is_readable('logs_studs.txt')) { - echo ' - <li><a role="button" class="btn btn-default btn-xs" href="'.str_replace('/admin','', Utils::get_server_name()).'admin/logs_studs.txt">'. _("Logs") .'</a></li>'; - } - } else { - echo ' - <li><a class="btn btn-default btn-xs" href="'. Utils::get_server_name().'">'. _("Home") .'</a></li> - <li><a class="btn btn-default btn-xs" href="http://contact.framasoft.org">'. _("Contact") .'</a></li> - <li><a class="btn btn-default btn-xs" href="'. Utils::get_server_name().'apropos.php">'. _("About") .'</a></li>'; - } - echo ' - </ul> - </footer> </div> <!-- .container --> </body> </html>'."\n"; diff --git a/choix_autre.php b/choix_autre.php index f51faf2a..66e8498b 100644 --- a/choix_autre.php +++ b/choix_autre.php @@ -64,8 +64,8 @@ if (Utils::issetAndNoEmpty('titre', $_SESSION) === false || Utils::issetAndNoEmp $registredate = explode("/",$_POST["champdatefin"]); if (is_array($registredate) == true && count($registredate) == 3) { $time = mktime(0,0,0,$registredate[1],$registredate[0],$registredate[2]); - if ($time > time() + 250000) { - $_SESSION["champdatefin"]=mktime(0,0,0,$registredate[1],$registredate[0],$registredate[2]); + if ($time > time() + (24*60*60)) { + $_SESSION["champdatefin"]=$time; } } } @@ -93,12 +93,51 @@ if (Utils::issetAndNoEmpty('titre', $_SESSION) === false || Utils::issetAndNoEmp Utils::print_header ( _("Removal date and confirmation (3 on 3)") ); bandeau_titre(_("Removal date and confirmation (3 on 3)")); + $removal_date=strftime(_("%A, den %e. %B %Y"), time()+15552000); + + // Sumary + $summary = '<ol>'; + for ($i=0;$i<count($_SESSION['choices']);$i++) { + + preg_match_all('/\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)/',$_SESSION['choices'][$i],$md_a_img); // Markdown [](href) + preg_match_all('/!\[(.*?)\]\((.*?)\)/',$_SESSION['choices'][$i],$md_img); // Markdown  + preg_match_all('/\[(.*?)\]\((.*?)\)/',$_SESSION['choices'][$i],$md_a); // Markdown [text](href) + if (isset($md_a_img[2][0]) && $md_a_img[2][0]!='' && isset($md_a_img[3][0]) && $md_a_img[3][0]!='') { // [](href) + + $li_subject_text = (isset($md_a_img[1][0]) && $md_a_img[1][0]!='') ? stripslashes($md_a_img[1][0]) : _("Choice") .' '.($i+1); + $li_subject_html = '<a href="'.$md_a_img[3][0].'"><img src="'.$md_a_img[2][0].'" class="img-responsive" alt="'.$li_subject_text.'" /></a>'; + + } elseif (isset($md_img[2][0]) && $md_img[2][0]!='') { //  + + $li_subject_text = (isset($md_img[1][0]) && $md_img[1][0]!='') ? stripslashes($md_img[1][0]) : _("Choice") .' '.($i+1); + $li_subject_html = '<img src="'.$md_img[2][0].'" class="img-responsive" alt="'.$li_subject_text.'" />'; + + } elseif (isset($md_a[2][0]) && $md_a[2][0]!='') { // [text](href) + + $li_subject_text = (isset($md_a[1][0]) && $md_a[1][0]!='') ? stripslashes($md_a[1][0]) : _("Choice") .' '.($i+1); + $li_subject_html = '<a href="'.$md_a[2][0].'">'.$li_subject_text.'</a>'; + + } else { // text only + + $li_subject_text = stripslashes($toutsujet[$i]); + $li_subject_html = $li_subject_text; + + } + + $summary .= '<li>'.$li_subject_html.'</li>'."\n"; + } + $summary .= '</ol>'; + echo ' <form name="formulaire" action="' . Utils::get_server_name() . 'choix_autre.php" method="POST" class="form-horizontal" role="form"> <div class="row"> - <div class="col-md-6 col-md-offset-3"> + <div class="col-md-8 col-md-offset-2"> + <div class="well summary"> + <h3>'. _("List of your choices").'</h3> + '. $summary .' + </div> <div class="alert alert-info"> - <p>' . _("Your poll will be automatically removed after 6 months.") . '<br />' . _("You can fix another removal date for it.") .'</p> + <p>' . _("Your poll will be automatically removed after 6 months:") . ' <strong>'.$removal_date.'</strong>.<br />' . _("You can fix another removal date for it.") .'</p> <div class="form-group"> <label for="champdatefin" class="col-sm-5 control-label">'. _("Removal date (optional)") .'</label> <div class="col-sm-6"> @@ -114,7 +153,10 @@ if (Utils::issetAndNoEmpty('titre', $_SESSION) === false || Utils::issetAndNoEmp <p>'. _("Once you have confirmed the creation of your poll, you will be automatically redirected on the administration page of your poll."). '</p> <p>' . _("Then, you will receive quickly two emails: one contening the link of your poll for sending it to the voters, the other contening the link to the administration page of your poll.") .'</p> </div> - <p class="text-right"><button name="confirmecreation" value="confirmecreation" type="submit" class="btn btn-success">'. _('Create the poll') . '</button></p> + <p class="text-right"> + <button class="btn btn-default" onclick="javascript:window.history.back();" title="'. _('Back to step 2') . '">'. _('Back') . '</button> + <button name="confirmecreation" value="confirmecreation" type="submit" class="btn btn-success">'. _('Create the poll') . '</button> + </p> </div> </div> </form>'."\n"; @@ -129,11 +171,12 @@ if (Utils::issetAndNoEmpty('titre', $_SESSION) === false || Utils::issetAndNoEmp echo ' <form name="formulaire" action="' . Utils::get_server_name() . 'choix_autre.php" method="POST" class="form-horizontal" role="form"> <div class="row"> - <div class="col-md-6 col-md-offset-3">'; + <div class="col-md-8 col-md-offset-2">'; echo ' <div class="alert alert-info"> - <p>'. _("To make a generic poll you need to propose at least two choices between differents subjects.") . '</p> - <p>'. _("You can add or remove additional choices with the buttons") .' <span class="glyphicon glyphicon-minus text-info"></span> <span class="glyphicon glyphicon-plus text-success"></span></p> + <p>'. _("To make a generic poll you need to propose at least two choices between differents subjects.") .'</p> + <p>'. _("You can add or remove additional choices with the buttons") .' <span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">'. _("Remove") .'</span> <span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _("Add") .'</span></p> + <p>'. _("It's possible to propose links or images by using "). '<a href="http://'.$lang.'.wikipedia.org/wiki/Markdown">'. _("the Markdown syntax") .'</a>.</p> </div>'."\n"; // Fields choices : 5 by default @@ -143,21 +186,52 @@ if (Utils::issetAndNoEmpty('titre', $_SESSION) === false || Utils::issetAndNoEmp echo ' <div class="form-group choice-field"> <label for="choice'.$i.'" class="col-sm-2 control-label">'. _("Choice") .' '.($i+1).'</label> - <div class="col-sm-10"> - <input type="text" class="form-control" name="choices[]" size="40" maxlength="40" value="'.$choice_value.'" id="choice'.$i.'" /> + <div class="col-sm-10 input-group"> + <input type="text" class="form-control" name="choices[]" size="40" value="'.$choice_value.'" id="choice'.$i.'" /> + <span class="input-group-addon btn-link md-a-img" title="'. _("Add a link or an image") .'" ><span class="glyphicon glyphicon-picture"></span> <span class="glyphicon glyphicon-link"></span></span> </div> </div>'."\n"; } echo ' - <div class="col-md-6"> + <div class="col-md-4"> <div class="btn-group btn-group"> - <button type="button" id="remove-a-choice" class="btn btn-default" title="'. _("Remove a choice") .'"><span class="glyphicon glyphicon-minus text-info"></span></button> - <button type="button" id="add-a-choice" class="btn btn-default" title="'. _("Add a choice") .'"><span class="glyphicon glyphicon-plus text-success"></span></button> + <button type="button" id="remove-a-choice" class="btn btn-default" title="'. _("Remove a choice") .'"><span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">'. _("Remove") .'</span></button> + <button type="button" id="add-a-choice" class="btn btn-default" title="'. _("Add a choice") .'"><span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _("Add") .'</span></button> </div> </div> - <div class="col-md-6 text-right"> - <button name="fin_sondage_autre" value="'._('Next').'" type="submit" class="btn btn-success disabled">'. _('Next') . '</button> + <div class="col-md-8 text-right"> + <a class="btn btn-default" href="'.Utils::get_server_name().'infos_sondage.php?choix_sondage=autre" title="'. _('Back to step 1') . '">'. _('Back') . '</a> + <button name="fin_sondage_autre" value="'._('Next').'" type="submit" class="btn btn-success disabled" title="'. _('Go to step 3') . '">'. _('Next') . '</button> + </div> + </div> + </div> + <div class="modal fade" id="md-a-imgModal" tabindex="-1" role="dialog" aria-labelledby="md-a-imgModalLabel" aria-hidden="true"> + <div class="modal-dialog"> + <div class="modal-content"> + <div class="modal-header"> + <button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">'. _('Close') . '</span></button> + <h4 class="modal-title" id="md-a-imgModalLabel">'. _("Add a link or an image") .'</h4> + </div> + <div class="modal-body"> + <p class="alert alert-info">'. _("These fields are optional. You can add a link, an image or both.") .'</p> + <div class="form-group"> + <label for="md-img"><span class="glyphicon glyphicon-picture"></span> '. _('URL of the image') . '</label> + <input id="md-img" type="text" placeholder="http://…" class="form-control" size="40" /> + </div> + <div class="form-group"> + <label for="md-a"><span class="glyphicon glyphicon-link"></span> '. _('Link') . '</label> + <input id="md-a" type="text" placeholder="http://…" class="form-control" size="40" /> + </div> + <div class="form-group"> + <label for="md-text">'. _('Alternative text') . '</label> + <input id="md-text" type="text" class="form-control" size="40" /> + </div> + </div> + <div class="modal-footer"> + <button type="button" class="btn btn-default" data-dismiss="modal">'. _('Cancel') . '</button> + <button type="button" class="btn btn-primary">'. _('Add') . '</button> + </div> </div> </div> </div> diff --git a/choix_date.php b/choix_date.php index aefafbe8..9302de19 100644 --- a/choix_date.php +++ b/choix_date.php @@ -75,6 +75,19 @@ if (!Utils::issetAndNoEmpty('nom', $_SESSION) && !Utils::issetAndNoEmpty('adress $_SESSION["toutchoix"]=substr($choixdate,1); + // Expiration date → 6 months after last day if not filled or in bad format + $_SESSION["champdatefin"]=end($temp_results)+15552000; + + if (Utils::issetAndNoEmpty('champdatefin')) { + $registredate = explode("/",$_POST["champdatefin"]); + if (is_array($registredate) == true && count($registredate) == 3) { + $time = mktime(0,0,0,$registredate[1],$registredate[0],$registredate[2]); + if ($time > time() + (24*60*60)) { + $_SESSION["champdatefin"]=$time; + } + } + } + ajouter_sondage(); } else { @@ -111,22 +124,50 @@ if (!Utils::issetAndNoEmpty('nom', $_SESSION) && !Utils::issetAndNoEmpty('adress $temp_array = array_unique($_SESSION["totalchoixjour"]); sort($temp_array); - $removal_date=strftime(_("%A, den %e. %B %Y"), end($temp_array)+2592000); + $removal_date=strftime(_("%A, den %e. %B %Y"), end($temp_array)+15552000); + + // Sumary + $summary = '<ul>'; + for ($i=0;$i<count($_SESSION["totalchoixjour"]);$i++) { + $summary .= '<li>'.strftime(_("%A, den %e. %B %Y"), $_SESSION["totalchoixjour"][$i]); + for ($j=0;$j<count($_SESSION['horaires'.$i]);$j++) { + if (isset($_SESSION['horaires'.$i][$j])) { + $summary .= ($j==0) ? ' : ' : ', '; + $summary .= $_SESSION['horaires'.$i][$j]; + } + } + $summary .= '</li>'."\n"; + } + $summary .= '</ul>'; echo ' <form name="formulaire" action="' . Utils::get_server_name() . 'choix_date.php" method="POST" class="form-horizontal" role="form"> <div class="row" id="selected-days"> <div class="col-md-8 col-md-offset-2"> <h2>'. _("Confirm the creation of your poll") .'</h2> - <div class="alert alert-info"> - <p>'. _("Your poll will expire automatically 2 days after the last date of your poll.") .'</p> - <p>'. _("Removal date:") .' <b> '.$removal_date.'</b></p> + <div class="well summary"> + <h3>'. _("List of your choices").'</h3> + '. $summary .' + </div> + <div class="alert alert-info clearfix"> + <p>' . _("Your poll will be automatically removed 6 months after the last date of your poll:") . ' <strong>'.$removal_date.'</strong>.<br />' . _("You can fix another removal date for it.") .'</p> + <div class="form-group"> + <label for="champdatefin" class="col-sm-5 control-label">'. _("Removal date (optional)") .'</label> + <div class="col-sm-6"> + <div class="input-group date"> + <span class="input-group-addon"><i class="glyphicon glyphicon-calendar text-info"></i></span> + <input type="text" class="form-control" id="champdatefin" data-date-format="'. _("dd/mm/yyyy") .'" aria-describedby="dateformat" name="champdatefin" value="" size="10" maxlength="10" placeholder="'. _("dd/mm/yyyy") .'" /> + </div> + </div> + <span id="dateformat" class="sr-only">'. _("(dd/mm/yyyy)") .'</span> + </div> </div> <div class="alert alert-warning"> <p>'. _("Once you have confirmed the creation of your poll, you will be automatically redirected on the administration page of your poll."). '</p> <p>' . _("Then, you will receive quickly two emails: one contening the link of your poll for sending it to the voters, the other contening the link to the administration page of your poll.") .'</p> </div> <p class="text-right"> + <button class="btn btn-default" onclick="javascript:window.history.back();" title="'. _('Back to step 2') . '">'. _('Back') . '</button> <button name="confirmation" value="confirmation" type="submit" class="btn btn-success">'. _('Create the poll') . '</button> </p> </div> @@ -143,16 +184,16 @@ if (!Utils::issetAndNoEmpty('nom', $_SESSION) && !Utils::issetAndNoEmpty('adress echo ' <form name="formulaire" action="' . Utils::get_server_name() . 'choix_date.php" method="POST" class="form-horizontal" role="form"> <div class="row" id="selected-days"> - <div class="col-md-8 col-md-offset-2"> + <div class="col-md-10 col-md-offset-1"> <h2>'. _("Choose the dates of your poll") .'</h2> <div class="alert alert-info"> <p>'. _("To schedule an event you need to propose at least two choices (two hours for one day or two days).").'</p> - <p>'. _("You can add or remove additionnal days and hours with the buttons") .' <span class="glyphicon glyphicon-minus text-info"></span> <span class="glyphicon glyphicon-plus text-success"></span></p> + <p>'. _("You can add or remove additionnal days and hours with the buttons") .' <span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">'. _("Remove") .'</span> <span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _("Add") .'</span></p> <p>'. _("For each selected day, you can choose, or not, meeting hours (e.g.: \"8h\", \"8:30\", \"8h-10h\", \"evening\", etc.)").'</p> </div>'; - // Fields days : 1 by default - $nb_days = (isset($_SESSION["totalchoixjour"])) ? count($_SESSION["totalchoixjour"]) : 1; + // Fields days : 3 by default + $nb_days = (isset($_SESSION["totalchoixjour"])) ? count($_SESSION["totalchoixjour"]) : 3; for ($i=0;$i<$nb_days;$i++) { $day_value = isset($_SESSION["totalchoixjour"][$i]) ? strftime( "%d/%m/%Y", $_SESSION["totalchoixjour"][$i]) : ''; echo ' @@ -161,8 +202,9 @@ if (!Utils::issetAndNoEmpty('nom', $_SESSION) && !Utils::issetAndNoEmpty('adress <legend> <div class="input-group date col-xs-7"> <span class="input-group-addon"><i class="glyphicon glyphicon-calendar text-info"></i></span> - <input type="text" class="form-control" id="day'.$i.'" title="'. _("Day") .' '. ($i+1) .'" data-date-format="'. _("dd/mm/yyyy") .'" name="days[]" value="'.$day_value.'" size="10" maxlength="10" placeholder="'. _("dd/mm/yyyy") .'" /> + <input type="text" class="form-control" id="day'.$i.'" title="'. _("Day") .' '. ($i+1) .'" data-date-format="'. _("dd/mm/yyyy") .'" aria-describedby="dateformat'.$i.'" name="days[]" value="'.$day_value.'" size="10" maxlength="10" placeholder="'. _("dd/mm/yyyy") .'" /> </div> + <span id="dateformat'.$i.'" class="sr-only">'. _("(dd/mm/yyyy)") .'</span> </legend>'."\n"; // Fields hours : 3 by default @@ -171,26 +213,26 @@ if (!Utils::issetAndNoEmpty('nom', $_SESSION) && !Utils::issetAndNoEmpty('adress echo ' <div class="col-sm-2"> <label for="d'.$i.'-h'.$j.'" class="sr-only control-label">'. _("Time") .' '. ($j+1) .'</label> - <input type="text" class="form-control hours" title="'.$day_value.' - '. _("Time") .' '. ($j+1) .'" placeholder="'. _("Time") .' '. ($j+1) .'" maxlength="11" id="d'.$i.'-h'.$j.'" name="horaires'.$i.'[]" value="'.$hour_value.'" /> + <input type="text" class="form-control hours" title="'.$day_value.' - '. _("Time") .' '. ($j+1) .'" placeholder="'. _("Time") .' '. ($j+1) .'" id="d'.$i.'-h'.$j.'" name="horaires'.$i.'[]" value="'.$hour_value.'" /> </div>'."\n"; } echo ' <div class="col-sm-2"><div class="btn-group btn-group-xs" style="margin-top: 5px;"> - <button type="button" title="'. _("Remove an hour") .'" class="remove-an-hour btn btn-default"><span class="glyphicon glyphicon-minus text-info"></span></button> - <button type="button" title="'. _("Add an hour") .'" class="add-an-hour btn btn-default"><span class="glyphicon glyphicon-plus text-success"></span></button> + <button type="button" title="'. _("Remove an hour") .'" class="remove-an-hour btn btn-default"><span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">'. _("Remove") .'</span></button> + <button type="button" title="'. _("Add an hour") .'" class="add-an-hour btn btn-default"><span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _("Add") .'</span></button> </div></div> </div> </fieldset>'; } echo ' - <div class="col-md-6"> - <button type="button" id="copyhours" class="btn btn-default disabled" title="'. _("Copy hours of the first day") .'"><span class="glyphicon glyphicon-sort-by-attributes-alt text-info"></span></button> + <div class="col-md-4"> + <button type="button" id="copyhours" class="btn btn-default disabled" title="'. _("Copy hours of the first day") .'"><span class="glyphicon glyphicon-sort-by-attributes-alt text-info"></span><span class="sr-only">'. _("Copy hours of the first day") .'</span></button> <div class="btn-group btn-group"> - <button type="button" id="remove-a-day" class="btn btn-default disabled" title="'. _("Remove a day") .'"><span class="glyphicon glyphicon-minus text-info"></span></button> - <button type="button" id="add-a-day" class="btn btn-default" title="'. _("Add a day") .'"><span class="glyphicon glyphicon-plus text-success"></span></button> + <button type="button" id="remove-a-day" class="btn btn-default disabled" title="'. _("Remove a day") .'"><span class="glyphicon glyphicon-minus text-info"></span><span class="sr-only">'. _("Remove") .'</span></button> + <button type="button" id="add-a-day" class="btn btn-default" title="'. _("Add a day") .'"><span class="glyphicon glyphicon-plus text-success"></span><span class="sr-only">'. _("Add") .'</span></button> </div> </div> - <div class="col-md-6 text-right"> + <div class="col-md-8 text-right"> <div class="btn-group"> <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown"> <span class="glyphicon glyphicon-remove text-danger"></span> '. _("Remove") . ' <span class="caret"></span> @@ -200,7 +242,8 @@ if (!Utils::issetAndNoEmpty('nom', $_SESSION) && !Utils::issetAndNoEmpty('adress <li><a id="resethours" href="javascript:void(0)">'. _("Remove all hours") .'</a></li> </ul> </div> - <button name="choixheures" value="'. _("Next") .'" type="submit" class="btn btn-success disabled">'. _('Next') . '</button> + <a class="btn btn-default" href="'.Utils::get_server_name().'infos_sondage.php?choix_sondage=date" title="'. _('Back to step 1') . '">'. _('Back') . '</a> + <button name="choixheures" value="'. _("Next") .'" type="submit" class="btn btn-success disabled" title="'. _('Go to step 3') . '">'. _("Next") .'</button> </div> </div> </div> diff --git a/contacts.php b/contacts.php deleted file mode 100644 index ff219c27..00000000 --- a/contacts.php +++ /dev/null @@ -1,144 +0,0 @@ -<?php -/** - * This software is governed by the CeCILL-B license. If a copy of this license - * is not distributed with this file, you can obtain one at - * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt - * - * Authors of STUdS (initial project): Guilhem BORGHESI (borghesi@unistra.fr) and Raphaël DROZ - * Authors of Framadate/OpenSondate: Framasoft (https://github.com/framasoft) - * - * ============================= - * - * Ce logiciel est régi par la licence CeCILL-B. Si une copie de cette licence - * ne se trouve pas avec ce fichier vous pouvez l'obtenir sur - * http://www.cecill.info/licences/Licence_CeCILL-B_V1-fr.txt - * - * Auteurs de STUdS (projet initial) : Guilhem BORGHESI (borghesi@unistra.fr) et Raphaël DROZ - * Auteurs de Framadate/OpenSondage : Framasoft (https://github.com/framasoft) - */ -namespace Framadate; - -include_once __DIR__ . '/app/inc/init.php'; - -session_start(); - -if (file_exists('bandeaux_local.php')) { - include_once('bandeaux_local.php'); -} else { - include_once('bandeaux.php'); -} - -// action du bouton annuler -if ((isset($_POST['envoiquestion'])) && - isset($_POST['nom']) && !empty($_POST['nom']) && - isset($_POST['adresse_mail']) && !empty($_POST['adresse_mail']) && Utils::isValidEmail($_POST['adresse_mail']) && - isset($_POST['question']) && !empty($_POST['question'])) { - $message=str_replace("\\","",$_POST["question"]); - $headers = 'Reply-To: '.$_POST['adresse_mail']; - - Utils::sendEmail( ADRESSEMAILADMIN, "" . _("[CONTACT] You have sent a question ") . "".NOMAPPLICATION, "" . _("You have a question from a user ") . " ".NOMAPPLICATION."\n\n" . _("User") . " : ".$_POST["nom"]."\n\n" . _("User's email address") . " : $_POST[adresse_mail]\n\n" . _("Message") . " :".$message,$headers ); - Utils::sendEmail( "$_POST[adresse_mail]", "" . _("[COPY] Someone has sent a question ") . "".NOMAPPLICATION, "" . _("Here is a copy of your question") . " :\n\n".$message." \n\n" . _("We're going to answer your question shortly.") . "\n\n" . _("Thanks for your confidence.") . "\n".NOMAPPLICATION ); - - //affichage de la page de confirmation d'envoi - Utils::print_header(_("Make your polls")); - bandeau_titre(_("Make your polls")); - - echo ' - <div class="alert alert-success"> - <h2>' . _("Your message has been sent!") . '</h2> - <p>' . _("Back to the homepage of ") . ' <a href="' . Utils::get_server_name() . '"> ' . NOMAPPLICATION . '</a>.</p> - </div>'."\n"; - bandeau_pied(); - session_unset(); - -} else { - $post_var = array('question', 'nom', 'adresse_mail', ); - foreach ($post_var as $var) { - if (isset($_POST[$var]) && !empty($_POST[$var])) { - $_SESSION[$var] = $_POST[$var]; - } else { - $_SESSION[$var] = null; - } - } - - /* - * Préparation des messages d'erreur - */ - - $errors = array( - 'name' => array ( - 'msg' => '', - 'aria' => '', - 'class' => '' - ), - 'email' => array ( - 'msg' => '', - 'aria' => '', - 'class' => '' - ), - 'question' => array ( - 'msg' => '', - 'aria' => '', - 'class' => '' - ), - 'state' => false - ); - - if (isset($_POST['envoiquestion']) && $_SESSION["nom"]=="") { - $errors['name']['aria'] = 'aria-describeby="#poll_name_error" '; $errors['name']['class'] = ' has-error'; - $errors['name']['msg'] = '<div class="alert alert-danger" ><p id="contact_name_error">'. _("Enter a name") .'</p></div>'; - $errors['state'] = true; - } - - if (isset($_POST['envoiquestion']) && ($_SESSION["adresse_mail"] =="" || !Utils::isValidEmail($_SESSION["adresse_mail"]))) { - $errors['email']['aria'] = 'aria-describeby="#poll_email_error" '; $errors['email']['class'] = ' has-error'; - $errors['email']['msg'] = '<div class="alert alert-danger" ><p id="contact_email_error">'. _("The address is not correct!") .'</p></div>'; - $errors['state'] = true; - } - if (isset($_POST['envoiquestion']) && $_SESSION["question"]=="") { - $errors['question']['aria'] = 'aria-describeby="#poll_question_error" '; $errors['question']['class'] = ' has-error'; - $errors['question']['msg'] = '<div class="alert alert-danger" ><p id="contact_question_error">'. _("You must ask a question!") .'</p></div>'; - $errors['state'] = true; - } - - //affichage de la page - if($errors['state']) { - Utils::print_header( _("Error!").' - '._("Contact us") ); - } else { - Utils::print_header( _("Contact us") ); - } - bandeau_titre(_("Contact us")); - - echo ' - <div class="row"> - <div class="col-md-6 col-md-offset-3"> - <form name=formulaire action="' . Utils::get_server_name() . 'contacts.php" method="POST" class="form-horizontal" role="form"> - <p>' . _("If you have questions, you can send a message here.") . '</p> - <div class="form-group'.$errors['name']['class'].'"> - <label for="name" class="col-sm-5 control-label">' . _("Your name") .'</label> - <div class="col-sm-7"> - <input type="text" maxlength="64" id="name" name="nom" class="form-control" '.$errors['name']['aria'].' value="'.$_SESSION["nom"].'" /> - </div> - </div> - '.$errors['name']['msg'].' - <div class="form-group'.$errors['email']['class'].'"> - <label for="email" class="col-sm-5 control-label">' . _("Your email address") . '</label> - <div class="col-sm-7"> - <input type="text" maxlength="64" id="email" name="adresse_mail" class="form-control" '.$errors['email']['aria'].' value="'.$_SESSION["adresse_mail"].'" /> - </div> - </div> - '.$errors['email']['msg'].' - <div class="form-group'.$errors['question']['class'].'"> - <label for="question" class="col-sm-5 control-label">' . _("Question") . '</label> - <div class="col-sm-7"> - <textarea name="question" id="question" rows="7" class="form-control" '.$errors['question']['aria'].'>'.$_SESSION["question"].'</textarea> - </div> - </div> - '.$errors['question']['msg'].' - <p class="text-right"><button type="submit" name="envoiquestion" value="'._("Send your question").'" class="btn btn-success">'._("Send your question").'</button></p> - </form> - </div> - </div>'."\n"; - - bandeau_pied(); -} diff --git a/creation_sondage.php b/creation_sondage.php index a45ed8dd..f036f889 100644 --- a/creation_sondage.php +++ b/creation_sondage.php @@ -45,27 +45,7 @@ function ajouter_sondage() $sondage=random(16); $sondage_admin=$sondage.random(8); - if ($_SESSION["formatsondage"]=="A"||$_SESSION["formatsondage"]=="A+") { - //extraction de la date de fin choisie - if ($_SESSION["champdatefin"]) { - if ($_SESSION["champdatefin"]>time()+250000) { - $date_fin=$_SESSION["champdatefin"]; - } - } else { - $date_fin=time()+15552000; - } - } - - if ($_SESSION["formatsondage"]=="D"||$_SESSION["formatsondage"]=="D+") { - //Calcul de la date de fin du sondage - $temp_array = array_unique($_SESSION["totalchoixjour"]); - sort($temp_array); - $date_fin= end($temp_array)+2592000; - } - - if (is_numeric($date_fin) === false) { - $date_fin = time()+15552000; - } + $date_fin = ($_SESSION["champdatefin"]) ? $_SESSION["champdatefin"] : $date_fin=time()+15552000; $sql = 'INSERT INTO sondage (id_sondage, commentaires, mail_admin, nom_admin, titre, id_sondage_admin, date_fin, format, mailsonde) @@ -90,10 +70,10 @@ function ajouter_sondage() $message = _("This is the message you have to send to the people you want to poll. \nNow, you have to send this message to everyone you want to poll."); $message .= "\n\n"; $message .= stripslashes(html_entity_decode($_SESSION["nom"],ENT_QUOTES,"UTF-8"))." " . _("hast just created a poll called") . " : \"".stripslashes(htmlspecialchars_decode($_SESSION["titre"],ENT_QUOTES))."\".\n"; - $message .= _("Thanks for filling the poll at the link above") . " :\n\n%s\n\n" . _("Thanks for your confidence.") . ",\n".NOMAPPLICATION; + $message .= _("Thanks for filling the poll at the link above") . " :\n\n%s\n\n" . _("Thanks for your confidence.") . "\n".NOMAPPLICATION; $message_admin = _("This message should NOT be sended to the polled people. It is private for the poll's creator.\n\nYou can now modify it at the link above"); - $message_admin .= " :\n\n"."%s \n\n" . _("Thanks for your confidence.") . ",\n".NOMAPPLICATION; + $message_admin .= " :\n\n"."%s \n\n" . _("Thanks for your confidence.") . "\n".NOMAPPLICATION; $message = sprintf($message, Utils::getUrlSondage($sondage)); $message_admin = sprintf($message_admin, Utils::getUrlSondage($sondage_admin, true)); diff --git a/css/bootstrap-accessibility.css b/css/bootstrap-accessibility.css deleted file mode 100644 index 7f040925..00000000 --- a/css/bootstrap-accessibility.css +++ /dev/null @@ -1,64 +0,0 @@ -.btn:focus { - outline: dotted 2px black; -} - -div.active:focus { - outline: dotted 1px black; -} - -a:focus { - outline: dotted 1px black; -} - -.close:hover, .close:focus { - outline: dotted 1px black; -} - -.nav > li > a:hover, .nav > li > a:focus { - outline: dotted 1px black; -} - -.carousel-inner > .item { - position: absolute; - top: -999999em; - display: block; - -webkit-transition: 0.6s ease-in-out left; - -moz-transition: 0.6s ease-in-out left; - -o-transition: 0.6s ease-in-out left; - transition: 0.6s ease-in-out left; -} -.carousel-inner > .active { - top: 0; -} -.carousel-inner > .active, -.carousel-inner > .next, -.carousel-inner > .prev { - position: relative; -} -.carousel-inner > .next, -.carousel-inner > .prev { - position: absolute; - top: 0; - width: 100%; -} - -.alert-success { - color: #2d4821; -} - -.alert-info { - color: #214c62; -} - -.alert-warning { - color: #6c4a00; - background-color: #f9f1c6; -} - -.alert-danger { - color: #d2322d; -} - -.alert-danger:hover { - color: #a82824; -} diff --git a/css/datepicker3.css b/css/datepicker3.css index aa78b1d4..81ddb079 100644 --- a/css/datepicker3.css +++ b/css/datepicker3.css @@ -12,8 +12,8 @@ border-radius: 4px; direction: ltr; /*.dow { - border-top: 1px solid #ddd !important; - }*/ + border-top: 1px solid #ddd !important; + }*/ } .datepicker-inline { width: 220px; @@ -127,9 +127,10 @@ .datepicker table tr td.today:hover, .datepicker table tr td.today.disabled, .datepicker table tr td.today.disabled:hover { - color: #000000; - background-color: #ffdb99; - border-color: #ffb733; + font-weight:bold; + /*color: #000000; + /*background-color: #ffdb99; + border-color: #ffb733;*/*/ } .datepicker table tr td.today:hover, .datepicker table tr td.today:hover:hover, @@ -151,9 +152,9 @@ .open .dropdown-toggle.datepicker table tr td.today:hover, .open .dropdown-toggle.datepicker table tr td.today.disabled, .open .dropdown-toggle.datepicker table tr td.today.disabled:hover { - color: #000000; + /*color: #000000; background-color: #ffcd70; - border-color: #f59e00; + border-color: #f59e00;*/ } .datepicker table tr td.today:active, .datepicker table tr td.today:hover:active, @@ -229,8 +230,8 @@ fieldset[disabled] .datepicker table tr td.today.active, fieldset[disabled] .datepicker table tr td.today:hover.active, fieldset[disabled] .datepicker table tr td.today.disabled.active, fieldset[disabled] .datepicker table tr td.today.disabled:hover.active { - background-color: #ffdb99; - border-color: #ffb733; + /*background-color: #ffdb99; + border-color: #ffb733;*/ } .datepicker table tr td.today:hover:hover { color: #000; @@ -250,8 +251,8 @@ fieldset[disabled] .datepicker table tr td.today.disabled:hover.active { .datepicker table tr td.range.today.disabled, .datepicker table tr td.range.today.disabled:hover { color: #000000; - background-color: #f7ca77; - border-color: #f1a417; + /*background-color: #f7ca77; + border-color: #f1a417;*/ border-radius: 0; } .datepicker table tr td.range.today:hover, @@ -274,9 +275,9 @@ fieldset[disabled] .datepicker table tr td.today.disabled:hover.active { .open .dropdown-toggle.datepicker table tr td.range.today:hover, .open .dropdown-toggle.datepicker table tr td.range.today.disabled, .open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover { - color: #000000; + /*color: #000000; background-color: #f4bb51; - border-color: #bf800c; + border-color: #bf800c;*/ } .datepicker table tr td.range.today:active, .datepicker table tr td.range.today:hover:active, @@ -352,16 +353,16 @@ fieldset[disabled] .datepicker table tr td.range.today.active, fieldset[disabled] .datepicker table tr td.range.today:hover.active, fieldset[disabled] .datepicker table tr td.range.today.disabled.active, fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active { - background-color: #f7ca77; - border-color: #f1a417; + /*background-color: #f7ca77; + border-color: #f1a417;*/ } .datepicker table tr td.selected, .datepicker table tr td.selected:hover, .datepicker table tr td.selected.disabled, .datepicker table tr td.selected.disabled:hover { color: #ffffff; - background-color: #999999; - border-color: #555555; + background-color: #9D74B5; + border-color: #8E65A6; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker table tr td.selected:hover, @@ -385,8 +386,8 @@ fieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active { .open .dropdown-toggle.datepicker table tr td.selected.disabled, .open .dropdown-toggle.datepicker table tr td.selected.disabled:hover { color: #ffffff; - background-color: #858585; - border-color: #373737; + background-color: #9D74B5; + border-color: #8E65A6; } .datepicker table tr td.selected:active, .datepicker table tr td.selected:hover:active, @@ -462,16 +463,16 @@ fieldset[disabled] .datepicker table tr td.selected.active, fieldset[disabled] .datepicker table tr td.selected:hover.active, fieldset[disabled] .datepicker table tr td.selected.disabled.active, fieldset[disabled] .datepicker table tr td.selected.disabled:hover.active { - background-color: #999999; - border-color: #555555; + background-color: #9D74B5; + border-color: #8E65A6; } .datepicker table tr td.active, .datepicker table tr td.active:hover, .datepicker table tr td.active.disabled, .datepicker table tr td.active.disabled:hover { color: #ffffff; - background-color: #428bca; - border-color: #357ebd; + background-color: #6A5687; + border-color: #5C4978; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker table tr td.active:hover, @@ -495,8 +496,8 @@ fieldset[disabled] .datepicker table tr td.selected.disabled:hover.active { .open .dropdown-toggle.datepicker table tr td.active.disabled, .open .dropdown-toggle.datepicker table tr td.active.disabled:hover { color: #ffffff; - background-color: #3276b1; - border-color: #285e8e; + background-color: #6A5687; + border-color: #5C4978; } .datepicker table tr td.active:active, .datepicker table tr td.active:hover:active, @@ -572,8 +573,8 @@ fieldset[disabled] .datepicker table tr td.active.active, fieldset[disabled] .datepicker table tr td.active:hover.active, fieldset[disabled] .datepicker table tr td.active.disabled.active, fieldset[disabled] .datepicker table tr td.active.disabled:hover.active { - background-color: #428bca; - border-color: #357ebd; + background-color: #6A5687; + border-color: #5C4978; } .datepicker table tr td span { display: block; @@ -599,8 +600,8 @@ fieldset[disabled] .datepicker table tr td.active.disabled:hover.active { .datepicker table tr td span.active.disabled, .datepicker table tr td span.active.disabled:hover { color: #ffffff; - background-color: #428bca; - border-color: #357ebd; + background-color: #6A5687; + border-color: #5C4978; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker table tr td span.active:hover, @@ -624,8 +625,8 @@ fieldset[disabled] .datepicker table tr td.active.disabled:hover.active { .open .dropdown-toggle.datepicker table tr td span.active.disabled, .open .dropdown-toggle.datepicker table tr td span.active.disabled:hover { color: #ffffff; - background-color: #3276b1; - border-color: #285e8e; + background-color: #6A5687; + border-color: #5C4978; } .datepicker table tr td span.active:active, .datepicker table tr td span.active:hover:active, @@ -701,8 +702,8 @@ fieldset[disabled] .datepicker table tr td span.active.active, fieldset[disabled] .datepicker table tr td span.active:hover.active, fieldset[disabled] .datepicker table tr td span.active.disabled.active, fieldset[disabled] .datepicker table tr td span.active.disabled:hover.active { - background-color: #428bca; - border-color: #357ebd; + background-color: #6A5687; + border-color: #5C4978; } .datepicker table tr td span.old, .datepicker table tr td span.new { diff --git a/css/frama.css b/css/frama.css new file mode 100644 index 00000000..4c43753d --- /dev/null +++ b/css/frama.css @@ -0,0 +1,450 @@ +/* Text */ +.text-muted, +.text-muted a, +a.text-muted { + color: #767676; + border-color: #767676; +} + +.text-muted a:hover, +.text-muted a:focus, +a.text-muted:hover, +a.text-muted:focus { + color: #5e5e5e; + border-color:#5e5e5e; + border-bottom-style:solid; +} +.text-primary, +.text-primary a, +a.text-primary { + color: #6A5687; + border-color: #6A5687; +} +.text-primary a:hover, +.text-primary a:focus, +a.text-primary:hover, +a.text-primary:focus { + color: #583C66; + border-color: #583C66; + border-bottom-style:solid; +} +.text-success, +.text-success a, +a.text-success { + color: #606E38; + border-color: #606E38; +} +.text-success a:hover, +.text-success a:focus, +a.text-success:hover, +a.text-success:focus { + color: #67753C; + border-color: #67753C; + border-bottom-style:solid; +} +.text-info, +.text-info a, +a.text-info { + color: #31748F; + border-color: #31748F; +} +.text-info a:hover, +.text-info a:focus, +a.text-info:hover, +a.text-info:focus { + color: #245569; + border-color: #31748F; + border-bottom-style:solid; +} +.text-warning, +.text-warning a, +a.text-warning { + color: #8A6E3B; + border-color: #8A6E3B; +} +.text-warning a:hover, +.text-warning a:focus, +a.text-warning:hover, +a.text-warning:focus { + color: #66522C; + border-color: #66522C; + border-bottom-style:solid; +} +.text-danger, +.text-danger a, +a.text-danger { + color: #A94E42; + border-color: #A94E42; +} +.text-danger a:hover, +.text-danger a:focus, +a.text-danger:hover, +a.text-danger:focus { + color: #843D34; + border-color: #843D34; + border-bottom-style:solid; +} + +/* Background */ +.bg-primary, +.bg-primary a, +a.bg-primary:focus, +a.bg-primary:hover { + color: #fff; + background-color: #6A5687; + border-color:#fff; +} +.bg-success, a.bg-success:hover { + background-color: #EAF0D8; +} +.bg-info, a.bg-info:hover { + background-color: #D9EFF7; +} +.bg-warning, a.bg-warning:hover { + background-color: #FCF3E3; +} +.bg-danger,a.bg-danger:hover { + background-color: #F2E7E5; +} + +/* Alerts */ +.alert-success a:not(.btn), .alert-info a:not(.btn), +.alert-warning a:not(.btn), .alert-danger a:not(.btn) { + text-decoration:none; + border-bottom-width: 1px; + border-bottom-style: dotted; +} +.alert-success a:not(.btn):hover, .alert-info a:not(.btn):hover, +.alert-warning a:not(.btn):hover, .alert-danger a:not(.btn):hover { + text-decoration:none; + border-bottom-style: solid; +} +.alert-success a:not(.btn), +.alert-success a:not(.btn):hover, +.alert-success { + color: #4A542C; + background:#EAF0D8; + border-color: #4A542C; +} +.alert-info a:not(.btn), +.alert-info a:not(.btn):hover, +.alert-info { + color: #245569; + background-color: #D9EFF7; + border-color: #245569; +} +.alert-warning a:not(.btn), +.alert-warning a:not(.btn):hover, +.alert-warning { + color: #66522C; + background-color: #FCF3E3; + border-color: #66522C; +} +.alert-danger a:not(.btn), +.alert-danger a:not(.btn):hover, +.alert-danger { + color: #843D34; + background-color: #F2E7E5; + border-color: #843D34; +} + +/* Buttons */ +.btn-default { + color: #333; + background-color: #fff; + border-color: #ccc; +} +.btn-default:hover, +.btn-default:focus, +.btn-default:active, +.btn-default.active, +.open > .dropdown-toggle.btn-default { + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} + +.btn-default.disabled, +.btn-default[disabled], +fieldset[disabled] .btn-default, +.btn-default.disabled:hover, +.btn-default[disabled]:hover, +fieldset[disabled] .btn-default:hover, +.btn-default.disabled:focus, +.btn-default[disabled]:focus, +fieldset[disabled] .btn-default:focus, +.btn-default.disabled:active, +.btn-default[disabled]:active, +fieldset[disabled] .btn-default:active, +.btn-default.disabled.active, +.btn-default[disabled].active, +fieldset[disabled] .btn-default.active { + background-color: #fff; + border-color: #ccc; +} + +.btn-default .badge { + color: #fff; + background-color: #767676; +} + +.btn-primary { + color: #fff; + background-color: #6A5687; + border-color: #5C4978; +} +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.open > .dropdown-toggle.btn-primary { + color: #fff; + background-color: #5E4A7A; + border-color: #513F69; +} +.btn-primary.disabled, +.btn-primary[disabled], +fieldset[disabled] .btn-primary, +.btn-primary.disabled:hover, +.btn-primary[disabled]:hover, +fieldset[disabled] .btn-primary:hover, +.btn-primary.disabled:focus, +.btn-primary[disabled]:focus, +fieldset[disabled] .btn-primary:focus, +.btn-primary.disabled:active, +.btn-primary[disabled]:active, +fieldset[disabled] .btn-primary:active, +.btn-primary.disabled.active, +.btn-primary[disabled].active, +fieldset[disabled] .btn-primary.active { + background-color: #6A5687; + border-color: #5C4978; +} +.btn-primary .badge { + color: #6A5687; + background-color: #fff; +} + +.btn-success { + color: #fff; + background-color: #849551; + border-color: #748544; +} +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.open > .dropdown-toggle.btn-success { + color: #fff; + background-color: #768745; + border-color: #67753C; +} +.btn-success.disabled, +.btn-success[disabled], +fieldset[disabled] .btn-success, +.btn-success.disabled:hover, +.btn-success[disabled]:hover, +fieldset[disabled] .btn-success:hover, +.btn-success.disabled:focus, +.btn-success[disabled]:focus, +fieldset[disabled] .btn-success:focus, +.btn-success.disabled:active, +.btn-success[disabled]:active, +fieldset[disabled] .btn-success:active, +.btn-success.disabled.active, +.btn-success[disabled].active, +fieldset[disabled] .btn-success.active { + background-color: #849551; + border-color: #748544; +} +.btn-success .badge { + color: #849551; + background-color: #fff; +} + +.btn-info { + color: #fff; + background-color: #366F86; + border-color: #2C6278; +} +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.open > .dropdown-toggle.btn-info { + color: #fff; + background-color: #2D647A; + border-color: #275669; +} +.btn-info.disabled, +.btn-info[disabled], +fieldset[disabled] .btn-info, +.btn-info.disabled:hover, +.btn-info[disabled]:hover, +fieldset[disabled] .btn-info:hover, +.btn-info.disabled:focus, +.btn-info[disabled]:focus, +fieldset[disabled] .btn-info:focus, +.btn-info.disabled:active, +.btn-info[disabled]:active, +fieldset[disabled] .btn-info:active, +.btn-info.disabled.active, +.btn-info[disabled].active, +fieldset[disabled] .btn-info.active { + background-color: #366F86; + border-color: #2C6278; +} +.btn-info .badge { + color: #366F86; + background-color: #fff; +} + +.btn-warning { + color: #fff; + background-color: #DBA306; + border-color: #CC9600; +} +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.open > .dropdown-toggle.btn-warning { + color: #fff; + background-color: #CF9800; + border-color: #BD8A00; +} +.btn-warning.disabled, +.btn-warning[disabled], +fieldset[disabled] .btn-warning, +.btn-warning.disabled:hover, +.btn-warning[disabled]:hover, +fieldset[disabled] .btn-warning:hover, +.btn-warning.disabled:focus, +.btn-warning[disabled]:focus, +fieldset[disabled] .btn-warning:focus, +.btn-warning.disabled:active, +.btn-warning[disabled]:active, +fieldset[disabled] .btn-warning:active, +.btn-warning.disabled.active, +.btn-warning[disabled].active, +fieldset[disabled] .btn-warning.active { + background-color: #DBA306; + border-color: #CC9600; +} +.btn-warning .badge { + color: #DBA306; + background-color: #fff; +} + +.btn-danger { + color: #fff; + background-color: #CC2D18; + border-color: #BD2511; +} +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.open > .dropdown-toggle.btn-danger { + color: #fff; + background-color: #BF2511; + border-color: #AD220F; +} +.btn-danger.disabled, +.btn-danger[disabled], +fieldset[disabled] .btn-danger, +.btn-danger.disabled:hover, +.btn-danger[disabled]:hover, +fieldset[disabled] .btn-danger:hover, +.btn-danger.disabled:focus, +.btn-danger[disabled]:focus, +fieldset[disabled] .btn-danger:focus, +.btn-danger.disabled:active, +.btn-danger[disabled]:active, +fieldset[disabled] .btn-danger:active, +.btn-danger.disabled.active, +.btn-danger[disabled].active, +fieldset[disabled] .btn-danger.active { + background-color: #CC2D18; + border-color: #BD2511; +} +.btn-danger .badge { + color: #CC2D18; + background-color: #fff; +} + +.btn-orange { + color: #fff; + background-color: #D2703A; + border-color: #C26430; +} +.btn-orange:hover, +.btn-orange:focus, +.btn-orange:active, +.btn-orange.active, +.open > .dropdown-toggle.btn-orange { + color: #fff; + background-color: #C46531; + border-color: #B35C2D; +} +.btn-orange.disabled, +.btn-orange[disabled], +fieldset[disabled] .btn-orange, +.btn-orange.disabled:hover, +.btn-orange[disabled]:hover, +fieldset[disabled] .btn-orange:hover, +.btn-orange.disabled:focus, +.btn-orange[disabled]:focus, +fieldset[disabled] .btn-orange:focus, +.btn-orange.disabled:active, +.btn-orange[disabled]:active, +fieldset[disabled] .btn-orange:active, +.btn-orange.disabled.active, +.btn-orange[disabled].active, +fieldset[disabled] .btn-orange.active { + background-color: #D2703A; + border-color: #C26430; +} +.btn-orange .badge { + color: #D2703A; + background-color: #fff; +} + +.btn-link { + font-weight: normal; + color: #366F86; + cursor: pointer; + border-radius: 0; +} +.btn-link, +.btn-link:active, +.btn-link[disabled], +fieldset[disabled] .btn-link { + background-color: transparent; + -webkit-box-shadow: none; + box-shadow: none; +} +.btn-link, +.btn-link:hover, +.btn-link:focus, +.btn-link:active { + border-color: transparent; +} +.btn-link:hover, +.btn-link:focus { + color: #134C63; + 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: #767676; + text-decoration: none; +} +.btn-link .badge { + color: #fff; + background-color: #767676; +} + diff --git a/css/style.css b/css/style.css index 7ab6f744..8ff42240 100644 --- a/css/style.css +++ b/css/style.css @@ -15,76 +15,24 @@ * Auteurs d'OpenSondage : Framasoft (https://github.com/framasoft) */ -/* Calendrier dans choix_date.php */ -div.calendrier table { - border:2px solid #ccf; - background-color: #CCF; - margin-left: auto; - margin-right: auto; +body { + font-family: "DejaVu Sans", Verdana, Geneva, sans-serif; + color:#333; + background:#eee; } -div.calendrier td { - height: 40px; -} - -div.calendrier td.libre:hover, -div.calendrier td.choisi:hover { - opacity: 0.8; -} - -/*entête calendrier */ -.choix_date_mois { - font-weight: bold; - font-size: larger; -} - -/*jour de la semaine dans calendrier*/ -div.calendrier td.joursemaine { - width:14%; - text-align: center; - border: 2px; - background-color: white; - height: 40px; -} -/*jour avant le premier jour du mois dans calendrier*/ -div.calendrier td.avant { - text-align: center; - border: 2px; - font-family:arial; - font-size:13px; - background-color: #EEEEEE; -} -/*jour libre dans calendrier*/ -div.calendrier td.libre { - text-align: center; - border: 2px; - background-color: #66FF99; -} -/*jour deja selectionné dans calendrier*/ -div.calendrier td.choisi { - text-align: center; - border: 2px; - background-color: #54ADF7; -} - -.bouton { - border:0px; - padding: 12px 30px 6px; - margin:0px; - cursor:pointer; - font-family:arial; - font-size:13px; -} -/*les boutons pour choisir un jour non selectionné*/ -.ON { - background-color: #66FF99; +.trait { /* hr */ + background-color: #EEE; + height: 11px; + margin:15px 0px; + border:none; } -/*les boutons pour deselectionner un jour deja choisi*/ -.OFF { - background-color: #54ADF7; +.ombre { + background-color: #FFF; + box-shadow: -4px 6px 9px rgba(50, 50, 50, 0.5); + margin:30px auto; } -/* </calendrier> */ /* Commentaires */ div.comment{ @@ -108,12 +56,24 @@ main, header, footer, .container .jumbotron { padding:24px 30px; } +.summary h3 { + margin-top:0; +} + +.summary { + font-weight:bold; +} + +.summary img { + max-width:100px; +} + /* Effet sur les images en page d'accueil */ -.opacity { - opacity: 0.6; +.opacity img { + opacity: 0.8; } -.opacity:hover { +.opacity:hover img { opacity: 1; } @@ -146,6 +106,7 @@ h3.control-label { font-weight: 700; font-size: 14px; line-height: 1.42857; + margin-top:0; } caption { @@ -156,7 +117,8 @@ caption { /* adminstuds.php */ #title-form h2 .btn-edit, #email-form .btn-edit, -#description-form .btn-edit { +#description-form .btn-edit, +#poll-rules-form .btn-edit { position:absolute; left:-2000px; } @@ -166,7 +128,9 @@ caption { #email-form .btn-edit:focus, #email-form:hover .btn-edit, #description-form .btn-edit:focus, -#description-form:hover .btn-edit { +#description-form:hover .btn-edit, +#poll-rules-form .btn-edit:focus, +#poll-rules-form:hover .btn-edit { position:relative !important; left:0; padding: 0px 10px; @@ -180,10 +144,18 @@ caption { margin-bottom:0; } +#poll-rules-form p, +.jumbotron p.well { + font-size:16px; +} +.jumbotron p { + font-weight: normal; +} + /* Tableau du sondage */ #tableContainer { overflow-x:auto; - margin:0 auto; + margin:20px auto; } table.results { @@ -210,8 +182,12 @@ table.results tbody td { table.results thead th { text-align:center; border:2px solid white; - padding:1px 5px; + padding:5px; min-width:40px; + font-size:12px; + max-width:100px; + overflow:hidden; + text-overflow:ellipsis; } table.results thead .btn { @@ -308,23 +284,23 @@ table.results .btn-link.btn-sm { } .yes input[type="radio"]:checked + label { /* =.btn-success.active */ - color: #FFF; - background-color: #449D44; - border-color: #398439; + color: #fff; + background-color: #768745; + border-color: #67753C; box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.125) inset; } .ifneedbe input[type="radio"]:checked + label { /* =.btn-warning.active */ - color: #FFF; - background-color: #EC971F; - border-color: #D58512; + color: #fff; + background-color: #CF9800; + border-color: #BD8A00; box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.125) inset; } .no input[type="radio"]:checked + label { /* =.btn-danger.active */ - color: #FFF; - background-color: #C9302C; - border-color: #AC2925; + color: #fff; + background-color: #BF2511; + border-color: #AD220F; box-shadow: 0px 3px 5px rgba(0, 0, 0, 0.125) inset; } @@ -354,4 +330,11 @@ table.results .btn-link.btn-sm { border:none; background:transparent; } +/* choix_autre.php */ +.md-a-img { + text-decoration:none !important; +} +#md-a-imgModal .form-group { + margin:10px 0px; +} diff --git a/exportcsv.php b/exportcsv.php index a99b703c..fd868bff 100644 --- a/exportcsv.php +++ b/exportcsv.php @@ -34,44 +34,57 @@ $nbcolonnes=substr_count($dsondage->sujet,',')+1; $toutsujet=explode(",",$dsondage->sujet); //affichage des sujets du sondage -$input =";"; +$input =","; foreach ($toutsujet as $value) { if ($dsondage->format=="D"||$dsondage->format=="D+") { - if (strpos($dsondage->sujet,'@') !== false) { - $days=explode("@",$value); - $input.= date("j/n/Y",$days[0]).';'; - } else { - $input.= date("j/n/Y",$values).';'; - } + if (strpos($dsondage->sujet,'@') !== false) { + $days=explode("@",$value); + $input.= '"'.date("j/n/Y",$days[0]).'",'; + } else { + $input.= '"'.date("j/n/Y",$values).'",'; + } } else { - $input.= $value.';'; + + preg_match_all('/\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)/',$value,$md_a_img); // Markdown [](href) + preg_match_all('/!\[(.*?)\]\((.*?)\)/',$value,$md_img); // Markdown  + preg_match_all('/\[(.*?)\]\((.*?)\)/',$value,$md_a); // Markdown [text](href) + if (isset($md_a_img[2][0]) && $md_a_img[2][0]!='' && isset($md_a_img[3][0]) && $md_a_img[3][0]!='') { // [](href) + $subject_text = (isset($md_a_img[1][0]) && $md_a_img[1][0]!='') ? stripslashes($md_a_img[1][0]) : _("Choice") .' '.($i+1); + } elseif (isset($md_img[2][0]) && $md_img[2][0]!='') { //  + $subject_text = (isset($md_img[1][0]) && $md_img[1][0]!='') ? stripslashes($md_img[1][0]) : _("Choice") .' '.($i+1); + } elseif (isset($md_a[2][0]) && $md_a[2][0]!='') { // [text](href) + $subject_text = (isset($md_a[1][0]) && $md_a[1][0]!='') ? stripslashes($md_a[1][0]) : _("Choice") .' '.($i+1); + } else { // text only + $subject_text = stripslashes($value); + } + $input.= '"'.html_entity_decode($subject_text).'",'; } } $input.="\r\n"; if (strpos($dsondage->sujet,'@') !== false) { - $input.=";"; + $input.=","; foreach ($toutsujet as $value) { $heures=explode("@",$value); - $input.= $heures[1].';'; + $input.= '"'.$heures[1].'",'; } $input.="\r\n"; } -while ( $data=$user_studs->FetchNextObject(false)) { +while ( $data=$user_studs->FetchNextObject(false)) { // Le nom de l'utilisateur $nombase=html_entity_decode(str_replace("°","'",$data->nom)); - $input.=$nombase.';'; + $input.= '"'.$nombase.'",'; //affichage des resultats $ensemblereponses=$data->reponses; for ($k=0;$k<$nbcolonnes;$k++) { $car=substr($ensemblereponses,$k,1); switch ($car) { - case "1": $input .= _('Yes').';'; $somme[$k]++; break; - case "2": $input .= _('Ifneedbe').';'; break; - default: $input .= _('No').';'; break; + case "1": $input .= '"'._('Yes').'",'; $somme[$k]++; break; + case "2": $input .= '"'._('Ifneedbe').'",'; break; + default: $input .= '"'._('No').'",'; break; } } @@ -86,6 +99,6 @@ header( 'Content-Length: '.$filesize ); header( 'Content-Disposition: attachment; filename="'.$filename.'"' ); header( 'Cache-Control: max-age=10' ); -echo $input; +echo str_replace('"','""',$input); die(); diff --git a/images/classic.png b/images/classic.png index ea40b3ad2d437931252c6e229e72ef5c18b854e0..b9f7bbb90874e637b8b932558ef1558b33f4ebe9 100644 GIT binary patch literal 23737 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 literal 12630 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 Mrz%?}{Wb7^0ghBU;s5{u diff --git a/images/date.png b/images/date.png index 0217b9dc04dfae25e499e02dedb3ed963d5ab322..089e0534f39937e4d5e779dd8850f50dda3fcd70 100644 GIT binary patch literal 23500 zcmdSAWmH^E(<nMvkOYDUmjHo*3?u}13$B9?7J@T446Xr!+h7S6Y;X^QO9)AD2sXI8 zOOW7~N8a~+zH`sHXMOjcKX=bsd#&!>RbAHAUDY*rlXr^%LPc2xSpXUu8bJR32e_L7 zNCU7iFflPPu<l=2SXd9RAK_r%KaU?i#C=5cn3$O8F%c07In5IiQYtbcA__(dDq324 zdU}#4Pnn<6G1Jh|)BS-2?H&~S0X6{+4gno05h>k&`?>o9Ai_a=j@E{O_7s3lgoZ(c zcJ~cH13&|yWBftxzaNYTm{{28XgK#@A%p-l3=F^n44jAf53ta&umEW27?=Poq6fqz zj4w5?NhP0xHFZoA;KO9(Pq<(4I49*-FH<n_Nol#b1tsQu9$CWCe*3QD(99K<Tf=P5 z!Yds-`izx7<metZ_5GZGO#F|T|3H2(pZkvjL;!R&^gpEb-~l?upQPP?B*G+Sd`Tjy zafn6AZTd7Q=fSJ$j^QOTDQU2C0{lou^X=U<;1R|>Lqr%v0CB)gii)RZgc^yQb_v`% zB*#8KDSwsVX<&G_#2)Dm+d8{cCu<bw@@e`5k%#`_*-ZCcK$J$m)?e*{jyUv%TsEA` zUcpFMk}KJ>Kij}6voH0Vk?3MIv2QaiXud1_)wZKJyhjumSC;poP+#sP_^<YV2Qhoz zNLFg+PbE@lDJnsbtCy(LT3r$|$97O&bmO2@mQ%Hx#bx}SI?ekjDrnE8AT4UH8w$6I zem_$xNoFrb0^oJWNN@5UriRlb*FU)92>Z{cPi`!w-_FI{KCKoem;N+QnDzdfsm``d zCEbX9-!1VTwI<^6WuH$%YR8(r<D1;_`=a;k3EhudTKEt29Iow==ujr>1#r#wgp%2V z?r$+T9sCD+KLqKSwK14@opevoBe-zfy+Bm&$2EBT2l_wsdqG+sDA0EOEjUBr|3F{m zfQ(rif92l+SVYQ=gPCJj{vX-T(y5e$%Q^q8L|uY^fQ$WyNe<oY|9^;xEua=ugzi`P zKNCQua$RQ(<3O;PKBL|^Epq2gSCHc{*`U_{2lM-<UAGlTJ+`j&`Eym28^haXaa4qo zSg_PE%^$gw+$KGkV#f}u)GkCS&oI-V=2+dWaV#?UptJTz)8dQt+H$WJV-%h&5BR^i zEW!mUs^fu^(321V1W@AdM#I5b%{5wGz<9#-6KJ(A?JdeAkZ<U+M*Q8L<NK@0l-Lar z(#^0mv}6Xz535~8EemO_D$AjrE1BYY7&JKx^vD)n*z#B#6>W}>_nT0CqFSO7hJJLM zB>%anhjONtE{QR1^*IV^SX~ZAnZw+=b_jOW%gyU6U|_GHPTswqQA5tuXY%@<n9XHd zLW@q={zu0X<tctDaNnu1w9T)iWV6G-zWkpbUhx6X1m)vX_56~aK<ot1zp;TJ`SCcr z<y!MGxt*C~^dnff1oNXdapA%0$$TTHD8(NI7!5!)IVO6R$5Xgh>IX)NwYWHV)1{0I ztB*F`O9&LDT<tR>90l@|Q*qdt$>`WGe33*UqbRAtnUr#lVdl;Cc*s&P`{qYzM>N%B zTQ2PwC<a`e{N~L&&&B9y?Qtq>vnL+vXEC#vW1cTjr-<T*>eG!3e7RvT?y3+rAf!=V zXLpfm)loU+*QVc;TEp?nqU8)0g|0_*y=SG#-_;POYDtA)cv4wQZuVnB0#8lm-HJ|? zU6YD5GDmXiz#vN0Tv)zw*Tal3?J7;oGW#bDEI?Iayf$OX?@%GF;bxt<lI~KepDV<R zJLMgq`lwRHF?idO3?LhgV(uHdJg<)FPVS=E48edFUt-y%x|V^IRyKE;1E46VJ%Xtg z^(wYuSv{2o@|C0{5Mia|LKCVOk_b6>m{gcOQUoKP|7{=192%=aeM3B*6+B<1vLNb; z23V2|MKNE9B^IV7ic0P+35*3)L{m&yr?&tB*NyDCn5>5(c+%lLsx_|PEZ8Y&vtxT> zv+=;m4B(_}vLoY@>*TXGj`>gUz?*}I%XW8wKDBZ1n0ni@q3hZkZIJJd;Ojr|fdl^- zuCb;4bv%+P=!a!~z+_Xs_AA6f$8VFuyx$J$_{47I`K#j{?Vjw(ISc4%O}qzKXf#9b zc$rP2crSvti`IRKil1KVSN79uqp|!OB`JdKPkO<D|Hanb*;m@9`wkyW-2rsu4voqW z7kr3^XBVs7xRh9BEX_q}8|7nv<Jq7l!SHO?caOJu!{=ic4C_i(qhv<$IoLF3NJ>aa ziDi8w8R%q|>l3^so4SI@pFWjhi|&^N%Nxr_UuH>)P7osqeFM#CY~{S=T7;p7WZ%Nx z)khjCII}Anxi#fG=#XZ<^$c##;y|@3?b=o7IO;?p;Cd16f!9DRs-^mbl5)d@43}=+ zCLbvTlI{`G<oN^Adh#KNat*}d8^iM)D_y}3x)Tn;a`!~zflKJ<r}}SkzzZ&UKNRdV zgOkHRYfZ*f<bkljdcD$UcCow1O__eMd%QGJ?36O?WRG2gX2#NMy&eYhG-G!o>2@Z` ze3X8Zs851*!){Y2RU?SY2oFyltd-cEA3W)Crc?L1@|?t@xw{b*Qq_nz0g<i{oHO%6 zIV)=PEVQ8TjrnWZ)?$*&@w9UfvvF}vYgF?J>HY1T<(vfW0H^%!1Uou4Z>?MBeXR)$ z7<)1r?HbMo3ZBfe5RmuuP%tq#Vn=k*j>p*H@kMn|elcye!}hdKKM;<ac37LU9WS8E zjN*+Qw?kI3AU-^N`v(3lP^XyXs7Sr#oH-~X`e05w5$e#MpzHryzYlA#E@>yF(OL@P zyhg?+TS9G|7b&<%T;7#X=A$LnE?Si7@LXa^&|5Pth5?|e<>cj#(N@lVDcz`8r}X}& z32!!mPT8RbAylY7v%jZ<#=(&3fF+S-j*4WN7x81UJxpgo+VfOZqnX;q%Bwz*)TyT2 zuTsT5cE~rp$Tiw^SU!PyC&E(gEd6r8OkK)J1Xbnw_`ud&olx5qs@Br+5||O=Nhl{> zyh>YFtu%>6G)O6t#bzF!n3U>N-9BH+@a7F#Q?ZrT0Ato2fKVz4VXg2PnWI=UuZ70= zyjEe%bLF6$Mq~Ez?fQPlob5zPnMatu^nihR!}Qc+gn}faO7ia4FtLNi3lH5=J&l@q zoIwnbmFqku?S}J}%G?30)IiBN-Ds~#n7ogyp@YaWSJSZ=vvIc4kVn<|^Ths9EU%ou zkz(`l%hrM|UE^)BiG5lti@GU0)w*n*V%=`ChGP+^3O7%<OJ)QxmBKGMNnm<3lu=^w zoiM(E!yMxr=QEvJwwPy1>^AaJnLyRg-CnO5l>}H+VrfIJk%$rK_Q5D(FcF=JdrjG} zkPd2K(1g)2pUW#rN!vVlS!Q_BA0Z2_71}Hn;m80Ia)SEeXYG^ZdS@**NXn9)6TXng z4q|w-K^BbA5%d=H@gC-#91<H*&u!S@u$Q#P!z6y-!RD^BCgdR|S~o#H;ZQ%5RhOe+ za~6--*<r}}4ywmX2dCinM!J4M2Yk0Z>5|{DQCXQ%3U*HS<ep)C&P}aaLK4*AEZTf4 z83-W$ygu=k>>}&gw?yVCCOOlIPYI+fDL-eL`dH2-a3^NVG8cUIg+&jI6z3ysIN-+7 zb8u)JcYGn?`_m*e%$Uwtn09AEC8whM!qZMcTn$a4ksULm6D#d=f;D2Cd4XCfFAwi= zv!D^XO<hx0%MNp5Fa+pS+v=OmW?pHa51F146h6$-CU#L;qDm7;BS9Q5SF>}*%+9}+ zB3@B_Dio=c{3!pOFwPPL3q6^%h%nnpa#pf5!#JVhXq+^chGaYu4T#CrM1&XRwco55 z>n|Ct{dP<6RV2A-m+8+!(v_GUsE|%g#SU}K)R!Op_!q+4Z#M!WtQF5egx-9uY9H~# zpKv^{Tgy3pDosqj@}>sO8Cx3*@&zb@hAkYU&3R~8H@iAB2P-s;U9wklG|)=uqWVHF zKxX-=5Z$mr&Bv%-PKNK1`^UIvn(~SS{D4&1;_e<Ms&DWzRG1<cxc2=Wfcume|EUae zryPV%`~m<lPy9mgELZTL;v2^=UgSTv4&-zH^Ux!{fVINyVp}#7602K?e@RLkEF<?n zXPW}I=HKEEPfh~xdmG39v2PGrdweOVi1F#rY9;thIzC+K$%gZft>S-sV5&_sv#B!% z4ahZpiQ`QYAx{#U)WaKRVxXHP*(jfTGw=UAZs-mmty`F%pcp&s&c<n75Lho*#Hs(B zEoECV-Bg8-Mvq2bjhLT~EOswA&l1_0GDo8z6C$ezgf@CvX@jy9nHLF|#~>D#&3&VL zl&uCJB07gz;~j2oMo<%Y#nz75gE>C)ZJU4~lLyrXYA~WUrY={`uYoAxNpY87cTH0A zApQVXg;cnrq7G4`aBodsi$g^+*g;3o;dtTYxL=;NM-=&|w8C-YHEY?>93@Dt<zNW2 zc~(h0po?||=DT?|<6djs%y-qF%G_&nero7^Dv~=4v#8Q3UkxFRxjNUmT+htoCe)M3 zwCtWNJLmKeJJ}(?et$HhnWfWcI5NE^GbzMJs39^_3oQ|7O{4EL;N=h)$6HjD!^;wj zu%<~}?TRz45!%&$zsmTCp%_6Lidp1NoXos<MhH#s+gy+@v}SVmu&d5fjp1`mc&JN$ z#^#{YCIv6h!jU(wSR{R!6z}P95+LE0(wARd@!T*2tl<=e!n15hS%{o#ee}GzY`ggN zH;fjNK>kQs7e^Dv@^*Cd>1iYXPsQG5(mWas$JCB;<werPxX!>gfGScPO#E-=811zL zvpVRtCV8v<hP?W_xbPVt?HU6|BesJ`&!Dv>omIM}p?KGI@%hUQZ-u;xkD@FO$2e$M z899I6w4Ps1Ltx{AMN)B2YOckl?INyIkzs<M=AW`E`&W&bRDHwIx!q9@WlgwRtDqJ& z#?5I6?_e73l4Kg^FVAY|hW+C{W{hE%ojq7<;U0ZxU$xxDlYb!c7%yAzlDqvg70nYu zhUpcf1eWl<S%vt%x76iqdo$9u%nh|~oN)&)2QqW0^j%~_agUZo#RlIB@-3d!R$3eA zXpv^74BOIxr2~m`<=2;$wu2q78lT8dvu1-c{fbb+B>Qs4dENE}V+Oh`XkRYy&HI05 z;#oJWr14tX*Wz1{kO37Xs0WXlN@xi;K^w0Ro~e8<dc^m=>I+Bo7PznxMSh^?WE)MG zSlZ6oq;st+H}VX1Q{$uZHBQt)4x&kRN;tZj9T=L7F`I?WurGrDs&}Hn#lwcX;yEof z1#ZJb_ZS#2m*qzasHOINsM8R<FecX<o8{uUT(v%(J4a9>jx-L-U$#N3{ikiDH4fLo z+wE+Xrp3))X>*$$FH!=Pb#<=QdkyUwTllEII>GT`aZx?xs3^C9{4<Vg;K1yxx`Uf3 zTLCnvktn^s?rU$_d5H#$vWM~u^>@<Mxli>IC-}9ssV0TnCLewdkUEIGPaoc~rG^2O zB9s7Ff!Pua4#HoAuO#-$&~lpqR_uV9N$+W*T21O_XF;MzYBXN9({aJBt27sPfHvMi zo=Vw+&)!nrdv>2^WUO}MW(<>ddU{do#fqpHDXpaK?Zw1|^}LLfxy`3D^G35%FU>Yb zB;Ux@Z;sBHE_VvQ7^#a5NhW>dtW%=UMS~9IR(-!IV!e~VDz{r!Gl?>YeG!6S`pD{3 zVU~MCYO>Vz{#z11QOZWmRr<qs!FK?kz#Tkw7_MTVW~3}J!Rn6VLS);_bBOYM=u7fn zJjUh)BjH0c%ny?KMjmi4XMyp0=4KLRqKC&aKlw&9H|aMwCb>E0Wq&B;E2ka*;7q#B z8#cu3u~5p(3?lg{Sl+NIOa_;thS`;?RE1(Tgp!uC(%>-M?=}@SuAA-h`%ScYb%<}4 zw1b$;Gg)xf9DA1hrs>mDrPuns+`Od84js%?b=K}-Hu!PMnl7(s2+dWST3=>0A^B=s z4h>zXShd(5!6mSnSJRROE$cz@F1Gvw#dZlfY0tJPl$wO?ArME6s-ndZR(&}Pkp~I_ z)HP~0ypL<`369>5{?fWEH7n4t8XV>*<1py8^o?@ed+j8UPb!qp#t`bPN-EjC^rLYu zUFu|TCjX@suV>oMqdvQo{J8}flG}8<fi#(zz}&;|%Tg>E<?4H@o9}J1Vb(lOQweWs zKG*8mQ_B)&T4do;E~~L0J$%iB=P*+|S?0p`7#LP($7sM$auDy_AziC0q!VPbJGtgz zpT6}L)@Jr1!3$1O_R~p>aCr>LkZJyA<Fjy#-F_Nb;VZ*WQQuHAoJJY%Q}z#-)SD=` z1C!$AC6&@+m$Ik_1mI&?pNM>AgRR|j?*KP1t%ciJRQFbTj79(LxDEP*EcmTsXUBJX zmEA`!gG5KZP<45v@+yx;Jxfv<xl;M@<1&#lGtET$^Q?U!Us|tDPYoQg9W%wk8l?Iv zT@f6G+}BW5u^kARBl#)7X7Bo3M}EtBjQiaRjy!nGDJlAhIRkA*^Gf#T0XayVSFNOo zT$Etzsc`k9($3;X?GMZE07o8KJCP0w21EF7_-sHP!Y>;(Jm+-%qssU>2qNX;d{Wts zro4X`RI0d0u<Apa5auB<;0FLw%|wGlAn$dTvIMTweH(yg0$ujoyx`b#%3S_Gx^?5^ ztJs7oK^1#w0#C>Md#dM!*Xf!%o35Qr7%of6o0wEVhO3!2Kpy+nM6(u;eo?nGmDr<& z7pJI#kHt$em2{RfQ+&c*zMT_l=934szaAUeatn?!WeRA}c%=vY-6i@LD6FV^Lpj!M zNyd5I{^ozcmdBKN4;M<*^|Ai%2}b|M3yF?(>)uc$m7}v<_`6G^FaBG2hav%j(R22J zYg`KQBh3zjuiPD=NvtH6%7EZ`ewrDPSNmq1(aR_4x8bKK8MeARz+1g!b{>;JrP!ur zlKEA*inf(aRy3D9h+LGe?)3;|D!#7awhwpsaNLuW3XJY7)}DkkXIOP5hEmG&*XwtH zTv6EGZHbWv%J*=0$SP^Q)o4XF`aKz)uyV3+Nx2N>s%_ChR}$V4ZC$>RyCWk(eGM3? zo&4xsLgpO+SPC>U%nL;%{R(ecIFYOP5H)ZIkn!H~PR~s-eE1plL8i7Io{A(!Fk-MX z&~8xDa2O2V%s)tld}`*;Gm^!P&zEvOi+@z`{>7#$cf6_x{j*zbZ3mMeGwaymq7An@ z0NSKr9M^=g)Y~kqU$+`NMF}AhxD)_^+CW?iG;_3dvTpHO?+mu#-%H=$r<j*pV>fE3 zcB9MLQ1y28dW}1iHSlDr?3zLQfKxE0JHWmu+D<`!z)e@SDC|OLI8PT^S6E%Q#SJfn ze=)F!$0Hp9Sr|^N0ciSE7I}7?rxTN7vy&ND_RKw#!6kj|(er9;T`$)$b<?kniq?Ay zFK%K4<hG+<AAGv!ytRE?saI&|)A*;d^%B}ALOXNxQ>b52&OYe(Y3U3sLhNk-UcH=s z@e`x;Zt3#fq;hQwX@)%PfL<sn`j@0y$*aibUaxP)j+aam%71I+_*7VCx8aG^-U|gA zM;0zy7DcHSS`xy8+yXl7c~`agoVBg)j<QW5WMY3vG2x@iBh#N577Q8tBJVFtN?jeW zV$y^P1_rloF{)fI{F{!#Gk@LN%$WVsQz_X+8i+&>1=?4@FT7unE^Sv_VPQ%%qBw%; zd)wmuTU3?3RC?2^Hn24Zkdj8$?;b(n40ZInGkZXTe4Lp5nqqawyD83gPz|nAA)7sL zS)qGr(rb~P{r$ou&_Ky?Yi^`ueRwB<DDUUQWnA{NB&k^4h813|HH5Mw=Qe9g8F z+K;NK=Zm*hkGCs_#}|UXU3?Ino}TQ5a#X`Nw7v=#-W)LYUqA<+{t6hTYl`WNk9+Es zW%(JTzATO-bge_H@BBrpu0!CVI*sqU`o!KSDZ#mD-@nA?_LnfV2Y{nSWOYxOq0cEG z((aiIT~X*ncEz@eNFA;6C0td4UwtX^NW<mVmJg;rL|3gh`-}wQ^ae6{^l58zT5nE9 z&}wS<ja~~9nDw1bd<pLg)4Nx8j^zH6HJYK9Cdns_4-*QWAR3S$<8Co-RaJ~gfL9gA zBTKH{{5_wKl9uASw)e|-)*EBO1kVgD5rusrSJBR+?}om_67h=*PdgTq{4~qoK!&&` zBL`QFSXGXoa|m#=84ij~*c0X_jYkS31DwnFlmx`f@K(bj1yx@-A#d)N{C;Ng5K3VY zXhL!z*JA>$+WAjb>mMmH?ZM(q&fCXdZ$#-kT>_(|+pu`up!0Z$&A$U6iGRd8C4!$Y zZROj^p}(-lC2Sp5Bf=<p#;JGc%@2IzUY14GcLhKKMvxFAo|zNl4G@W02dtrj+{90k zO**Ym9q!??tCN@>c|kFXpzK*FPBZYJyPz}EvvDvig`2)uk!L|PXl1Ll0x9kQ&F8wJ zw*%9XVyC&U5<OZgRs@S9fl9}GaXGn3D}qAPP1BRRyJRC}3!%6-L<`r`<u<*#9$Ocb zV}%bnI0HVOPYM^VCENil{oKw7wl2&Aral>Yj_x1^`}@7r^J`|nym?%9nf+|}WnwRI zg^H!FqG?v0ItGzKu53N2l;rE=4Jrz-wI^el<~3s;FCG*~GG03_m1a$sd{emtjDXf` z=24fQp}VxB$K7{;&tgqJ*lyP~;=4l?RRvpYKB^#cnYvKM9%9l|FarG{8xSndfYItJ zDZtdH%kCAKnJ-c<Hp5}uF(>{!?&{S}VU>qkAJc9B<#wN<SHxNTaqXp_KIGqYiv~CO z>(ifEP3S;0`_*d0k_$(-dnap*(0<RF-AeCN#?xu09FqeeCgbYZ3`Fs^ecDQnU&JpV zw@97%^r9?BGpeK&m9mz72hfOFx{PIp&1rsBQW4CenAtY^mJ_GkIDB(G%KF2{T`a_; zrCGCXq*;@KXaprSoZBg(!LnwYaox;%2lPCLm{yUN!C5|b`RKA23#>hYwWG`hvOWto zKp3oc1@L>NvP}}ICntO!TSSzxIt^h=wG<{entO;MxpY6`w|wZ4GR73m+Dm5k`R*Ri zVdT^fvD1CFI#*EeO0}+*Q3m8C+VNv4?UYLC*dCu<8nK3Sfq!ud#Dj-6g>29^0O;9D zSXCK7&6cXN!+!a<>|PU(qs*+{9bSG2=V+MmL)wscYG_wG7jgzPHjX~5e=P)=l`&b9 z{qR(X*1Wh-QeiG3K66Wek_O+Adh4+il|885+X6=dR}tJ92oM19Lg6zfk{%z6L!mD0 zMl#Qg87Fv^5T-0L{tngH-B~cu_Gq4RJv&xyh0@QQ<aS|`27_jqM=T=sNgMS{DQZ93 zYv)<1TrzSnlP|Z&5A0z`<ONLkT>Sk~Mv|ueb#1#5!Drh~#A{eRKaC&D`gM^`|B$Vk z&iX2ni5wELAHEvDxT5$xla;1Ntd!GYAv8ndEGDhvALYdJ0OweE+E?iM6k2-+_{DPv z=rOsKuWZcY5)KU6DDeE=?2|u~R;nUR!p5mmSt{@>cB)BZ_{`$7HF9?4DTJ36S6+Ob zQaE{ydPlh;?qqEB$}mge4uEqy;nMCF^iXEEf0nDv(43#$ye@v%^K#QhrJ?G5k{o(= zd_w<f2A;KFrwYB{!>q&y*#$eI3U5&<R}E!$H0lH#5yl1z$L1TcB)!*s87Vd19zQ35 z*mCL!gIdlRJXgH8N^D?5dqXg6yaBbo5>Pu?VK3jTqHH;5Z!HxLId%z->Espst$PR9 z5WE9?tOyv5e@Nbv5#u4Ouq$U%?rZXd>+#{1PC><T${k?s=?hXb1JdF?%Z0@ORO(z4 zaAZtI<yOlkQ{(3ji;57AXda{Rh!Z!#iouUd>7Vasl<em}N)ZG82hHZvmUkD!2q!%e z_nHm0QP7}IFT0P(whhKhWj{J-QCp5ERlOx^7pQD-p3B8{$vSTW9<RFe{H{Ms|F)ts zsQwNz;|FQotEj7M=PbET++6cNT7}!Ur=(6_(prv-vGigjX1CBqU&R8E(J`h-T~j*M z>9o>T@<r=MM5`XPzhM{K-%YZA``PGz9W4c|QM8{WiW!h$sn#ww^0k#+-vNAo8gV5C zH1@>h{i3nhiW8U~LBmskgfj)O54PQFwM`=Q!4|Z!`z;j=q8PYv%i_4795W?+bopzp z0>1jX4w67S7pIre$0-~LQ`d&`pHJf40mOw07KEgl7q}d)9fD_A<l2xd_R7hE(Y&}x zMfi36J5Y?I*m*;aA%9w2zND<m_HUaS3LXngpH94TnlzxJQHEEca6{{I&_G@(0CNoy zG}9lsH-1c7?DA&N_HA%vl#?dVja5tF1zEf>fE~DZ-lF1HDTfsnOP8hBdV0x}(q447 z)Ge1FGW1G6B|?QClTpDpekJQPw8-bwJt(r%X_cuv%WIFvUwXI}hImmkJ)1SdVn(T` z%f@Kv8_8R4l;BPMnd*BU1ZdVi)Hc1l6X%rWf4glad>o$;%}mm=LdlD4?zNd@!BtvJ zr9STmF)b9<Mr%_m3Q08%w)FnY#INmFg@=vx&VTrk_fj7aupKc^8eBg6YwZjB0MS-& zuv>&v%14K9A3A;1CncD3l1n|_puko9i-g?HdR+!?LKdG{|JcMaYJZVkoZVzMnQ+KE z!1Fe*yY#%F`+T*5QgA~JOvg2o?0BEh3yHnsI8nbQr3CVEJ7o`d(YHR&8}`x0C5`15 z7R)rSueTd!d7SZHrfQ~y37-h4oDGb`>@VP94NkZw(ES&sihio(cJs?=(zF}(`AY+3 z<rZB!0Ng%XjQWpcKe^@@jVe6~YhOu$;2+xg8SRx41!Ht_xRW2ZoB3C%i+1m=b@FYx zAi9G^i=zliKwoN7rC`#*+U(u5fn=mdV&@SRLdNt2Pm4d+=UwA(b36-gk{dx-$GjKq zAPhmav%DM$6)bw7jxf)l`$jLSE;?Np;3Rj^+n!P%FwJx*bbt4yDR*dGp_c2k+~@C{ z65gvs*jKcJHTOYh7`M01XlgdEv!1Lc`kPLSZ+vocgnfaD-@j30?P<0*FkP>i^l81G zW@@B#%sEWenyF-|o6+fJA;4TDqqQScpro9A)#WY|LmN5GT&8AR3O0^T2383dj1XwI zJLyQ!IKT7ZNPg?=c+rmLZg}%Q!L7}*+3#)ydziGX4*vx;NQjjkK*ejtlO-O8+?MGk zZ|<Olt5}Q)vl|Z(?5l&4@`D3C6U$>U4-3=22Y4(EOmdvx_60O+9qiw)Awk_^)Ez*= zTPZ-nEv8xNEM*1T00Lj8WABh3#9?s9FpS)>iNKqVu<v&s7pMx!vwTqeL$!KnJY(Z? zsG~R09pHk1{<=Qkkk?zFcfZyY=z8|Vn?9HQ<H*6{HP`6yH9z}?)?jJ?_L6^A+)|_Q zg$wBKd^3CM|MtGJsD<#Og(3q0tRR}fVE~IUZI&f+7~b=EKwMQdme041{$4_dEFp6v zAPF_HbM)Oec)QFn3)cRaTX}88+}_}08FH#tag?DK39;k5xGz<jto~?Y!AeQh16XmI zTP<FkwIAk*An0k3u|Ueg7*$1*qIdY4nXi!_69@C0^DAR)RPnepg_1K;!lyXz0C}Z9 zTDQl_Xrg=VR?a8hA5d{l!wj1A<1>gty6qm(iMC0ums@E&CJUANmU!~CUR@BavtN1q zdNtR$Sqg{1OUv^`M$RJi;FE&mz<JkpXWqoU_Z>GEb{Es4u)^)~<HCDbwFjx~0gU%> z)Nyuvj}Q9pvpGA3b=27BYo9l)Pf?#r>U%S_+q4!(&JR{azMGgi{~LwdS?8PE>pI^( zx~9=noeRzTkr`CRH`iewN_QPZt0u+UL7#->Dv*5nJ2H?TFvBDSbHbzo(@y0(ZnSQ) zOxpVzrnpC9B@jZL2wlN3lwm9_{gtA=3|qfw&Pe7Y3l##a?vx+XOFOt?AV@!rU+Sx6 znD6H76-H%)a!~r@BNH6RO|Fi9j`k(<YrDXvTR35D>@fG{;PgY{DR(9BMwC4VmNad1 z(40}6LZ#E2&G9pmOG)%|f+ZrTH+a47Iz8ljT&vxbVnpmH^Nxok^Y%)7Wx{*0mf}W1 z``zZT8!NI!3Ors$oDqlHgG#QW`BdAj>{cE~ZI`_L<x9um!t%gW8mYP-HhCo|vu&Wj zc)RM!Th*lQ2s-8heNC!;;w^9xh5SnN#CrSgrufYq@($3Oa7{L`^BbGLY(v~r=f>_V zudaDhN{l5aQ$)77S<Hx@Y4!H!lFe_E2q^&z$564RYo(8U4n}lC$k!yC5EYwX+MFV~ z_{%gY$-zB~H;-2LkH@MnIh$KaIeE8d>*(awHElJdM!(T^V!ESd5Fb)&x1K)?k*9T_ zT4sOB0%Pev1AXV>@O=?dtO}Gz1Adv6Jw_9pbrZERO6lNzzdRJ?;9{E*_-&202{M(# z0>$=LoK=b%pNsLw2=yx6{S?~1)qbILDo7u>oOtR-bS}LYtMBIAtT~v|#Z>&QSe_Y+ zwkCFIrmL==e0j4W&pd=}S2rF(dY0D>{i=GwBx2-RPkFWUYYg@2*7DN@$NkBR?Brxi zHkOWOu{Kg6Ak^Hm!T~m$wb$N%1xs{5N^4GNSO$|hVimiXBWi)Ot2D(7P;-ndL9!3= z#SbkZW>PQ(g()Fg)K~53?M!2Aj4-MVBVb3fkAtOw`?+x_JMq(Ji?giHDrV-&)qsz3 z*jc*Jtg*~6v{rvrxrtjPSPaWOWfy61N`Bb|I$|m1l8bdBPCn{j272yJbis>hHAYS> zod$>J-k{A0#uLcG2CR7wWLa#qilSwb`q<wHEO92Y5zP_^4Cp=n+IsKQhOP%JB?Vip z1h2lH?^q#ekrcC_=f<?dC6(m&s<+Ab?OlT~5uq!-Ed({X`3Q}ZDmU8j7GU7VeDIdu zw!y^~9jvK(;NszBt0Q!;(kBq!?fJh{s;}5Z=<$eX#=s%vsc~ZdPX{9VbuGE46yYh1 zoHod^N=`8fDJ?{?{J5e#1*RhdN#>9=3N}^iZSKCT8s>Pf(jYq92tRyVMi!-em7-Fg zlr~dcW8+<P-y|N^-|*jOll%*7u62pq(>LFT&Ct|ruDBOwO2^7+Mu6e+c*5GWo%M0{ zcBLZ(_c}EGONSF_mu0+c!w4#;X&}ojarL5ZdZrv}v*Qup%XH@}S9?L?R|5{}1kW>< z^s%W5JsId3$w;2abF{RhMUaOYj>H?Ak`SBV(%`{K%7e1zVevDL&2Kd|GV#Ugv{Ev} z!*dDl>pVI^5JBIxbS>60kB1h^6HkSn=7d+Uq@a@XyECqH<HM4wo|GgN8>D`L%lCQd z?LlNW?6bnC!U>t=ENZs&r^>FD6<DeAyqFV@QTX<i;-qRDkz=S6cfpr*c{5>*)OUa< zSw3oM4L1i@5|HQh99c1a!wRotfFn%huTN|n)VJR|X|4{qV-tX5F7~}PYA;HUxa6~a z@@)i}n5K$9-Zbs>AKATDB#a71PMy-5`|>|tCfk;3YEp2uzCk;etP6j3weReu%>QEe zQwQQr2CGeR@H^Grv$UhU8_{W=cfTIW<yx18D>V$*v&=Q&JOp>JGq8G<E2Sx!g*|<Z z65Yq#5$#AWdCRQiXjJrua1I%s_FX{-T`B{JQA;=4)x=J*#U<OmtsJn<G2l5pTuQOt zdXs8=HFhcgn+~sns$5Rt`*%L1AN{z08q-<sW2e?@iM=lCUnn=r4FA~~)o;;P`gmyH z6I(bKR<sT<F;<^esr!T;EDNsGdhNXJrE}>nSZSd0vIl|6ZrNj<0yHY~%5%l}Ivvca z-QG3#9a1D%YyV_;@<HZX>Q^~@^N^i4R`r?QSu-&*V?=p1Qyzx9D34+pxN`|VTtOV< zOl=vnV3|9Cw!`vu#tYePN<{okmw1Fmal~BJUqfCR@rFwq7hKN~#JtjM?Eg$$M8_FY zU@!Vn`u1nJKr7z6Wok(L`1gm-66TD;teT1477|t;$-Yj<>l-(#rHn^gaCB5oM4acX zRwCDzooKv2{xVoqiW%xwjMq}oykHe%@pb(X0nZN&>1N<sSn|JG+c2rLF}wqO4Y<1W zUjbflT8wW2E%0DC(hMOi*Z?a^5#Qi`4q9+ZZf-F<iwv2?AhXkee+xqCu;32xY3nMw zaFx{@IGSq0Au`r7zL5P5G#}4Yo}Y{;Fw%^a@0JHLko0+>w@ZV|l{y7nH3#bJ_qikg z7q{ZNC3^pj{1CL_xyUL4h+iy?;Yk)ZZth8TQKD4YMRxqSq#9bnUn9V3*PmX}eaP`k z^Ut>yPpK{VXjA3Sk;Q+Fr_nZ$b^9gf_ReTqgn!Oz(t?O(3Kz#-9uJ}vuH%!B#aCV4 zJU?bKo6ceUz5O4!v>{@dn}*?BgJz2M1g~S&>Akq))#n=-sk($~B!75m>8c117p0Ip zI`5w~I%UEs2%h=K<1w6jBV?G1nY>hG55|*kdg`kkwrfQ2uE+j-j~gc=(zvL!*ebWM zs_P4L2xKJT87;{fj0y`aZ2Q>tHT5u|ghDBYQl>AJ1FC<%)ko42JWrne1<tMS`Fae$ z)KGvd+WifRR(ayP@%8E*pd4(Ea8=aMOffEGG&yq}c3DoE-D9+2h7+bj7@6Yx%r6Ff zuQF<(S3~l50NeYTfygElHv1cw%2&Nh?WcKLsZqbv?f~7XKeIQvq{&qXN5~K2O`3a> zM#$fPOC?m#G=1lk#OjYr;{(kHeYEf6;!6(Q-rn)q4URSI=6HgUtax^=FzD%s8nO~X zy$Z!y3$crPMG3BZ=BqgBk}_c_JF;;rE}?1TdIzA-=FsKz#jyoj^v8aMk7O}+q08Hg zUFeAhGd-)luQRb8$rF+hwtH{iFZ?;?<yUkIvjx(^@DBPrKp2DWpzK+%%Nq2ft&BcZ z>>6^-Xn41W{r+yzgzBw<YM6n&jh=$4b7mJ^jxkA0+WCsp-Vcx4%Q%c=M;ck{T?hsA zTKAQEs`$|*db-l5-#2J_dNjpBy@ioYR9+r8-*TB_R%>e%m@}OJxEZwTbI|vyEqjh{ z<meag-0y|;cG0E$UHFe`L5e}wtU;LmvP*g7b5Pbs3}WcoKd|6W4t1Kyj!Ei%SoV2~ zfNEVqpoT-#BlqVU6cj+#Dw60d-u&SKew8DoWV&I-W`(p5(Sy!!uwg-Hk`#lyU(_zb ztQpKU%zX4l`xGbo^%KY?q#NzMblrTo6>B`)C$j!D2K~p^==CdMj<olez}4)x&J}VZ zhg+ikDXj@MRnzES<<N>aP=Ara_yscqAdsl7!Z{jck@EZ{7W$FcqC_Y$M__7@0IIti zccs1dwnby*X?=tsJ$U`tswF;^7|BetqJ<ar*Gf`>7mOena%9lK@+_<=d*j;`)iKt& z8YAHG8Y?FGuVN>kXRlie2MkN)g)oO_2G0DJwmeXDnT#&9(wy~0<VZ3Os)594xaWk1 z38v$a>yW^_@A!I6IfN{^MDkT7Zg}Op#1uLQ(1{@Z>{_15ytmwyPQbNx)o|839`DY8 zP_MVz`_ez>2<pOS9o37RShcG>Xs>O%3aA`ytEQ(CC<=DCAyH1bKlH$#jA5S9ix>@= zSLe>9%(~>eI+?IgIcIA;O+|(zV*dPuhJ;R-YlmrKi%n@>U19X^82JXpmNe*$8Hgy~ zmg_)i>DbEi*F;@w{J(_Aj=7@Y(}gw@eL&}ZZ$I8Izgg*8{{k+ZG+8?QDPG;MMA6ld zhUBE+4BH^RhQICTiKqKXzh2@OaBv_(;*UHzd*hpt?$oQ3Za&M)RW@cMyRD8C@!2wA zM)Y$+?N;W+LeCD&$!!SKr5c{{H3=bU`j041SLh!O6#c&u(3Sk_>anJxokq7?tmJz| z!==W?*y&3}E%0hr1g(oj+nBpXtAkKgQlUS8VuN-h(HuqMvnh5SK|fWcvT}U+sh!;< zNi^?9%8rHTSQ=<j*QP3O&14<p7Rx-Crn(#1XZka-UMX15PC@<AQhzBP3fllPX7$um z3^%^tneV07i9MyGZKf4T^bWHXvso>8O$@*0;pYlXrq1x6SX~QFj5s|23puBGi5r-{ zr0_!9zVWLhcY&L*JbRW_AHMxWv2<HR1&R`!TccCkIp{K~2ExUokiS}vBME$w(A?;z z_)!<TLU{|#_HE@WPJ6P~#sffj2%|k4<0?>ZD!76?ixpUrsVGpm@cRav*yuj0%n%>; z9%&Y@_CW2S&vq)8cWcnvZ-B!{m*mw0bk%o=N|tGUs0vKTiP#v^!wM*z&u67o_~6KL zD_lj19_BLuyE}*bkXunsPaGf9E5^35@Sz+|o*kw8+G8e01tw=q$L?ZVd9qg~WIn$V zZ;|-s-*xgmVoS7Jg_F32q3nY{?NGr;nQoxwURR*m@GUY<YzJ@ti@(d#Ya1mcQ-}C? zt-L^PH4<YFa@NA{a?=UFQvc;n&+F;X;^ZzT>Q~psX``_FqR(9Okgv_9z0QDXj@j-Y zP$IGRcLKg^7{JhcyZFa1_;ef>7g1s?uSFP@h(NhacrS%%QV8Gl1LCAu0ABA7{UOCk zK)F!Y^#f7*9sLsW$x7UPPlc=Le|gIzeYV8e=XQG3?|03FyRusTCOFp?ufHZmg%XS1 zui@~Kw>YYLdCpYHTl%Fg?gkT=<s~)aYowV_31FXR`CAsd7|Qz#*h#gD$^Ux8L#S&e z4$zf%V=Gs{W$QG<>~#n5qb=chY9`!@2iwSt5<R9ZZ!XsNpN;SK3N9)9pzu|_eLQ9* zXi#80R=XJ4RsS_IB~L2+m<Gfs(5sFsrP&R&{WKms-M<rcsN&5!q1w=nIg#rJOY1~b z=Vg4nzfuI0|Gp2(0uIWAdX<sDhgfx<_>(K`=VN|mw-|JBr$tHN;m=tG>#z3st~e~# zM^;ps5!UM6>cZhn$=bETc{lXK(ER3@Rz&$mlJx7*^6{UZIdsa2EeAgiQr1x7i!V3t z0FZZnBg{CZse<acU9!BHZrcb!0ZQg^8Z+Pif{kgd9yn=yeoY6aIboJ~TjpQW7T0V` zF8LC*iw=pbc>U6{Rn&qf1M-XByyGV_zyxvFW7bR%81knb?^I8ZPZtRBjuB?sPiZV- zry#z=c(i85a;@v-(ggGBFLXb=95Z&yd}qi|@Ipk|_j9|~{DXb3dL6AP^(7e>!%iv@ z_r$W53J;+Cx<X}j{<oxe4L>+~u(4F)vkB0CtaJxoZdXU^e*Lf{+HZdK{ou#apKk6* zf4`i~#+-Zb+JPzd4zQp%_ZQg}Y0xE}cg{MDmG2AxtMx#hH1nGUBCydEf3B02k0?PW zd?0%R{VyTD+wwqJt-9DXMph=Rgl2=9I<0K)v>V!*88`nSx>1|R@L>wo65@oGUmBwM zN6+fW&<kXgS0%IxWRP`6(pY9j@|ft^S<L7XLn(#D_Vw;Mz}NaNqzLwhc>nN-|8EN| z@wF#bA}_GV^^nQ1-^*>1r#c{5*GQaLVR2;P$&h8E&0|^qQr=uHgG?6u2OlRCc@K|C zJ&FSP(LK@{z=+aP?&`!S6&Ha-Q7Ri)sS1c+-eo#@>_dZ8D6`N@JT6_ZDZ*5bU8iXr z9$$gM8^kYtDci7Vu|K)0)P7qqKpDnl$hiqG=Ev-o%J9l9)S`A&=Wu2l+~0tC^lF(K z-KX%u+od{Z0@pWmqmz-%25*q==}?#B(F8;H!{vN_>Nl{lP*@5|b`(QH31G#@ie9T` zU8&@<3u2c^|K-6pEtWEcZw!yI`D(*tqCE>Tz&J>bmt9r>==vd~!U8xv_66b!JsP_> zoA^gw5mq?a!yPIlRZhdElv24@!<KddFgB;Q&>-YOiJ@aq2S&86ALZ!8F8K$C%%_cV zGStCb-06wV`PdUjFcIlhfoWM;-ifLB^5y2&Y+D88^QePa*}Rz6m?v`aEYr2va(jtW zlS&bGv7LK6ShgTgKASl)0giCT)B0M3_1s*4%DY0V<w}2-091C_hn#1^9nf(~)oZIv z)9|Z0s2nPqI?*MwUcvTJh+I-#Qi>6T_Z_+H8qrL!;ep(Vk^;~B-S0#Ba#XNp$N6O` zM{0f@{wFC9R<Z>4Rv)a4)j8h**u+2I)=qU@XWtH8PDF3b&E2v>$MxQ~in$!ex~`#y z4vP8y9);XGk>e~n&GmE~AF_IBM4GZ*dt%AUZl4j*tG0W8y8dGv@E#iy8B^hDcm8l8 zI%uZr{=|^hEyWb_9G2Mf_}dSUI8m>EO(v=}^P;#>Y71Rlo?v!LHnKlDoO^2f0Gf~W zTF1p0Pk3-|rom+pXU<wRYNl4_C!-`*mkw;T$K<P6+c?|Bp|Hs6<k|ng0E#_1^A7Ne zuR_}Rlc1NJ;PH;t`B?h>-y4$X?{n#plS`)5B=2D{Bjwx6&HQp#i1#b1WWGW1HP*8L z)StsX{V{C%$Ak#qeboCyVlKlf;GmKh-lts5p=h4D^1eVAI-%{@c?X!ffo7E%SiVwe zee|R=($vP{Tiuod4kWRR*tsF0S)9d{!!lya5^hB0n2!q*wnJ7vsv2A!G9ldlvfF_X zxJN<#3w2rQPk%eKqgt{Mc7L;diQ-J2o07xjHN(eMBurvt1j>KCFUX<^^($-pd&Fo- z{n8y^_ZDeaX72a6>>7{%%=H*maNF10tk2AXW%n8A{hJa8{1KvFBWS*IJ>J0b9-ag| zmZv>PX|p%`t+}Z^2Yi*w*}bl8UGTw%W&DNPGE{ZSem^<qIUu&JY>h?2NgkUvqhU?k zv-(Af!xNQY#t$8+85^K%iO+jD94zRhb^(PV<CfHNRLTPI{O|@TJcy68%=+U3b*`QE zR@$m|cx_|rQZgH<!<LU0)a~+a)dQ?<patT1pI;3o;QR85^@^`y{~>F(f2pL-V$3R{ znFfnZ08i%!I<iTL&yE_BYX82`HB;SI2pun;+%;4{u2o`Ljg$JwfL&cQvQVyxi?fe% z>wG3SRd{!857AbmNUZ^|<q=?E0Pvd$&<3JG5$q$0iOn21Y#fY=;1a$6BPAIBIwqEt z{wuJq5KHnp6;%c&m6DS6@t7zcq(Wo1&&3t(Q=0us)}B$7l}5%`FlIX;8dQIR^icbf z6x2Z#g^&q5@+S^o_xEB^Yu&6`%36GVi)IwlMCH*AE7~^mn>Ds5E1K4m=KPv6l9&pX zrbj<8aa9x^LS|fe!eF91<><Hq^Kz{kOrC&U&Q=B+<2al5@y*=NanC04r!PA}ed<bB zw`;HCTG#rEHk!s~MUbPE!=j{?uZBMk`;gd)P1>v{I9Ra3&|XX8p$UMcA_RnMT*3HM z!&RLLKVqjkIT`Z>7BryRHqb@5Yz2<oa@_ab@5J8Z1GH`jYO|&KwP*I7YJLUjO4gsK zlq=e#^WU5CC6OCb*YEL#Q|t=OI_qwaKzJ<in-v_Iq*4(I4TfI{w-?wt?em1nvsr*& zW!2hH8gp<b4i8Q0DH9hs^5lNck|z@u|LahQWiG3jO1YSnOjGDYxuLf#wwI=HnuoW+ zCRwkLrtfvwspwSK3rlHvw8T_9Ap})+xP-YzIQ}e0wvh<M89F?!#f8?tjrSm#^tw(T z(wG!oG(1s}CZ3+<0TD4g6EbvGea<&n1RitIa^i>kK)*XB`gcJmPyhB7t8{~JTkYr$ zIlZ5?%3B;C$M%fg8lHJ!xq;O*AqMf_)?NBT&dUes*w+u+g34nmf~|1$2Dz~vX_s5Z z25Npw{pcBv7k|>rG1zf{zL5*XE1vyYScKSWmnWYi%^Z6snYA0nWN&6S(@Sq$S7b-$ zSLnX9_C?T-z8-;B-!86b&Y<vNf4s<A0{y8lQ5N&z+|==UnTvgSj{&DbU~0<Ov*_X< zuqbE;RZsV<lj>#qoAV&oVcvHkmF||^J7dAANv@wbC2yAhZyel6H33<R%R${h<Fm)V zpZH;@1m9vUNT7a9$i&CFRe$=vu~wG$o=J_l5+v|ISTlCId#bWUH?6uT^ZRgNi;BA_ zYW^$nmc6{+28Im^+-XB0L7ShvLBCY;YTDUtls`}3jpZYuiQdBo<@kkfaI$w9j#zT^ zTm7*qCp;}X1Pvp-lllf$o*h7-cthF+6$X*cRYFcqa<{AXar}I-vnPhW-m=q!%k^Zz z`nJ%q<&^2PIl5%Vjr|1X#yTxvI&*V06pLpjLnPGPH&ACjF9!c*a8Qa?W?rPT6=pJ9 z=6zzP4S<(!*>+@XJN$YQF&y?{ZMglN*Y$mX(Py(JkioM=)fzEmQ{?_9??xIBMmJA{ z&!qUG(Fs1^pM7A?xR?wUGZ8s4;qS6n>Cbfbb0>=6<yx%lI@kbV6?4A6%hId9Jf_y; z$crkUFO8dN8)fO<6k4Y=<u^i2HtE&7X$0TGxyjM@Nto+nbK}cMS3KG8cO6v=QNirm z+K`4;SV$nkjH-)zP?%#C3UxO0>;6gHyDC`gC2ytG(1KQ0hQ9%DEIxbe`9zdN?+3Ax zQU67H?bYzH?lkLs96Wg|g)GJ`lYGh{!6|LMm&d&?wp1&F`B7%4*Nt|fUOk5!N0dFk zkdTQq7t1P({uhWU*m)+nJ-{Bvqb}4$!lC|#HNKT8m3Bru(^S6xn=#%hk8@ZCrUk3> z4}!xA>US}{fq)nMc-r}+-W+5hhB_6y;G~jNGUY9gL;ojRo43@-t|eAV?ZJobYI29O z*-w8S1gRKNoxdygrac6f<{2NV6ZQXQ0>A$K+2q50Wvo>P6`bpP+I7dNI@Q0OCHvpE zqL7_91f8Fn=KZSw{x}M({tj8h0;FVT1rS&kPXkAcqio0`w|p!v$ba)8LwZ~mLy)ti zp^P1&bW3ky3>UMsTSu<6qSm8k%Z453x`g?JJ`lSbNc~j*8m?O7;v`S~19u2s^!Nm1 zuk<QcVuU)6u;7a&`&4`$GvWu0;-nMMb~ed&d-o`sE%3F*dRylCMQUUW@}RwYZt4;| ztiNacOi(Z!HRD#0_w;QBN;z2|Fq<&`RTh)3*Q}RTeQW|q!(58|gx@uWZ=7?rKP8`; zPm`AMwV=qW4D-W|0c+M1spd#4`GzfVy+(ybq>D_DBd$FGWA3nGI)R4*Ll&L_b$#YV zpD5W2hK|VbxjGW^ai{wDF~X#xKI&QAiG7&DV1=qzEbo)#PrmKo9?hnMPn!-iTTf)v z-*h$1=Y07D3O~RZ6okjrNX7F8c2FOccZR*xnO@iQW|2uZ8hl)b#Z)=7SB1PxfeB>^ zmq8CE#+RCPKUSneL>Ig%n{7-L!6A5=a2eey=Q-9JTfC2zk*ya!_eY+=%A9o5+ao&O z<OO=sKVQBGr>yF8eWRmaV{zrLM_>_4zrUP$@oQ-_ZEz-L9PVL%?rEwitxg8Bn)CH) z6`Dw!0y$Wq7`Qa5w;hAELiC7Xx161zx~|l*Wg#kux1;Y@X&lG)=1z%*$bt%+FziRB z5}t`alaZV1bSO_e?6+e1JSk=}>+yETE|_=<?E@iGu81We;fyr}F8x7Wqh_M_?%SK_ z+Hy%`j9Cl80>~4k>+5^E#d-jx`Lfop8@Y?v5(4h}{n2~!=cnUjmyJ0KkFFu(1xQqh z(7l)VKwk=zGhPsc$qC-PxiKgb%!2)cTQnx9PVSHDd2Gj&mK}~ZG4IQ%eR9E|X~BE< zLbl$xeHqQ}9oN)*5SLY&W>KKCM-@st@h}mgq%I?$kVLw&8qe>=e{`eW9^dD})X>@e z(B@kbh_#mJ9eZYuAI;Q><^Fw=+vvl-qN#oTsch_x)`g4etz55bNJgc(<r!y81EMZD zz7`6AX@B#2oYM9u1s95~9edx4LOkSLye?G!;`sEBnp@wD0k4XN-PoetzbH!kgRC}i ze&RHFcIdr)T#qAvl~w${*x4o^Y-c-mC0h@?`lG$6^+)HLFAr9@6KVD$5R&mVsoWCY zk?xA*#1wo-Hz)a6=v4)k*d0Lq-HRH2jH#{wJnZTS=*WjBM$F09$k>K(i30PK6kZAs zCj5*eW-D(OGzIJj_2VVOD)dO}?+NLza|JA48T1H`Eys}+ofZAM11RH7k0b7j%W&l_ zk!uYIpf>0Ksvtw+^}nhxz$e0sn!2*Bi`h&c4`uVCjx5_>_-X&+ujJXhx+bw4tMuA$ zQU4B9C+HPLF0%@NirSHQzn9@Nim>mPeDR7&d4Ygsg-Yc2vbra^CY9w|4?+z0A(GF0 z>vI<1(=;|O#}aGgT}|`>1RIvv+a<j^7I~zDJp@`d)dr~qO5A2mnU-@FUuvJb;!%fR zaP%wuU+r9XRFhfL2SF(!O%Q2{K<ES!Ll;p5DTbbej!2Ofqy<Dk6a<l85>cvj0t8+{ z3Iqfeq&EqKF1;*G1QeyL?;Bb6+daGcowNUZ=e&P>e?8~Uz2`nNznOcVJM-L`WHE+2 zDn1KQwr0Tf%+q5vIU$jEKN@c^Jgn?D6aJj#Ik3SK>ljhMj(UL8R!we+(Mp6z`w;n= zne>?25ajv<n!D*(ZR`p%W9M>QyfA)Z(G4;-_CN~(zEE03wuBPz=|5$<4!j&l{t6Ey zX=B|Q13WjlDpc}%{gEREUK#b>?N#9(D`V@-vp_NQXcBg*6jH0!4BE-^4ELxSYF&a! zN-PE(9jTH9p0zzhMzR$9^rxX5hk8RGn|((6!-!Cp3AV4%aE=-Now5;do;uxQ#G_SJ z7}J_Xs%s+6be0{d$I8kIA1gV<;I_B`sx1GqP#h>|JE;<+1Vz|AQ!e@<;@TPn00W9S zxlHw;y7U4ZHCy!TA$j$HgGU8Y$~L~+kWy>bubQiCj=X({z{8BSoJnW5A!$JrpDd?n zlueAVuKvWqLXbMw+zaI<W2m8g=CTTRn%jVwzb`%4bDOM?*S^jx3XqgSv}hV@FeeA@ zf~}WJEjRQ-3UEbRcpnKW&8;%r>e->*MDNWxk)!fuq-qml3^wSF+IN%yY>!8{UyEs* zU&h!>LIx~a?b?gp-RGzn=eP3JF~#c4M@;nPd1>R@DS|{1*@co^aN%T$1dVQ+UlLd9 ze!J@Oh|=fnYo*;h+Iel}D#m;<d2^T7mBMwf!+PsKO-IxV#LcT2u*S3vL}BC|NwqMZ z<&7l+JN>Ck#h{@eaZ=NENkDorpBK~`vA2C_P$ODltLXWSYp=f|FNLtXde9OQl=B&M z?OxY6#9@QcXN+H08~4@Gy^8545Be%?btX$Hl-IyTs*|qIYLMkA;X0ZkYDD%xid=!D zRWPTMy?e4lS1f@4<XV2614Xbe#So;qefL3!TG@3?e|?SECV$KqFzJr5uYWtM`S!nQ z?C0V#Lu$(@mP(G|l0at+P)M<{Ua2V{J4}vZr&#jo%pPT}^2ImMVMN;Xug&$aTN;1> z5Bh?N&f~r!$_3g+)wc*isXf@uJ(2gR?!Q_H+~ml5OvtZcH&U*#44uk^Gt1;Fx1XhE z2h4{{-{oN+r#04<vgD;^&Z_HGmWQ0sF!};2CUdEJ5pHXCGa~<$r(=pjqYCj7zMbt| zxfX_AayQLQ@F^ue`L)8D&M&R?OecMuC3OY#L_czWN#&Ty>u_#Daiv72hAYRn$NOD! z8jP2#<=1$1E_dv1U0R$?@fclZ0bS0cQ!0)-HFo|%QTcr&B1Zw9gH3V5O}F`mfv#SA z5)JYY4MIvAT5a#YM4B$aGtVe?bvW~XQqB&Obv#}XmYf>2VP$EmEfqD2!-bxDxZ6jX zQH(y!Izl1@<Z$nuGPAKa7sk**A4=2%a>^148(H~N0p(HiSY%10GNyA_k^!PJS3zTZ z4Ww`<dd@i7-lLq0ht6u==8XWiW5N~9UIPegBF<}tR?ZHW_rSgpY+`j_9hFMG@_zp< zf0R!<U4jC1AD0q~4U}Y3k;YR$+@&`E_iij#p}T+Ayl{UWPX^AMfM$Pl{nDEm06^EX z#OcJ9D=I^JC1u!qnOVt%LNk*hQxVs;h)EYst<4qbPx&e(vv3*Au0iBocFbMICd1no zK*iY4xxjB_cdUW2Md0R{*Iw&3wWlWFuQt!c>}DvG7qT<z8m@1uRqL#8Oy%ryS;MHO z9sg2e??wHT9~D6?Ihy3NnJsj?0+T}O%Ptgo{2B(UF8kSKG^}3BWqOhEGi0@>x3P=k z=Q4^3xyH!qU4|kxqIEm365=9zr_ieK^GCWZBRL^VDD{VKa}K3DEfsMeGRE6m^Ey~3 z<nm{u(u`jpXe)<es37;NXd<HX#|@Va<mEin%)GI5RMieE`HI4F{#d$+f2`DI!5IZs zb$n#gGyax1r35LMSD*k#wz|U8o>H;(<l82BpHS7M`2@q+sq8R7(0JACb1EzM#Aimf zS*iC5rkS^F*<(`bu13IZ`i?sl%OCnsxwp7l<~?WE7C=d4xyJpdRE5#AK7W{_@lgDi zllO)a4<*0ntdP*AQqo#d#h8pRq{slQ^nXM($F&%)t4hnu1G|yWVS+})lI9p#M7(AN zUwe<5ZbyG#qKlh$pJ)al3D=_oC<n3#O$j*EKfY4uS2Gj0HJi!8H5j1V`m+t^M6lBJ zFN`zSxpww6O1H2Nwx2zc`T~0w!uS0~ch14AoixOx)sn}|;~qHmm<6$8v~OG*k{4{B zWR`#f+?n)Dns_HqZHI){)=woBtf(c+{Bn^{Xq2Rw;;iSv82-c?@pKYW*QNBaQ>{!! z8@FV{@zMX6KhJn;)B=8~^`s1Kxn`3%ZXVk}`Bv^D>H@e!80WM%V*R|Mp?`pPY)RC% zD{To3zpm8TGm<_i^|E|iHDArWJ?cWtTXQPH?Ns>hk~5W49YM|A@iGi#CAL=e@A_?H z#J!tToXfhd&3!i#m;e41mQK=>WvmiAHYV^f#`%>|&qk|QPap+ON}IhhMV)N6ab>s9 zl3%FeQ*%d*aR0=l+bRCV_$(Pcelo0X#fiB2B5tFh36v2&*ul4RwvNr4S?97QuTZ4- z`OX?jArFs>=~*+FHMRDR>D(VufhrKcyIM$kt7E4MBKKQ@(1}0f0-5~5)1tHVyV=vq zj^cRQ1O@i?Q61oak?{~ujAOR>*}z)6vDzu=UT{X%Ts_61(1?FDQHF%tIBK%|EZh6+ zP|}AmFbxN*jt?R+%;$yn7(u9FK1~ciw&;<tuzqGJfzvklUW@i^zD>1A&k4a&idx6{ zX$x`i#uj`lyH<z?#%(4VEKn^Uy?)X?%^+7qVtZcnq(GoJtLz?|oR>@Zb)9|g3v{1& z2h`k!JA7D4?-M66u6?D6NDt{gcQ-!TJWkmv*?w1it<NR2d)z?6<pIkse9(!&<Yr>Z z)us28-U(k3+l!%`6h==6w4TkAsrLkwcV7`CtFuW(I5(Lr7GKT%;?YiK%({+P+C<b` z%Ak=<F1DT}+&l&3liW=+r<~nd!-h`hw>W>M>>@zXD==mUs@|(srIj$g@TI6g`5=xl z)&sJD!9~gmWzujKWG*vU3OOZ7wRmQnTZYH_gnxP@Q)IjYWIcWJiKN<IxYWbSTzeoX z9sUEvp(A*qd}i_M>ey8n;m7Rey_Z5EvnAzg;?;|o4^mk4Ym2w4Dx!scH>&-p5tR%j zwbr1rFvy3Cjgv)g^xdHGo*srV2Tp65J8LwALP;T&NpX|==2<4?jD1|*9s>0V6=G@E z)+aZ)m(UmC4ufCu0gojX7d}{%AmT<>q$ORXM%2{#vs=ba2b+@Wa+d-yYwj}M!qrET znt?ZcagV#oG6Q526v+*TWs&V@!n2)`Av<$Jn)AHk@t)<?k$wHl3oiu|0PXNkgZZa* zus8AMDseNz9<2CkNk^NPBh~ia6?9u6jhm4VkHod!hgKD%EXWF7<*vWJ#bx<nCCGW@ z>O^6~sM9#+(-J8njUN3Lf>WfGGO^41=9u<?!_<{Bz|(tyXlEUFXl@uc`3$@7J@4Sg z-27ZVonZPf>eP|#qIQP`MO-Rxg%z!SFh#2dC0iQELu)N(Cc96~dbz`3{;GYHw{YzQ zdZ^3M_*4V0Km%}<8JsZc$4NF{hyaE`;6>ys5KIX*A6kO$HTS=8J>WJ9=S-BX^A!uN zpNM9qxRauS5Y}deaB0wUt5wrB{FzFV(B>MpR_a-)fqVW)m<MRH#Ss%nts|9H$?ir& zzZPCQH8mLssKX}}P5k5&(tog_-s|F4ks_Zr90>GvxRca%qwAHYgwU?XW(WPpKKX+( z@EcO-xxGBGtt(fH=%Kf*LvVBk{w!R?Mk&!xG(JK;!q`rhJvsDa0qoL(*B_7s=Z>Up z4$FI|dO>Pu#cm<m&2pQ=2fJMtHEHyQ`qrOjI&G=NjC3C$tMYyDvx3cUH-i^J$9%6? zl~`I(%&}E(eqZ@Rgz3eO!Qi6!PJ)sk$E7OS7fh)Yc3QDM`~#&RM%fD#Cyr*~7Zv}S zIS<EMQ6nV{vo>ne)aZP0S>F-J)8yB;+24EqFhOeWDs_i>Iq>kcv|h!q+smcAXfSq% zHP7&U!$b^12(6lLyqI4nHL3Hx>w}rZ9BmUdFwPtEj%1xXIR<}?;jxAfk<L~WgcoGS z&BQw_s4$?M$q|0tu3F$i!h7T;8i1s36OA_wtn}APW4~{S|0w#jZJzvCW@L%2w7!$q zb2u+_qvH&H5$lAx<1E7OAfEPZp^5$A3RvRlU22NKf&IPQueVTho8<4UwC^RUpXLvo zu-L{s2V6(gL5)^gzqdCY&C<6g`e%6hSxD%<s0OkGIJ}b;4MBq}VYi_TMX!2405=${ z5$H87%$f~9qE&g$_Tyz*(_!Dy8+;2VPOUcoHrKTQz{9%F{Z-(nPL4W43d#mrWJGIk z;AQ62_|jKq0FAFxt0kE}{a#8?e0Jjch9$-0PTf;y<M~@s(mI5EHrb(z!Eq>=h`RG_ zH1k%|{(5%6Uli8OjydL568!G6I-i?V(BnJHx9Cfp<OXyyqIkh5A`Xs|rIo&!WUQsD zY^vAMA%d{TziJUT2%wOxH4RBy<>f3+GqkA-CrTdwoKkPQe}A-?BwESy`1P(7koBql z^7lVcCH@y8q?c_#D?df7{%X{w|5}CQa;l0vu}1e}SBBeZQ5sGVQj=Qem8LEBFBtzl z@?PZAHW>v0<MAQ2R$M4&!<#H98ON!tGLQ3nG#XYNIL&x>+&g^pja#m9m!eF~&2Mrh zB{8W7G8Y`=>2C$D<lM_X=KGE6N$H%w5M|Qc@}tSI*3hqBM1DWrP&SE{F~N!o@5sU- zSt%WFecdU|^$*srEGm3w<)>aAw)1Q1=R6dWZNAQXgGt{v<Ov(VB=lIJM#s7^7CeFK z|K-obbFvBpxdj7rm+L5f<I&`^BJ8`Oss)>dBwM(fv0n3&c6K&)c~Z>ySll2`V<9q^ zRtnLSL}WZatonu}n;H()gs}ZX#C#g9gr;S?h&CB!Rp)T%w(uCO^a2UG_-`Eyf;Ed4 zGOmx~K_0JNcQ5c0Y7-eggzxD2YBX%jGSkx{3ue6NooFHbf3_-{<OUCS!}}iRLfHpm zfic$E#L-y=PBn5C5=S7jgC<R&my=F$GU^8bBn45m6=5G=NViTGg~kLQ>!AF`-z)d7 zqxP<<kBENc?kdqfA-en7n|9dPo03A2GjJtI4=7?MwNZ#hhWjsQnxUSnW&JJ65`4-v z>DCIm;P0#Zg}9fnGw<3*0gTcTOcYnSTA&=SWnbVj9slY-w&s6s_kTOmd@AjfCp$Gx z{+$)dxbkCHF*x9U{<!gaLDE=snLXr8gW&Ll$1;;~8|ZeZCj6>$=pxAf!4z}3YtOww zJ$gtkT`d;_B`yw1^5m*#)%ILll3;Ejh#~z-)F~J7yLDZ7_k^42`6yb*Zo^2Bk;g_L z%AF#BE>$t+wx>3bKd4ZQN!R}m`7gocp|tR|WI{*tb%X`}w$whS3Nsz2s1uIn1hzG_ V^|#8G)XJK_7Yz9CZ?OG)>_56%v26eV literal 15920 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 JQrsx$e*t|ueGmWu diff --git a/images/logo-framadate.png b/images/logo-framadate.png index 84094c0cd5bc0fb071036bc51d578d09e7ca9b7d..367b15007abe07dafb0d22631b91a46f9c51ed1d 100644 GIT binary patch literal 2580 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 literal 4783 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 JPDHLkV1j$*D&+tG diff --git a/index.php b/index.php index a778d356..301b52e7 100644 --- a/index.php +++ b/index.php @@ -32,26 +32,61 @@ session_start(); // affichage de la page Utils::print_header( _("Home") ); -bandeau_titre(_("Organiser des rendez-vous simplement, librement.")); +bandeau_titre(_("Make your polls")); echo ' - <div class="row text-center"> - <div class="col-md-6"> - <p><a href="'.Utils::get_server_name().'infos_sondage.php?choix_sondage=date" role="button"> - <img class="opacity" src="'.Utils::get_server_name().'images/date.png" alt="" /> - <br /><span class="btn btn-warning btn-lg"><span class="glyphicon glyphicon-calendar"></span> + <div class="row"> + <div class="col-md-6 text-center"> + <p><a href="'.Utils::get_server_name().'infos_sondage.php?choix_sondage=date" class="opacity" role="button"> + <img class="img-responsive center-block" src="'.Utils::get_server_name().'images/date.png" alt="" /> + <br /><span class="btn btn-primary btn-lg"><span class="glyphicon glyphicon-calendar"></span> '. _('Schedule an event') . '</span> </a></p> </div> - <div class="col-md-6"> - <p><a href="'.Utils::get_server_name().'infos_sondage.php?choix_sondage=autre" role="button"> - <img alt="" class="opacity" src="'.Utils::get_server_name().'images/classic.png" /> - <br /><span class="btn btn-primary btn-lg"><span class="glyphicon glyphicon-stats"></span> - '. _('Make a poll') . '</span> + <div class="col-md-6 text-center"> + <p><a href="'.Utils::get_server_name().'infos_sondage.php?choix_sondage=autre" class="opacity" role="button"> + <img alt="" class="img-responsive center-block" src="'.Utils::get_server_name().'images/classic.png" /> + <br /><span class="btn btn-info btn-lg"><span class="glyphicon glyphicon-stats"></span> + '. _('Make a classic poll') . '</span> </a></p> </div> </div> - <div class="row text-center"> - <p>'. _("or") .' <a href="' . Utils::getUrlSondage('aqg259dth55iuhwm').'">'. _("view an example") .'</a></p> + <hr /> + <div class="row"> + <div class="col-md-4"> + <h2>'. _('What is that?') . '</h2> + <p class="text-center"><span class="glyphicon glyphicon-question-sign" style="font-size:50px"></span></p> + <p>'. _('Framadate is an online service for planning an appointment or make a decision quickly and easily. No registration is required.') .'</p> + <p>'. _('Here is how it works:') . '</p> + <ol> + <li>'. _('Make a poll') . '</li> + <li>'. _('Define dates or subjects to choose') . '</li> + <li>'. _('Send the poll link to your friends or colleagues') . '</li> + <li>'. _('Discuss and make a decision') . '</li> + </ol> + <p>'. _('Do you want to ') . '<a href="' . Utils::getUrlSondage('aqg259dth55iuhwm').'">'. _("view an example?") .'</a></p> + </div> + <div class="col-md-4"> + <h2>'. _('The software') .'</h2> + <p class="text-center"><span class="glyphicon glyphicon-cloud" style="font-size:50px"></span></p> + <p>'. _('Framadate was initially based on '). '<a href="https://sourcesup.cru.fr/projects/studs/">Studs</a>'. _(' a software developed by the University of Strasbourg. Today, it is devevoped by the association Framasoft') .'.</p> + <p>'. _('This software needs javascript and cookies enabled. It is compatible with the following web browsers:') .'</p> + <ul> + <li>Microsoft Internet Explorer 9+</li> + <li>Google Chrome 19+</li> + <li>Firefox 12+</li> + <li>Safari 5+</li> + <li>Opera 11+</li> + </ul> + <p>'. _('It is governed by the ').'<a href="http://www.cecill.info">'. _('CeCILL-B license').'</a>.</p> + </div> + <div class="col-md-4"> + <h2>'. _('Cultivate your garden') .'</h2> + <p class="text-center"><span class="glyphicon glyphicon-tree-deciduous" style="font-size:50px"></span></p> + <p>'. _('To participate in the software development, suggest improvements or simply download it, please visit ') .'<a href="https://git.framasoft.org/framasoft/framadate">'._('the development site').'</a>.</p> + <br /> + <p>'. _('If you want to install the software for your own use and thus increase your independence, we help you on:') .'</p> + <p class="text-center"><a href="http://framacloud.org/cultiver-son-jardin/installation-de-framadate/" class="btn btn-success"><span class="glyphicon glyphicon-tree-deciduous"></span> framacloud.org</a></p> + </div> </div>'."\n"; bandeau_pied(); diff --git a/infos_sondage.php b/infos_sondage.php index b430f494..d1ddbf08 100644 --- a/infos_sondage.php +++ b/infos_sondage.php @@ -154,31 +154,31 @@ $errors = array( ); if (!$_SESSION["titre"] && Utils::issetAndNoEmpty("poursuivre") ) { - $errors['title']['aria'] = 'aria-describeby="#poll_title_error" '; $errors['title']['class'] = ' has-error'; + $errors['title']['aria'] = 'aria-describeby="poll_title_error" '; $errors['title']['class'] = ' has-error'; $errors['title']['msg'] = '<div class="alert alert-danger" ><p id="poll_title_error">' . _("Enter a title") . '</p></div>'; } elseif ($erreur_injection_titre) { - $errors['title']['aria'] = 'aria-describeby="#poll_title_error" '; $errors['title']['class'] = ' has-error'; + $errors['title']['aria'] = 'aria-describeby="poll_title_error" '; $errors['title']['class'] = ' has-error'; $errors['title']['inject'] = '<div class="alert alert-danger"><p id="poll_title_error">' . _("Characters < > and \" are not permitted") . '</p></div>'; } if ($erreur_injection_commentaires) { - $errors['description']['aria'] = 'aria-describeby="#poll_comment_error" '; $errors['description']['class'] = ' has-error'; + $errors['description']['aria'] = 'aria-describeby="poll_comment_error" '; $errors['description']['class'] = ' has-error'; $errors['description']['msg'] = '<div class="alert alert-danger"><p id="poll_comment_error">' . _("Characters < > and \" are not permitted") . '</p></div>'; } if (!$_SESSION["nom"] && Utils::issetAndNoEmpty("poursuivre")) { - $errors['name']['aria'] = 'aria-describeby="#poll_name_error" '; $errors['name']['class'] = ' has-error'; + $errors['name']['aria'] = 'aria-describeby="poll_name_error" '; $errors['name']['class'] = ' has-error'; $errors['name']['msg'] = '<div class="alert alert-danger"><p id="poll_name_error">' . _("Enter a name") . '</p></div>'; } elseif ($erreur_injection_nom) { - $errors['name']['aria'] = 'aria-describeby="#poll_name_error" '; $errors['name']['class'] = ' has-error'; + $errors['name']['aria'] = 'aria-describeby="poll_name_error" '; $errors['name']['class'] = ' has-error'; $errors['name']['msg'] = '<div class="alert alert-danger"><p id="poll_name_error">' . _("Characters < > and \" are not permitted") . '</p></div>'; } if (!$_SESSION["adresse"] && Utils::issetAndNoEmpty("poursuivre")) { - $errors['email']['aria'] = 'aria-describeby="#poll_name_error" '; $errors['email']['class'] = ' has-error'; + $errors['email']['aria'] = 'aria-describeby="poll_name_error" '; $errors['email']['class'] = ' has-error'; $errors['email']['msg'] = '<div class="alert alert-danger"><p id="poll_email_error">' . _("Enter an email address") . '</p></div>'; } elseif ($erreur_adresse && Utils::issetAndNoEmpty("poursuivre")) { - $errors['email']['aria'] = 'aria-describeby="#poll_email_error" '; $errors['email']['class'] = ' has-error'; + $errors['email']['aria'] = 'aria-describeby="poll_email_error" '; $errors['email']['class'] = ' has-error'; $errors['email']['msg'] = '<div class="alert alert-danger"><p id="poll_email_error">' . _("The address is not correct! (You should enter a valid email address in order to receive the link to your poll)") . '</p></div>'; } @@ -272,7 +272,7 @@ echo ' <p class="text-right"> <input type="hidden" name="choix_sondage" value="'. $choix_sondage .'"/> - <button name="poursuivre" value="'. $choix_sondage .'" type="submit" class="btn btn-success">'. _('Next') . '</button> + <button name="poursuivre" value="'. $choix_sondage .'" type="submit" class="btn btn-success" title="'. _('Go to step 2') . '">'. _('Next') . '</button> </p> <script type="text/javascript"> document.formulaire.titre.focus(); </script> diff --git a/js/bootstrap-accessibility.js b/js/bootstrap-accessibility.js deleted file mode 100644 index 50728f58..00000000 --- a/js/bootstrap-accessibility.js +++ /dev/null @@ -1,406 +0,0 @@ -/* ======================================================================== -* Extends Bootstrap v3.1.1 - -* Copyright (c) <2014> eBay Software Foundation - -* All rights reserved. - -* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -* Neither the name of eBay or any of its subsidiaries or affiliates nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* ======================================================================== */ - -(function($) { - "use strict"; - - var uniqueId = function(prefix) { - return (prefix || 'ui-id') + '-' + Math.floor((Math.random()*1000)+1) - } - - // Alert Extension - // =============================== - - $('.alert').attr('role', 'alert') - $('.close').removeAttr('aria-hidden').wrapInner('<span aria-hidden="true"></span>').append('<span class="sr-only">Close</span>') - - // TOOLTIP Extension - // =============================== - - var showTooltip = $.fn.tooltip.Constructor.prototype.show - , hideTooltip = $.fn.tooltip.Constructor.prototype.hide - - $.fn.tooltip.Constructor.prototype.show = function () { - showTooltip.apply(this, arguments) - var $tip = this.tip() - , tooltipID = $tip.attr('id') || uniqueId('ui-tooltip') - $tip.attr({'role':'tooltip','id' : tooltipID}) - this.$element.attr('aria-describedby', tooltipID) - } - - $.fn.tooltip.Constructor.prototype.hide = function () { - hideTooltip.apply(this, arguments) - removeMultiValAttributes(this.$element, 'aria-describedby', this.tip().attr('id')) - return this - } - - // Popover Extension - // =============================== - var showPopover = $.fn.popover.Constructor.prototype.setContent - , hideTPopover = $.fn.popover.Constructor.prototype.hide - - $.fn.popover.Constructor.prototype.setContent = function(){ - showPopover.apply(this, arguments) - var $tip = this.tip() - , tooltipID = $tip.attr('id') || uniqueId('ui-tooltip') - $tip.attr({'role':'alert','id' : tooltipID}) - this.$element.attr('aria-describedby', tooltipID) - this.$element.focus() - } - $.fn.popover.Constructor.prototype.hide = function(){ - hideTooltip.apply(this, arguments) - removeMultiValAttributes(this.$element, 'aria-describedby', this.tip().attr('id')) - } - - //Modal Extension - $('.modal-dialog').attr( {'role' : 'document'}) - var modalhide = $.fn.modal.Constructor.prototype.hide - $.fn.modal.Constructor.prototype.hide = function(){ - var modalOpener = this.$element.parent().find('[data-target="#' + this.$element.attr('id') + '"]') - modalhide.apply(this, arguments) - modalOpener.focus() - } - - // DROPDOWN Extension - // =============================== - - var toggle = '[data-toggle=dropdown]' - , $par - , firstItem - , focusDelay = 200 - , menus = $(toggle).parent().find('ul').attr('role','menu') - , lis = menus.find('li').attr('role','presentation') - - lis.find('a').attr({'role':'menuitem', 'tabIndex':'-1'}) - $(toggle).attr({ 'aria-haspopup':'true', 'aria-expanded': 'false'}) - - $(toggle).parent().on('shown.bs.dropdown',function(e){ - $par = $(this) - var $toggle = $par.find(toggle) - $toggle.attr('aria-expanded','true') - - setTimeout(function(){ - firstItem = $('.dropdown-menu [role=menuitem]:visible', $par)[0] - try{ firstItem.focus()} catch(ex) {} - }, focusDelay) - }) - - $(toggle).parent().on('hidden.bs.dropdown',function(e){ - $par = $(this) - var $toggle = $par.find(toggle) - $toggle.attr('aria-expanded','false') - }) - - //Adding Space Key Behaviour, opens on spacebar - $.fn.dropdown.Constructor.prototype.keydown = function (e) { - var $par - , firstItem - if (!/(32)/.test(e.keyCode)) return - $par = $(this).parent() - $(this).trigger ("click") - e.preventDefault() && e.stopPropagation() - } - - $(document) - .on('focusout.dropdown.data-api', '.dropdown-menu', function(e){ - var $this = $(this) - , that = this - setTimeout(function() { - if(!$.contains(that, document.activeElement)){ - $this.parent().removeClass('open') - $this.parent().find('[data-toggle=dropdown]').attr('aria-expanded','false') - } - }, 150) - }) - .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , $.fn.dropdown.Constructor.prototype.keydown) - - - // Tab Extension - // =============================== - - var $tablist = $('.nav-tabs') - , $lis = $tablist.children('li') - , $tabs = $tablist.find('[data-toggle="tab"], [data-toggle="pill"]') - - $tablist.attr('role', 'tablist') - $lis.attr('role', 'presentation') - $tabs.attr('role', 'tab') - - $tabs.each(function( index ) { - var tabpanel = $($(this).attr('href')) - , tab = $(this) - , tabid = tab.attr('id') || uniqueId('ui-tab') - - tab.attr('id', tabid) - - if(tab.parent().hasClass('active')){ - tab.attr( { 'tabIndex' : '0', 'aria-selected' : 'true', 'aria-controls': tab.attr('href').substr(1) } ) - tabpanel.attr({ 'role' : 'tabpanel', 'tabIndex' : '0', 'aria-hidden' : 'false', 'aria-labelledby':tabid }) - }else{ - tab.attr( { 'tabIndex' : '-1', 'aria-selected' : 'false', 'aria-controls': tab.attr('href').substr(1) } ) - tabpanel.attr( { 'role' : 'tabpanel', 'tabIndex' : '-1', 'aria-hidden' : 'true', 'aria-labelledby':tabid } ) - } - }) - - $.fn.tab.Constructor.prototype.keydown = function (e) { - var $this = $(this) - , $items - , $ul = $this.closest('ul[role=tablist] ') - , index - , k = e.which || e.keyCode - - $this = $(this) - if (!/(37|38|39|40)/.test(k)) return - - $items = $ul.find('[role=tab]:visible') - index = $items.index($items.filter(':focus')) - - if (k == 38 || k == 37) index-- // up & left - if (k == 39 || k == 40) index++ // down & right - - - if(index < 0) index = $items.length -1 - if(index == $items.length) index = 0 - - var nextTab = $items.eq(index) - if(nextTab.attr('role') ==='tab'){ - - nextTab.tab('show') //Comment this line for dynamically loaded tabPabels, to save Ajax requests on arrow key navigation - .focus() - } - // nextTab.focus() - - e.preventDefault() - e.stopPropagation() - } - - $(document).on('keydown.tab.data-api','[data-toggle="tab"], [data-toggle="pill"]' , $.fn.tab.Constructor.prototype.keydown) - - var tabactivate = $.fn.tab.Constructor.prototype.activate; - $.fn.tab.Constructor.prototype.activate = function (element, container, callback) { - var $active = container.find('> .active') - $active.find('[data-toggle=tab]').attr({ 'tabIndex' : '-1','aria-selected' : false }) - $active.filter('.tab-pane').attr({ 'aria-hidden' : true,'tabIndex' : '-1' }) - - tabactivate.apply(this, arguments) - - element.addClass('active') - element.find('[data-toggle=tab]').attr({ 'tabIndex' : '0','aria-selected' : true }) - element.filter('.tab-pane').attr({ 'aria-hidden' : false,'tabIndex' : '0' }) - } - - - // Collapse Extension - // =============================== - - var $colltabs = $('[data-toggle="collapse"]') - $colltabs.attr({ 'role':'tab', 'aria-selected':'false', 'aria-expanded':'false' }) - $colltabs.each(function( index ) { - var colltab = $(this) - , collpanel = (colltab.attr('data-target')) ? $(colltab.attr('data-target')) : $(colltab.attr('href')) - , parent = colltab.attr('data-parent') - , collparent = parent && $(parent) - , collid = colltab.attr('id') || uniqueId('ui-collapse') - - $(collparent).find('div:not(.collapse,.panel-body), h4').attr('role','presentation') - - colltab.attr('id', collid) - if(collparent){ - collparent.attr({ 'role' : 'tablist', 'aria-multiselectable' : 'true' }) - if(collpanel.hasClass('in')){ - colltab.attr({ 'aria-controls': colltab.attr('href').substr(1), 'aria-selected':'true', 'aria-expanded':'true', 'tabindex':'0' }) - collpanel.attr({ 'role':'tabpanel', 'tabindex':'0', 'aria-labelledby':collid, 'aria-hidden':'false' }) - }else{ - colltab.attr({'aria-controls' : colltab.attr('href').substr(1), 'tabindex':'-1' }) - collpanel.attr({ 'role':'tabpanel', 'tabindex':'-1', 'aria-labelledby':collid, 'aria-hidden':'true' }) - } - } - }) - - var collToggle = $.fn.collapse.Constructor.prototype.toggle - $.fn.collapse.Constructor.prototype.toggle = function(){ - var prevTab = this.$parent && this.$parent.find('[aria-expanded="true"]') , href - - if(prevTab){ - var prevPanel = prevTab.attr('data-target') || (href = prevTab.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') - , $prevPanel = $(prevPanel) - , $curPanel = this.$element - , par = this.$parent - , curTab - - if (this.$parent) curTab = this.$parent.find('[data-toggle=collapse][href="#' + this.$element.attr('id') + '"]') - - collToggle.apply(this, arguments) - - if ($.support.transition) { - this.$element.one($.support.transition.end, function(){ - - prevTab.attr({ 'aria-selected':'false','aria-expanded':'false', 'tabIndex':'-1' }) - $prevPanel.attr({ 'aria-hidden' : 'true','tabIndex' : '-1'}) - - curTab.attr({ 'aria-selected':'true','aria-expanded':'true', 'tabIndex':'0' }) - - if($curPanel.hasClass('in')){ - $curPanel.attr({ 'aria-hidden' : 'false','tabIndex' : '0' }) - }else{ - curTab.attr({ 'aria-selected':'false','aria-expanded':'false'}) - $curPanel.attr({ 'aria-hidden' : 'true','tabIndex' : '-1' }) - } - }) - } - }else{ - collToggle.apply(this, arguments) - } - } - - $.fn.collapse.Constructor.prototype.keydown = function (e) { - var $this = $(this) - , $items - , $tablist = $this.closest('div[role=tablist] ') - , index - , k = e.which || e.keyCode - - $this = $(this) - if (!/(32|37|38|39|40)/.test(k)) return - if(k==32) $this.click() - - $items = $tablist.find('[role=tab]') - index = $items.index($items.filter(':focus')) - - if (k == 38 || k == 37) index-- // up & left - if (k == 39 || k == 40) index++ // down & right - if(index < 0) index = $items.length -1 - if(index == $items.length) index = 0 - - $items.eq(index).focus() - - e.preventDefault() - e.stopPropagation() - - } - - $(document).on('keydown.collapse.data-api','[data-toggle="collapse"]' , $.fn.collapse.Constructor.prototype.keydown) - - // Carousel Extension - // =============================== - - $('.carousel').each(function (index) { - var $this = $(this) - , prev = $this.find('[data-slide="prev"]') - , next = $this.find('[data-slide="next"]') - , $options = $this.find('.item') - , $listbox = $options.parent() - - $this.attr( { 'data-interval' : 'false', 'data-wrap' : 'false' } ) - $listbox.attr('role', 'listbox') - $options.attr('role', 'option') - - var spanPrev = document.createElement('span') - spanPrev.setAttribute('class', 'sr-only') - spanPrev.innerHTML='Previous' - - var spanNext = document.createElement('span') - spanNext.setAttribute('class', 'sr-only') - spanNext.innerHTML='Next' - - prev.attr('role', 'button') - next.attr('role', 'button') - - prev.append(spanPrev) - next.append(spanNext) - - $options.each(function () { - var item = $(this) - if(item.hasClass('active')){ - item.attr({ 'aria-selected': 'true', 'tabindex' : '0' }) - }else{ - item.attr({ 'aria-selected': 'false', 'tabindex' : '-1' }) - } - }) - }) - - var slideCarousel = $.fn.carousel.Constructor.prototype.slide - $.fn.carousel.Constructor.prototype.slide = function (type, next) { - var $active = this.$element.find('.item.active') - , $next = next || $active[type]() - - slideCarousel.apply(this, arguments) - - $active - .one($.support.transition.end, function () { - $active.attr({'aria-selected':false, 'tabIndex': '-1'}) - $next.attr({'aria-selected':true, 'tabIndex': '0'}) - //.focus() - }) - } - - $.fn.carousel.Constructor.prototype.keydown = function (e) { - var $this = $(this) - , $ul = $this.closest('div[role=listbox]') - , $items = $ul.find('[role=option]') - , $parent = $ul.parent() - , k = e.which || e.keyCode - , index - , i - - if (!/(37|38|39|40)/.test(k)) return - - index = $items.index($items.filter('.active')) - if (k == 37 || k == 38) { // Up - $parent.carousel('prev') - index-- - if(index < 0) index = $items.length -1 - else $this.prev().focus() - - } - if (k == 39 || k == 40) { // Down - $parent.carousel('next') - index++ - if(index == $items.length) index = 0 - else { - $this.one($.support.transition.end, function () { - $this.next().focus() - }) - } - - } - - e.preventDefault() - e.stopPropagation() - } - $(document).on('keydown.carousel.data-api', 'div[role=option]', $.fn.carousel.Constructor.prototype.keydown) - - // GENERAL UTILITY FUNCTIONS - // =============================== - - var removeMultiValAttributes = function (el, attr, val) { - var describedby = (el.attr( attr ) || "").split( /\s+/ ) - , index = $.inArray(val, describedby) - if ( index !== -1 ) { - describedby.splice( index, 1 ) - } - describedby = $.trim( describedby.join( " " ) ) - if (describedby ) { - el.attr( attr, describedby ) - } else { - el.removeAttr( attr ) - } - } - - -})(jQuery); diff --git a/js/bootstrap-accessibility.min.js b/js/bootstrap-accessibility.min.js deleted file mode 100644 index efedae78..00000000 --- a/js/bootstrap-accessibility.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! bootstrap-accessibility-plugin - v1.0.2 - 2014-05-21 -* https://github.com/paypal/bootstrap-accessibility-plugin -* Copyright (c) 2014 PayPal Accessibility Team; Licensed BSD */ -!function($){"use strict";var uniqueId=function(prefix){return(prefix||"ui-id")+"-"+Math.floor(1e3*Math.random()+1)};$(".alert").attr("role","alert"),$(".close").removeAttr("aria-hidden").wrapInner('<span aria-hidden="true"></span>').append('<span class="sr-only">Fermer</span>');var showTooltip=$.fn.tooltip.Constructor.prototype.show,hideTooltip=$.fn.tooltip.Constructor.prototype.hide;$.fn.tooltip.Constructor.prototype.show=function(){showTooltip.apply(this,arguments);var $tip=this.tip(),tooltipID=$tip.attr("id")||uniqueId("ui-tooltip");$tip.attr({role:"tooltip",id:tooltipID}),this.$element.attr("aria-describedby",tooltipID)},$.fn.tooltip.Constructor.prototype.hide=function(){return hideTooltip.apply(this,arguments),removeMultiValAttributes(this.$element,"aria-describedby",this.tip().attr("id")),this};{var showPopover=$.fn.popover.Constructor.prototype.setContent;$.fn.popover.Constructor.prototype.hide}$.fn.popover.Constructor.prototype.setContent=function(){showPopover.apply(this,arguments);var $tip=this.tip(),tooltipID=$tip.attr("id")||uniqueId("ui-tooltip");$tip.attr({role:"alert",id:tooltipID}),this.$element.attr("aria-describedby",tooltipID),this.$element.focus()},$.fn.popover.Constructor.prototype.hide=function(){hideTooltip.apply(this,arguments),removeMultiValAttributes(this.$element,"aria-describedby",this.tip().attr("id"))},$(".modal-dialog").attr({role:"document"});var modalhide=$.fn.modal.Constructor.prototype.hide;$.fn.modal.Constructor.prototype.hide=function(){var modalOpener=this.$element.parent().find('[data-target="#'+this.$element.attr("id")+'"]');modalhide.apply(this,arguments),modalOpener.focus()};var $par,firstItem,toggle="[data-toggle=dropdown]",focusDelay=200,menus=$(toggle).parent().find("ul").attr("role","menu"),lis=menus.find("li").attr("role","presentation");lis.find("a").attr({role:"menuitem",tabIndex:"-1"}),$(toggle).attr({"aria-haspopup":"true","aria-expanded":"false"}),$(toggle).parent().on("shown.bs.dropdown",function(){$par=$(this);var $toggle=$par.find(toggle);$toggle.attr("aria-expanded","true"),setTimeout(function(){firstItem=$(".dropdown-menu [role=menuitem]:visible",$par)[0];try{firstItem.focus()}catch(ex){}},focusDelay)}),$(toggle).parent().on("hidden.bs.dropdown",function(){$par=$(this);var $toggle=$par.find(toggle);$toggle.attr("aria-expanded","false")}),$.fn.dropdown.Constructor.prototype.keydown=function(e){var $par;/(32)/.test(e.keyCode)&&($par=$(this).parent(),$(this).trigger("click"),e.preventDefault()&&e.stopPropagation())},$(document).on("focusout.dropdown.data-api",".dropdown-menu",function(){var $this=$(this),that=this;setTimeout(function(){$.contains(that,document.activeElement)||($this.parent().removeClass("open"),$this.parent().find("[data-toggle=dropdown]").attr("aria-expanded","false"))},150)}).on("keydown.bs.dropdown.data-api",toggle+", [role=menu]",$.fn.dropdown.Constructor.prototype.keydown);var $tablist=$(".nav-tabs"),$lis=$tablist.children("li"),$tabs=$tablist.find('[data-toggle="tab"], [data-toggle="pill"]');$tablist.attr("role","tablist"),$lis.attr("role","presentation"),$tabs.attr("role","tab"),$tabs.each(function(){var tabpanel=$($(this).attr("href")),tab=$(this),tabid=tab.attr("id")||uniqueId("ui-tab");tab.attr("id",tabid),tab.parent().hasClass("active")?(tab.attr({tabIndex:"0","aria-selected":"true","aria-controls":tab.attr("href").substr(1)}),tabpanel.attr({role:"tabpanel",tabIndex:"0","aria-hidden":"false","aria-labelledby":tabid})):(tab.attr({tabIndex:"-1","aria-selected":"false","aria-controls":tab.attr("href").substr(1)}),tabpanel.attr({role:"tabpanel",tabIndex:"-1","aria-hidden":"true","aria-labelledby":tabid}))}),$.fn.tab.Constructor.prototype.keydown=function(e){var $items,index,$this=$(this),$ul=$this.closest("ul[role=tablist] "),k=e.which||e.keyCode;if($this=$(this),/(37|38|39|40)/.test(k)){$items=$ul.find("[role=tab]:visible"),index=$items.index($items.filter(":focus")),(38==k||37==k)&&index--,(39==k||40==k)&&index++,0>index&&(index=$items.length-1),index==$items.length&&(index=0);var nextTab=$items.eq(index);"tab"===nextTab.attr("role")&&nextTab.tab("show").focus(),e.preventDefault(),e.stopPropagation()}},$(document).on("keydown.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"]',$.fn.tab.Constructor.prototype.keydown);var tabactivate=$.fn.tab.Constructor.prototype.activate;$.fn.tab.Constructor.prototype.activate=function(element,container){var $active=container.find("> .active");$active.find("[data-toggle=tab]").attr({tabIndex:"-1","aria-selected":!1}),$active.filter(".tab-pane").attr({"aria-hidden":!0,tabIndex:"-1"}),tabactivate.apply(this,arguments),element.addClass("active"),element.find("[data-toggle=tab]").attr({tabIndex:"0","aria-selected":!0}),element.filter(".tab-pane").attr({"aria-hidden":!1,tabIndex:"0"})};var $colltabs=$('[data-toggle="collapse"]');$colltabs.attr({role:"tab","aria-selected":"false","aria-expanded":"false"}),$colltabs.each(function(){var colltab=$(this),collpanel=$(colltab.attr("data-target")?colltab.attr("data-target"):colltab.attr("href")),parent=colltab.attr("data-parent"),collparent=parent&&$(parent),collid=colltab.attr("id")||uniqueId("ui-collapse");$(collparent).find("div:not(.collapse,.panel-body), h4").attr("role","presentation"),colltab.attr("id",collid),collparent&&(collparent.attr({role:"tablist","aria-multiselectable":"true"}),collpanel.hasClass("in")?(colltab.attr({"aria-controls":colltab.attr("href").substr(1),"aria-selected":"true","aria-expanded":"true",tabindex:"0"}),collpanel.attr({role:"tabpanel",tabindex:"0","aria-labelledby":collid,"aria-hidden":"false"})):(colltab.attr({"aria-controls":colltab.attr("href").substr(1),tabindex:"-1"}),collpanel.attr({role:"tabpanel",tabindex:"-1","aria-labelledby":collid,"aria-hidden":"true"})))});var collToggle=$.fn.collapse.Constructor.prototype.toggle;$.fn.collapse.Constructor.prototype.toggle=function(){var href,prevTab=this.$parent&&this.$parent.find('[aria-expanded="true"]');if(prevTab){{var curTab,prevPanel=prevTab.attr("data-target")||(href=prevTab.attr("href"))&&href.replace(/.*(?=#[^\s]+$)/,""),$prevPanel=$(prevPanel),$curPanel=this.$element;this.$parent}this.$parent&&(curTab=this.$parent.find('[data-toggle=collapse][href="#'+this.$element.attr("id")+'"]')),collToggle.apply(this,arguments),$.support.transition&&this.$element.one($.support.transition.end,function(){prevTab.attr({"aria-selected":"false","aria-expanded":"false",tabIndex:"-1"}),$prevPanel.attr({"aria-hidden":"true",tabIndex:"-1"}),curTab.attr({"aria-selected":"true","aria-expanded":"true",tabIndex:"0"}),$curPanel.hasClass("in")?$curPanel.attr({"aria-hidden":"false",tabIndex:"0"}):(curTab.attr({"aria-selected":"false","aria-expanded":"false"}),$curPanel.attr({"aria-hidden":"true",tabIndex:"-1"}))})}else collToggle.apply(this,arguments)},$.fn.collapse.Constructor.prototype.keydown=function(e){var $items,index,$this=$(this),$tablist=$this.closest("div[role=tablist] "),k=e.which||e.keyCode;$this=$(this),/(32|37|38|39|40)/.test(k)&&(32==k&&$this.click(),$items=$tablist.find("[role=tab]"),index=$items.index($items.filter(":focus")),(38==k||37==k)&&index--,(39==k||40==k)&&index++,0>index&&(index=$items.length-1),index==$items.length&&(index=0),$items.eq(index).focus(),e.preventDefault(),e.stopPropagation())},$(document).on("keydown.collapse.data-api",'[data-toggle="collapse"]',$.fn.collapse.Constructor.prototype.keydown),$(".carousel").each(function(){var $this=$(this),prev=$this.find('[data-slide="prev"]'),next=$this.find('[data-slide="next"]'),$options=$this.find(".item"),$listbox=$options.parent();$this.attr({"data-interval":"false","data-wrap":"false"}),$listbox.attr("role","listbox"),$options.attr("role","option");var spanPrev=document.createElement("span");spanPrev.setAttribute("class","sr-only"),spanPrev.innerHTML="Previous";var spanNext=document.createElement("span");spanNext.setAttribute("class","sr-only"),spanNext.innerHTML="Next",prev.attr("role","button"),next.attr("role","button"),prev.append(spanPrev),next.append(spanNext),$options.each(function(){var item=$(this);item.attr(item.hasClass("active")?{"aria-selected":"true",tabindex:"0"}:{"aria-selected":"false",tabindex:"-1"})})});var slideCarousel=$.fn.carousel.Constructor.prototype.slide;$.fn.carousel.Constructor.prototype.slide=function(type,next){var $active=this.$element.find(".item.active"),$next=next||$active[type]();slideCarousel.apply(this,arguments),$active.one($.support.transition.end,function(){$active.attr({"aria-selected":!1,tabIndex:"-1"}),$next.attr({"aria-selected":!0,tabIndex:"0"})})},$.fn.carousel.Constructor.prototype.keydown=function(e){var index,$this=$(this),$ul=$this.closest("div[role=listbox]"),$items=$ul.find("[role=option]"),$parent=$ul.parent(),k=e.which||e.keyCode;/(37|38|39|40)/.test(k)&&(index=$items.index($items.filter(".active")),(37==k||38==k)&&($parent.carousel("prev"),index--,0>index?index=$items.length-1:$this.prev().focus()),(39==k||40==k)&&($parent.carousel("next"),index++,index==$items.length?index=0:$this.one($.support.transition.end,function(){$this.next().focus()})),e.preventDefault(),e.stopPropagation())},$(document).on("keydown.carousel.data-api","div[role=option]",$.fn.carousel.Constructor.prototype.keydown);var removeMultiValAttributes=function(el,attr,val){var describedby=(el.attr(attr)||"").split(/\s+/),index=$.inArray(val,describedby);-1!==index&&describedby.splice(index,1),describedby=$.trim(describedby.join(" ")),describedby?el.attr(attr,describedby):el.removeAttr(attr)}}(jQuery); diff --git a/js/bootstrap-datepicker.js b/js/bootstrap-datepicker.js index 8267df96..12393773 100644 --- a/js/bootstrap-datepicker.js +++ b/js/bootstrap-datepicker.js @@ -22,1650 +22,1652 @@ (function($, undefined){ - var $window = $(window); - - function UTCDate(){ - return new Date(Date.UTC.apply(Date, arguments)); - } - function UTCToday(){ - var today = new Date(); - return UTCDate(today.getFullYear(), today.getMonth(), today.getDate()); - } - function alias(method){ - return function(){ - return this[method].apply(this, arguments); - }; - } - - var DateArray = (function(){ - var extras = { - get: function(i){ - return this.slice(i)[0]; - }, - contains: function(d){ - // Array.indexOf is not cross-browser; - // $.inArray doesn't work with Dates - var val = d && d.valueOf(); - for (var i=0, l=this.length; i < l; i++) - if (this[i].valueOf() === val) - return i; - return -1; - }, - remove: function(i){ - this.splice(i,1); - }, - replace: function(new_array){ - if (!new_array) - return; - if (!$.isArray(new_array)) - new_array = [new_array]; - this.clear(); - this.push.apply(this, new_array); - }, - clear: function(){ - this.splice(0); - }, - copy: function(){ - var a = new DateArray(); - a.replace(this); - return a; - } - }; - - return function(){ - var a = []; - a.push.apply(a, arguments); - $.extend(a, extras); - return a; - }; - })(); - - - // Picker object - - var Datepicker = function(element, options){ - this.dates = new DateArray(); - this.viewDate = UTCToday(); - this.focusDate = null; - - this._process_options(options); - - this.element = $(element); - this.isInline = false; - this.isInput = this.element.is('input'); - this.component = this.element.is('.date') ? this.element.find('.add-on, .input-group-addon, .btn') : false; - this.hasInput = this.component && this.element.find('input').length; - if (this.component && this.component.length === 0) - this.component = false; - - this.picker = $(DPGlobal.template); - this._buildEvents(); - this._attachEvents(); - - if (this.isInline){ - this.picker.addClass('datepicker-inline').appendTo(this.element); - } - else { - this.picker.addClass('datepicker-dropdown dropdown-menu'); - } - - if (this.o.rtl){ - this.picker.addClass('datepicker-rtl'); - } - - this.viewMode = this.o.startView; - - if (this.o.calendarWeeks) - this.picker.find('tfoot th.today') - .attr('colspan', function(i, val){ - return parseInt(val) + 1; - }); - - this._allow_update = false; - - this.setStartDate(this._o.startDate); - this.setEndDate(this._o.endDate); - this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled); - - this.fillDow(); - this.fillMonths(); - - this._allow_update = true; - - this.update(); - this.showMode(); - - if (this.isInline){ - this.show(); - } - }; - - Datepicker.prototype = { - constructor: Datepicker, - - _process_options: function(opts){ - // Store raw options for reference - this._o = $.extend({}, this._o, opts); - // Processed options - var o = this.o = $.extend({}, this._o); - - // Check if "de-DE" style date is available, if not language should - // fallback to 2 letter code eg "de" - var lang = o.language; - if (!dates[lang]){ - lang = lang.split('-')[0]; - if (!dates[lang]) - lang = defaults.language; - } - o.language = lang; - - switch (o.startView){ - case 2: - case 'decade': - o.startView = 2; - break; - case 1: - case 'year': - o.startView = 1; - break; - default: - o.startView = 0; - } - - switch (o.minViewMode){ - case 1: - case 'months': - o.minViewMode = 1; - break; - case 2: - case 'years': - o.minViewMode = 2; - break; - default: - o.minViewMode = 0; - } - - o.startView = Math.max(o.startView, o.minViewMode); - - // true, false, or Number > 0 - if (o.multidate !== true){ - o.multidate = Number(o.multidate) || false; - if (o.multidate !== false) - o.multidate = Math.max(0, o.multidate); - else - o.multidate = 1; - } - o.multidateSeparator = String(o.multidateSeparator); - - o.weekStart %= 7; - o.weekEnd = ((o.weekStart + 6) % 7); - - var format = DPGlobal.parseFormat(o.format); - if (o.startDate !== -Infinity){ - if (!!o.startDate){ - if (o.startDate instanceof Date) - o.startDate = this._local_to_utc(this._zero_time(o.startDate)); - else - o.startDate = DPGlobal.parseDate(o.startDate, format, o.language); - } - else { - o.startDate = -Infinity; - } - } - if (o.endDate !== Infinity){ - if (!!o.endDate){ - if (o.endDate instanceof Date) - o.endDate = this._local_to_utc(this._zero_time(o.endDate)); - else - o.endDate = DPGlobal.parseDate(o.endDate, format, o.language); - } - else { - o.endDate = Infinity; - } - } - - o.daysOfWeekDisabled = o.daysOfWeekDisabled||[]; - if (!$.isArray(o.daysOfWeekDisabled)) - o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/); - o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){ - return parseInt(d, 10); - }); - - var plc = String(o.orientation).toLowerCase().split(/\s+/g), - _plc = o.orientation.toLowerCase(); - plc = $.grep(plc, function(word){ - return (/^auto|left|right|top|bottom$/).test(word); - }); - o.orientation = {x: 'auto', y: 'auto'}; - if (!_plc || _plc === 'auto') - ; // no action - else if (plc.length === 1){ - switch (plc[0]){ - case 'top': - case 'bottom': - o.orientation.y = plc[0]; - break; - case 'left': - case 'right': - o.orientation.x = plc[0]; - break; - } - } - else { - _plc = $.grep(plc, function(word){ - return (/^left|right$/).test(word); - }); - o.orientation.x = _plc[0] || 'auto'; - - _plc = $.grep(plc, function(word){ - return (/^top|bottom$/).test(word); - }); - o.orientation.y = _plc[0] || 'auto'; - } - }, - _events: [], - _secondaryEvents: [], - _applyEvents: function(evs){ - for (var i=0, el, ch, ev; i < evs.length; i++){ - el = evs[i][0]; - if (evs[i].length === 2){ - ch = undefined; - ev = evs[i][1]; - } - else if (evs[i].length === 3){ - ch = evs[i][1]; - ev = evs[i][2]; - } - el.on(ev, ch); - } - }, - _unapplyEvents: function(evs){ - for (var i=0, el, ev, ch; i < evs.length; i++){ - el = evs[i][0]; - if (evs[i].length === 2){ - ch = undefined; - ev = evs[i][1]; - } - else if (evs[i].length === 3){ - ch = evs[i][1]; - ev = evs[i][2]; - } - el.off(ev, ch); - } - }, - _buildEvents: function(){ - if (this.isInput){ // single input - this._events = [ - [this.element, { - focus: $.proxy(this.show, this), - keyup: $.proxy(function(e){ - if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1) - this.update(); - }, this), - keydown: $.proxy(this.keydown, this) - }] - ]; - } - else if (this.component && this.hasInput){ // component: input + button - this._events = [ - // For components that are not readonly, allow keyboard nav - [this.element.find('input'), { - //focus: $.proxy(this.show, this), - keyup: $.proxy(function(e){ - if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1) - this.update(); - }, this), - keydown: $.proxy(this.keydown, this) - }], - [this.component, { - click: $.proxy(this.show, this) - }] - ]; - } - else if (this.element.is('div')){ // inline datepicker - this.isInline = true; - } - else { - this._events = [ - [this.element, { - click: $.proxy(this.show, this) - }] - ]; - } - this._events.push( - // Component: listen for blur on element descendants - [this.element, '*', { - blur: $.proxy(function(e){ - this._focused_from = e.target; - }, this) - }], - // Input: listen for blur on element - [this.element, { - blur: $.proxy(function(e){ - this._focused_from = e.target; - }, this) - }] - ); - - this._secondaryEvents = [ - [this.picker, { - click: $.proxy(this.click, this) - }], - [$(window), { - resize: $.proxy(this.place, this) - }], - [$(document), { - 'mousedown touchstart': $.proxy(function(e){ - // Clicked outside the datepicker, hide it - if (!( - this.element.is(e.target) || - this.element.find(e.target).length || - this.picker.is(e.target) || - this.picker.find(e.target).length - )){ - this.hide(); - } - }, this) - }] - ]; - }, - _attachEvents: function(){ - this._detachEvents(); - this._applyEvents(this._events); - }, - _detachEvents: function(){ - this._unapplyEvents(this._events); - }, - _attachSecondaryEvents: function(){ - this._detachSecondaryEvents(); - this._applyEvents(this._secondaryEvents); - }, - _detachSecondaryEvents: function(){ - this._unapplyEvents(this._secondaryEvents); - }, - _trigger: function(event, altdate){ - var date = altdate || this.dates.get(-1), - local_date = this._utc_to_local(date); - - this.element.trigger({ - type: event, - date: local_date, - dates: $.map(this.dates, this._utc_to_local), - format: $.proxy(function(ix, format){ - if (arguments.length === 0){ - ix = this.dates.length - 1; - format = this.o.format; - } - else if (typeof ix === 'string'){ - format = ix; - ix = this.dates.length - 1; - } - format = format || this.o.format; - var date = this.dates.get(ix); - return DPGlobal.formatDate(date, format, this.o.language); - }, this) - }); - }, - - show: function(){ - if (!this.isInline) - this.picker.appendTo('body'); - this.picker.show(); - this.place(); - this._attachSecondaryEvents(); - this._trigger('show'); - }, - - hide: function(){ - if (this.isInline) - return; - if (!this.picker.is(':visible')) - return; - this.focusDate = null; - this.picker.hide().detach(); - this._detachSecondaryEvents(); - this.viewMode = this.o.startView; - this.showMode(); - - if ( - this.o.forceParse && - ( - this.isInput && this.element.val() || - this.hasInput && this.element.find('input').val() - ) - ) - this.setValue(); - this._trigger('hide'); - }, - - remove: function(){ - this.hide(); - this._detachEvents(); - this._detachSecondaryEvents(); - this.picker.remove(); - delete this.element.data().datepicker; - if (!this.isInput){ - delete this.element.data().date; - } - }, - - _utc_to_local: function(utc){ - return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000)); - }, - _local_to_utc: function(local){ - return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000)); - }, - _zero_time: function(local){ - return local && new Date(local.getFullYear(), local.getMonth(), local.getDate()); - }, - _zero_utc_time: function(utc){ - return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate())); - }, - - getDates: function(){ - return $.map(this.dates, this._utc_to_local); - }, - - getUTCDates: function(){ - return $.map(this.dates, function(d){ - return new Date(d); - }); - }, - - getDate: function(){ - return this._utc_to_local(this.getUTCDate()); - }, - - getUTCDate: function(){ - return new Date(this.dates.get(-1)); - }, - - setDates: function(){ - var args = $.isArray(arguments[0]) ? arguments[0] : arguments; - this.update.apply(this, args); - this._trigger('changeDate'); - this.setValue(); - }, - - setUTCDates: function(){ - var args = $.isArray(arguments[0]) ? arguments[0] : arguments; - this.update.apply(this, $.map(args, this._utc_to_local)); - this._trigger('changeDate'); - this.setValue(); - }, - - setDate: alias('setDates'), - setUTCDate: alias('setUTCDates'), - - setValue: function(){ - var formatted = this.getFormattedDate(); - if (!this.isInput){ - if (this.component){ - this.element.find('input').val(formatted).change(); - } - } - else { - this.element.val(formatted).change(); - } - }, - - getFormattedDate: function(format){ - if (format === undefined) - format = this.o.format; - - var lang = this.o.language; - return $.map(this.dates, function(d){ - return DPGlobal.formatDate(d, format, lang); - }).join(this.o.multidateSeparator); - }, - - setStartDate: function(startDate){ - this._process_options({startDate: startDate}); - this.update(); - this.updateNavArrows(); - }, - - setEndDate: function(endDate){ - this._process_options({endDate: endDate}); - this.update(); - this.updateNavArrows(); - }, - - setDaysOfWeekDisabled: function(daysOfWeekDisabled){ - this._process_options({daysOfWeekDisabled: daysOfWeekDisabled}); - this.update(); - this.updateNavArrows(); - }, - - place: function(){ - if (this.isInline) - return; - var calendarWidth = this.picker.outerWidth(), - calendarHeight = this.picker.outerHeight(), - visualPadding = 10, - windowWidth = $window.width(), - windowHeight = $window.height(), - scrollTop = $window.scrollTop(); - - var zIndex = parseInt(this.element.parents().filter(function(){ - return $(this).css('z-index') !== 'auto'; - }).first().css('z-index'))+10; - var offset = this.component ? this.component.parent().offset() : this.element.offset(); - var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false); - var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false); - var left = offset.left, - top = offset.top; - - this.picker.removeClass( - 'datepicker-orient-top datepicker-orient-bottom '+ - 'datepicker-orient-right datepicker-orient-left' - ); - - if (this.o.orientation.x !== 'auto'){ - this.picker.addClass('datepicker-orient-' + this.o.orientation.x); - if (this.o.orientation.x === 'right') - left -= calendarWidth - width; - } - // auto x orientation is best-placement: if it crosses a window - // edge, fudge it sideways - else { - // Default to left - this.picker.addClass('datepicker-orient-left'); - if (offset.left < 0) - left -= offset.left - visualPadding; - else if (offset.left + calendarWidth > windowWidth) - left = windowWidth - calendarWidth - visualPadding; - } - - // auto y orientation is best-situation: top or bottom, no fudging, - // decision based on which shows more of the calendar - var yorient = this.o.orientation.y, - top_overflow, bottom_overflow; - if (yorient === 'auto'){ - top_overflow = -scrollTop + offset.top - calendarHeight; - bottom_overflow = scrollTop + windowHeight - (offset.top + height + calendarHeight); - if (Math.max(top_overflow, bottom_overflow) === bottom_overflow) - yorient = 'top'; - else - yorient = 'bottom'; - } - this.picker.addClass('datepicker-orient-' + yorient); - if (yorient === 'top') - top += height; - else - top -= calendarHeight + parseInt(this.picker.css('padding-top')); - - this.picker.css({ - top: top, - left: left, - zIndex: zIndex - }); - }, - - _allow_update: true, - update: function(){ - if (!this._allow_update) - return; - - var oldDates = this.dates.copy(), - dates = [], - fromArgs = false; - if (arguments.length){ - $.each(arguments, $.proxy(function(i, date){ - if (date instanceof Date) - date = this._local_to_utc(date); - dates.push(date); - }, this)); - fromArgs = true; - } - else { - dates = this.isInput - ? this.element.val() - : this.element.data('date') || this.element.find('input').val(); - if (dates && this.o.multidate) - dates = dates.split(this.o.multidateSeparator); - else - dates = [dates]; - delete this.element.data().date; - } - - dates = $.map(dates, $.proxy(function(date){ - return DPGlobal.parseDate(date, this.o.format, this.o.language); - }, this)); - dates = $.grep(dates, $.proxy(function(date){ - return ( - date < this.o.startDate || - date > this.o.endDate || - !date - ); - }, this), true); - this.dates.replace(dates); - - if (this.dates.length) - this.viewDate = new Date(this.dates.get(-1)); - else if (this.viewDate < this.o.startDate) - this.viewDate = new Date(this.o.startDate); - else if (this.viewDate > this.o.endDate) - this.viewDate = new Date(this.o.endDate); - - if (fromArgs){ - // setting date by clicking - this.setValue(); - } - else if (dates.length){ - // setting date by typing - if (String(oldDates) !== String(this.dates)) - this._trigger('changeDate'); - } - if (!this.dates.length && oldDates.length) - this._trigger('clearDate'); - - this.fill(); - }, - - fillDow: function(){ - var dowCnt = this.o.weekStart, - html = '<tr>'; - if (this.o.calendarWeeks){ - var cell = '<th class="cw"> </th>'; - html += cell; - this.picker.find('.datepicker-days thead tr:first-child').prepend(cell); - } - while (dowCnt < this.o.weekStart + 7){ - html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>'; - } - html += '</tr>'; - this.picker.find('.datepicker-days thead').append(html); - }, - - fillMonths: function(){ - var html = '', - i = 0; - while (i < 12){ - html += '<span class="month">'+dates[this.o.language].monthsShort[i++]+'</span>'; - } - this.picker.find('.datepicker-months td').html(html); - }, - - setRange: function(range){ - if (!range || !range.length) - delete this.range; - else - this.range = $.map(range, function(d){ - return d.valueOf(); - }); - this.fill(); - }, - - getClassNames: function(date){ - var cls = [], - year = this.viewDate.getUTCFullYear(), - month = this.viewDate.getUTCMonth(), - today = new Date(); - if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){ - cls.push('old'); - } - else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){ - cls.push('new'); - } - if (this.focusDate && date.valueOf() === this.focusDate.valueOf()) - cls.push('focused'); - // Compare internal UTC date with local today, not UTC today - if (this.o.todayHighlight && - date.getUTCFullYear() === today.getFullYear() && - date.getUTCMonth() === today.getMonth() && - date.getUTCDate() === today.getDate()){ - cls.push('today'); - } - if (this.dates.contains(date) !== -1) - cls.push('active'); - if (date.valueOf() < this.o.startDate || date.valueOf() > this.o.endDate || - $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1){ - cls.push('disabled'); - } - if (this.range){ - if (date > this.range[0] && date < this.range[this.range.length-1]){ - cls.push('range'); - } - if ($.inArray(date.valueOf(), this.range) !== -1){ - cls.push('selected'); - } - } - return cls; - }, - - fill: function(){ - var d = new Date(this.viewDate), - year = d.getUTCFullYear(), - month = d.getUTCMonth(), - startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity, - startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity, - endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity, - endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity, - todaytxt = dates[this.o.language].today || dates['en'].today || '', - cleartxt = dates[this.o.language].clear || dates['en'].clear || '', - tooltip; - this.picker.find('.datepicker-days thead th.datepicker-switch') - .text(dates[this.o.language].months[month]+' '+year); - this.picker.find('tfoot th.today') - .text(todaytxt) - .toggle(this.o.todayBtn !== false); - this.picker.find('tfoot th.clear') - .text(cleartxt) - .toggle(this.o.clearBtn !== false); - this.updateNavArrows(); - this.fillMonths(); - var prevMonth = UTCDate(year, month-1, 28), - day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth()); - prevMonth.setUTCDate(day); - prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7); - var nextMonth = new Date(prevMonth); - nextMonth.setUTCDate(nextMonth.getUTCDate() + 42); - nextMonth = nextMonth.valueOf(); - var html = []; - var clsName; - while (prevMonth.valueOf() < nextMonth){ - if (prevMonth.getUTCDay() === this.o.weekStart){ - html.push('<tr>'); - if (this.o.calendarWeeks){ - // ISO 8601: First week contains first thursday. - // ISO also states week starts on Monday, but we can be more abstract here. - var - // Start of current week: based on weekstart/current date - ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5), - // Thursday of this week - th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5), - // First Thursday of year, year from thursday - yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5), - // Calendar week: ms between thursdays, div ms per day, div 7 days - calWeek = (th - yth) / 864e5 / 7 + 1; - html.push('<td class="cw">'+ calWeek +'</td>'); - - } - } - clsName = this.getClassNames(prevMonth); - clsName.push('day'); - - if (this.o.beforeShowDay !== $.noop){ - var before = this.o.beforeShowDay(this._utc_to_local(prevMonth)); - if (before === undefined) - before = {}; - else if (typeof(before) === 'boolean') - before = {enabled: before}; - else if (typeof(before) === 'string') - before = {classes: before}; - if (before.enabled === false) - clsName.push('disabled'); - if (before.classes) - clsName = clsName.concat(before.classes.split(/\s+/)); - if (before.tooltip) - tooltip = before.tooltip; - } - - clsName = $.unique(clsName); - html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>'); - if (prevMonth.getUTCDay() === this.o.weekEnd){ - html.push('</tr>'); - } - prevMonth.setUTCDate(prevMonth.getUTCDate()+1); - } - this.picker.find('.datepicker-days tbody').empty().append(html.join('')); - - var months = this.picker.find('.datepicker-months') - .find('th:eq(1)') - .text(year) - .end() - .find('span').removeClass('active'); - - $.each(this.dates, function(i, d){ - if (d.getUTCFullYear() === year) - months.eq(d.getUTCMonth()).addClass('active'); - }); - - if (year < startYear || year > endYear){ - months.addClass('disabled'); - } - if (year === startYear){ - months.slice(0, startMonth).addClass('disabled'); - } - if (year === endYear){ - months.slice(endMonth+1).addClass('disabled'); - } - - html = ''; - year = parseInt(year/10, 10) * 10; - var yearCont = this.picker.find('.datepicker-years') - .find('th:eq(1)') - .text(year + '-' + (year + 9)) - .end() - .find('td'); - year -= 1; - var years = $.map(this.dates, function(d){ - return d.getUTCFullYear(); - }), - classes; - for (var i = -1; i < 11; i++){ - classes = ['year']; - if (i === -1) - classes.push('old'); - else if (i === 10) - classes.push('new'); - if ($.inArray(year, years) !== -1) - classes.push('active'); - if (year < startYear || year > endYear) - classes.push('disabled'); - html += '<span class="' + classes.join(' ') + '">'+year+'</span>'; - year += 1; - } - yearCont.html(html); - }, - - updateNavArrows: function(){ - if (!this._allow_update) - return; - - var d = new Date(this.viewDate), - year = d.getUTCFullYear(), - month = d.getUTCMonth(); - switch (this.viewMode){ - case 0: - if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){ - this.picker.find('.prev').css({visibility: 'hidden'}); - } - else { - this.picker.find('.prev').css({visibility: 'visible'}); - } - if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){ - this.picker.find('.next').css({visibility: 'hidden'}); - } - else { - this.picker.find('.next').css({visibility: 'visible'}); - } - break; - case 1: - case 2: - if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear()){ - this.picker.find('.prev').css({visibility: 'hidden'}); - } - else { - this.picker.find('.prev').css({visibility: 'visible'}); - } - if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear()){ - this.picker.find('.next').css({visibility: 'hidden'}); - } - else { - this.picker.find('.next').css({visibility: 'visible'}); - } - break; - } - }, - - click: function(e){ - e.preventDefault(); - var target = $(e.target).closest('span, td, th'), - year, month, day; - if (target.length === 1){ - switch (target[0].nodeName.toLowerCase()){ - case 'th': - switch (target[0].className){ - case 'datepicker-switch': - this.showMode(1); - break; - case 'prev': - case 'next': - var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1); - switch (this.viewMode){ - case 0: - this.viewDate = this.moveMonth(this.viewDate, dir); - this._trigger('changeMonth', this.viewDate); - break; - case 1: - case 2: - this.viewDate = this.moveYear(this.viewDate, dir); - if (this.viewMode === 1) - this._trigger('changeYear', this.viewDate); - break; - } - this.fill(); - break; - case 'today': - var date = new Date(); - date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); - - this.showMode(-2); - var which = this.o.todayBtn === 'linked' ? null : 'view'; - this._setDate(date, which); - break; - case 'clear': - var element; - if (this.isInput) - element = this.element; - else if (this.component) - element = this.element.find('input'); - if (element) - element.val("").change(); - this.update(); - this._trigger('changeDate'); - if (this.o.autoclose) - this.hide(); - break; - } - break; - case 'span': - if (!target.is('.disabled')){ - this.viewDate.setUTCDate(1); - if (target.is('.month')){ - day = 1; - month = target.parent().find('span').index(target); - year = this.viewDate.getUTCFullYear(); - this.viewDate.setUTCMonth(month); - this._trigger('changeMonth', this.viewDate); - if (this.o.minViewMode === 1){ - this._setDate(UTCDate(year, month, day)); - } - } - else { - day = 1; - month = 0; - year = parseInt(target.text(), 10)||0; - this.viewDate.setUTCFullYear(year); - this._trigger('changeYear', this.viewDate); - if (this.o.minViewMode === 2){ - this._setDate(UTCDate(year, month, day)); - } - } - this.showMode(-1); - this.fill(); - } - break; - case 'td': - if (target.is('.day') && !target.is('.disabled')){ - day = parseInt(target.text(), 10)||1; - year = this.viewDate.getUTCFullYear(); - month = this.viewDate.getUTCMonth(); - if (target.is('.old')){ - if (month === 0){ - month = 11; - year -= 1; - } - else { - month -= 1; - } - } - else if (target.is('.new')){ - if (month === 11){ - month = 0; - year += 1; - } - else { - month += 1; - } - } - this._setDate(UTCDate(year, month, day)); - } - break; - } - } - if (this.picker.is(':visible') && this._focused_from){ - $(this._focused_from).focus(); - } - delete this._focused_from; - }, - - _toggle_multidate: function(date){ - var ix = this.dates.contains(date); - if (!date){ - this.dates.clear(); - } - else if (ix !== -1){ - this.dates.remove(ix); - } - else { - this.dates.push(date); - } - if (typeof this.o.multidate === 'number') - while (this.dates.length > this.o.multidate) - this.dates.remove(0); - }, - - _setDate: function(date, which){ - if (!which || which === 'date') - this._toggle_multidate(date && new Date(date)); - if (!which || which === 'view') - this.viewDate = date && new Date(date); - - this.fill(); - this.setValue(); - this._trigger('changeDate'); - var element; - if (this.isInput){ - element = this.element; - } - else if (this.component){ - element = this.element.find('input'); - } - if (element){ - element.change(); - } - if (this.o.autoclose && (!which || which === 'date')){ - this.hide(); - } - }, - - moveMonth: function(date, dir){ - if (!date) - return undefined; - if (!dir) - return date; - var new_date = new Date(date.valueOf()), - day = new_date.getUTCDate(), - month = new_date.getUTCMonth(), - mag = Math.abs(dir), - new_month, test; - dir = dir > 0 ? 1 : -1; - if (mag === 1){ - test = dir === -1 - // If going back one month, make sure month is not current month - // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02) - ? function(){ - return new_date.getUTCMonth() === month; - } - // If going forward one month, make sure month is as expected - // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02) - : function(){ - return new_date.getUTCMonth() !== new_month; - }; - new_month = month + dir; - new_date.setUTCMonth(new_month); - // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11 - if (new_month < 0 || new_month > 11) - new_month = (new_month + 12) % 12; - } - else { - // For magnitudes >1, move one month at a time... - for (var i=0; i < mag; i++) - // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)... - new_date = this.moveMonth(new_date, dir); - // ...then reset the day, keeping it in the new month - new_month = new_date.getUTCMonth(); - new_date.setUTCDate(day); - test = function(){ - return new_month !== new_date.getUTCMonth(); - }; - } - // Common date-resetting loop -- if date is beyond end of month, make it - // end of month - while (test()){ - new_date.setUTCDate(--day); - new_date.setUTCMonth(new_month); - } - return new_date; - }, - - moveYear: function(date, dir){ - return this.moveMonth(date, dir*12); - }, - - dateWithinRange: function(date){ - return date >= this.o.startDate && date <= this.o.endDate; - }, - - keydown: function(e){ - if (this.picker.is(':not(:visible)')){ - if (e.keyCode === 27) // allow escape to hide and re-show picker - this.show(); - return; - } - var dateChanged = false, - dir, newDate, newViewDate, - focusDate = this.focusDate || this.viewDate; - switch (e.keyCode){ - case 27: // escape - if (this.focusDate){ - this.focusDate = null; - this.viewDate = this.dates.get(-1) || this.viewDate; - this.fill(); - } - else - this.hide(); - e.preventDefault(); - break; - case 37: // left - case 39: // right - if (!this.o.keyboardNavigation) - break; - dir = e.keyCode === 37 ? -1 : 1; - if (e.ctrlKey){ - newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir); - newViewDate = this.moveYear(focusDate, dir); - this._trigger('changeYear', this.viewDate); - } - else if (e.shiftKey){ - newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir); - newViewDate = this.moveMonth(focusDate, dir); - this._trigger('changeMonth', this.viewDate); - } - else { - newDate = new Date(this.dates.get(-1) || UTCToday()); - newDate.setUTCDate(newDate.getUTCDate() + dir); - newViewDate = new Date(focusDate); - newViewDate.setUTCDate(focusDate.getUTCDate() + dir); - } - if (this.dateWithinRange(newDate)){ - this.focusDate = this.viewDate = newViewDate; - this.setValue(); - this.fill(); - e.preventDefault(); - } - break; - case 38: // up - case 40: // down - if (!this.o.keyboardNavigation) - break; - dir = e.keyCode === 38 ? -1 : 1; - if (e.ctrlKey){ - newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir); - newViewDate = this.moveYear(focusDate, dir); - this._trigger('changeYear', this.viewDate); - } - else if (e.shiftKey){ - newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir); - newViewDate = this.moveMonth(focusDate, dir); - this._trigger('changeMonth', this.viewDate); - } - else { - newDate = new Date(this.dates.get(-1) || UTCToday()); - newDate.setUTCDate(newDate.getUTCDate() + dir * 7); - newViewDate = new Date(focusDate); - newViewDate.setUTCDate(focusDate.getUTCDate() + dir * 7); - } - if (this.dateWithinRange(newDate)){ - this.focusDate = this.viewDate = newViewDate; - this.setValue(); - this.fill(); - e.preventDefault(); - } - break; - case 32: // spacebar - // Spacebar is used in manually typing dates in some formats. - // As such, its behavior should not be hijacked. - break; - case 13: // enter - focusDate = this.focusDate || this.dates.get(-1) || this.viewDate; - this._toggle_multidate(focusDate); - dateChanged = true; - this.focusDate = null; - this.viewDate = this.dates.get(-1) || this.viewDate; - this.setValue(); - this.fill(); - if (this.picker.is(':visible')){ - e.preventDefault(); - if (this.o.autoclose) - this.hide(); - } - break; - case 9: // tab - this.focusDate = null; - this.viewDate = this.dates.get(-1) || this.viewDate; - this.fill(); - this.hide(); - break; - } - if (dateChanged){ - if (this.dates.length) - this._trigger('changeDate'); - else - this._trigger('clearDate'); - var element; - if (this.isInput){ - element = this.element; - } - else if (this.component){ - element = this.element.find('input'); - } - if (element){ - element.change(); - } - } - }, - - showMode: function(dir){ - if (dir){ - this.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir)); - } - this.picker - .find('>div') - .hide() - .filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName) - .css('display', 'block'); - this.updateNavArrows(); - } - }; - - var DateRangePicker = function(element, options){ - this.element = $(element); - this.inputs = $.map(options.inputs, function(i){ - return i.jquery ? i[0] : i; - }); - delete options.inputs; - - $(this.inputs) - .datepicker(options) - .bind('changeDate', $.proxy(this.dateUpdated, this)); - - this.pickers = $.map(this.inputs, function(i){ - return $(i).data('datepicker'); - }); - this.updateDates(); - }; - DateRangePicker.prototype = { - updateDates: function(){ - this.dates = $.map(this.pickers, function(i){ - return i.getUTCDate(); - }); - this.updateRanges(); - }, - updateRanges: function(){ - var range = $.map(this.dates, function(d){ - return d.valueOf(); - }); - $.each(this.pickers, function(i, p){ - p.setRange(range); - }); - }, - dateUpdated: function(e){ - // `this.updating` is a workaround for preventing infinite recursion - // between `changeDate` triggering and `setUTCDate` calling. Until - // there is a better mechanism. - if (this.updating) - return; - this.updating = true; - - var dp = $(e.target).data('datepicker'), - new_date = dp.getUTCDate(), - i = $.inArray(e.target, this.inputs), - l = this.inputs.length; - if (i === -1) - return; - - $.each(this.pickers, function(i, p){ - if (!p.getUTCDate()) - p.setUTCDate(new_date); - }); - - if (new_date < this.dates[i]){ - // Date being moved earlier/left - while (i >= 0 && new_date < this.dates[i]){ - this.pickers[i--].setUTCDate(new_date); - } - } - else if (new_date > this.dates[i]){ - // Date being moved later/right - while (i < l && new_date > this.dates[i]){ - this.pickers[i++].setUTCDate(new_date); - } - } - this.updateDates(); - - delete this.updating; - }, - remove: function(){ - $.map(this.pickers, function(p){ p.remove(); }); - delete this.element.data().datepicker; - } - }; - - function opts_from_el(el, prefix){ - // Derive options from element data-attrs - var data = $(el).data(), - out = {}, inkey, - replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])'); - prefix = new RegExp('^' + prefix.toLowerCase()); - function re_lower(_,a){ - return a.toLowerCase(); - } - for (var key in data) - if (prefix.test(key)){ - inkey = key.replace(replace, re_lower); - out[inkey] = data[key]; - } - return out; - } - - function opts_from_locale(lang){ - // Derive options from locale plugins - var out = {}; - // Check if "de-DE" style date is available, if not language should - // fallback to 2 letter code eg "de" - if (!dates[lang]){ - lang = lang.split('-')[0]; - if (!dates[lang]) - return; - } - var d = dates[lang]; - $.each(locale_opts, function(i,k){ - if (k in d) - out[k] = d[k]; - }); - return out; - } - - var old = $.fn.datepicker; - $.fn.datepicker = function(option){ - var args = Array.apply(null, arguments); - args.shift(); - var internal_return; - this.each(function(){ - var $this = $(this), - data = $this.data('datepicker'), - options = typeof option === 'object' && option; - if (!data){ - var elopts = opts_from_el(this, 'date'), - // Preliminary otions - xopts = $.extend({}, defaults, elopts, options), - locopts = opts_from_locale(xopts.language), - // Options priority: js args, data-attrs, locales, defaults - opts = $.extend({}, defaults, locopts, elopts, options); - if ($this.is('.input-daterange') || opts.inputs){ - var ropts = { - inputs: opts.inputs || $this.find('input').toArray() - }; - $this.data('datepicker', (data = new DateRangePicker(this, $.extend(opts, ropts)))); - } - else { - $this.data('datepicker', (data = new Datepicker(this, opts))); - } - } - if (typeof option === 'string' && typeof data[option] === 'function'){ - internal_return = data[option].apply(data, args); - if (internal_return !== undefined) - return false; - } - }); - if (internal_return !== undefined) - return internal_return; - else - return this; - }; - - var defaults = $.fn.datepicker.defaults = { - autoclose: false, - beforeShowDay: $.noop, - calendarWeeks: false, - clearBtn: false, - daysOfWeekDisabled: [], - endDate: Infinity, - forceParse: true, - format: 'mm/dd/yyyy', - keyboardNavigation: true, - language: 'en', - minViewMode: 0, - multidate: false, - multidateSeparator: ',', - orientation: "auto", - rtl: false, - startDate: -Infinity, - startView: 0, - todayBtn: false, - todayHighlight: false, - weekStart: 0 - }; - var locale_opts = $.fn.datepicker.locale_opts = [ - 'format', - 'rtl', - 'weekStart' - ]; - $.fn.datepicker.Constructor = Datepicker; - var dates = $.fn.datepicker.dates = { - en: { - days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], - daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], - daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], - months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], - monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], - today: "Today", - clear: "Clear" - } - }; - - var DPGlobal = { - modes: [ - { - clsName: 'days', - navFnc: 'Month', - navStep: 1 - }, - { - clsName: 'months', - navFnc: 'FullYear', - navStep: 1 - }, - { - clsName: 'years', - navFnc: 'FullYear', - navStep: 10 - }], - isLeapYear: function(year){ - return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)); - }, - getDaysInMonth: function(year, month){ - return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; - }, - validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g, - nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g, - parseFormat: function(format){ - // IE treats \0 as a string end in inputs (truncating the value), - // so it's a bad format delimiter, anyway - var separators = format.replace(this.validParts, '\0').split('\0'), - parts = format.match(this.validParts); - if (!separators || !separators.length || !parts || parts.length === 0){ - throw new Error("Invalid date format."); - } - return {separators: separators, parts: parts}; - }, - parseDate: function(date, format, language){ - if (!date) - return undefined; - if (date instanceof Date) - return date; - if (typeof format === 'string') - format = DPGlobal.parseFormat(format); - var part_re = /([\-+]\d+)([dmwy])/, - parts = date.match(/([\-+]\d+)([dmwy])/g), - part, dir, i; - if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){ - date = new Date(); - for (i=0; i < parts.length; i++){ - part = part_re.exec(parts[i]); - dir = parseInt(part[1]); - switch (part[2]){ - case 'd': - date.setUTCDate(date.getUTCDate() + dir); - break; - case 'm': - date = Datepicker.prototype.moveMonth.call(Datepicker.prototype, date, dir); - break; - case 'w': - date.setUTCDate(date.getUTCDate() + dir * 7); - break; - case 'y': - date = Datepicker.prototype.moveYear.call(Datepicker.prototype, date, dir); - break; - } - } - return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0); - } - parts = date && date.match(this.nonpunctuation) || []; - date = new Date(); - var parsed = {}, - setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'], - setters_map = { - yyyy: function(d,v){ - return d.setUTCFullYear(v); - }, - yy: function(d,v){ - return d.setUTCFullYear(2000+v); - }, - m: function(d,v){ - if (isNaN(d)) - return d; - v -= 1; - while (v < 0) v += 12; - v %= 12; - d.setUTCMonth(v); - while (d.getUTCMonth() !== v) - d.setUTCDate(d.getUTCDate()-1); - return d; - }, - d: function(d,v){ - return d.setUTCDate(v); - } - }, - val, filtered; - setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m']; - setters_map['dd'] = setters_map['d']; - date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); - var fparts = format.parts.slice(); - // Remove noop parts - if (parts.length !== fparts.length){ - fparts = $(fparts).filter(function(i,p){ - return $.inArray(p, setters_order) !== -1; - }).toArray(); - } - // Process remainder - function match_part(){ - var m = this.slice(0, parts[i].length), - p = parts[i].slice(0, m.length); - return m === p; - } - if (parts.length === fparts.length){ - var cnt; - for (i=0, cnt = fparts.length; i < cnt; i++){ - val = parseInt(parts[i], 10); - part = fparts[i]; - if (isNaN(val)){ - switch (part){ - case 'MM': - filtered = $(dates[language].months).filter(match_part); - val = $.inArray(filtered[0], dates[language].months) + 1; - break; - case 'M': - filtered = $(dates[language].monthsShort).filter(match_part); - val = $.inArray(filtered[0], dates[language].monthsShort) + 1; - break; - } - } - parsed[part] = val; - } - var _date, s; - for (i=0; i < setters_order.length; i++){ - s = setters_order[i]; - if (s in parsed && !isNaN(parsed[s])){ - _date = new Date(date); - setters_map[s](_date, parsed[s]); - if (!isNaN(_date)) - date = _date; - } - } - } - return date; - }, - formatDate: function(date, format, language){ - if (!date) - return ''; - if (typeof format === 'string') - format = DPGlobal.parseFormat(format); - var val = { - d: date.getUTCDate(), - D: dates[language].daysShort[date.getUTCDay()], - DD: dates[language].days[date.getUTCDay()], - m: date.getUTCMonth() + 1, - M: dates[language].monthsShort[date.getUTCMonth()], - MM: dates[language].months[date.getUTCMonth()], - yy: date.getUTCFullYear().toString().substring(2), - yyyy: date.getUTCFullYear() - }; - val.dd = (val.d < 10 ? '0' : '') + val.d; - val.mm = (val.m < 10 ? '0' : '') + val.m; - date = []; - var seps = $.extend([], format.separators); - for (var i=0, cnt = format.parts.length; i <= cnt; i++){ - if (seps.length) - date.push(seps.shift()); - date.push(val[format.parts[i]]); - } - return date.join(''); - }, - headTemplate: '<thead>'+ - '<tr>'+ - '<th class="prev">«</th>'+ - '<th colspan="5" class="datepicker-switch"></th>'+ - '<th class="next">»</th>'+ - '</tr>'+ - '</thead>', - contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>', - footTemplate: '<tfoot>'+ - '<tr>'+ - '<th colspan="7" class="today"></th>'+ - '</tr>'+ - '<tr>'+ - '<th colspan="7" class="clear"></th>'+ - '</tr>'+ - '</tfoot>' - }; - DPGlobal.template = '<div class="datepicker">'+ - '<div class="datepicker-days">'+ - '<table class=" table-condensed">'+ - DPGlobal.headTemplate+ - '<tbody></tbody>'+ - DPGlobal.footTemplate+ - '</table>'+ - '</div>'+ - '<div class="datepicker-months">'+ - '<table class="table-condensed">'+ - DPGlobal.headTemplate+ - DPGlobal.contTemplate+ - DPGlobal.footTemplate+ - '</table>'+ - '</div>'+ - '<div class="datepicker-years">'+ - '<table class="table-condensed">'+ - DPGlobal.headTemplate+ - DPGlobal.contTemplate+ - DPGlobal.footTemplate+ - '</table>'+ - '</div>'+ - '</div>'; - - $.fn.datepicker.DPGlobal = DPGlobal; - - - /* DATEPICKER NO CONFLICT - * =================== */ - - $.fn.datepicker.noConflict = function(){ - $.fn.datepicker = old; - return this; - }; - - - /* DATEPICKER DATA-API - * ================== */ - - $(document).on( - 'focus.datepicker.data-api click.datepicker.data-api', - '[data-provide="datepicker"]', - function(e){ - var $this = $(this); - if ($this.data('datepicker')) - return; - e.preventDefault(); - // component click requires us to explicitly show it - $this.datepicker('show'); - } - ); - $(function(){ - $('[data-provide="datepicker-inline"]').datepicker(); - }); + var $window = $(window); + + function UTCDate(){ + return new Date(Date.UTC.apply(Date, arguments)); + } + function UTCToday(){ + var today = new Date(); + return UTCDate(today.getFullYear(), today.getMonth(), today.getDate()); + } + function alias(method){ + return function(){ + return this[method].apply(this, arguments); + }; + } + + var DateArray = (function(){ + var extras = { + get: function(i){ + return this.slice(i)[0]; + }, + contains: function(d){ + // Array.indexOf is not cross-browser; + // $.inArray doesn't work with Dates + var val = d && d.valueOf(); + for (var i=0, l=this.length; i < l; i++) + if (this[i].valueOf() === val) + return i; + return -1; + }, + remove: function(i){ + this.splice(i,1); + }, + replace: function(new_array){ + if (!new_array) + return; + if (!$.isArray(new_array)) + new_array = [new_array]; + this.clear(); + this.push.apply(this, new_array); + }, + clear: function(){ + this.splice(0); + }, + copy: function(){ + var a = new DateArray(); + a.replace(this); + return a; + } + }; + + return function(){ + var a = []; + a.push.apply(a, arguments); + $.extend(a, extras); + return a; + }; + })(); + + + // Picker object + + var Datepicker = function(element, options){ + this.dates = new DateArray(); + this.viewDate = UTCToday(); + this.focusDate = null; + + this._process_options(options); + + this.element = $(element); + this.isInline = false; + this.isInput = this.element.is('input'); + this.component = this.element.is('.date') ? this.element.find('.add-on, .input-group-addon, .btn') : false; + this.hasInput = this.component && this.element.find('input').length; + if (this.component && this.component.length === 0) + this.component = false; + + this.picker = $(DPGlobal.template); + this._buildEvents(); + this._attachEvents(); + + if (this.isInline){ + this.picker.addClass('datepicker-inline').appendTo(this.element); + } + else { + this.picker.addClass('datepicker-dropdown dropdown-menu'); + } + + if (this.o.rtl){ + this.picker.addClass('datepicker-rtl'); + } + + this.viewMode = this.o.startView; + + if (this.o.calendarWeeks) + this.picker.find('tfoot th.today') + .attr('colspan', function(i, val){ + return parseInt(val) + 1; + }); + + this._allow_update = false; + + this.setStartDate(this._o.startDate); + this.setEndDate(this._o.endDate); + this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled); + + this.fillDow(); + this.fillMonths(); + + this._allow_update = true; + + this.update(); + this.showMode(); + + if (this.isInline){ + this.show(); + } + }; + + Datepicker.prototype = { + constructor: Datepicker, + + _process_options: function(opts){ + // Store raw options for reference + this._o = $.extend({}, this._o, opts); + // Processed options + var o = this.o = $.extend({}, this._o); + + // Check if "de-DE" style date is available, if not language should + // fallback to 2 letter code eg "de" + var lang = o.language; + if (!dates[lang]){ + lang = lang.split('-')[0]; + if (!dates[lang]) + lang = defaults.language; + } + o.language = lang; + + switch (o.startView){ + case 2: + case 'decade': + o.startView = 2; + break; + case 1: + case 'year': + o.startView = 1; + break; + default: + o.startView = 0; + } + + switch (o.minViewMode){ + case 1: + case 'months': + o.minViewMode = 1; + break; + case 2: + case 'years': + o.minViewMode = 2; + break; + default: + o.minViewMode = 0; + } + + o.startView = Math.max(o.startView, o.minViewMode); + + // true, false, or Number > 0 + if (o.multidate !== true){ + o.multidate = Number(o.multidate) || false; + if (o.multidate !== false) + o.multidate = Math.max(0, o.multidate); + else + o.multidate = 1; + } + o.multidateSeparator = String(o.multidateSeparator); + + o.weekStart %= 7; + o.weekEnd = ((o.weekStart + 6) % 7); + + var format = DPGlobal.parseFormat(o.format); + if (o.startDate !== -Infinity){ + if (!!o.startDate){ + if (o.startDate instanceof Date) + o.startDate = this._local_to_utc(this._zero_time(o.startDate)); + else + o.startDate = DPGlobal.parseDate(o.startDate, format, o.language); + } + else { + o.startDate = -Infinity; + } + } + if (o.endDate !== Infinity){ + if (!!o.endDate){ + if (o.endDate instanceof Date) + o.endDate = this._local_to_utc(this._zero_time(o.endDate)); + else + o.endDate = DPGlobal.parseDate(o.endDate, format, o.language); + } + else { + o.endDate = Infinity; + } + } + + o.daysOfWeekDisabled = o.daysOfWeekDisabled||[]; + if (!$.isArray(o.daysOfWeekDisabled)) + o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/); + o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){ + return parseInt(d, 10); + }); + + var plc = String(o.orientation).toLowerCase().split(/\s+/g), + _plc = o.orientation.toLowerCase(); + plc = $.grep(plc, function(word){ + return (/^auto|left|right|top|bottom$/).test(word); + }); + o.orientation = {x: 'auto', y: 'auto'}; + if (!_plc || _plc === 'auto') + ; // no action + else if (plc.length === 1){ + switch (plc[0]){ + case 'top': + case 'bottom': + o.orientation.y = plc[0]; + break; + case 'left': + case 'right': + o.orientation.x = plc[0]; + break; + } + } + else { + _plc = $.grep(plc, function(word){ + return (/^left|right$/).test(word); + }); + o.orientation.x = _plc[0] || 'auto'; + + _plc = $.grep(plc, function(word){ + return (/^top|bottom$/).test(word); + }); + o.orientation.y = _plc[0] || 'auto'; + } + }, + _events: [], + _secondaryEvents: [], + _applyEvents: function(evs){ + for (var i=0, el, ch, ev; i < evs.length; i++){ + el = evs[i][0]; + if (evs[i].length === 2){ + ch = undefined; + ev = evs[i][1]; + } + else if (evs[i].length === 3){ + ch = evs[i][1]; + ev = evs[i][2]; + } + el.on(ev, ch); + } + }, + _unapplyEvents: function(evs){ + for (var i=0, el, ev, ch; i < evs.length; i++){ + el = evs[i][0]; + if (evs[i].length === 2){ + ch = undefined; + ev = evs[i][1]; + } + else if (evs[i].length === 3){ + ch = evs[i][1]; + ev = evs[i][2]; + } + el.off(ev, ch); + } + }, + _buildEvents: function(){ + if (this.isInput){ // single input + this._events = [ + [this.element, { + focus: $.proxy(this.show, this), + keyup: $.proxy(function(e){ + if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1) + this.update(); + }, this), + keydown: $.proxy(this.keydown, this) + }] + ]; + } + else if (this.component && this.hasInput){ // component: input + button + this._events = [ + // For components that are not readonly, allow keyboard nav + [this.element.find('input'), { + // <framadate> + //focus: $.proxy(this.show, this), + // </framadate> + keyup: $.proxy(function(e){ + if ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1) + this.update(); + }, this), + keydown: $.proxy(this.keydown, this) + }], + [this.component, { + click: $.proxy(this.show, this) + }] + ]; + } + else if (this.element.is('div')){ // inline datepicker + this.isInline = true; + } + else { + this._events = [ + [this.element, { + click: $.proxy(this.show, this) + }] + ]; + } + this._events.push( + // Component: listen for blur on element descendants + [this.element, '*', { + blur: $.proxy(function(e){ + this._focused_from = e.target; + }, this) + }], + // Input: listen for blur on element + [this.element, { + blur: $.proxy(function(e){ + this._focused_from = e.target; + }, this) + }] + ); + + this._secondaryEvents = [ + [this.picker, { + click: $.proxy(this.click, this) + }], + [$(window), { + resize: $.proxy(this.place, this) + }], + [$(document), { + 'mousedown touchstart': $.proxy(function(e){ + // Clicked outside the datepicker, hide it + if (!( + this.element.is(e.target) || + this.element.find(e.target).length || + this.picker.is(e.target) || + this.picker.find(e.target).length + )){ + this.hide(); + } + }, this) + }] + ]; + }, + _attachEvents: function(){ + this._detachEvents(); + this._applyEvents(this._events); + }, + _detachEvents: function(){ + this._unapplyEvents(this._events); + }, + _attachSecondaryEvents: function(){ + this._detachSecondaryEvents(); + this._applyEvents(this._secondaryEvents); + }, + _detachSecondaryEvents: function(){ + this._unapplyEvents(this._secondaryEvents); + }, + _trigger: function(event, altdate){ + var date = altdate || this.dates.get(-1), + local_date = this._utc_to_local(date); + + this.element.trigger({ + type: event, + date: local_date, + dates: $.map(this.dates, this._utc_to_local), + format: $.proxy(function(ix, format){ + if (arguments.length === 0){ + ix = this.dates.length - 1; + format = this.o.format; + } + else if (typeof ix === 'string'){ + format = ix; + ix = this.dates.length - 1; + } + format = format || this.o.format; + var date = this.dates.get(ix); + return DPGlobal.formatDate(date, format, this.o.language); + }, this) + }); + }, + + show: function(){ + if (!this.isInline) + this.picker.appendTo('body'); + this.picker.show(); + this.place(); + this._attachSecondaryEvents(); + this._trigger('show'); + }, + + hide: function(){ + if (this.isInline) + return; + if (!this.picker.is(':visible')) + return; + this.focusDate = null; + this.picker.hide().detach(); + this._detachSecondaryEvents(); + this.viewMode = this.o.startView; + this.showMode(); + + if ( + this.o.forceParse && + ( + this.isInput && this.element.val() || + this.hasInput && this.element.find('input').val() + ) + ) + this.setValue(); + this._trigger('hide'); + }, + + remove: function(){ + this.hide(); + this._detachEvents(); + this._detachSecondaryEvents(); + this.picker.remove(); + delete this.element.data().datepicker; + if (!this.isInput){ + delete this.element.data().date; + } + }, + + _utc_to_local: function(utc){ + return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000)); + }, + _local_to_utc: function(local){ + return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000)); + }, + _zero_time: function(local){ + return local && new Date(local.getFullYear(), local.getMonth(), local.getDate()); + }, + _zero_utc_time: function(utc){ + return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate())); + }, + + getDates: function(){ + return $.map(this.dates, this._utc_to_local); + }, + + getUTCDates: function(){ + return $.map(this.dates, function(d){ + return new Date(d); + }); + }, + + getDate: function(){ + return this._utc_to_local(this.getUTCDate()); + }, + + getUTCDate: function(){ + return new Date(this.dates.get(-1)); + }, + + setDates: function(){ + var args = $.isArray(arguments[0]) ? arguments[0] : arguments; + this.update.apply(this, args); + this._trigger('changeDate'); + this.setValue(); + }, + + setUTCDates: function(){ + var args = $.isArray(arguments[0]) ? arguments[0] : arguments; + this.update.apply(this, $.map(args, this._utc_to_local)); + this._trigger('changeDate'); + this.setValue(); + }, + + setDate: alias('setDates'), + setUTCDate: alias('setUTCDates'), + + setValue: function(){ + var formatted = this.getFormattedDate(); + if (!this.isInput){ + if (this.component){ + this.element.find('input').val(formatted).change(); + } + } + else { + this.element.val(formatted).change(); + } + }, + + getFormattedDate: function(format){ + if (format === undefined) + format = this.o.format; + + var lang = this.o.language; + return $.map(this.dates, function(d){ + return DPGlobal.formatDate(d, format, lang); + }).join(this.o.multidateSeparator); + }, + + setStartDate: function(startDate){ + this._process_options({startDate: startDate}); + this.update(); + this.updateNavArrows(); + }, + + setEndDate: function(endDate){ + this._process_options({endDate: endDate}); + this.update(); + this.updateNavArrows(); + }, + + setDaysOfWeekDisabled: function(daysOfWeekDisabled){ + this._process_options({daysOfWeekDisabled: daysOfWeekDisabled}); + this.update(); + this.updateNavArrows(); + }, + + place: function(){ + if (this.isInline) + return; + var calendarWidth = this.picker.outerWidth(), + calendarHeight = this.picker.outerHeight(), + visualPadding = 10, + windowWidth = $window.width(), + windowHeight = $window.height(), + scrollTop = $window.scrollTop(); + + var zIndex = parseInt(this.element.parents().filter(function(){ + return $(this).css('z-index') !== 'auto'; + }).first().css('z-index'))+10; + var offset = this.component ? this.component.parent().offset() : this.element.offset(); + var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false); + var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false); + var left = offset.left, + top = offset.top; + + this.picker.removeClass( + 'datepicker-orient-top datepicker-orient-bottom '+ + 'datepicker-orient-right datepicker-orient-left' + ); + + if (this.o.orientation.x !== 'auto'){ + this.picker.addClass('datepicker-orient-' + this.o.orientation.x); + if (this.o.orientation.x === 'right') + left -= calendarWidth - width; + } + // auto x orientation is best-placement: if it crosses a window + // edge, fudge it sideways + else { + // Default to left + this.picker.addClass('datepicker-orient-left'); + if (offset.left < 0) + left -= offset.left - visualPadding; + else if (offset.left + calendarWidth > windowWidth) + left = windowWidth - calendarWidth - visualPadding; + } + + // auto y orientation is best-situation: top or bottom, no fudging, + // decision based on which shows more of the calendar + var yorient = this.o.orientation.y, + top_overflow, bottom_overflow; + if (yorient === 'auto'){ + top_overflow = -scrollTop + offset.top - calendarHeight; + bottom_overflow = scrollTop + windowHeight - (offset.top + height + calendarHeight); + if (Math.max(top_overflow, bottom_overflow) === bottom_overflow) + yorient = 'top'; + else + yorient = 'bottom'; + } + this.picker.addClass('datepicker-orient-' + yorient); + if (yorient === 'top') + top += height; + else + top -= calendarHeight + parseInt(this.picker.css('padding-top')); + + this.picker.css({ + top: top, + left: left, + zIndex: zIndex + }); + }, + + _allow_update: true, + update: function(){ + if (!this._allow_update) + return; + + var oldDates = this.dates.copy(), + dates = [], + fromArgs = false; + if (arguments.length){ + $.each(arguments, $.proxy(function(i, date){ + if (date instanceof Date) + date = this._local_to_utc(date); + dates.push(date); + }, this)); + fromArgs = true; + } + else { + dates = this.isInput + ? this.element.val() + : this.element.data('date') || this.element.find('input').val(); + if (dates && this.o.multidate) + dates = dates.split(this.o.multidateSeparator); + else + dates = [dates]; + delete this.element.data().date; + } + + dates = $.map(dates, $.proxy(function(date){ + return DPGlobal.parseDate(date, this.o.format, this.o.language); + }, this)); + dates = $.grep(dates, $.proxy(function(date){ + return ( + date < this.o.startDate || + date > this.o.endDate || + !date + ); + }, this), true); + this.dates.replace(dates); + + if (this.dates.length) + this.viewDate = new Date(this.dates.get(-1)); + else if (this.viewDate < this.o.startDate) + this.viewDate = new Date(this.o.startDate); + else if (this.viewDate > this.o.endDate) + this.viewDate = new Date(this.o.endDate); + + if (fromArgs){ + // setting date by clicking + this.setValue(); + } + else if (dates.length){ + // setting date by typing + if (String(oldDates) !== String(this.dates)) + this._trigger('changeDate'); + } + if (!this.dates.length && oldDates.length) + this._trigger('clearDate'); + + this.fill(); + }, + + fillDow: function(){ + var dowCnt = this.o.weekStart, + html = '<tr>'; + if (this.o.calendarWeeks){ + var cell = '<th class="cw"> </th>'; + html += cell; + this.picker.find('.datepicker-days thead tr:first-child').prepend(cell); + } + while (dowCnt < this.o.weekStart + 7){ + html += '<th class="dow">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>'; + } + html += '</tr>'; + this.picker.find('.datepicker-days thead').append(html); + }, + + fillMonths: function(){ + var html = '', + i = 0; + while (i < 12){ + html += '<span class="month">'+dates[this.o.language].monthsShort[i++]+'</span>'; + } + this.picker.find('.datepicker-months td').html(html); + }, + + setRange: function(range){ + if (!range || !range.length) + delete this.range; + else + this.range = $.map(range, function(d){ + return d.valueOf(); + }); + this.fill(); + }, + + getClassNames: function(date){ + var cls = [], + year = this.viewDate.getUTCFullYear(), + month = this.viewDate.getUTCMonth(), + today = new Date(); + if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){ + cls.push('old'); + } + else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){ + cls.push('new'); + } + if (this.focusDate && date.valueOf() === this.focusDate.valueOf()) + cls.push('focused'); + // Compare internal UTC date with local today, not UTC today + if (this.o.todayHighlight && + date.getUTCFullYear() === today.getFullYear() && + date.getUTCMonth() === today.getMonth() && + date.getUTCDate() === today.getDate()){ + cls.push('today'); + } + if (this.dates.contains(date) !== -1) + cls.push('active'); + if (date.valueOf() < this.o.startDate || date.valueOf() > this.o.endDate || + $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1){ + cls.push('disabled'); + } + if (this.range){ + if (date > this.range[0] && date < this.range[this.range.length-1]){ + cls.push('range'); + } + if ($.inArray(date.valueOf(), this.range) !== -1){ + cls.push('selected'); + } + } + return cls; + }, + + fill: function(){ + var d = new Date(this.viewDate), + year = d.getUTCFullYear(), + month = d.getUTCMonth(), + startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity, + startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity, + endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity, + endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity, + todaytxt = dates[this.o.language].today || dates['en'].today || '', + cleartxt = dates[this.o.language].clear || dates['en'].clear || '', + tooltip; + this.picker.find('.datepicker-days thead th.datepicker-switch') + .text(dates[this.o.language].months[month]+' '+year); + this.picker.find('tfoot th.today') + .text(todaytxt) + .toggle(this.o.todayBtn !== false); + this.picker.find('tfoot th.clear') + .text(cleartxt) + .toggle(this.o.clearBtn !== false); + this.updateNavArrows(); + this.fillMonths(); + var prevMonth = UTCDate(year, month-1, 28), + day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth()); + prevMonth.setUTCDate(day); + prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7); + var nextMonth = new Date(prevMonth); + nextMonth.setUTCDate(nextMonth.getUTCDate() + 42); + nextMonth = nextMonth.valueOf(); + var html = []; + var clsName; + while (prevMonth.valueOf() < nextMonth){ + if (prevMonth.getUTCDay() === this.o.weekStart){ + html.push('<tr>'); + if (this.o.calendarWeeks){ + // ISO 8601: First week contains first thursday. + // ISO also states week starts on Monday, but we can be more abstract here. + var + // Start of current week: based on weekstart/current date + ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5), + // Thursday of this week + th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5), + // First Thursday of year, year from thursday + yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5), + // Calendar week: ms between thursdays, div ms per day, div 7 days + calWeek = (th - yth) / 864e5 / 7 + 1; + html.push('<td class="cw">'+ calWeek +'</td>'); + + } + } + clsName = this.getClassNames(prevMonth); + clsName.push('day'); + + if (this.o.beforeShowDay !== $.noop){ + var before = this.o.beforeShowDay(this._utc_to_local(prevMonth)); + if (before === undefined) + before = {}; + else if (typeof(before) === 'boolean') + before = {enabled: before}; + else if (typeof(before) === 'string') + before = {classes: before}; + if (before.enabled === false) + clsName.push('disabled'); + if (before.classes) + clsName = clsName.concat(before.classes.split(/\s+/)); + if (before.tooltip) + tooltip = before.tooltip; + } + + clsName = $.unique(clsName); + html.push('<td class="'+clsName.join(' ')+'"' + (tooltip ? ' title="'+tooltip+'"' : '') + '>'+prevMonth.getUTCDate() + '</td>'); + if (prevMonth.getUTCDay() === this.o.weekEnd){ + html.push('</tr>'); + } + prevMonth.setUTCDate(prevMonth.getUTCDate()+1); + } + this.picker.find('.datepicker-days tbody').empty().append(html.join('')); + + var months = this.picker.find('.datepicker-months') + .find('th:eq(1)') + .text(year) + .end() + .find('span').removeClass('active'); + + $.each(this.dates, function(i, d){ + if (d.getUTCFullYear() === year) + months.eq(d.getUTCMonth()).addClass('active'); + }); + + if (year < startYear || year > endYear){ + months.addClass('disabled'); + } + if (year === startYear){ + months.slice(0, startMonth).addClass('disabled'); + } + if (year === endYear){ + months.slice(endMonth+1).addClass('disabled'); + } + + html = ''; + year = parseInt(year/10, 10) * 10; + var yearCont = this.picker.find('.datepicker-years') + .find('th:eq(1)') + .text(year + '-' + (year + 9)) + .end() + .find('td'); + year -= 1; + var years = $.map(this.dates, function(d){ + return d.getUTCFullYear(); + }), + classes; + for (var i = -1; i < 11; i++){ + classes = ['year']; + if (i === -1) + classes.push('old'); + else if (i === 10) + classes.push('new'); + if ($.inArray(year, years) !== -1) + classes.push('active'); + if (year < startYear || year > endYear) + classes.push('disabled'); + html += '<span class="' + classes.join(' ') + '">'+year+'</span>'; + year += 1; + } + yearCont.html(html); + }, + + updateNavArrows: function(){ + if (!this._allow_update) + return; + + var d = new Date(this.viewDate), + year = d.getUTCFullYear(), + month = d.getUTCMonth(); + switch (this.viewMode){ + case 0: + if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){ + this.picker.find('.prev').css({visibility: 'hidden'}); + } + else { + this.picker.find('.prev').css({visibility: 'visible'}); + } + if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){ + this.picker.find('.next').css({visibility: 'hidden'}); + } + else { + this.picker.find('.next').css({visibility: 'visible'}); + } + break; + case 1: + case 2: + if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear()){ + this.picker.find('.prev').css({visibility: 'hidden'}); + } + else { + this.picker.find('.prev').css({visibility: 'visible'}); + } + if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear()){ + this.picker.find('.next').css({visibility: 'hidden'}); + } + else { + this.picker.find('.next').css({visibility: 'visible'}); + } + break; + } + }, + + click: function(e){ + e.preventDefault(); + var target = $(e.target).closest('span, td, th'), + year, month, day; + if (target.length === 1){ + switch (target[0].nodeName.toLowerCase()){ + case 'th': + switch (target[0].className){ + case 'datepicker-switch': + this.showMode(1); + break; + case 'prev': + case 'next': + var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1); + switch (this.viewMode){ + case 0: + this.viewDate = this.moveMonth(this.viewDate, dir); + this._trigger('changeMonth', this.viewDate); + break; + case 1: + case 2: + this.viewDate = this.moveYear(this.viewDate, dir); + if (this.viewMode === 1) + this._trigger('changeYear', this.viewDate); + break; + } + this.fill(); + break; + case 'today': + var date = new Date(); + date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); + + this.showMode(-2); + var which = this.o.todayBtn === 'linked' ? null : 'view'; + this._setDate(date, which); + break; + case 'clear': + var element; + if (this.isInput) + element = this.element; + else if (this.component) + element = this.element.find('input'); + if (element) + element.val("").change(); + this.update(); + this._trigger('changeDate'); + if (this.o.autoclose) + this.hide(); + break; + } + break; + case 'span': + if (!target.is('.disabled')){ + this.viewDate.setUTCDate(1); + if (target.is('.month')){ + day = 1; + month = target.parent().find('span').index(target); + year = this.viewDate.getUTCFullYear(); + this.viewDate.setUTCMonth(month); + this._trigger('changeMonth', this.viewDate); + if (this.o.minViewMode === 1){ + this._setDate(UTCDate(year, month, day)); + } + } + else { + day = 1; + month = 0; + year = parseInt(target.text(), 10)||0; + this.viewDate.setUTCFullYear(year); + this._trigger('changeYear', this.viewDate); + if (this.o.minViewMode === 2){ + this._setDate(UTCDate(year, month, day)); + } + } + this.showMode(-1); + this.fill(); + } + break; + case 'td': + if (target.is('.day') && !target.is('.disabled')){ + day = parseInt(target.text(), 10)||1; + year = this.viewDate.getUTCFullYear(); + month = this.viewDate.getUTCMonth(); + if (target.is('.old')){ + if (month === 0){ + month = 11; + year -= 1; + } + else { + month -= 1; + } + } + else if (target.is('.new')){ + if (month === 11){ + month = 0; + year += 1; + } + else { + month += 1; + } + } + this._setDate(UTCDate(year, month, day)); + } + break; + } + } + if (this.picker.is(':visible') && this._focused_from){ + $(this._focused_from).focus(); + } + delete this._focused_from; + }, + + _toggle_multidate: function(date){ + var ix = this.dates.contains(date); + if (!date){ + this.dates.clear(); + } + else if (ix !== -1){ + this.dates.remove(ix); + } + else { + this.dates.push(date); + } + if (typeof this.o.multidate === 'number') + while (this.dates.length > this.o.multidate) + this.dates.remove(0); + }, + + _setDate: function(date, which){ + if (!which || which === 'date') + this._toggle_multidate(date && new Date(date)); + if (!which || which === 'view') + this.viewDate = date && new Date(date); + + this.fill(); + this.setValue(); + this._trigger('changeDate'); + var element; + if (this.isInput){ + element = this.element; + } + else if (this.component){ + element = this.element.find('input'); + } + if (element){ + element.change(); + } + if (this.o.autoclose && (!which || which === 'date')){ + this.hide(); + } + }, + + moveMonth: function(date, dir){ + if (!date) + return undefined; + if (!dir) + return date; + var new_date = new Date(date.valueOf()), + day = new_date.getUTCDate(), + month = new_date.getUTCMonth(), + mag = Math.abs(dir), + new_month, test; + dir = dir > 0 ? 1 : -1; + if (mag === 1){ + test = dir === -1 + // If going back one month, make sure month is not current month + // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02) + ? function(){ + return new_date.getUTCMonth() === month; + } + // If going forward one month, make sure month is as expected + // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02) + : function(){ + return new_date.getUTCMonth() !== new_month; + }; + new_month = month + dir; + new_date.setUTCMonth(new_month); + // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11 + if (new_month < 0 || new_month > 11) + new_month = (new_month + 12) % 12; + } + else { + // For magnitudes >1, move one month at a time... + for (var i=0; i < mag; i++) + // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)... + new_date = this.moveMonth(new_date, dir); + // ...then reset the day, keeping it in the new month + new_month = new_date.getUTCMonth(); + new_date.setUTCDate(day); + test = function(){ + return new_month !== new_date.getUTCMonth(); + }; + } + // Common date-resetting loop -- if date is beyond end of month, make it + // end of month + while (test()){ + new_date.setUTCDate(--day); + new_date.setUTCMonth(new_month); + } + return new_date; + }, + + moveYear: function(date, dir){ + return this.moveMonth(date, dir*12); + }, + + dateWithinRange: function(date){ + return date >= this.o.startDate && date <= this.o.endDate; + }, + + keydown: function(e){ + if (this.picker.is(':not(:visible)')){ + if (e.keyCode === 27) // allow escape to hide and re-show picker + this.show(); + return; + } + var dateChanged = false, + dir, newDate, newViewDate, + focusDate = this.focusDate || this.viewDate; + switch (e.keyCode){ + case 27: // escape + if (this.focusDate){ + this.focusDate = null; + this.viewDate = this.dates.get(-1) || this.viewDate; + this.fill(); + } + else + this.hide(); + e.preventDefault(); + break; + case 37: // left + case 39: // right + if (!this.o.keyboardNavigation) + break; + dir = e.keyCode === 37 ? -1 : 1; + if (e.ctrlKey){ + newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir); + newViewDate = this.moveYear(focusDate, dir); + this._trigger('changeYear', this.viewDate); + } + else if (e.shiftKey){ + newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir); + newViewDate = this.moveMonth(focusDate, dir); + this._trigger('changeMonth', this.viewDate); + } + else { + newDate = new Date(this.dates.get(-1) || UTCToday()); + newDate.setUTCDate(newDate.getUTCDate() + dir); + newViewDate = new Date(focusDate); + newViewDate.setUTCDate(focusDate.getUTCDate() + dir); + } + if (this.dateWithinRange(newDate)){ + this.focusDate = this.viewDate = newViewDate; + this.setValue(); + this.fill(); + e.preventDefault(); + } + break; + case 38: // up + case 40: // down + if (!this.o.keyboardNavigation) + break; + dir = e.keyCode === 38 ? -1 : 1; + if (e.ctrlKey){ + newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir); + newViewDate = this.moveYear(focusDate, dir); + this._trigger('changeYear', this.viewDate); + } + else if (e.shiftKey){ + newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir); + newViewDate = this.moveMonth(focusDate, dir); + this._trigger('changeMonth', this.viewDate); + } + else { + newDate = new Date(this.dates.get(-1) || UTCToday()); + newDate.setUTCDate(newDate.getUTCDate() + dir * 7); + newViewDate = new Date(focusDate); + newViewDate.setUTCDate(focusDate.getUTCDate() + dir * 7); + } + if (this.dateWithinRange(newDate)){ + this.focusDate = this.viewDate = newViewDate; + this.setValue(); + this.fill(); + e.preventDefault(); + } + break; + case 32: // spacebar + // Spacebar is used in manually typing dates in some formats. + // As such, its behavior should not be hijacked. + break; + case 13: // enter + focusDate = this.focusDate || this.dates.get(-1) || this.viewDate; + this._toggle_multidate(focusDate); + dateChanged = true; + this.focusDate = null; + this.viewDate = this.dates.get(-1) || this.viewDate; + this.setValue(); + this.fill(); + if (this.picker.is(':visible')){ + e.preventDefault(); + if (this.o.autoclose) + this.hide(); + } + break; + case 9: // tab + this.focusDate = null; + this.viewDate = this.dates.get(-1) || this.viewDate; + this.fill(); + this.hide(); + break; + } + if (dateChanged){ + if (this.dates.length) + this._trigger('changeDate'); + else + this._trigger('clearDate'); + var element; + if (this.isInput){ + element = this.element; + } + else if (this.component){ + element = this.element.find('input'); + } + if (element){ + element.change(); + } + } + }, + + showMode: function(dir){ + if (dir){ + this.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir)); + } + this.picker + .find('>div') + .hide() + .filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName) + .css('display', 'block'); + this.updateNavArrows(); + } + }; + + var DateRangePicker = function(element, options){ + this.element = $(element); + this.inputs = $.map(options.inputs, function(i){ + return i.jquery ? i[0] : i; + }); + delete options.inputs; + + $(this.inputs) + .datepicker(options) + .bind('changeDate', $.proxy(this.dateUpdated, this)); + + this.pickers = $.map(this.inputs, function(i){ + return $(i).data('datepicker'); + }); + this.updateDates(); + }; + DateRangePicker.prototype = { + updateDates: function(){ + this.dates = $.map(this.pickers, function(i){ + return i.getUTCDate(); + }); + this.updateRanges(); + }, + updateRanges: function(){ + var range = $.map(this.dates, function(d){ + return d.valueOf(); + }); + $.each(this.pickers, function(i, p){ + p.setRange(range); + }); + }, + dateUpdated: function(e){ + // `this.updating` is a workaround for preventing infinite recursion + // between `changeDate` triggering and `setUTCDate` calling. Until + // there is a better mechanism. + if (this.updating) + return; + this.updating = true; + + var dp = $(e.target).data('datepicker'), + new_date = dp.getUTCDate(), + i = $.inArray(e.target, this.inputs), + l = this.inputs.length; + if (i === -1) + return; + + $.each(this.pickers, function(i, p){ + if (!p.getUTCDate()) + p.setUTCDate(new_date); + }); + + if (new_date < this.dates[i]){ + // Date being moved earlier/left + while (i >= 0 && new_date < this.dates[i]){ + this.pickers[i--].setUTCDate(new_date); + } + } + else if (new_date > this.dates[i]){ + // Date being moved later/right + while (i < l && new_date > this.dates[i]){ + this.pickers[i++].setUTCDate(new_date); + } + } + this.updateDates(); + + delete this.updating; + }, + remove: function(){ + $.map(this.pickers, function(p){ p.remove(); }); + delete this.element.data().datepicker; + } + }; + + function opts_from_el(el, prefix){ + // Derive options from element data-attrs + var data = $(el).data(), + out = {}, inkey, + replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])'); + prefix = new RegExp('^' + prefix.toLowerCase()); + function re_lower(_,a){ + return a.toLowerCase(); + } + for (var key in data) + if (prefix.test(key)){ + inkey = key.replace(replace, re_lower); + out[inkey] = data[key]; + } + return out; + } + + function opts_from_locale(lang){ + // Derive options from locale plugins + var out = {}; + // Check if "de-DE" style date is available, if not language should + // fallback to 2 letter code eg "de" + if (!dates[lang]){ + lang = lang.split('-')[0]; + if (!dates[lang]) + return; + } + var d = dates[lang]; + $.each(locale_opts, function(i,k){ + if (k in d) + out[k] = d[k]; + }); + return out; + } + + var old = $.fn.datepicker; + $.fn.datepicker = function(option){ + var args = Array.apply(null, arguments); + args.shift(); + var internal_return; + this.each(function(){ + var $this = $(this), + data = $this.data('datepicker'), + options = typeof option === 'object' && option; + if (!data){ + var elopts = opts_from_el(this, 'date'), + // Preliminary otions + xopts = $.extend({}, defaults, elopts, options), + locopts = opts_from_locale(xopts.language), + // Options priority: js args, data-attrs, locales, defaults + opts = $.extend({}, defaults, locopts, elopts, options); + if ($this.is('.input-daterange') || opts.inputs){ + var ropts = { + inputs: opts.inputs || $this.find('input').toArray() + }; + $this.data('datepicker', (data = new DateRangePicker(this, $.extend(opts, ropts)))); + } + else { + $this.data('datepicker', (data = new Datepicker(this, opts))); + } + } + if (typeof option === 'string' && typeof data[option] === 'function'){ + internal_return = data[option].apply(data, args); + if (internal_return !== undefined) + return false; + } + }); + if (internal_return !== undefined) + return internal_return; + else + return this; + }; + + var defaults = $.fn.datepicker.defaults = { + autoclose: false, + beforeShowDay: $.noop, + calendarWeeks: false, + clearBtn: false, + daysOfWeekDisabled: [], + endDate: Infinity, + forceParse: true, + format: 'mm/dd/yyyy', + keyboardNavigation: true, + language: 'en', + minViewMode: 0, + multidate: false, + multidateSeparator: ',', + orientation: "auto", + rtl: false, + startDate: -Infinity, + startView: 0, + todayBtn: false, + todayHighlight: false, + weekStart: 0 + }; + var locale_opts = $.fn.datepicker.locale_opts = [ + 'format', + 'rtl', + 'weekStart' + ]; + $.fn.datepicker.Constructor = Datepicker; + var dates = $.fn.datepicker.dates = { + en: { + days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], + daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], + daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + monthsShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], + today: "Today", + clear: "Clear" + } + }; + + var DPGlobal = { + modes: [ + { + clsName: 'days', + navFnc: 'Month', + navStep: 1 + }, + { + clsName: 'months', + navFnc: 'FullYear', + navStep: 1 + }, + { + clsName: 'years', + navFnc: 'FullYear', + navStep: 10 + }], + isLeapYear: function(year){ + return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0)); + }, + getDaysInMonth: function(year, month){ + return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; + }, + validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g, + nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g, + parseFormat: function(format){ + // IE treats \0 as a string end in inputs (truncating the value), + // so it's a bad format delimiter, anyway + var separators = format.replace(this.validParts, '\0').split('\0'), + parts = format.match(this.validParts); + if (!separators || !separators.length || !parts || parts.length === 0){ + throw new Error("Invalid date format."); + } + return {separators: separators, parts: parts}; + }, + parseDate: function(date, format, language){ + if (!date) + return undefined; + if (date instanceof Date) + return date; + if (typeof format === 'string') + format = DPGlobal.parseFormat(format); + var part_re = /([\-+]\d+)([dmwy])/, + parts = date.match(/([\-+]\d+)([dmwy])/g), + part, dir, i; + if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){ + date = new Date(); + for (i=0; i < parts.length; i++){ + part = part_re.exec(parts[i]); + dir = parseInt(part[1]); + switch (part[2]){ + case 'd': + date.setUTCDate(date.getUTCDate() + dir); + break; + case 'm': + date = Datepicker.prototype.moveMonth.call(Datepicker.prototype, date, dir); + break; + case 'w': + date.setUTCDate(date.getUTCDate() + dir * 7); + break; + case 'y': + date = Datepicker.prototype.moveYear.call(Datepicker.prototype, date, dir); + break; + } + } + return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0); + } + parts = date && date.match(this.nonpunctuation) || []; + date = new Date(); + var parsed = {}, + setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'], + setters_map = { + yyyy: function(d,v){ + return d.setUTCFullYear(v); + }, + yy: function(d,v){ + return d.setUTCFullYear(2000+v); + }, + m: function(d,v){ + if (isNaN(d)) + return d; + v -= 1; + while (v < 0) v += 12; + v %= 12; + d.setUTCMonth(v); + while (d.getUTCMonth() !== v) + d.setUTCDate(d.getUTCDate()-1); + return d; + }, + d: function(d,v){ + return d.setUTCDate(v); + } + }, + val, filtered; + setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m']; + setters_map['dd'] = setters_map['d']; + date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0); + var fparts = format.parts.slice(); + // Remove noop parts + if (parts.length !== fparts.length){ + fparts = $(fparts).filter(function(i,p){ + return $.inArray(p, setters_order) !== -1; + }).toArray(); + } + // Process remainder + function match_part(){ + var m = this.slice(0, parts[i].length), + p = parts[i].slice(0, m.length); + return m === p; + } + if (parts.length === fparts.length){ + var cnt; + for (i=0, cnt = fparts.length; i < cnt; i++){ + val = parseInt(parts[i], 10); + part = fparts[i]; + if (isNaN(val)){ + switch (part){ + case 'MM': + filtered = $(dates[language].months).filter(match_part); + val = $.inArray(filtered[0], dates[language].months) + 1; + break; + case 'M': + filtered = $(dates[language].monthsShort).filter(match_part); + val = $.inArray(filtered[0], dates[language].monthsShort) + 1; + break; + } + } + parsed[part] = val; + } + var _date, s; + for (i=0; i < setters_order.length; i++){ + s = setters_order[i]; + if (s in parsed && !isNaN(parsed[s])){ + _date = new Date(date); + setters_map[s](_date, parsed[s]); + if (!isNaN(_date)) + date = _date; + } + } + } + return date; + }, + formatDate: function(date, format, language){ + if (!date) + return ''; + if (typeof format === 'string') + format = DPGlobal.parseFormat(format); + var val = { + d: date.getUTCDate(), + D: dates[language].daysShort[date.getUTCDay()], + DD: dates[language].days[date.getUTCDay()], + m: date.getUTCMonth() + 1, + M: dates[language].monthsShort[date.getUTCMonth()], + MM: dates[language].months[date.getUTCMonth()], + yy: date.getUTCFullYear().toString().substring(2), + yyyy: date.getUTCFullYear() + }; + val.dd = (val.d < 10 ? '0' : '') + val.d; + val.mm = (val.m < 10 ? '0' : '') + val.m; + date = []; + var seps = $.extend([], format.separators); + for (var i=0, cnt = format.parts.length; i <= cnt; i++){ + if (seps.length) + date.push(seps.shift()); + date.push(val[format.parts[i]]); + } + return date.join(''); + }, + headTemplate: '<thead>'+ + '<tr>'+ + '<th class="prev">«</th>'+ + '<th colspan="5" class="datepicker-switch"></th>'+ + '<th class="next">»</th>'+ + '</tr>'+ + '</thead>', + contTemplate: '<tbody><tr><td colspan="7"></td></tr></tbody>', + footTemplate: '<tfoot>'+ + '<tr>'+ + '<th colspan="7" class="today"></th>'+ + '</tr>'+ + '<tr>'+ + '<th colspan="7" class="clear"></th>'+ + '</tr>'+ + '</tfoot>' + }; + DPGlobal.template = '<div class="datepicker">'+ + '<div class="datepicker-days">'+ + '<table class=" table-condensed">'+ + DPGlobal.headTemplate+ + '<tbody></tbody>'+ + DPGlobal.footTemplate+ + '</table>'+ + '</div>'+ + '<div class="datepicker-months">'+ + '<table class="table-condensed">'+ + DPGlobal.headTemplate+ + DPGlobal.contTemplate+ + DPGlobal.footTemplate+ + '</table>'+ + '</div>'+ + '<div class="datepicker-years">'+ + '<table class="table-condensed">'+ + DPGlobal.headTemplate+ + DPGlobal.contTemplate+ + DPGlobal.footTemplate+ + '</table>'+ + '</div>'+ + '</div>'; + + $.fn.datepicker.DPGlobal = DPGlobal; + + + /* DATEPICKER NO CONFLICT + * =================== */ + + $.fn.datepicker.noConflict = function(){ + $.fn.datepicker = old; + return this; + }; + + + /* DATEPICKER DATA-API + * ================== */ + + $(document).on( + 'focus.datepicker.data-api click.datepicker.data-api', + '[data-provide="datepicker"]', + function(e){ + var $this = $(this); + if ($this.data('datepicker')) + return; + e.preventDefault(); + // component click requires us to explicitly show it + $this.datepicker('show'); + } + ); + $(function(){ + $('[data-provide="datepicker-inline"]').datepicker(); + }); }(window.jQuery)); diff --git a/js/core.js b/js/core.js index 4ba26e9e..0472981b 100644 --- a/js/core.js +++ b/js/core.js @@ -2,14 +2,56 @@ $(document).ready(function() { var lang = $('html').attr('lang'); // Datepicker - $('.input-group.date').datepicker({ - format: "dd/mm/yyyy", - todayBtn: "linked", - orientation: "top left", - autoclose: true, - language: lang + var framadatepicker = function() { + $('.input-group.date').datepicker({ + format: "dd/mm/yyyy", + todayBtn: "linked", + orientation: "top left", + autoclose: true, + language: lang, + todayHighlight: true, + beforeShowDay: function (date){ + var $selected_days = new Array(); + $('#selected-days input[id^="day"]').each(function() { + if($(this).val()!='') { + $selected_days.push($(this).val()); + } + }); + for(i = 0; i < $selected_days.length; i++){ + var $selected_date = $selected_days[i].split('/'); + + if (date.getFullYear() == $selected_date[2] && (date.getMonth()+1) == $selected_date[1] && date.getDate() == $selected_date[0]){ + return { + classes: 'disabled selected' + }; + } + } + } + }); + }; + + + var datepickerfocus = false; // a11y : datepicker not display on focus until there is one click on the button + + $(document).on('click','.input-group.date .input-group-addon', function() { + datepickerfocus = true; + // Re-init datepicker config before displaying + $(this).parent().datepicker(framadatepicker()); + $(this).parent().datepicker('show'); + + // Trick to refresh calendar + $('.datepicker-days .prev').trigger('click'); + $('.datepicker-days .next').trigger('click'); + // .active must be clicable in order to unfill the form + $('.datepicker-days .active').removeClass('disabled'); }); + $(document).on('focus','.input-group.date input', function() { + if(datepickerfocus) { + $(this).parent('.input-group.date').datepicker(framadatepicker()); + $(this).parent('.input-group.date').datepicker('show'); + } + }); /** * choix_date.php **/ @@ -95,6 +137,7 @@ $(document).ready(function() { $(this).addClass('disabled'); } }; + SubmitDaysAvalaible(); }); // Button "Add a day" @@ -116,28 +159,17 @@ $(document).ready(function() { last_day.after('<fieldset>'+new_day_html+'</fieldset>'); $('#day'+(nb_days)).focus(); $('#remove-a-day, #copyhours').removeClass('disabled'); - - // Repeat datepicker init (junk code but it works for added days) - $('.input-group.date').datepicker({ - format: "dd/mm/yyyy", - todayBtn: "linked", - orientation: "top left", - autoclose: true, - language: lang - }); - }); // Button "Remove a day" $('#remove-a-day').on('click', function() { - var nb_days = $('#selected-days fieldset').length; - $('#selected-days fieldset:last').remove(); + var nb_days = $('#selected-days fieldset').length; $('#day'+(nb_days-1)).focus(); if ( nb_days == 1) { $('#remove-a-day, #copyhours').addClass('disabled'); }; - + SubmitDaysAvalaible(); }); // Title update on hours and buttons -/+ hours @@ -180,8 +212,8 @@ $(document).ready(function() { } } - $(document).on('change','.hours, #selected-days fieldset legend input', function() { - SubmitDaysAvalaible() + $(document).on('keyup, change','.hours, #selected-days fieldset legend input', function() { + SubmitDaysAvalaible(); }); SubmitDaysAvalaible(); @@ -220,14 +252,13 @@ $(document).ready(function() { // Button "Remove a choice" $('#remove-a-choice').on('click', function() { - var nb_choices = $('.choice-field').length; - $('.choice-field:last').remove(); - $('#choice'+(nb_choices-2)).focus(); - if (nb_choices == 3) { - $('#remove-a-choice, button[name="fin_sondage_autre"]').addClass('disabled'); + var nb_choices = $('.choice-field').length; + $('#choice'+(nb_choices-1)).focus(); + if (nb_choices == 2) { + $('#remove-a-choice').addClass('disabled'); }; - + SubmitChoicesAvalaible(); }); // 2 choices filled and you can submit @@ -245,11 +276,31 @@ $(document).ready(function() { } } - $(document).on('change','.choice-field input', function() { - SubmitChoicesAvalaible() + $(document).on('keyup, change','.choice-field input', function() { + SubmitChoicesAvalaible(); }); SubmitChoicesAvalaible(); + $(document).on('click', '.md-a-img', function() { + $('#md-a-imgModal').modal('show'); + $('#md-a-imgModal .btn-primary').attr('value',$(this).prev().attr('id')); + }); + $('#md-a-imgModal .btn-primary').on('click', function() { + if($('#md-img').val()!='' && $('#md-a').val()!='') { + $('#'+$(this).val()).val('[.val()+')]('+$('#md-a').val()+')'); + } else if ($('#md-img').val()!='') { + $('#'+$(this).val()).val('.val()+')'); + } else if ($('#md-a').val()!='') { + $('#'+$(this).val()).val('['+$('#md-text').val()+']('+$('#md-a').val()+')'); + } else { + $('#'+$(this).val()).val($('#md-text').val()); + } + $('#md-a-imgModal').modal('hide'); + $('#md-img').val(''); $('#md-a').val('');$('#md-text').val(''); + }); + + + /** * adminstuds.php **/ @@ -296,4 +347,67 @@ $(document).ready(function() { return false; }); + $('#poll-rules-form .btn-edit').on('click', function() { + $('#poll-rules-form p').hide(); + $('#poll-rules-form .js-poll-rules').removeClass("hidden"); + $('.js-poll-rules select').focus(); + return false; + }); + + $('#poll-rules-form .btn-cancel').on('click', function() { + $('#poll-rules-form p').show(); + $('#poll-rules-form .js-poll-rules').addClass("hidden"); + $('.js-poll-rules .btn-edit').focus(); + return false; + }); + + // Horizontal scroll buttons + if($('.results').width() > $('.container').width()) { + $('.scroll-buttons').removeClass('hidden'); + } + + var $scroll_page = 1; + var $scroll_scale = $('#tableContainer').width()*2/3; + + $('.scroll-left').addClass('disabled'); + + $('.scroll-left').click(function(){ + $('.scroll-right').removeClass('disabled'); + $( "#tableContainer" ).animate({ + scrollLeft: $scroll_scale*($scroll_page-1) + }, 1000); + if($scroll_page == 1) { + $(this).addClass('disabled'); + } else { + $scroll_page = $scroll_page-1; + } + return false; + }); + $('.scroll-right').click(function(){ + $('.scroll-left').removeClass('disabled'); + $( "#tableContainer" ).animate({ + scrollLeft: $scroll_scale*($scroll_page) + }, 1000); + + if($scroll_scale*($scroll_page+1) > $( ".results" ).width()) { + $(this).addClass('disabled'); + } else { + $scroll_page++; + } + return false; + }); + +}); + +// Vote form moving to the top or to the bottom +$(window).scroll(function() { + var $table_offset = $('.results thead').offset(); + if($table_offset != undefined && $(window).scrollTop() < $table_offset.top) { + $('.results tbody').prepend($('#vote-form')); + $('#tableContainer').before($('.scroll-buttons')); + } else { + $('#addition').before($('#vote-form')); + $('#tableContainer').after($('.scroll-buttons')); + } + }); diff --git a/locale/fr_FR/LC_MESSAGES/Studs.mo b/locale/fr_FR/LC_MESSAGES/Studs.mo index d18288035b93332ae163a6904a396d897fa1d409..24470428c56647ac18659ee62cd002b9d008d641 100644 GIT binary patch literal 18559 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 C^2GK4 delta 6278 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 M$2Yk6mO`@r3o;PWuK)l5 diff --git a/locale/fr_FR/LC_MESSAGES/Studs.po b/locale/fr_FR/LC_MESSAGES/Studs.po index 80c85775..130647cf 100644 --- a/locale/fr_FR/LC_MESSAGES/Studs.po +++ b/locale/fr_FR/LC_MESSAGES/Studs.po @@ -21,6 +21,9 @@ msgstr "" msgid "Make your polls" msgstr "Organiser des rendez-vous simplement, librement." +msgid "Home" +msgstr "Accueil" + msgid "Poll" msgstr "Sondage" @@ -45,6 +48,12 @@ msgstr "Modifier" msgid "Next" msgstr "Continuer" +msgid "Back" +msgstr "Précédent" + +msgid "Close" +msgstr "Fermer" + msgid "Your name" msgstr "Votre nom" @@ -55,7 +64,7 @@ msgid "Description" msgstr "Description" msgid "Back to the homepage of " -msgstr "Retournez à la page d'accueil de" +msgstr "Retourner à la page d'accueil de" msgid "Error!" msgstr "Erreur !" @@ -79,30 +88,80 @@ msgstr "Changer la langue" msgid "Select the language" msgstr "Choisir la langue" -########### Footer ########### -msgid "Home" -msgstr "Accueil" - -msgid "About" -msgstr "Informations générales" - -msgid "Contact" -msgstr "Contact" - ############ Homepage ############ msgid "Schedule an event" msgstr "Créer un sondage spécial dates" -msgid "Make a poll" +msgid "Make a classic poll" msgstr "Créer un sondage classique" -msgid "or" -msgstr "ou" +# 1st section +msgid "What is that?" +msgstr "Prise en main" + +msgid "Framadate is an online service for planning an appointment or make a decision quickly and easily. No registration is required." +msgstr "Framadate est un service en ligne permettant de planifier un rendez-vous ou prendre des décisions rapidement et simplement. Aucune inscription préalable n’est nécessaire." + +msgid "Here is how it works:" +msgstr "Voici comment ça fonctionne :" + +msgid "Make a poll" +msgstr "Créez un sondage" + +msgid "Define dates or subjects to choose" +msgstr "Déterminez les dates ou les sujets à choisir" + +msgid "Send the poll link to your friends or colleagues" +msgstr "Envoyez le lien du sondage à vos amis ou collègues" + +msgid "Discuss and make a decision" +msgstr "Discutez et prennez votre décision" + +msgid "Do you want to " +msgstr "Voulez-vous " + +msgid "view an example?" +msgstr "voir un exemple ?" + +# 2nd section +msgid "The software" +msgstr "Le logiciel" + +msgid "Framadate was initially based on " +msgstr "Framadate est initialement basé sur " + +msgid " a software developed by the University of Strasbourg. Today, it is devevoped by the association Framasoft" +msgstr " un logiciel développé par l'Université de Strasbourg. Aujourd'hui, son développement est assuré par l’association Framasoft" -msgid "view an example" -msgstr "voir un exemple" +msgid "This software needs javascript and cookies enabled. It is compatible with the following web browsers:" +msgstr "Ce logiciel requiert l’activation du javascript et des cookies. Il est compatible avec les navigateurs web suivant :" + +msgid "It is governed by the " +msgstr "Il est régi par la " + +msgid "CeCILL-B license" +msgstr "licence CeCILL-B" + +# 3rd section +msgid "Cultivate your garden" +msgstr "Cultivez votre jardin" + +msgid "To participate in the software development, suggest improvements or simply download it, please visit " +msgstr "Pour participer au développement du logiciel, proposer des améliorations ou simplement le télécharger, rendez-vous sur " + +msgid "the development site" +msgstr "le site de développement" + +msgid "If you want to install the software for your own use and thus increase your independence, we help you on:" +msgstr "Si vous souhaitez installer ce logiciel pour votre propre usage et ainsi gagner en autonomie, nous vous aidons sur :" ############## Poll ############## +msgid "Poll administration" +msgstr "Administration du sondage" + +msgid "Legend:" +msgstr "Légende :" + # Jumbotron adminstuds.php (+ studs.php) msgid "Back to the poll" msgstr "Retour au sondage" @@ -158,6 +217,27 @@ msgstr "Lien public du sondage" msgid "Admin link of the pool" msgstr "Lien d'administration du sondage" +msgid "Poll rules" +msgstr "Permissions du sondage" + +msgid "Edit the poll rules" +msgstr "Modifier les permissions du sondage" + +msgid "Votes and comments are locked" +msgstr "Les votes et commentaires sont verrouillés" + +msgid "Votes and comments are open" +msgstr "Les votes et commentaires sont ouverts" + +msgid "Votes are editable" +msgstr "Les votes sont modifiables" + +msgid "Save the new rules" +msgstr "Enregistrer les nouvelles permissions" + +msgid "Cancel the rules edit" +msgstr "Annuler le changement de permissions" + # Help text adminstuds.php msgid "As poll administrator, you can change all the lines of this poll with this button " msgstr "En tant qu'administrateur, vous pouvez modifier toutes les lignes de ce sondage avec ce bouton " @@ -176,6 +256,9 @@ msgid "If you want to vote in this poll, you have to give your name, choose the msgstr "Pour participer à ce sondage, veuillez entrer votre nom, choisir toutes les valeurs qui vous conviennent et valider votre choix avec le bouton en bout de ligne." # Poll results +msgid "Votes of the poll " +msgstr "Votes du sondage " + msgid "Remove the column" msgstr "Effacer la colonne" @@ -233,6 +316,15 @@ msgstr "votes" msgid "for" msgstr "à " +msgid "Remove all the votes" +msgstr "Supprimer tous les votes" + +msgid "Scroll to the left" +msgstr "Faire défiler à gauche" + +msgid "Scroll to the right" +msgstr "Faire défiler à droite" + # Comments msgid "Comments of polled people" msgstr "Commentaires de sondés" @@ -252,6 +344,9 @@ msgstr "Envoyer le commentaire" msgid "anonyme" msgstr "anonyme" +msgid "Remove all the comments" +msgstr "Supprimer tous les commentaires" + # Add a colum adminstuds.php msgid "Column's adding" msgstr "Ajout de colonne" @@ -320,6 +415,9 @@ msgstr "Vous souhaitez que les sondés puissent modifier leur ligne eux-mêmes." msgid "To receive an email for each new vote." msgstr "Vous souhaitez recevoir un mail à chaque participation d'un sondé." +msgid "Go to step 2" +msgstr "Aller à l'étape 2" + # Errors info_sondage.php msgid "Enter a title" msgstr "Il faut saisir un titre !" @@ -337,6 +435,9 @@ msgstr "L'adresse saisie n'est pas correcte ! (Il faut une adresse valide pour r msgid "You haven't filled the first section of the poll creation." msgstr "Vous n'avez pas renseigné la première page du sondage" +msgid "Back to step 1" +msgstr "Revenir à l’étape 1" + ########### Step 2 ########### # Step 2 choix_date.php msgid "Poll dates (2 on 3)" @@ -391,15 +492,42 @@ msgstr "Pour créer un sondage classique, vous devez proposer au moins deux choi msgid "You can add or remove additional choices with the buttons" msgstr "Vous pouvez ajouter ou supprimer des choix supplémentaires avec les boutons" +msgid "It's possible to propose links or images by using " +msgstr "Il est possible d’insérer des liens ou des images en utilisant " + +msgid "the Markdown syntax" +msgstr "la syntaxe Markdown" + msgid "Choice" msgstr "Choix" +msgid "Add a link or an image" +msgstr "Ajouter un lien ou une image" + +msgid "These fields are optional. You can add a link, an image or both." +msgstr "Ces champs sont optionnels. Vous pouvez ajouter un lien, une image ou les deux." + +msgid "URL of the image" +msgstr "URL de l'image" + +msgid "Link" +msgstr "Lien" + +msgid "Alternative text" +msgstr "Texte alternatif" + msgid "Remove a choice" msgstr "Supprimer un choix" msgid "Add a choice" msgstr "Ajouter un choix" +msgid "Back to step 2" +msgstr "Revenir à l’étape 2" + +msgid "Go to step 3" +msgstr "Aller à l’étape 3" + ########### Step 3 ########### msgid "Removal date and confirmation (3 on 3)" msgstr "Date d'expiration et confirmation (3 sur 3)" @@ -407,6 +535,9 @@ msgstr "Date d'expiration et confirmation (3 sur 3)" msgid "Confirm the creation of your poll" msgstr "Confirmez la création de votre sondage" +msgid "List of your choices" +msgstr "Liste de vos choix" + msgid "Once you have confirmed the creation of your poll, you will be automatically redirected on the administration page of your poll." msgstr "Une fois que vous aurez confirmé la création du sondage, vous serez redirigé automatiquement vers la page d'administration de votre sondage." @@ -417,15 +548,15 @@ msgid "Create the poll" msgstr "Créer le sondage" # Step 3 choix_date.php -msgid "Your poll will expire automatically 2 days after the last date of your poll." -msgstr "Votre sondage sera automatiquement effacé après la date la plus tardive." +msgid "Your poll will be automatically removed 6 months after the last date of your poll:" +msgstr "Votre sondage sera automatiquement effacé 6 mois après la date la plus tardive :" msgid "Removal date:" msgstr "Date de suppression :" # Step 3 choix_autre.php -msgid "Your poll will be automatically removed after 6 months." -msgstr "Votre sondage sera automatiquement effacé dans 6 mois." +msgid "Your poll will be automatically removed after 6 months:" +msgstr "Votre sondage sera automatiquement effacé dans 6 mois :" msgid "You can fix another removal date for it." msgstr "Néanmoins vous pouvez décider ci-dessous d'une date plus rapprochée pour la suppression de votre sondage." @@ -433,29 +564,6 @@ msgstr "Néanmoins vous pouvez décider ci-dessous d'une date plus rapprochée p msgid "Removal date (optional)" msgstr "Date de fin (facultative)" -########### Contact ######### -msgid "Contact us" -msgstr "Nous contacter" - -msgid "If you have questions, you can send a message here." -msgstr "Pour toutes questions ou suggestions vous pouvez laisser un message via ce formulaire." - -msgid "Question" -msgstr "Question" - -msgid "Send your question" -msgstr "Envoyer votre question" - -msgid "Your message has been sent!" -msgstr "Votre message a bien été envoyé !" - -# Errors contact.php -msgid "The address is not correct!" -msgstr "L'adresse saisie n'est pas correcte !" - -msgid "You must ask a question!" -msgstr "Vous devez poser au moins une question !" - ############# Admin ############# msgid "Polls administrator" msgstr "Administrateur de la base" @@ -512,57 +620,28 @@ msgstr "" msgid "Thanks for your confidence." msgstr "Merci de votre confiance." -# Mails adminstuds.php -msgid "[ADMINISTRATOR] New title for your poll" -msgstr "[ADMINISTRATEUR] Changement du titre du sondage avec " - -msgid "" -"You have changed the title of your poll. \n" -"You can modify this poll with this link" -msgstr "" -"Vous avez modifié le titre de votre sondage. \n" -"Vous pouvez modifier ce sondage au lien suivant" - -msgid "[ADMINISTRATOR] New description for your poll" -msgstr "[ADMINISTRATEUR] Changement de description de votre sondage " +msgid "\n" +"--\n\n" +"« La route est longue, mais la voie est libre… »\n" +"Framasoft ne vit que par vos dons (déductibles des impôts).\n" +"Merci d'avance pour votre soutien http://soutenir.framasoft.org." +msgstr "\n" +"--\n\n" +"« La route est longue, mais la voie est libre… »\n" +"Framasoft ne vit que par vos dons (déductibles des impôts).\n" +"Merci d'avance pour votre soutien http://soutenir.framasoft.org." -msgid "" -"You have changed the description of your poll. \n" -"You can modify this poll with this link" -msgstr "" -"Vous avez modifié la description de votre sondage. \n" -"Vous pouvez modifier ce sondage au lien suivant" - -msgid "[ADMINISTRATOR] New email address for your poll" -msgstr "[ADMINISTRATEUR] Changement d'adresse électronique de l'administrateur avec " +# Mails adminstuds.php +msgid "[ADMINISTRATOR] New settings for your poll" +msgstr "[ADMINISTRATEUR] Changement de configuration du sondage" msgid "" -"You have changed your email address in your poll. \n" +"You have changed the settings of your poll. \n" "You can modify this poll with this link" msgstr "" -"Vous avez modifié l'adresse mail associé à votre sondage. \n" +"Vous avez modifié la configuration de votre sondage. \n" "Vous pouvez modifier ce sondage au lien suivant" -msgid "[ADMINISTRATOR] Removing of your poll" -msgstr "[ADMINISTRATEUR] Suppression de sondage" - -msgid "" -"You have removed your poll. \n" -"You can make new polls with this link" -msgstr "" -"Vous supprimé un sondage. \n" -"Vous pouvez faire de nouveaux sondages au lien suivant" - -msgid "[ADMINISTRATOR] New column for your poll" -msgstr "[ADMINISTRATEUR] Ajout d'une nouvelle colonne au sondage " - -msgid "" -"You have added a new column in your poll. \n" -"You can inform the voters of this change with this link" -msgstr "" -"Vous avez ajouté une colonne à votre sondage. \n" -"Vous pouvez informer vos utilisateurs de ce changement en leur envoyant l'adresse suivante" - # Mails creation_sondage.php msgid "" "This is the message you have to send to the people you want to poll. \n" @@ -591,28 +670,3 @@ msgstr "Réservé à l'auteur" msgid "For sending to the polled users" msgstr "Pour diffusion aux sondés" - -# Mails contact.php -msgid "[CONTACT] You have sent a question " -msgstr "[CONTACT] Envoi de question " - -msgid "You have a question from a user " -msgstr "Vous avez une question d'utilisateur de " - -msgid "User" -msgstr "Utilisateur" - -msgid "User's email address" -msgstr "Adresse utilisateur" - -msgid "Message" -msgstr "Message" - -msgid "[COPY] Someone has sent a question " -msgstr "[COPIE] Envoi de question " - -msgid "Here is a copy of your question" -msgstr "Voici une copie de votre question" - -msgid "We're going to answer your question shortly." -msgstr "Nous allons prendre en compte votre message rapidement." diff --git a/studs.php b/studs.php index 425ec853..7abd5a6b 100644 --- a/studs.php +++ b/studs.php @@ -320,7 +320,7 @@ $td_headers = array(); // for a11y, headers="M1 D4 H5" on each td $radio_title = array(); // date for // Dates poll -if ($dsondage->format=="D"||$dsondage->format=="D+") { +if ($dsondage->format=="D"||$dsondage->format=="D+"||$dsondage->format=="D-") { $tr_months = '<tr><th role="presentation"></th>'; $tr_days = '<tr><th role="presentation"></th>'; @@ -366,7 +366,7 @@ if ($dsondage->format=="D"||$dsondage->format=="D+") { $hour = substr($current, strpos($current, '@')-count($current)+2); if ($hour != "") { - $tr_hours .= '<th class="bg-info'.$rbd.'" id="H'.$i.'">'.$hour.'</th>'; + $tr_hours .= '<th class="bg-info'.$rbd.'" id="H'.$i.'" title="'.$hour.'">'.$hour.'</th>'; $radio_title[$i] .= ' - '.$hour; $td_headers[$i] .= ' H'.$i; } else { @@ -396,11 +396,35 @@ if ($dsondage->format=="D"||$dsondage->format=="D+") { $td_headers[$i]='';$radio_title[$i]=''; // init before concatenate // Subjects - $tr_subjects .= '<th class="bg-info" id="S'.preg_replace("/[^a-zA-Z0-9]_+/", "", stripslashes($toutsujet[$i])).'">'.stripslashes($toutsujet[$i]).'</th>'; + preg_match_all('/\[!\[(.*?)\]\((.*?)\)\]\((.*?)\)/',$toutsujet[$i],$md_a_img); // Markdown [](href) + preg_match_all('/!\[(.*?)\]\((.*?)\)/',$toutsujet[$i],$md_img); // Markdown  + preg_match_all('/\[(.*?)\]\((.*?)\)/',$toutsujet[$i],$md_a); // Markdown [text](href) + if (isset($md_a_img[2][0]) && $md_a_img[2][0]!='' && isset($md_a_img[3][0]) && $md_a_img[3][0]!='') { // [](href) + + $th_subject_text = (isset($md_a_img[1][0]) && $md_a_img[1][0]!='') ? stripslashes($md_a_img[1][0]) : _("Choice") .' '.($i+1); + $th_subject_html = '<a href="'.$md_a_img[3][0].'"><img src="'.$md_a_img[2][0].'" class="img-responsive" alt="'.$th_subject_text.'" /></a>'; + + } elseif (isset($md_img[2][0]) && $md_img[2][0]!='') { //  + + $th_subject_text = (isset($md_img[1][0]) && $md_img[1][0]!='') ? stripslashes($md_img[1][0]) : _("Choice") .' '.($i+1); + $th_subject_html = '<img src="'.$md_img[2][0].'" class="img-responsive" alt="'.$th_subject_text.'" />'; + + } elseif (isset($md_a[2][0]) && $md_a[2][0]!='') { // [text](href) + + $th_subject_text = (isset($md_a[1][0]) && $md_a[1][0]!='') ? stripslashes($md_a[1][0]) : _("Choice") .' '.($i+1); + $th_subject_html = '<a href="'.$md_a[2][0].'">'.$th_subject_text.'</a>'; + + } else { // text only + + $th_subject_text = stripslashes($toutsujet[$i]); + $th_subject_html = $th_subject_text; + + } + $tr_subjects .= '<th class="bg-info" id="S'.$i.'" title="'.$th_subject_text.'">'.$th_subject_html.'</th>'; $border[$i] = false; - $td_headers[$i] .= stripslashes($toutsujet[$i]); - $radio_title[$i] .= stripslashes($toutsujet[$i]); + $td_headers[$i] .= 'S'.$i; + $radio_title[$i] .= $th_subject_text; } @@ -411,13 +435,35 @@ if ($dsondage->format=="D"||$dsondage->format=="D+") { echo ' <form name="formulaire" action="' . Utils::getUrlSondage($dsondage->id_sondage) . '" method="POST"> <input type="hidden" name="sondage" value="' . $numsondage . '"/> - +'; +if ($dsondage->format=="A-" || $dsondage->format=="D-") { + echo ' + <div class="alert alert-danger"> + <p>' . _("The administrator locked this poll, votes and comments are frozen, it's not possible to participate anymore.") . '</p> + <p><b>' . _('Legend:'). '</b> <span class="glyphicon glyphicon-ok"></span> =' . _('Yes') . ', <b>(<span class="glyphicon glyphicon-ok"></span>)</b> = ' . _('Ifneedbe') . ', <span class="glyphicon glyphicon-ban-circle"></span> = ' . _('No') . '</span></p> + </div>'; +} else { + echo ' <div class="alert alert-info"> <p>' . _("If you want to vote in this poll, you have to give your name, choose the values that fit best for you and validate with the plus button at the end of the line.") . '</p> + <p><b>' . _('Legend:'). '</b> <span class="glyphicon glyphicon-ok"></span> =' . _('Yes') . ', <b>(<span class="glyphicon glyphicon-ok"></span>)</b> = ' . _('Ifneedbe') . ', <span class="glyphicon glyphicon-ban-circle"></span> = ' . _('No') . '</span></p> + </div>'; +} +echo' + <div class="hidden row scroll-buttons" aria-hidden="true"> + <div class="btn-group pull-right"> + <button class="btn btn-sm btn-link scroll-left" title="' . _('Scroll to the left') . '"> + <span class="glyphicon glyphicon-chevron-left"></span> + </button> + <button class="btn btn-sm btn-link scroll-right" title="' . _('Scroll to the right') . '"> + <span class="glyphicon glyphicon-chevron-right"></span> + </button> + </div> </div> + <div id="tableContainer" class="tableContainer"> <table class="results"> - <caption>'._('Votes of the poll ').$title.'</caption> + <caption class="sr-only">'._('Votes of the poll ').$title.'</caption> <thead>'. $thead . '</thead> <tbody>'; @@ -499,8 +545,12 @@ while ($data = $user_studs->FetchNextObject(false)) { //a la fin de chaque ligne se trouve les boutons modifier if ($compteur != $ligneamodifier && ($dsondage->format=="A+"||$dsondage->format=="D+") && $mod_ok) { - echo '<td><button type="submit" class="btn btn-link btn-sm" name="modifierligne'.$compteur.'" title="'. _('Edit the line:') .' '.stripslashes($nombase).'"> - <span class="glyphicon glyphicon-pencil"></span></button></td>'."\n"; + echo ' + <td> + <button type="submit" class="btn btn-link btn-sm" name="modifierligne'.$compteur.'" title="'. _('Edit the line:') .' '.stripslashes($nombase).'"> + <span class="glyphicon glyphicon-pencil"></span><span class="sr-only">' . _('Edit') . '</span> + </button> + </td>'."\n"; } //demande de confirmation pour modification de ligne @@ -517,7 +567,7 @@ while ($data = $user_studs->FetchNextObject(false)) { } // affichage de la ligne pour un nouvel utilisateur -if (( !(USE_REMOTE_USER && isset($_SERVER['REMOTE_USER'])) || !$user_mod) && $ligneamodifier==-1) { +if (( !(USE_REMOTE_USER && isset($_SERVER['REMOTE_USER'])) || !$user_mod) && $ligneamodifier==-1 && ($dsondage->format!="A-" && $dsondage->format!="D-")) { //affichage de la case vide de texte pour un nouvel utilisateur echo '<tr id="vote-form"> <td class="bg-info" style="padding:5px"> @@ -562,71 +612,56 @@ if (( !(USE_REMOTE_USER && isset($_SERVER['REMOTE_USER'])) || !$user_mod) && $li // Addition and Best choice //affichage de la ligne contenant les sommes de chaque colonne -$tr_addition = '<tr><td>'. _("Addition") .'</td>'; -$tr_bestchoice = '<tr><td></td>'; -$meilleurecolonne = 0; - -for ($i = 0; $i < $nbcolonnes; $i++) { - if (isset($somme[$i]) && $somme[$i] > 0 ) { - if (isset($somme[$i]) && $somme[$i] > $meilleurecolonne){ - $meilleurecolonne = $somme[$i]; - } - $tr_addition .= '<td>'.$somme[$i].'</td>'; - } else { - $tr_addition .= '<td></td>'; - } -} -$tr_addition .= '<td></td></tr>'; - -//recuperation des valeurs des sujets et adaptation pour affichage -$toutsujet = explode(",", $dsondage->sujet); - +$tr_addition = '<tr id="addition"><td>'. _("Addition") .'</td>'; +$meilleurecolonne = max($somme); $compteursujet = 0; $meilleursujet = '<ul style="list-style:none">'; for ($i = 0; $i < $nbcolonnes; $i++) { + if (isset($somme[$i]) && $somme[$i] > 0 ) { + if (in_array($i, array_keys($somme, max($somme)))){ - if (isset($somme[$i]) && $somme[$i] > 0 && $somme[$i] == $meilleurecolonne){ - $tr_bestchoice .= '<td><span class="glyphicon glyphicon-star text-warning"></span></td>'; + $tr_addition .= '<td><span class="glyphicon glyphicon-star text-warning"></span><span>'.$somme[$i].'</span></td>'; - if ($dsondage->format == "D" || $dsondage->format == "D+") { - $meilleursujetexport = $toutsujet[$i]; + $meilleursujet.= '<li><b>'.$radio_title[$i].'</b></li>'; + $compteursujet++; - if (strpos($toutsujet[$i], '@') !== false) { - $toutsujetdate = explode("@", $toutsujet[$i]); - $meilleursujet .= '<li><b>'.strftime(_("%A, den %e. %B %Y"),$toutsujetdate[0]). ' - ' . $toutsujetdate[1].'</b></li>'; - } else { - $meilleursujet .= '<li><b>'.strftime(_("%A, den %e. %B %Y"),$toutsujet[$i]).'</b></li>'; - } } else { - $meilleursujet.= '<li><b>'.$toutsujet[$i].'</b></li>'; + $tr_addition .= '<td>'.$somme[$i].'</td>'; } - $compteursujet++; - } else { - $tr_bestchoice .= '<td></td>'; + $tr_addition .= '<td></td>'; } } -$tr_bestchoice .= '<td></td></tr>'; +$tr_addition .= '<td></td></tr>'; $meilleursujet = str_replace("°", "'", $meilleursujet).'</ul>'; $vote_str = ($meilleurecolonne > 1) ? $vote_str = _('votes') : _('vote'); // Print Addition and Best choice -echo $tr_addition."\n".$tr_bestchoice.' +echo $tr_addition.' </tbody> </table> - <div class="col-sm-4 col-sm-offset-4"><p>'."\n"; + </div> + <div class="row">'."\n"; if ($compteursujet == 1) { - echo '<span class="glyphicon glyphicon-star text-warning"></span> ' . _("The best choice at this time is:") . '</p>' . $meilleursujet . '<p>' . _("with") . ' <b>' . $meilleurecolonne . '</b> ' . $vote_str . ".\n"; + echo ' + <div class="col-sm-6 col-sm-offset-3 alert alert-success"> + <p><span class="glyphicon glyphicon-star text-warning"></span> ' . _("The best choice at this time is:") . '</p> + ' . $meilleursujet . ' + <p>' . _("with") . ' <b>' . $meilleurecolonne . '</b> ' . $vote_str . '.</p> + </div>'."\n"; } elseif ($compteursujet > 1) { - echo '<span class="glyphicon glyphicon-star text-warning"></span> ' . _("The bests choices at this time are:") . '</p>' . $meilleursujet . '<p>' . _("with") . ' <b>' . $meilleurecolonne . '</b> ' . $vote_str . ".\n"; + echo ' + <div class="col-sm-6 col-sm-offset-3 alert alert-success"> + <p><span class="glyphicon glyphicon-star text-warning"></span> ' . _("The bests choices at this time are:") . '</p> + ' . $meilleursujet . ' + <p>' . _("with") . ' <b>' . $meilleurecolonne . '</b> ' . $vote_str . '.</p> + </div>'."\n"; } echo ' - </p></div> </div> - <hr />'; // Comments @@ -635,7 +670,7 @@ $sql = $connect->Prepare($sql); $comment_user=$connect->Execute($sql, array($numsondage)); if ($comment_user->RecordCount() != 0) { - echo '<div class="row"><h3>' . _("Comments of polled people") . '</h3>'."\n"; + echo '<div><h3>' . _("Comments of polled people") . '</h3>'."\n"; while($dcomment = $comment_user->FetchNextObject(false)) { echo ' @@ -647,8 +682,10 @@ if ($comment_user->RecordCount() != 0) { echo '</div>'; } + +if ($dsondage->format!="A-" && $dsondage->format!="D-") { echo ' - <div class="row hidden-print alert alert-info"> + <div class="hidden-print alert alert-info"> <div class="col-md-6 col-md-offset-3"> <fieldset id="add-comment"><legend>' . _("Add a comment in the poll") . '</legend> <div class="form-group"> @@ -661,10 +698,12 @@ echo ' <p class="text-center"><input type="submit" name="ajoutcomment" value="'. _("Send the comment") .'" class="btn btn-success"></p> </fieldset> </div> - </div> - </div> -</form> + <div class="clearfix"></div> + </div>'; +} -<a id="bas"></a>'; +echo ' + </div> +</form>'; bandeau_pied(); -- GitLab