public interface: rework
This commit is contained in:
parent
23dc467631
commit
37fa6a1955
@ -29,9 +29,15 @@ body {
|
|||||||
.point {
|
.point {
|
||||||
text-shadow: 0 0 20px #0055ff;
|
text-shadow: 0 0 20px #0055ff;
|
||||||
}
|
}
|
||||||
|
.navbar-inverse .point {
|
||||||
|
text-shadow: 0 0 12px #0055ff;
|
||||||
|
}
|
||||||
.end .point {
|
.end .point {
|
||||||
text-shadow: 0 0 20px #ff5500;
|
text-shadow: 0 0 20px #ff5500;
|
||||||
}
|
}
|
||||||
|
.navbar-inverse .end .point {
|
||||||
|
text-shadow: 0 0 12px #ff5500;
|
||||||
|
}
|
||||||
@-webkit-keyframes clockanim {
|
@-webkit-keyframes clockanim {
|
||||||
0% { opacity: 1.0; }
|
0% { opacity: 1.0; }
|
||||||
50% { opacity: 0; }
|
50% { opacity: 0; }
|
||||||
@ -107,3 +113,53 @@ h1 small.authors {
|
|||||||
transition-delay: 0.7s;
|
transition-delay: 0.7s;
|
||||||
transition-duration: 0s;
|
transition-duration: 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.carousel-indicators {
|
||||||
|
bottom: -10px;
|
||||||
|
}
|
||||||
|
.carousel-caption {
|
||||||
|
padding: 0;
|
||||||
|
position: static;
|
||||||
|
}
|
||||||
|
.carousel .table {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.carousel .table-condensed td {
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table th.frotated {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
.table th.rotated {
|
||||||
|
height: 100px;
|
||||||
|
width: 40px;
|
||||||
|
min-width: 40px;
|
||||||
|
max-width: 40px;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: bottom;
|
||||||
|
padding: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 0.9;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
th.rotated > div {
|
||||||
|
position: relative;
|
||||||
|
top: 0px;
|
||||||
|
left: -50px;
|
||||||
|
height: 100%;
|
||||||
|
transform: skew(45deg,0deg);
|
||||||
|
overflow: hidden;
|
||||||
|
border: 1px solid #000;
|
||||||
|
}
|
||||||
|
th.rotated div span {
|
||||||
|
transform: skew(-45deg,0deg) rotate(45deg);
|
||||||
|
position: absolute;
|
||||||
|
bottom: 40px;
|
||||||
|
left: -35px;
|
||||||
|
display: inline-block;
|
||||||
|
width: 110px;
|
||||||
|
text-align: left;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
@ -60,29 +60,81 @@ angular.module("FICApp")
|
|||||||
}
|
}
|
||||||
updTime();
|
updTime();
|
||||||
})
|
})
|
||||||
.controller("DataController", function($scope, $http, $rootScope, $timeout) {
|
.controller("EventsController", function($scope, $http, $interval) {
|
||||||
$rootScope.refresh = function() {
|
$scope.events = [];
|
||||||
$timeout.cancel($scope.cbd);
|
var refreshEvents = function() {
|
||||||
$scope.cbd = $timeout($rootScope.refresh, 4200);
|
$http.get("/events.json").then(function(response) {
|
||||||
$http.get("/demo.json").success(function(demo) {
|
if ($scope.lasteventsetag != undefined && $scope.lasteventsetag == response.headers().etag)
|
||||||
$scope.my = demo;
|
return;
|
||||||
});
|
$scope.lasteventsetag = response.headers().etag;
|
||||||
$http.get("/events.json").success(function(evts) {
|
|
||||||
var events = {};
|
var events = response.data;
|
||||||
var now = new Date();
|
var now = new Date();
|
||||||
angular.forEach(evts, function(event, key) {
|
var key = 0;
|
||||||
events["e" + event.id] = event;
|
angular.forEach($scope.events, function(event) {
|
||||||
event.since = now.getTime() - now.getTimezoneOffset() * 60000 - Date.parse(event.time);
|
event.keep = 0;
|
||||||
});
|
});
|
||||||
$scope.events = events;
|
angular.forEach(events, function(event) {
|
||||||
|
event.time = Date.parse(event.time);
|
||||||
|
//event.since = now.getTime() - now.getTimezoneOffset() * 60000 - event.time;
|
||||||
|
event.since = now.getTime() - event.time;
|
||||||
|
event.keep = 1;
|
||||||
|
while (key <= $scope.events.length) {
|
||||||
|
if (key >= $scope.events.length) {
|
||||||
|
$scope.events.push(event);
|
||||||
|
break;
|
||||||
|
} else if (event.id == $scope.events[key].id) {
|
||||||
|
$scope.events[key].txt = event.txt;
|
||||||
|
$scope.events[key].time = event.time;
|
||||||
|
$scope.events[key].kind = event.kind;
|
||||||
|
$scope.events[key].since = event.since;
|
||||||
|
$scope.events[key].keep = 1;
|
||||||
|
break;
|
||||||
|
} else if (event.time > $scope.events[key].time) {
|
||||||
|
$scope.events.unshift(event);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
key += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
$http.get("/public.json").success(function(scene) {
|
angular.forEach($scope.events, function(event, i) {
|
||||||
$scope.scene = scene;
|
if (event.keep == 0) {
|
||||||
|
$scope.events.splice(i, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
refreshEvents()
|
||||||
|
$interval(refreshEvents, 2100);
|
||||||
|
})
|
||||||
|
.controller("DataController", function($scope, $http, $rootScope, $interval) {
|
||||||
|
var refreshScene = function() {
|
||||||
|
$http.get("/public.json").then(function(response) {
|
||||||
|
if ($scope.lastpublicetag == response.headers().etag)
|
||||||
|
return;
|
||||||
|
$scope.lastpublicetag = response.headers().etag;
|
||||||
|
|
||||||
|
$scope.scene = response.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var refreshData = function() {
|
||||||
|
$http.get("/my.json").then(function(response) {
|
||||||
|
if ($scope.lastmyetag == response.headers().etag)
|
||||||
|
return;
|
||||||
|
$scope.lastmyetag = response.headers().etag;
|
||||||
|
|
||||||
|
$scope.my = response.data;
|
||||||
});
|
});
|
||||||
$http.get("/stats.json").success(function(stats) {
|
$http.get("/stats.json").success(function(stats) {
|
||||||
$scope.stats = stats;
|
$scope.stats = stats;
|
||||||
});
|
});
|
||||||
$http.get("/themes.json").success(function(themes) {
|
$http.get("/themes.json").then(function(response) {
|
||||||
|
if ($scope.lastthemeetag == response.headers().etag)
|
||||||
|
return;
|
||||||
|
$scope.lastthemeetag = response.headers().etag;
|
||||||
|
|
||||||
|
var themes = response.data;
|
||||||
$scope.themes = themes;
|
$scope.themes = themes;
|
||||||
$scope.max_gain = 0;
|
$scope.max_gain = 0;
|
||||||
angular.forEach(themes, function(theme, key) {
|
angular.forEach(themes, function(theme, key) {
|
||||||
@ -94,7 +146,13 @@ angular.module("FICApp")
|
|||||||
$scope.max_gain += theme.gain;
|
$scope.max_gain += theme.gain;
|
||||||
}, themes);
|
}, themes);
|
||||||
});
|
});
|
||||||
$http.get("/teams.json").success(function(teams) {
|
$http.get("/teams.json").then(function(response) {
|
||||||
|
if ($scope.lastteametag == response.headers().etag)
|
||||||
|
return;
|
||||||
|
$scope.lastteametag = response.headers().etag;
|
||||||
|
|
||||||
|
var teams = response.data;
|
||||||
|
|
||||||
$scope.teams_count = Object.keys(teams).length
|
$scope.teams_count = Object.keys(teams).length
|
||||||
$scope.teams = teams;
|
$scope.teams = teams;
|
||||||
|
|
||||||
@ -106,7 +164,15 @@ angular.module("FICApp")
|
|||||||
}
|
}
|
||||||
}, $scope.rank);
|
}, $scope.rank);
|
||||||
});
|
});
|
||||||
console.log("refresh!");
|
|
||||||
}
|
}
|
||||||
$rootScope.refresh();
|
refreshData();
|
||||||
|
refreshScene();
|
||||||
|
$interval(refreshData, 4200);
|
||||||
|
$interval(refreshScene, 900);
|
||||||
|
})
|
||||||
|
.controller("TeamController", function($scope, $http, $interval) {
|
||||||
|
$scope.mystats = null;
|
||||||
|
$http.get("/api/teams/" + $scope.team.id + "/stats.json").success(function(mstats) {
|
||||||
|
$scope.mystats = mstats;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -20,60 +20,18 @@
|
|||||||
<base href="/">
|
<base href="/">
|
||||||
<script src="/js/angular.min.js"></script>
|
<script src="/js/angular.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body style="overflow: hidden;" ng-controller="DataController">
|
<body style="overflow: hidden;" class="container-fluid" ng-controller="DataController">
|
||||||
|
<div class="row" style="margin-top: 10px">
|
||||||
|
<div class="col-xs-8">
|
||||||
<noscript>
|
<noscript>
|
||||||
<div class="alert alert-danger">
|
<div class="alert alert-danger">
|
||||||
<strong>Veuillez activer le JavaScript.</strong> Ce site requiert un navigateur interprêtant le JavaScript pour fonctionner. Veuillez l'activer ou en télécharger un supportant cette technologie.
|
<strong>Veuillez activer le JavaScript.</strong> Ce site requiert un navigateur interprêtant le JavaScript pour fonctionner. Veuillez l'activer ou en télécharger un supportant cette technologie.
|
||||||
</div>
|
</div>
|
||||||
</noscript>
|
</noscript>
|
||||||
|
|
||||||
<div class="navbar navbar-default" ng-controller="TimeController" style="box-shadow: 0px 10px 10px 0px #313539; position:fixed; top:0; width:100vw; z-index:1;">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="navbar-header" style="width: 100px">
|
|
||||||
<a href="/">
|
|
||||||
<img src="/img/fic.png" alt="Forum International de la Cybersécurité" class="center-block">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="navbar-right" style="width: 100px">
|
|
||||||
<a href="http://www.epita.fr/">
|
|
||||||
<img src="/img/epita.png" alt="Epita" class="center-block">
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<div class="text-center" ng-show="time.hours === 0 || time.hours" style="margin-top: -5px; ">
|
|
||||||
<div id="clock" ng-class="{expired: time.expired, end: time.end}">
|
|
||||||
<span id="hours">{{ time.hours | time }}</span>
|
|
||||||
<span class="point">:</span>
|
|
||||||
<span id="min">{{ time.minutes | time }}</span>
|
|
||||||
<span class="point">:</span>
|
|
||||||
<span id="sec">{{ time.seconds | time }}</span>
|
|
||||||
</div>
|
|
||||||
<div style="font-size: 18px; margin-top: -15px; text-shadow: 0 0 6px #446688;">
|
|
||||||
<span ng-show="!time.end && time.duration != time.remaining">Temps restant du challenge forensic</span>
|
|
||||||
<span ng-show="!time.end && time.duration == time.remaining">Le challenge forensic va bientôt commencer !</span>
|
|
||||||
<span ng-show="time.end">Le challenge forensic est terminé !</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="clock" class="col-sm-8" ng-show="!(time.hours === 0 || time.hours)">
|
|
||||||
{{ time.start | date:"shortDate" }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--div style="margin: 5px 0;">
|
|
||||||
Bandeau Twitter catchant #FIC2016
|
|
||||||
</div-->
|
|
||||||
|
|
||||||
<div class="container-fluid text-justify" style="margin-top: 110px; padding: 10px; width: 99%">
|
|
||||||
<div class="row">
|
|
||||||
|
|
||||||
<div class="col-sm-8">
|
|
||||||
|
|
||||||
<div ng-repeat="(k,s) in scene" class="repeatedd-item">
|
<div ng-repeat="(k,s) in scene" class="repeatedd-item">
|
||||||
|
|
||||||
<div class="well" ng-show="true || s.type == 'welcome' && !s.go">
|
<div class="well" ng-if="s.type == 'welcome' && !s.params.hide && s.params.kind == 'init'">
|
||||||
<h1>Bienvenue au challenge forensic !</h1>
|
<h1>Bienvenue au challenge forensic !</h1>
|
||||||
<p class="lead text-justify">
|
<p class="lead text-justify">
|
||||||
Avant de vous installer, venez récupérer votre clef USB auprès
|
Avant de vous installer, venez récupérer votre clef USB auprès
|
||||||
@ -81,22 +39,22 @@
|
|||||||
de vous authentifier auprès de notre serveur.
|
de vous authentifier auprès de notre serveur.
|
||||||
</p>
|
</p>
|
||||||
<p class="lead text-justify">
|
<p class="lead text-justify">
|
||||||
Une fois connecté au réseau, vous pouvez accéder au serveur à :
|
Une fois connecté au réseau, contactez notre serveur sur :
|
||||||
<span style="display: block; font-size: 200%" class="text-center">
|
<span style="display: block; font-size: 200%" class="text-center">
|
||||||
<a href="https://fic.srs.epita.fr/"><span class="text-info">https://fic.srs.epita.fr/</span></a>
|
<a style="font-family: mono" href="https://fic.srs.epita.fr/"><span class="text-info">https://fic.srs.epita.fr/</span></a>
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel panel-success" ng-show="true || s.type == 'welcome' && s.go == 1 && startIn">
|
<div class="panel panel-success" ng-if="s.type == 'welcome' && !s.params.hide && s.params.kind == 'countdown'">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h3 class="panel-title"><strong>Le challenge forensic 2017 est sur le point de démarrer !</strong></h3>
|
<h3 class="panel-title"><strong>Le challenge forensic 2017 est sur le point de commencer !</strong></h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body text-center" style="font-size: 450%;" ng-show="startIn">{{ startIn }}</div>
|
<div class="panel-body text-center" style="font-size: 450%;" ng-if="startIn">{{ startIn }}</div>
|
||||||
<div class="panel-body text-center" style="font-size: 450%;" ng-show="!startIn">Go, go, go !</div>
|
<div class="panel-body text-center" style="font-size: 450%;" ng-if="!startIn">Go, go, go !</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="well" ng-show="true || s.type == 'welcome' && s.go == 2">
|
<div class="well" ng-if="s.type == 'welcome' && !s.params.hide && s.params.kind == 'public'">
|
||||||
<h1>Bienvenue au challenge forensic !</h1>
|
<h1>Bienvenue au challenge forensic !</h1>
|
||||||
<p class="lead text-justify">
|
<p class="lead text-justify">
|
||||||
Durant ce challenge, les équipes doivent remonter des scénarii
|
Durant ce challenge, les équipes doivent remonter des scénarii
|
||||||
@ -114,56 +72,83 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="well" ng-show="s.type == 'message'">
|
<div class="well" ng-if="s.type == 'message' && !s.params.hide">
|
||||||
<h1 ng-show="s.title"><strong>{{ s.title }}</strong></h1>
|
<h1 ng-if="s.params.title"><strong>{{ s.params.title }}</strong></h1>
|
||||||
<p ng-show="s.lead" class="lead text-justify">{{ s.lead }}</p>
|
<p ng-if="s.params.lead" class="lead text-justify">{{ s.params.lead }}</p>
|
||||||
<p ng-bind-html="s.html" ng-show="s.html"></p>
|
<p ng-bind-html="s.params.html" ng-if="s.params.html"></p>
|
||||||
<p ng-show="s.text">{{ s.text }}</p>
|
<p ng-if="s.params.text">{{ s.params.text }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="panel {{ s.kind }}" ng-show="s.type == 'panel'">
|
<div class="panel {{ s.params.kind }}" ng-if="s.type == 'panel' && !s.params.hide">
|
||||||
<div class="panel-heading" ng-show="s.title">
|
<div class="panel-heading" ng-if="s.params.title">
|
||||||
<h3 class="panel-title">{{ s.title }}</h3>
|
<h3 class="panel-title">{{ s.params.title }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body" ng-show="s.text">{{ s.text }}</div>
|
<div class="panel-body" ng-if="s.params.text">{{ s.params.text }}</div>
|
||||||
<div class="panel-body" ng-show="s.html" ng-bind-html="s.html"></div>
|
<div class="panel-body" ng-if="s.params.html" ng-bind-html="s.params.html"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="well" ng-show="s.type == 'exercice'">
|
<div class="well" ng-if="s.type == 'exercice' && !s.params.hide">
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
<strong>{{ themes[my.exercices[s.id].theme_id].exercices[s.id].title }} du challenge {{ themes[my.exercices[s.id].theme_id].name }}</strong>
|
<strong>Challenge <em>{{ themes[my.exercices[s.params.exercice].theme_id].exercices[s.params.exercice].title }}</em> du thème {{ themes[my.exercices[s.params.exercice].theme_id].name }}</strong>
|
||||||
<small class="authors" ng-show="themes[my.exercices[s.id].theme_id].authors">par {{ themes[my.exercices[s.id].theme_id].authors }}</small>
|
<small class="authors" ng-if="themes[my.exercices[s.params.exercice].theme_id].authors">par {{ themes[my.exercices[s.params.exercice].theme_id].authors }}</small>
|
||||||
</p>
|
</p>
|
||||||
<p ng-bind-html="my.exercices[s.id].statement"></p>
|
<p ng-bind-html="my.exercices[s.params.exercice].statement"></p>
|
||||||
<ul class="list-inline">
|
<ul class="list-inline">
|
||||||
<li>{{ themes[my.exercices[s.id].theme_id].exercices[s.id].gain }} points</li>
|
<li>Rapporte <ng-pluralize count="themes[my.exercices[s.params.exercice].theme_id].exercices[s.params.exercice].gain" when="{'0': 'aucun point', 'one': '{} point', 'other': '{} points'}"></ng-pluralize></li>
|
||||||
<li>{{ my.exercices[s.id].files.length }} fichiers disponibles</li>
|
<li><ng-pluralize count="my.exercices[s.params.exercice].files.length" when="{'0': 'Aucun fichier disponible', 'one': '{} fichier disponible', 'other': '{} fichiers disponibles'}"></ng-pluralize></li>
|
||||||
<li>Tenté par {{ themes[my.exercices[s.id].theme_id].exercices[s.id].tried }} équipes</li>
|
<li ng-if="my.exercices[s.params.exercice].hints.length"><ng-pluralize count="my.exercices[s.params.exercice].hints.length" when="{'0': 'Aucun indice disponible', 'one': '{} indice disponible', 'other': '{} indices disponibles'}"></ng-pluralize></li>
|
||||||
<li>{{ my.exercices[s.id].solved_number }} tentatives</li>
|
<li>Tenté par <ng-pluralize count="themes[my.exercices[s.params.exercice].theme_id].exercices[s.params.exercice].tried" when="{'0': 'aucune équipe', 'one': '{} équipe', 'other': '{} équipes'}"></ng-pluralize></li>
|
||||||
<li>Résolu par {{ themes[my.exercices[s.id].theme_id].exercices[s.id].solved }} équipes</li>
|
<li><ng-pluralize count="my.exercices[s.params.exercice].solved_number" when="{'0': 'aucun tentative', 'one': '{} tentative', 'other': '{} tentatives'}"></ng-pluralize></li>
|
||||||
|
<li>Résolu par <ng-pluralize count="themes[my.exercices[s.params.exercice].theme_id].exercices[s.params.exercice].solved" when="{'0': 'aucune équipe', 'one': '{} équipe', 'other': '{} équipes'}"></ng-pluralize></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="table table-bordered table-striped" ng-show="s.type == 'table'">
|
<div class="panel" ng-if="s.type == 'table' && !s.params.hide">
|
||||||
|
<table class="table table-bordered table-striped table-condensed">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th class="frotated"></th>
|
||||||
<th class="text-center">Niveau 1</th>
|
<th class="rotated" ng-repeat="(tid,th) in themes" ng-if="s.params.themes.indexOf(tid-0) !== -1"><div><span>{{ th.name }}</span></div></th>
|
||||||
<th class="text-center">Niveau 2</th>
|
|
||||||
<th class="text-center">Niveau 3</th>
|
|
||||||
<th class="text-center">Niveau 4</th>
|
|
||||||
<th class="text-center">Niveau 5</th>
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody ng-if="s.params.kind == 'levels'">
|
||||||
<tr ng-repeat="th in s.themes">
|
<tr ng-repeat="lvl in [1,2,3,4,5]">
|
||||||
<th>{{ themes[th].name }}</th>
|
<th class="text-center"><nobr>Niveau {{ lvl }}</nobr></th>
|
||||||
<td ng-repeat="ex in themes[th].exercices" class="text-center" ng-class="{'text-primary': ex.solved == 0, 'text-success': ex.solved >= 1, 'text-bold': ex.solved >= 1, 'text-warning': ex.solved == 0 && ex.tried}" ng-show="ex.solved || ex.tried || $first"><span ng-show="ex.solved">{{ ex.solved }}</span><span ng-show="!ex.solved">{{ ex.tried }}</span></td>
|
<td ng-repeat="(tid,th) in themes" class="text-center" ng-if="s.params.themes.indexOf(tid-0) !== -1">
|
||||||
|
<span ng-repeat="exercice in th.exercices" ng-if="$index == lvl-1 && (exercice.tried || lvl == 1)" ng-class="{'text-primary': exercice.solved == 0, 'text-success': exercice.solved >= 1, 'text-bold': exercice.solved >= 1, 'text-warning': exercice.solved == 0 && exercice.tried}">
|
||||||
|
<span ng-if="exercice.solved">{{ exercice.solved }}</span>
|
||||||
|
<span ng-if="!exercice.solved">{{ exercice.tried }}</span>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
<tbody ng-if="s.params.kind == 'teams'">
|
||||||
|
<tr ng-repeat="team in rank | orderBy: 'rank' | limitTo: s.params.limit: s.params.begin" ng-if="s.params.teams.indexOf(team.id-0) !== -1" ng-controller="TeamController">
|
||||||
|
<th class="text-center">{{ team.rank }}<sup ng-if="team.rank == 1">er</sup><sup ng-if="team.rank > 1">e</sup><br><span style="text-overflow: ellipsis; display: inline-block; width: 82px;overflow: hidden;">{{ team.name }}</span></th>
|
||||||
|
<td ng-repeat="(tid,th) in themes" class="text-center" ng-if="mystats && s.params.themes.indexOf(tid-0) !== -1">
|
||||||
|
<span ng-class="{'text-success': mystats.themes[tid].solved}">{{ mystats.themes[tid].solved }}/{{ mystats.themes[tid].total }}</span>
|
||||||
|
<span ng-class="{'text-warning': mystats.themes[tid].solved < mystats.themes[tid].tried}">({{ mystats.themes[tid].tries }})</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<tfoot ng-if="s.params.total" ng-init="team={id:0}">
|
||||||
|
<tr ng-controller="TeamController">
|
||||||
|
<td class="text-right">
|
||||||
|
<span ng-if="s.params.kind == 'levels'">Résolus</span>
|
||||||
|
<span ng-if="s.params.kind == 'teams'">Total résolus</span><br>
|
||||||
|
Tentatives
|
||||||
|
</td>
|
||||||
|
<td ng-repeat="(tid,th) in themes" class="text-center" ng-if="mystats && s.params.themes.indexOf(tid-0) !== -1">
|
||||||
|
<strong>{{ mystats.themes[tid].solved }}</strong><br>
|
||||||
|
{{ mystats.themes[tid].tries }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
<table class="table table-bordered table-striped" ng-show="s.type == 'rank'">
|
<div class="panel" ng-if="s.type == 'rank' && !s.params.hide">
|
||||||
|
<table class="table table-bordered table-striped table-condensed">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="text-right">Place</th>
|
<th class="text-right">Place</th>
|
||||||
@ -171,31 +156,139 @@
|
|||||||
<th>Score</th>
|
<th>Score</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody ng-show="s.which == 'general'">
|
<tbody ng-if="s.params.which == 'general'">
|
||||||
<tr ng-repeat="r in rank | orderBy: 'rank' | limitTo: 7">
|
<tr ng-repeat="r in rank | orderBy: 'rank' | limitTo: s.params.limit: s.params.begin">
|
||||||
<th class="text-right">{{ r.rank }}<sup ng-show="r.rank == 1">er</sup><sup ng-show="r.rank > 1">e</sup></th>
|
<th class="text-right">{{ r.rank }}<sup ng-if="r.rank == 1">er</sup><sup ng-if="r.rank > 1">e</sup></th>
|
||||||
<td>{{ r.name }}</td>
|
<td>{{ r.name }}</td>
|
||||||
<td>{{ r.score }}</td>
|
<td>{{ r.score }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col-sm-4">
|
<div class="col-xs-4">
|
||||||
|
|
||||||
<div ng-repeat="e in events" class="repeated6-item">
|
<div ng-controller="EventsController">
|
||||||
|
<div ng-repeat="e in events | limitTo: 7" class="repeated-item">
|
||||||
<div class="alert" ng-class="e.kind">
|
<div class="alert" ng-class="e.kind">
|
||||||
<div class="heading">{{ e.since | since }}</div>
|
<div class="heading">{{ e.since | since }}</div>
|
||||||
<span ng-bind-html="e.txt"></span>
|
<span ng-bind-html="e.txt"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a href="https://srs.epita.fr/">
|
<div style="box-shadow: 0px -5px 5px 5px #272b30; position: fixed; bottom: calc(14vh - 1px); right: 0; width: 33vw;" class="navbar navbar-inverse">
|
||||||
<img src="/img/srs.png" class="center-block" alt="Epita">
|
<div class="text-center" ng-if="time.hours === 0 || time.hours" style="margin-top: -5px;" ng-controller="TimeController">
|
||||||
</a>
|
<div id="clock" ng-class="{expired: time.expired, end: time.end}" style="font-size: 50px" ng-cloak>
|
||||||
|
<span id="hours">{{ time.hours | time }}</span>
|
||||||
|
<span class="point">:</span>
|
||||||
|
<span id="min">{{ time.minutes | time }}</span>
|
||||||
|
<span class="point">:</span>
|
||||||
|
<span id="sec">{{ time.seconds | time }}</span>
|
||||||
|
</div>
|
||||||
|
<div style="font-size: 18px; margin-top: -15px; text-shadow: 0 0 6px #446688;">
|
||||||
|
<span ng-if="!time.end && time.duration != time.remaining">Temps restant du challenge forensic</span>
|
||||||
|
<span ng-if="!time.end && time.duration == time.remaining">Le challenge forensic va bientôt commencer !</span>
|
||||||
|
<span ng-if="time.end">Le challenge forensic est terminé !</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="clock" class="col-sm-6" ng-if="!(time.hours === 0 || time.hours)">
|
||||||
|
{{ time.start | date:"shortDate" }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="position: fixed; bottom: 0; right: 0; width: 33vw; height: 14vh" class="navbar navbar-inverse">
|
||||||
|
<div class="carousel slide" id="carousel-logos" data-ride="carousel">
|
||||||
|
<div class="carousel-inner">
|
||||||
|
<div class="item active">
|
||||||
|
<div class="carousel-caption">
|
||||||
|
<a href="http://www.epita.fr/"><img src="/img/epita.png" alt="Epita" style="width:30%"></a>
|
||||||
|
<a href="https://srs.epita.fr/"><img src="/img/srs.png" alt="Laboratoire SRS" style="width:30%"></a>
|
||||||
|
<img src="/img/rcc.png" alt="Réserve Citoyenne Cyberdéfense" style="width:30%">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="carousel-caption" style="padding: 0 10px">
|
||||||
|
<h2>Bienvenue au challenge forensic !</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="carousel-caption">
|
||||||
|
<p class="text-justify text-bold" style="padding: 20px 16px; font-size: 111%">
|
||||||
|
Ce challenge met en scène des scénarii d'attaques auxquels
|
||||||
|
nos systèmes d'information font faces chaque jour.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="carousel-caption">
|
||||||
|
<p class="text-justify text-bold" style="padding: 20px 16px; font-size: 111%">
|
||||||
|
Les 42 équipes doivent, en 4 heures, retracer les attaques à la
|
||||||
|
recherche des données exfiltrées.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="carousel-caption row" style="padding: 12px">
|
||||||
|
<div class="col-xs-4">
|
||||||
|
<a href="https://www.epita.fr/"><img src="/img/epita.png" alt="Épita" style="height: 10vh"></a>
|
||||||
|
</div>
|
||||||
|
<p class="col-xs-8 text-bold" style="font-size: 111%">
|
||||||
|
Les challenges ont été réalisés par les étudiants de la
|
||||||
|
spécialisation SRS de l'Épita
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="carousel-caption row" style="padding: 12px">
|
||||||
|
<div class="col-xs-4">
|
||||||
|
<img src="/img/rcc.png" alt="Réserve Citoyenne Cyberdéfense" style="max-width:100%; max-height: 11vh">
|
||||||
|
</div>
|
||||||
|
<p class="col-xs-8 text-bold" style="padding: 10px 10px 10px 0; font-size: 111%">
|
||||||
|
Avec le parrainage du réseau de la Réserve Citoyenne Cyberdéfense
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="carousel-caption" style="padding: 3px 25px; width: 32vw;">
|
||||||
|
<table class="table table-bordered table-condensed table-striped">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>11 h</td>
|
||||||
|
<td>Accueil des équipes</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>11 h 30</td>
|
||||||
|
<td>Début du challenge</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>15 h 30</td>
|
||||||
|
<td>Fin du challenge</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>16 h 00</td>
|
||||||
|
<td>Remise des prix</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<div class="carousel-caption row" style="padding: 12px">
|
||||||
|
<p class="text-bold" style="padding: 5px; font-size: 105%">
|
||||||
|
Retrouvez la correction des challenges dès demain sur :
|
||||||
|
<span style="display: block; font-size: 150%" class="text-center">
|
||||||
|
<a style="font-family: mono" href="https://fic.srs.epita.fr/"><span class="text-info">https://fic.srs.epita.fr/</span></a>
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -209,5 +302,10 @@
|
|||||||
<script src="/js/i18n/angular-locale_fr-fr.js"></script>
|
<script src="/js/i18n/angular-locale_fr-fr.js"></script>
|
||||||
<script src="/js/public.js"></script>
|
<script src="/js/public.js"></script>
|
||||||
<script src="/js/common.js"></script>
|
<script src="/js/common.js"></script>
|
||||||
|
<script>
|
||||||
|
$(".carousel").carousel({
|
||||||
|
interval: 21000
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user