├── keys
└── README.txt
├── app.js
├── public
├── no.mp3
├── yes.mp3
├── no5s.ogg
├── no5s.wav
├── soon.png
├── images
│ ├── close.gif
│ ├── error.png
│ ├── notice.png
│ ├── icn_edit.png
│ ├── icn_tags.png
│ ├── icn_user.png
│ ├── sidebar.png
│ ├── success.png
│ ├── warning.png
│ ├── btn_submit.png
│ ├── header_bg.png
│ ├── icn_audio.png
│ ├── icn_folder.png
│ ├── icn_logout.png
│ ├── icn_photo.png
│ ├── icn_profile.png
│ ├── icn_search.png
│ ├── icn_trash.png
│ ├── icn_video.png
│ ├── btn_submit_2.png
│ ├── btn_view_site.png
│ ├── header_shadow.png
│ ├── icn_add_user.png
│ ├── icn_jump_back.png
│ ├── icn_security.png
│ ├── icn_settings.png
│ ├── post_message.png
│ ├── secondary_bar.png
│ ├── icn_alert_error.png
│ ├── icn_alert_info.png
│ ├── icn_categories.png
│ ├── icn_edit_article.png
│ ├── icn_new_article.png
│ ├── icn_view_users.png
│ ├── module_footer_bg.png
│ ├── sidebar_divider.png
│ ├── sidebar_shadow.png
│ ├── breadcrumb_divider.png
│ ├── icn_alert_success.png
│ ├── icn_alert_warning.png
│ ├── secondary_bar_shadow.png
│ └── table_sorter_header.png
├── img
│ ├── tile_bg.jpg
│ ├── 230690_700b.jpg
│ ├── page_bg_center.jpg
│ ├── cropped-proposta02.jpg
│ ├── glyphicons-halflings.png
│ ├── glyphicons-halflings-white.png
│ └── Consuela_Family_Guy_Pink_by_djluckyremix.png
├── stylesheets
│ ├── style.css
│ ├── login.css
│ ├── jquery.countdown.css
│ └── jquery.toastmessage.css
├── js
│ ├── jquery.equalHeight.js
│ ├── hideshow.js
│ └── jquery.tablesorter.min.js
├── css
│ └── ie.css
└── javascripts
│ ├── admin.js
│ ├── jquery.countdown.css
│ ├── themes
│ ├── grid.js
│ ├── skies.js
│ ├── dark-blue.js
│ ├── dark-green.js
│ └── gray.js
│ ├── jquery.scrollTo-1.4.2-min.js
│ ├── bootstrap-alert.js
│ ├── index.js
│ ├── bootstrap-popover.js
│ ├── jquery.countdown.js
│ ├── bootstrap-tab.js
│ ├── bootstrap-transition.js
│ ├── bootstrap-collapse.js
│ ├── bootstrap-modal.js
│ ├── script.js
│ ├── jquery.toastmessage.js
│ └── bootstrap-tooltip.js
├── views
├── admin
│ ├── dashboard_good.jade
│ ├── dashboard.jade
│ ├── config
│ │ ├── comms.jade
│ │ └── options.jade
│ ├── insert
│ │ ├── addCategory.jade
│ │ ├── addChallenge.jade
│ │ ├── addTeam.jade
│ │ └── addProblem.jade
│ ├── edit
│ │ ├── editChallenge.jade
│ │ ├── editTeam.jade
│ │ ├── editCategory.jade
│ │ └── editProblem.jade
│ ├── list
│ │ ├── listCategories.jade
│ │ ├── listTeams.jade
│ │ ├── listProblems.jade
│ │ └── listChallenges.jade
│ ├── layout.jade
│ └── index.jade
├── session
│ └── login.jade
├── layout.jade
├── score.jade
└── index.jade
├── config.js
├── BD
├── db.js
├── salts.sql
└── tournament.sql
├── package.json
├── routes
├── sessions.js
├── score.js
├── index.js
└── administration.js
└── README.md
/keys/README.txt:
--------------------------------------------------------------------------------
1 | Your https keys go here
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/app.js
--------------------------------------------------------------------------------
/public/no.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/no.mp3
--------------------------------------------------------------------------------
/public/yes.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/yes.mp3
--------------------------------------------------------------------------------
/public/no5s.ogg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/no5s.ogg
--------------------------------------------------------------------------------
/public/no5s.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/no5s.wav
--------------------------------------------------------------------------------
/public/soon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/soon.png
--------------------------------------------------------------------------------
/public/images/close.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/close.gif
--------------------------------------------------------------------------------
/public/images/error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/error.png
--------------------------------------------------------------------------------
/public/images/notice.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/notice.png
--------------------------------------------------------------------------------
/public/img/tile_bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/img/tile_bg.jpg
--------------------------------------------------------------------------------
/public/images/icn_edit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_edit.png
--------------------------------------------------------------------------------
/public/images/icn_tags.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_tags.png
--------------------------------------------------------------------------------
/public/images/icn_user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_user.png
--------------------------------------------------------------------------------
/public/images/sidebar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/sidebar.png
--------------------------------------------------------------------------------
/public/images/success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/success.png
--------------------------------------------------------------------------------
/public/images/warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/warning.png
--------------------------------------------------------------------------------
/public/img/230690_700b.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/img/230690_700b.jpg
--------------------------------------------------------------------------------
/public/images/btn_submit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/btn_submit.png
--------------------------------------------------------------------------------
/public/images/header_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/header_bg.png
--------------------------------------------------------------------------------
/public/images/icn_audio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_audio.png
--------------------------------------------------------------------------------
/public/images/icn_folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_folder.png
--------------------------------------------------------------------------------
/public/images/icn_logout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_logout.png
--------------------------------------------------------------------------------
/public/images/icn_photo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_photo.png
--------------------------------------------------------------------------------
/public/images/icn_profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_profile.png
--------------------------------------------------------------------------------
/public/images/icn_search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_search.png
--------------------------------------------------------------------------------
/public/images/icn_trash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_trash.png
--------------------------------------------------------------------------------
/public/images/icn_video.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_video.png
--------------------------------------------------------------------------------
/public/img/page_bg_center.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/img/page_bg_center.jpg
--------------------------------------------------------------------------------
/public/stylesheets/style.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/stylesheets/style.css
--------------------------------------------------------------------------------
/public/images/btn_submit_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/btn_submit_2.png
--------------------------------------------------------------------------------
/public/images/btn_view_site.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/btn_view_site.png
--------------------------------------------------------------------------------
/public/images/header_shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/header_shadow.png
--------------------------------------------------------------------------------
/public/images/icn_add_user.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_add_user.png
--------------------------------------------------------------------------------
/public/images/icn_jump_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_jump_back.png
--------------------------------------------------------------------------------
/public/images/icn_security.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_security.png
--------------------------------------------------------------------------------
/public/images/icn_settings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_settings.png
--------------------------------------------------------------------------------
/public/images/post_message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/post_message.png
--------------------------------------------------------------------------------
/public/images/secondary_bar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/secondary_bar.png
--------------------------------------------------------------------------------
/views/admin/dashboard_good.jade:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/views/admin/dashboard_good.jade
--------------------------------------------------------------------------------
/public/images/icn_alert_error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_alert_error.png
--------------------------------------------------------------------------------
/public/images/icn_alert_info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_alert_info.png
--------------------------------------------------------------------------------
/public/images/icn_categories.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_categories.png
--------------------------------------------------------------------------------
/public/images/icn_edit_article.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_edit_article.png
--------------------------------------------------------------------------------
/public/images/icn_new_article.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_new_article.png
--------------------------------------------------------------------------------
/public/images/icn_view_users.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_view_users.png
--------------------------------------------------------------------------------
/public/images/module_footer_bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/module_footer_bg.png
--------------------------------------------------------------------------------
/public/images/sidebar_divider.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/sidebar_divider.png
--------------------------------------------------------------------------------
/public/images/sidebar_shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/sidebar_shadow.png
--------------------------------------------------------------------------------
/public/img/cropped-proposta02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/img/cropped-proposta02.jpg
--------------------------------------------------------------------------------
/public/images/breadcrumb_divider.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/breadcrumb_divider.png
--------------------------------------------------------------------------------
/public/images/icn_alert_success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_alert_success.png
--------------------------------------------------------------------------------
/public/images/icn_alert_warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/icn_alert_warning.png
--------------------------------------------------------------------------------
/public/img/glyphicons-halflings.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/img/glyphicons-halflings.png
--------------------------------------------------------------------------------
/public/images/secondary_bar_shadow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/secondary_bar_shadow.png
--------------------------------------------------------------------------------
/public/images/table_sorter_header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/images/table_sorter_header.png
--------------------------------------------------------------------------------
/public/img/glyphicons-halflings-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/img/glyphicons-halflings-white.png
--------------------------------------------------------------------------------
/public/img/Consuela_Family_Guy_Pink_by_djluckyremix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PTCoreSec/CTF-Scoreboard/HEAD/public/img/Consuela_Family_Guy_Pink_by_djluckyremix.png
--------------------------------------------------------------------------------
/views/admin/dashboard.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | header
8 | h3 Welcome to Administration.
9 | .module_content
10 | p You can admin and do stuff..
11 | //
12 | end of styles article
13 | .spacer
14 |
--------------------------------------------------------------------------------
/public/stylesheets/login.css:
--------------------------------------------------------------------------------
1 | .container {
2 | width: 300px;
3 | }
4 |
5 | /* The white background content wrapper */
6 | .container > .content {
7 | padding: 20px;
8 | margin: 0 -20px;
9 | }
10 |
11 | .login-form {
12 | margin-left: 65px;
13 | }
14 |
15 | legend {
16 | margin-right: -50px;
17 | font-weight: bold;
18 | color: #404040;
19 | }
--------------------------------------------------------------------------------
/views/session/login.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block scripts
4 | link(rel='stylesheet', href='/stylesheets/login.css')
5 |
6 | block content
7 | div.container
8 | div.content
9 | div.row
10 | div.login-form
11 | form(action='/login', method='POST')
12 | fieldset
13 | div.clearfix
14 | input.text-input(type='text', name='username', id='username', placeholder='User')
15 | div.clearfix
16 | input.text-input(type='password', name='password', id='password', placeholder='Password')
17 | button.btn.btn-primary(type='submit') Login
--------------------------------------------------------------------------------
/config.js:
--------------------------------------------------------------------------------
1 | var config = {};
2 |
3 | config.db = {};
4 | config.dbHashes = {};
5 |
6 | // Complete DB
7 | config.db.host = ''; // <-- Insert host
8 | config.db.user = ''; // <-- Insert user
9 | config.db.password = ''; // <-- Insert password
10 | //Don't Change.
11 | config.db.database = 'torneio';
12 |
13 | // Password Salt DB
14 | config.dbHashes.host = ''; // <-- Insert host
15 | config.dbHashes.user = ''; // <-- Insert user
16 | config.dbHashes.password = ''; // <-- Insert password
17 | //Don't Change.
18 | config.dbHashes.database = 'passsalts';
19 |
20 | module.exports = config;
21 |
--------------------------------------------------------------------------------
/views/admin/config/comms.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | form
8 | header
9 | h3 Communications
10 | .module_content
11 | fieldset
12 | label Global Message
13 | input(id='message', type='text', name='message', value='')
14 | .clear
15 | footer
16 | .submit_link
17 | input.alt_btn(id='sendMessage', type='submit', value='Submit')
18 | //
19 | end of post new article
20 | .spacer
--------------------------------------------------------------------------------
/BD/db.js:
--------------------------------------------------------------------------------
1 | //Config
2 | var config = require('../config.js');
3 | var mysql = require('mysql');
4 |
5 | var connections = {};
6 |
7 | connections.connection = mysql.createConnection({
8 | host : config.db.host,
9 | user : config.db.user,
10 | password : config.db.password,
11 | database : config.db.database,
12 | });
13 |
14 | connections.connectionHashes = mysql.createConnection({
15 | host : config.dbHashes.host,
16 | user : config.dbHashes.user,
17 | password : config.dbHashes.password,
18 | database : config.dbHashes.database,
19 | });
20 |
21 | module.exports = connections;
22 |
--------------------------------------------------------------------------------
/public/js/jquery.equalHeight.js:
--------------------------------------------------------------------------------
1 | // make sure the $ is pointing to JQuery and not some other library
2 | (function($){
3 | // add a new method to JQuery
4 |
5 | $.fn.equalHeight = function() {
6 | // find the tallest height in the collection
7 | // that was passed in (.column)
8 | tallest = 0;
9 | this.each(function(){
10 | thisHeight = $(this).height();
11 | if( thisHeight > tallest)
12 | tallest = thisHeight;
13 | });
14 |
15 | // set each items height to use the tallest value found
16 | this.each(function(){
17 | $(this).height(tallest);
18 | });
19 | }
20 | })(jQuery);
--------------------------------------------------------------------------------
/views/admin/insert/addCategory.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | form(action='insertCategory', method='POST')
8 | header
9 | h3 Create New Category
10 | .module_content
11 | fieldset
12 | label Category Name
13 | input(type='text', name='categoryName', value='')
14 | fieldset
15 | label Category Description
16 | textarea(rows='12', name='description')
17 | .clear
18 | footer
19 | .submit_link
20 | input.alt_btn(type='submit', value='Submit')
21 | input(type='submit', value='Reset')
22 | //
23 | end of post new article
24 | .spacer
--------------------------------------------------------------------------------
/views/admin/edit/editChallenge.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | form(action='insertChallenge', method='POST')
8 | header
9 | h3 Create Challenge
10 | .module_content
11 | fieldset
12 | label Challenge Name
13 | input(type='text', name='challengeName', value='')
14 | fieldset
15 | label Challenge Description
16 | textarea(rows='12', name='description')
17 | .clear
18 | footer
19 | .submit_link
20 | input.alt_btn(type='submit', value='Submit')
21 | input(type='submit', value='Reset')
22 | //
23 | end of post new article
24 | .spacer
--------------------------------------------------------------------------------
/views/admin/insert/addChallenge.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | form(action='insertChallenge', method='POST')
8 | header
9 | h3 Create Challenge
10 | .module_content
11 | fieldset
12 | label Challenge Name
13 | input(type='text', name='challengeName', value='')
14 | fieldset
15 | label Challenge Description
16 | textarea(rows='12', name='description')
17 | .clear
18 | footer
19 | .submit_link
20 | input.alt_btn(type='submit', value='Submit')
21 | input(type='submit', value='Reset')
22 | //
23 | end of post new article
24 | .spacer
--------------------------------------------------------------------------------
/public/css/ie.css:
--------------------------------------------------------------------------------
1 | .quick_search {
2 | text-align: center;
3 | padding: 14px 0 0px 0;
4 | }
5 |
6 | .quick_search input[type=text] {
7 | text-align: left;
8 | height: 22px;
9 | width: 88%;
10 | color: #ccc;
11 | padding-left: 2%;
12 | padding-top: 5px;
13 | background: #fff url(../images/icn_search.png) no-repeat;
14 | background-position: 10px 6px;
15 | }
16 |
17 | .toggleLink {
18 | display: inline;
19 | float: none;
20 | margin-left: 2%
21 | }
22 |
23 | html ul.tabs li.active, html ul.tabs li.active a:hover {
24 | background: #ccc;
25 | }
26 |
27 | input[type=submit].btn_post_message {
28 | background: url(../images/post_message.png) no-repeat;
29 | }
30 |
31 | fieldset input[type=text] {
32 | margin-left: -10px;
33 | }
34 |
35 |
36 | fieldset select {
37 | margin-left: -10px
38 | }
39 |
40 | fieldset textarea {
41 | margin-left: -10px;
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/views/admin/edit/editTeam.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | form(action='/editTeam/#{team.idteams}', method='POST')
8 | header
9 | h3 Edit Team
10 | .module_content
11 | fieldset
12 | label Team Name
13 | input(type='text', name='teamName', value='#{team.name}')
14 | fieldset
15 | label Team Description
16 | textarea(rows='12', name='description') #{team.description}
17 | .clear
18 | footer
19 | .submit_link
20 | input.alt_btn(type='submit', value='Submit')
21 | input(type='submit', value='Reset')
22 | //
23 | end of post new article
24 | .spacer
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "PTCoreSec-Scoreboard-CTF"
3 | , "version": "0.1"
4 | , "author": {
5 | "name": "PTCoreSec"
6 | , "email": "ptcoresec@ptcoresec.eu"
7 | }
8 | , "contributors": [
9 | {
10 | "name": "Gank"
11 | , "email": "Gank@ptcoresec.eu"
12 | }
13 | ,{
14 | "name": "Maluko"
15 | , "email": "Maluko@ptcoresec.eu"
16 | }
17 | ,{
18 | "name": "Balgan"
19 | , "email": "Balgan@ptcoresec.eu"
20 | }
21 | ]
22 | , "dependencies": {
23 | "express": "2.5.8"
24 | , "jade": "0.26.3"
25 | , "connect-redis": "1.4.0"
26 | , "cookie": "0.0.4"
27 | , "mysql": "2.0.0-alpha3"
28 | , "node_hash": "0.2.0"
29 | , "passport": "0.1.10"
30 | , "passport-local": "0.1.3"
31 | , "randomstring": "1.0.1"
32 | , "redis": "0.7.2"
33 | , "socket.io": "0.9.6"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/views/admin/edit/editCategory.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | form(action='/editCategory/#{category.idgrupos_problemas}', method='POST')
8 | header
9 | h3 Edit Category
10 | .module_content
11 | fieldset
12 | label Category Name
13 | input(type='text', name='categoryName', value='#{category.name}')
14 | fieldset
15 | label Category Description
16 | textarea(rows='12', name='description') #{category.desc}
17 | .clear
18 | footer
19 | .submit_link
20 | input.alt_btn(type='submit', value='Submit')
21 | input(type='submit', value='Reset')
22 | //
23 | end of post new article
24 | .spacer
--------------------------------------------------------------------------------
/views/admin/list/listCategories.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | header
8 | h3.tabs_involved List Categories
9 | .tab_container
10 | #tab1.tab_content
11 | table.tablesorter(cellspacing='0')
12 | thead
13 | tr
14 | th Name
15 | th Description
16 | th Actions
17 | tbody
18 | - each categorie in categories
19 | tr
20 | td #{categorie.name}
21 | td #{categorie.desc}
22 | td
23 | a(href='editCategory/#{categorie.idgrupos_problemas}')
24 | input(type='image', src='images/icn_edit.png', title='Edit')
25 | a(href='deleteCategory/#{categorie.idgrupos_problemas}')
26 | input(type='image', src='images/icn_trash.png', title='Trash')
27 | //
28 | end of #tab1
29 | //
30 | end of .tab_container
31 | //
32 | end of content manager article
33 | .spacer
34 |
--------------------------------------------------------------------------------
/views/admin/list/listTeams.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | header
8 | h3.tabs_involved List teams
9 | .tab_container
10 | #tab1.tab_content
11 | table.tablesorter(cellspacing='0')
12 | thead
13 | tr
14 | //
15 | th ID
16 | th Name
17 | th Description
18 | th Actions
19 | tbody
20 | - each team in teams
21 | tr
22 | //
23 | td #{team.idteams}
24 | td #{team.name}
25 | td #{team.description}
26 | td
27 | a(href='editTeam/#{team.idteams}')
28 | input(type='image', src='images/icn_edit.png', title='Edit')
29 | a(href='deleteTeam/#{team.idteams}')
30 | input(type='image', src='images/icn_trash.png', title='Trash')
31 | //
32 | end of #tab1
33 | //
34 | end of .tab_container
35 | //
36 | end of content manager article
37 | .spacer
38 |
--------------------------------------------------------------------------------
/public/javascripts/admin.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 |
3 |
4 | var socket = io.connect();
5 | var selectedGroup = -1;
6 | var selectedProblem = -1;
7 |
8 |
9 |
10 | $("#reset").click(function() {
11 | console.log('reset');
12 | socket.emit('reloadConfig');
13 | });
14 |
15 | $("#reloadConfig").click(function() {
16 | console.log('reload config');
17 | socket.emit('reloadConfig');
18 | });
19 |
20 | $("#sendMessage").click(function() {
21 | /* stop form from submitting normally */
22 | event.preventDefault();
23 | console.log('send message');
24 | socket.emit('globalMessage', {message: $('#message').val(), sticky: true});
25 | });
26 |
27 | $("#category").change(function() {
28 | selectedGroup = $(this).find("option:selected").attr("idgroup");
29 | selectedProblem = $(this).find("option:selected").attr("idproblem");
30 | });
31 |
32 | $("#adminActivateProblem").click(function() {
33 | console.log('send message to activate '+selectedGroup+' - '+selectedProblem);
34 | socket.emit('adminActivateProblem', {group: selectedGroup, problem: selectedProblem});
35 | });
36 |
37 | });
38 |
--------------------------------------------------------------------------------
/routes/sessions.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | exports.requiresLogin = function(req, res, next){
4 | if(req.session.passport.user){
5 | req.session.teamId = req.user[0].idteams;
6 | req.session.user = req.user[0].name;
7 | req.session.administrationLevel = req.user[0].administrationLevel;
8 | next();
9 | } else {
10 | res.render('session/login', { title: 'PTCoreSec Login' });
11 | }
12 | }
13 |
14 | exports.requiresAdminLogin = function(req, res, next){
15 | if(req.session.passport.user && req.user[0].administrationLevel == 2){
16 | req.session.teamId = req.user[0].idteams;
17 | req.session.user = req.user[0].name;
18 | req.session.administrationLevel = req.user[0].administrationLevel;
19 | next();
20 | } else {
21 | res.render('session/login', { title: 'PTCoreSec Login' });
22 | }
23 | }
24 |
25 | exports.login = function(req, res) {
26 | req.session.path = req.route.path;
27 | res.render('session/login', { title: 'PTCoreSec Login' });
28 | }
29 |
30 | exports.logout = function(req, res) {
31 | req.logOut();
32 | req.session.administrationLevel = '';
33 | req.session.user = '';
34 | req.session.teamId = '';
35 | res.cookie('teamid', null);
36 | res.redirect('/');
37 | }
38 |
39 |
40 |
--------------------------------------------------------------------------------
/views/admin/list/listProblems.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | header
8 | h3.tabs_involved List Problems
9 | .tab_container
10 | #tab1.tab_content
11 | table.tablesorter(cellspacing='0')
12 | thead
13 | tr
14 | th Group Name
15 | //
16 | th Problem ID
17 | th Description
18 | th Answer
19 | th Points
20 | th Level
21 | th Actions
22 | tbody
23 | - each problem in problems
24 | tr
25 | td #{problem.name}
26 | //
27 | td #{problem.idproblemas}
28 | td #{problem.description}
29 | td #{problem.resposta}
30 | td #{problem.points}
31 | td #{problem.level}
32 | td
33 | a(href='editProblem/#{problem.idproblemas}')
34 | input(type='image', src='images/icn_edit.png', title='Edit')
35 | a(href='deleteProblem/#{problem.idproblemas}')
36 | input(type='image', src='images/icn_trash.png', title='Trash')
37 | //
38 | end of #tab1
39 | //
40 | end of .tab_container
41 | //
42 | end of content manager article
43 | .spacer
44 |
--------------------------------------------------------------------------------
/public/js/hideshow.js:
--------------------------------------------------------------------------------
1 | // Andy Langton's show/hide/mini-accordion @ http://andylangton.co.uk/jquery-show-hide
2 |
3 | // this tells jquery to run the function below once the DOM is ready
4 | $(document).ready(function() {
5 |
6 | // choose text for the show/hide link - can contain HTML (e.g. an image)
7 | var showText='Show';
8 | var hideText='Hide';
9 |
10 | // initialise the visibility check
11 | var is_visible = false;
12 |
13 | // append show/hide links to the element directly preceding the element with a class of "toggle"
14 | $('.toggle').prev().append(' '+hideText+'');
15 |
16 | // hide all of the elements with a class of 'toggle'
17 | $('.toggle').show();
18 |
19 | // capture clicks on the toggle links
20 | $('a.toggleLink').click(function() {
21 |
22 | // switch visibility
23 | is_visible = !is_visible;
24 |
25 | // change the link text depending on whether the element is shown or hidden
26 | if ($(this).text()==showText) {
27 | $(this).text(hideText);
28 | $(this).parent().next('.toggle').slideDown('slow');
29 | }
30 | else {
31 | $(this).text(showText);
32 | $(this).parent().next('.toggle').slideUp('slow');
33 | }
34 |
35 | // return false so any link destination is not followed
36 | return false;
37 |
38 | });
39 | });
--------------------------------------------------------------------------------
/views/admin/insert/addTeam.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | form(action='insertTeam', method='POST')
8 | header
9 | h3 Create Team
10 | .module_content
11 | fieldset
12 | label Team Name
13 | input(type='text', name='teamName', value='')
14 | fieldset
15 | label User Type
16 | select(name='type')
17 | option(value='0') Normal
18 | option(value='2') Admin
19 | fieldset
20 | label Password
21 | input(type='password', name='teamPassword', value='')
22 | fieldset
23 | label Confirm Password
24 | input(type='password', name='confirmTeamPassord)
25 | fieldset
26 | label Team Description
27 | textarea(rows='12', name='description')
28 | .clear
29 | footer
30 | .submit_link
31 | input.alt_btn(type='submit', value='Submit')
32 | input(type='submit', value='Reset')
33 | //
34 | end of post new article
35 | .spacer
--------------------------------------------------------------------------------
/views/admin/edit/editProblem.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | form(action='/editProblem/#{problem.idproblemas}', method='POST')
8 | header
9 | h3 Edit Problem
10 | .module_content
11 | fieldset
12 | label Category
13 | select(name='category')
14 | - each categorie in categories
15 | - if (categorie.idgrupos_problemas==problem.idgrupos_problemas)
16 | option(value='#{categorie.idgrupos_problemas}', selected='selected') #{categorie.name}
17 | - else
18 | option(value='#{categorie.idgrupos_problemas}') #{categorie.name}
19 | fieldset
20 | label Answer
21 | input(type='text', name='answer', value='#{problem.resposta}')
22 | fieldset
23 | label Level
24 | input(type='text', name='level', value='#{problem.level}')
25 | fieldset
26 | label Points
27 | input(type='text', name='points', value='#{problem.points}')
28 | fieldset
29 | label Category Description
30 | textarea(rows='12', name='description') #{problem.description}
31 | .clear
32 | footer
33 | .submit_link
34 | input.alt_btn(type='submit', value='Submit')
35 | input(type='submit', value='Reset')
36 | //
37 | end of post new article
38 | .spacer
--------------------------------------------------------------------------------
/public/stylesheets/jquery.countdown.css:
--------------------------------------------------------------------------------
1 | .countdownHolder{
2 | width:97%;
3 | margin:0 auto;
4 | font: 16px/1.5 'Open Sans Condensed',sans-serif;
5 | text-align:right;
6 | letter-spacing:-3px;
7 | }
8 |
9 | .position{
10 | display: inline-block;
11 | height: 1.6em;
12 | overflow: hidden;
13 | position: relative;
14 | width: 1.05em;
15 | }
16 |
17 | .digit{
18 | position:absolute;
19 | display:block;
20 | width:1em;
21 | background-color:#444;
22 | border-radius:0.2em;
23 | text-align:center;
24 | color:#fff;
25 | letter-spacing:-1px;
26 | }
27 |
28 | .digit.static{
29 | box-shadow:1px 1px 1px rgba(4, 4, 4, 0.35);
30 |
31 | background-image: linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
32 | background-image: -o-linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
33 | background-image: -moz-linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
34 | background-image: -webkit-linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
35 | background-image: -ms-linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
36 |
37 | background-image: -webkit-gradient(
38 | linear,
39 | left bottom,
40 | left top,
41 | color-stop(0.5, #3A3A3A),
42 | color-stop(0.5, #444444)
43 | );
44 | }
45 |
46 | /**
47 | * You can use these classes to hide parts
48 | * of the countdown that you don't need.
49 | */
50 |
51 | .countDays{ /* display:none !important;*/ }
52 | .countDiv0{ /* display:none !important;*/ }
53 | .countHours{}
54 | .countDiv1{}
55 | .countMinutes{}
56 | .countDiv2{}
57 | .countSeconds{}
58 |
59 |
60 | .countDiv{
61 | display:inline-block;
62 | width:16px;
63 | height:1.6em;
64 | position:relative;
65 | }
66 |
67 | .countDiv:before,
68 | .countDiv:after{
69 | position:absolute;
70 | width:5px;
71 | height:5px;
72 | background-color:#444;
73 | border-radius:50%;
74 | left:50%;
75 | margin-left:-3px;
76 | top:0.5em;
77 | box-shadow:1px 1px 1px rgba(4, 4, 4, 0.5);
78 | content:'';
79 | }
80 |
81 | .countDiv:after{
82 | top:0.9em;
83 | }
--------------------------------------------------------------------------------
/public/javascripts/jquery.countdown.css:
--------------------------------------------------------------------------------
1 | .countdownHolder{
2 | width:450px;
3 | margin:0 auto;
4 | font: 40px/1.5 'Open Sans Condensed',sans-serif;
5 | text-align:center;
6 | letter-spacing:-3px;
7 | }
8 |
9 | .position{
10 | display: inline-block;
11 | height: 1.6em;
12 | overflow: hidden;
13 | position: relative;
14 | width: 1.05em;
15 | }
16 |
17 | .digit{
18 | position:absolute;
19 | display:block;
20 | width:1em;
21 | background-color:#444;
22 | border-radius:0.2em;
23 | text-align:center;
24 | color:#fff;
25 | letter-spacing:-1px;
26 | }
27 |
28 | .digit.static{
29 | box-shadow:1px 1px 1px rgba(4, 4, 4, 0.35);
30 |
31 | background-image: linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
32 | background-image: -o-linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
33 | background-image: -moz-linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
34 | background-image: -webkit-linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
35 | background-image: -ms-linear-gradient(bottom, #3A3A3A 50%, #444444 50%);
36 |
37 | background-image: -webkit-gradient(
38 | linear,
39 | left bottom,
40 | left top,
41 | color-stop(0.5, #3A3A3A),
42 | color-stop(0.5, #444444)
43 | );
44 | }
45 |
46 | /**
47 | * You can use these classes to hide parts
48 | * of the countdown that you don't need.
49 | */
50 |
51 | .countDays{ /* display:none !important;*/ }
52 | .countDiv0{ /* display:none !important;*/ }
53 | .countHours{}
54 | .countDiv1{}
55 | .countMinutes{}
56 | .countDiv2{}
57 | .countSeconds{}
58 |
59 |
60 | .countDiv{
61 | display:inline-block;
62 | width:16px;
63 | height:1.6em;
64 | position:relative;
65 | }
66 |
67 | .countDiv:before,
68 | .countDiv:after{
69 | position:absolute;
70 | width:5px;
71 | height:5px;
72 | background-color:#444;
73 | border-radius:50%;
74 | left:50%;
75 | margin-left:-3px;
76 | top:0.5em;
77 | box-shadow:1px 1px 1px rgba(4, 4, 4, 0.5);
78 | content:'';
79 | }
80 |
81 | .countDiv:after{
82 | top:0.9em;
83 | }
--------------------------------------------------------------------------------
/views/admin/insert/addProblem.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | form(action='insertProblem', method='POST')
8 | header
9 | h3 Create New Problem
10 | .module_content
11 | fieldset
12 | label Category
13 | select(name='category')
14 | - each categorie in categories
15 | option(value='#{categorie.idgrupos_problemas}') #{categorie.name}
16 | fieldset
17 | label Answer
18 | input(type='text', name='answer', value='')
19 | fieldset
20 | label Level
21 | select(name='level')
22 | option(value='1') 1
23 | option(value='2') 2
24 | option(value='3') 3
25 | option(value='4') 4
26 | fieldset
27 | label Points
28 | select(name='points')
29 | option(value='100') 100
30 | option(value='200') 200
31 | option(value='300') 300
32 | option(value='400') 400
33 | option(value='500') 500
34 | option(value='600') 600
35 | option(value='700') 700
36 | option(value='800') 800
37 | option(value='900') 900
38 | option(value='1000') 1000
39 | //
40 | input(type='text', name='points', value='')
41 | fieldset
42 | label Category Description
43 | textarea(rows='12', name='description')
44 | .clear
45 | footer
46 | .submit_link
47 | input.alt_btn(type='submit', value='Submit')
48 | input(type='submit', value='Reset')
49 | //
50 | end of post new article
51 | .spacer
--------------------------------------------------------------------------------
/public/javascripts/themes/grid.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Grid theme for Highcharts JS
3 | * @author Torstein Hønsi
4 | */
5 |
6 | Highcharts.theme = {
7 | colors: ['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'],
8 | chart: {
9 | backgroundColor: {
10 | linearGradient: [0, 0, 500, 500],
11 | stops: [
12 | [0, 'rgb(255, 255, 255)'],
13 | [1, 'rgb(240, 240, 255)']
14 | ]
15 | },
16 | borderWidth: 2,
17 | plotBackgroundColor: 'rgba(255, 255, 255, .9)',
18 | plotShadow: true,
19 | plotBorderWidth: 1
20 | },
21 | title: {
22 | style: {
23 | color: '#000',
24 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif'
25 | }
26 | },
27 | subtitle: {
28 | style: {
29 | color: '#666666',
30 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif'
31 | }
32 | },
33 | xAxis: {
34 | gridLineWidth: 1,
35 | lineColor: '#000',
36 | tickColor: '#000',
37 | labels: {
38 | style: {
39 | color: '#000',
40 | font: '11px Trebuchet MS, Verdana, sans-serif'
41 | }
42 | },
43 | title: {
44 | style: {
45 | color: '#333',
46 | fontWeight: 'bold',
47 | fontSize: '12px',
48 | fontFamily: 'Trebuchet MS, Verdana, sans-serif'
49 |
50 | }
51 | }
52 | },
53 | yAxis: {
54 | minorTickInterval: 'auto',
55 | lineColor: '#000',
56 | lineWidth: 1,
57 | tickWidth: 1,
58 | tickColor: '#000',
59 | labels: {
60 | style: {
61 | color: '#000',
62 | font: '11px Trebuchet MS, Verdana, sans-serif'
63 | }
64 | },
65 | title: {
66 | style: {
67 | color: '#333',
68 | fontWeight: 'bold',
69 | fontSize: '12px',
70 | fontFamily: 'Trebuchet MS, Verdana, sans-serif'
71 | }
72 | }
73 | },
74 | legend: {
75 | itemStyle: {
76 | font: '9pt Trebuchet MS, Verdana, sans-serif',
77 | color: 'black'
78 |
79 | },
80 | itemHoverStyle: {
81 | color: '#039'
82 | },
83 | itemHiddenStyle: {
84 | color: 'gray'
85 | }
86 | },
87 | labels: {
88 | style: {
89 | color: '#99b'
90 | }
91 | }
92 | };
93 |
94 | // Apply the theme
95 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
96 |
--------------------------------------------------------------------------------
/public/javascripts/themes/skies.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Skies theme for Highcharts JS
3 | * @author Torstein Hønsi
4 | */
5 |
6 | Highcharts.theme = {
7 | colors: ["#514F78", "#42A07B", "#9B5E4A", "#72727F", "#1F949A", "#82914E", "#86777F", "#42A07B"],
8 | chart: {
9 | className: 'skies',
10 | borderWidth: 0,
11 | plotShadow: true,
12 | plotBackgroundImage: '/demo/gfx/skies.jpg',
13 | plotBackgroundColor: {
14 | linearGradient: [0, 0, 250, 500],
15 | stops: [
16 | [0, 'rgba(255, 255, 255, 1)'],
17 | [1, 'rgba(255, 255, 255, 0)']
18 | ]
19 | },
20 | plotBorderWidth: 1
21 | },
22 | title: {
23 | style: {
24 | color: '#3E576F',
25 | font: '16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
26 | }
27 | },
28 | subtitle: {
29 | style: {
30 | color: '#6D869F',
31 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
32 | }
33 | },
34 | xAxis: {
35 | gridLineWidth: 0,
36 | lineColor: '#C0D0E0',
37 | tickColor: '#C0D0E0',
38 | labels: {
39 | style: {
40 | color: '#666',
41 | fontWeight: 'bold'
42 | }
43 | },
44 | title: {
45 | style: {
46 | color: '#666',
47 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
48 | }
49 | }
50 | },
51 | yAxis: {
52 | alternateGridColor: 'rgba(255, 255, 255, .5)',
53 | lineColor: '#C0D0E0',
54 | tickColor: '#C0D0E0',
55 | tickWidth: 1,
56 | labels: {
57 | style: {
58 | color: '#666',
59 | fontWeight: 'bold'
60 | }
61 | },
62 | title: {
63 | style: {
64 | color: '#666',
65 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
66 | }
67 | }
68 | },
69 | legend: {
70 | itemStyle: {
71 | font: '9pt Trebuchet MS, Verdana, sans-serif',
72 | color: '#3E576F'
73 | },
74 | itemHoverStyle: {
75 | color: 'black'
76 | },
77 | itemHiddenStyle: {
78 | color: 'silver'
79 | }
80 | },
81 | labels: {
82 | style: {
83 | color: '#3E576F'
84 | }
85 | }
86 | };
87 |
88 | // Apply the theme
89 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
90 |
--------------------------------------------------------------------------------
/public/javascripts/jquery.scrollTo-1.4.2-min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * jQuery.ScrollTo - Easy element scrolling using jQuery.
3 | * Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
4 | * Dual licensed under MIT and GPL.
5 | * Date: 5/25/2009
6 | * @author Ariel Flesler
7 | * @version 1.4.2
8 | *
9 | * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
10 | */
11 | ;(function(d){var k=d.scrollTo=function(a,i,e){d(window).scrollTo(a,i,e)};k.defaults={axis:'xy',duration:parseFloat(d.fn.jquery)>=1.3?0:1};k.window=function(a){return d(window)._scrollable()};d.fn._scrollable=function(){return this.map(function(){var a=this,i=!a.nodeName||d.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!i)return a;var e=(a.contentWindow||a).document||a.ownerDocument||a;return d.browser.safari||e.compatMode=='BackCompat'?e.body:e.documentElement})};d.fn.scrollTo=function(n,j,b){if(typeof j=='object'){b=j;j=0}if(typeof b=='function')b={onAfter:b};if(n=='max')n=9e9;b=d.extend({},k.defaults,b);j=j||b.speed||b.duration;b.queue=b.queue&&b.axis.length>1;if(b.queue)j/=2;b.offset=p(b.offset);b.over=p(b.over);return this._scrollable().each(function(){var q=this,r=d(q),f=n,s,g={},u=r.is('html,body');switch(typeof f){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(f)){f=p(f);break}f=d(f,this);case'object':if(f.is||f.style)s=(f=d(f)).offset()}d.each(b.axis.split(''),function(a,i){var e=i=='x'?'Left':'Top',h=e.toLowerCase(),c='scroll'+e,l=q[c],m=k.max(q,i);if(s){g[c]=s[h]+(u?0:l-r.offset()[h]);if(b.margin){g[c]-=parseInt(f.css('margin'+e))||0;g[c]-=parseInt(f.css('border'+e+'Width'))||0}g[c]+=b.offset[h]||0;if(b.over[h])g[c]+=f[i=='x'?'width':'height']()*b.over[h]}else{var o=f[h];g[c]=o.slice&&o.slice(-1)=='%'?parseFloat(o)/100*m:o}if(/^\d+$/.test(g[c]))g[c]=g[c]<=0?0:Math.min(g[c],m);if(!a&&b.queue){if(l!=g[c])t(b.onAfterFirst);delete g[c]}});t(b.onAfter);function t(a){r.animate(g,j,b.easing,a&&function(){a.call(this,n,b)})}}).end()};k.max=function(a,i){var e=i=='x'?'Width':'Height',h='scroll'+e;if(!d(a).is('html,body'))return a[h]-d(a)[e.toLowerCase()]();var c='client'+e,l=a.ownerDocument.documentElement,m=a.ownerDocument.body;return Math.max(l[h],m[h])-Math.min(l[c],m[c])};function p(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);
--------------------------------------------------------------------------------
/views/admin/config/options.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | form(action='editOptions', method='POST')
8 | header
9 | h3 General Options
10 | .module_content
11 | fieldset
12 | label Start Date
13 | input(type='text', name='startDate', value='#{config.start_date}')
14 | fieldset
15 | label End Date
16 | input(type='text', name='endDate', value='#{config.end_date}')
17 | fieldset
18 | label Random Problem Interval
19 | input(type='text', name='random_problem_opening_interval', value='#{config.random_problem_opening_interval}')
20 | .clear
21 | footer
22 | .submit_link
23 | input.alt_btn(type='submit', value='Submit')
24 | input.alt_btn(id='reloadConfig', type='submit', value='Reload Options at Server')
25 | article.module.width_full
26 | form(action='resetTeamlogs', method='POST')
27 | header
28 | h3 Reset Stuff
29 | .module_content
30 | fieldset
31 | p This will only reset team logs for now.
32 | .clear
33 | footer
34 | .submit_link
35 | input.alt_btn(id='reset', type='submit', value='Reset')
36 | article.module.width_full
37 | form
38 | header
39 | h3 Open Problem
40 | .module_content
41 | fieldset
42 | p Select problem to Open.
43 | fieldset
44 | label Category
45 | select(id='category', name='category')
46 | option
47 | - each categorie in categories
48 | option(value='#{categorie.idgrupos_problemas}', idproblem='#{categorie.idproblemas}', idgroup='#{categorie.idgrupos_problemas}') #{categorie.name} - #{categorie.points}
49 | .clear
50 | footer
51 | .submit_link
52 | input.alt_btn(id='adminActivateProblem', type='submit', value='Open')
53 | //
54 | end of post new article
55 | .spacer
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
ptcoresec-scoreboard-ctf
2 | ========================
3 |
4 | A scoreboard used for CTF jeopardy style events
5 |
6 | This is a scoreboard that can be used for jeopardy style tournaments. It was developed by us to be used in our capture the flag security events.
7 |
8 | INSTALLATION (Version 0.1)
9 |
10 | You need to have NodeJS, Redis and MySQL installed:
11 |
12 | We have tested the scoreboard with Ubuntu 12.04 64 bits, NodeJS versions 0.6.12 and 0.8.1, Redis version 2.2.12 and 2.4.15.
13 |
14 |
15 |
16 | sudo apt-get update
17 | sudo apt-get install nodejs redis-server mysql-server
18 |
19 |
20 |
21 | In the folder DB you will find two SQL scripts to import, tournament.sql (Complete database) and salts.sql (Password salts).
22 |
23 |
24 | cd BD
25 | mysql -u username -p < tournament.sql
26 | mysql -u username -p < salts.sql
27 |
28 |
29 |
30 | Go back to the main folder and configure the config.js file to use your MySQL database, it will look like this,
31 |
32 |
33 | var config = {};
34 |
35 | config.db = {};
36 | config.dbHashes = {};
37 |
38 | // Complete DB
39 | config.db.host = ''; // <-- Insert host
40 | config.db.user = ''; // <-- Insert user
41 | config.db.password = ''; // <-- Insert password
42 | //Don't Change.
43 | config.db.database = 'torneio';
44 |
45 | // Password Salt DB
46 | config.dbHashes.host = ''; // <-- Insert host
47 | config.dbHashes.user = ''; // <-- Insert user
48 | config.dbHashes.password = ''; // <-- Insert password
49 | //Don't Change.
50 | config.dbHashes.database = 'passsalts';
51 |
52 | module.exports = config;
53 |
54 |
55 |
56 | We will now generate keys to be used for HTTPS.
57 |
58 | You can generate the privatekey.pem and certificate.pem files using the following commands:
59 |
60 |
61 | cd keys
62 | openssl genrsa -out privatekey.pem 1024
63 | openssl req -new -key privatekey.pem -out certrequest.csr
64 | openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
65 |
66 |
67 |
68 | Now you just need to run node.
69 |
70 |
71 | cd ptcoresec-scoreboard-ctf
72 | node app.js
73 |
74 |
75 |
76 |
77 | You can then browse to https://server-address:3000 and login with username Administrator and password 123456
78 |
79 |
80 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/public/javascripts/bootstrap-alert.js:
--------------------------------------------------------------------------------
1 | /* ==========================================================
2 | * bootstrap-alert.js v2.0.2
3 | * http://twitter.github.com/bootstrap/javascript.html#alerts
4 | * ==========================================================
5 | * Copyright 2012 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ========================================================== */
19 |
20 |
21 | !function( $ ){
22 |
23 | "use strict"
24 |
25 | /* ALERT CLASS DEFINITION
26 | * ====================== */
27 |
28 | var dismiss = '[data-dismiss="alert"]'
29 | , Alert = function ( el ) {
30 | $(el).on('click', dismiss, this.close)
31 | }
32 |
33 | Alert.prototype = {
34 |
35 | constructor: Alert
36 |
37 | , close: function ( e ) {
38 | var $this = $(this)
39 | , selector = $this.attr('data-target')
40 | , $parent
41 |
42 | if (!selector) {
43 | selector = $this.attr('href')
44 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
45 | }
46 |
47 | $parent = $(selector)
48 | $parent.trigger('close')
49 |
50 | e && e.preventDefault()
51 |
52 | $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
53 |
54 | $parent
55 | .trigger('close')
56 | .removeClass('in')
57 |
58 | function removeElement() {
59 | $parent
60 | .trigger('closed')
61 | .remove()
62 | }
63 |
64 | $.support.transition && $parent.hasClass('fade') ?
65 | $parent.on($.support.transition.end, removeElement) :
66 | removeElement()
67 | }
68 |
69 | }
70 |
71 |
72 | /* ALERT PLUGIN DEFINITION
73 | * ======================= */
74 |
75 | $.fn.alert = function ( option ) {
76 | return this.each(function () {
77 | var $this = $(this)
78 | , data = $this.data('alert')
79 | if (!data) $this.data('alert', (data = new Alert(this)))
80 | if (typeof option == 'string') data[option].call($this)
81 | })
82 | }
83 |
84 | $.fn.alert.Constructor = Alert
85 |
86 |
87 | /* ALERT DATA-API
88 | * ============== */
89 |
90 | $(function () {
91 | $('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
92 | })
93 |
94 | }( window.jQuery );
--------------------------------------------------------------------------------
/public/javascripts/index.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 | var socket = io.connect();
3 |
4 | socket.on('globalMessage', function (data) {
5 | $().toastmessage('showToast', {
6 | text : data.message,
7 | sticky : data.sticky,
8 | type : 'notice'
9 | });
10 | });
11 |
12 | socket.on('start', function (data) {
13 | window.location.reload(true);
14 | });
15 |
16 | socket.on('reconnect', function (data) {
17 | window.location.reload(true);
18 | });
19 |
20 | socket.on('activateProblem', function (data) {
21 | $("div#"+data.group+''+data.problem).removeClass("pontuacao_closed");
22 | $('#'+data.group+''+data.problem).addClass("pontuacao_no_answer");
23 | $().toastmessage('showToast', {
24 | text : 'le wild problem appeared..',
25 | sticky : false,
26 | type : 'notice'
27 | });
28 | });
29 |
30 | socket.on('answers', function (data) {
31 | var teamid = data.teamid;
32 | var teamname = data.teamname;
33 | var group = data.group;
34 | var groupname = data.groupname;
35 | var problema = data.problem;
36 | var correct = data.correct;
37 | var sum_of_points = data.sum_of_points;
38 | //var myDate = new Date();
39 | var myDate = new Date(data.time);
40 | var timezone_delay = -myDate.getTimezoneOffset()*60*1000;
41 | myDate = new Date(myDate.getTime() + timezone_delay);
42 | var found = false;
43 |
44 | //console.log('Recebi pontos da team '+teamid+ ' - '+teamname+' - pontos '+sum_of_points+' data- '+myDate);
45 |
46 | for(var i = 0; chart.series[i]; i++){
47 | if(chart.series[i].options.id == teamid){
48 | if (!sum_of_points){
49 | sum_of_points = 0;
50 | }
51 | found = true;
52 | //console.log(chart.series[i].legendItem);
53 | var el = $(chart.series[i].legendItem.element);
54 | el.text(teamname+' - '+sum_of_points);
55 | var myCss = function(){el.css("font-size","12px")};
56 | myCss();
57 | el.hover(myCss).click(myCss);
58 | chart.series[i].addPoint({name: groupname, x: myDate.getTime(), y:parseInt(sum_of_points)});
59 | }
60 | }
61 | if(correct){
62 | $("div#"+group+''+problema).removeClass("pontuacao_no_answer");
63 | $("div#"+group+''+problema).removeClass("pontuacao_selected");
64 | $("div#"+group+''+problema).addClass("pontuacao_correct");
65 | }
66 | });
67 |
68 | socket.on('leader', function (data) {
69 | var leaderBoard = "";
70 | for(var i = 0; data.teams[i]; i++){
71 | var name = data.teams[i].name;
72 | var points = 0;
73 | if(data.teams[i].points){
74 | points = data.teams[i].points;
75 | }
76 | if(data.teams[i].idteams == $('#teamId').attr("team")){
77 | leaderBoard +=''+name+' - '+points+'
';
78 | }
79 | else{
80 | leaderBoard +=''+name+' - '+points+'
';
81 | }
82 | }
83 |
84 | document.getElementById("scores").innerHTML = leaderBoard;
85 | });
86 | });
87 |
--------------------------------------------------------------------------------
/public/stylesheets/jquery.toastmessage.css:
--------------------------------------------------------------------------------
1 | .toast-container {
2 | width: 280px;
3 | z-index: 9999;
4 | }
5 |
6 |
7 | * html .toast-container {
8 | position: absolute;
9 | }
10 |
11 | .toast-item {
12 | height: auto;
13 | background: #333;
14 | opacity: 0.9;
15 | -moz-border-radius: 10px;
16 | -webkit-border-radius: 10px;
17 | color: #eee;
18 | padding-top: 20px;
19 | padding-bottom: 20px;
20 | padding-left: 6px;
21 | padding-right: 6px;
22 | font-family: lucida Grande;
23 | font-size: 14px;
24 | border: 2px solid #999;
25 | display: block;
26 | position: relative;
27 | margin: 0 0 12px 0;
28 | }
29 |
30 | .toast-item p {
31 | text-align: left;
32 | margin-left: 50px;
33 | margin-top: 10px;
34 | }
35 |
36 | .toast-item-close {
37 | background:url(../images/close.gif);
38 | width:22px;
39 | height:22px;
40 | position: absolute;
41 | top:7px;
42 | right:7px;
43 | }
44 |
45 | .toast-item-image {
46 | width:32px;
47 | height: 32px;
48 | margin-left: 10px;
49 | margin-top: 10px;
50 | margin-right: 10px;
51 | float:left;
52 | }
53 |
54 | .toast-item-image-notice {
55 | background:url(../images/notice.png);
56 | }
57 |
58 | .toast-item-image-success {
59 | background:url(../images/success.png);
60 | }
61 |
62 | .toast-item-image-warning {
63 | background:url(../images/warning.png);
64 | }
65 |
66 | .toast-item-image-error {
67 | background:url(../images/error.png);
68 | }
69 |
70 |
71 | /**
72 | * toast types
73 | *
74 | * pattern: toast-type-[value]
75 | * where 'value' is the real value of the plugin option 'type'
76 | *
77 | */
78 | .toast-type-notice {
79 | color: white;
80 | }
81 |
82 | .toast-type-success {
83 | color: white;
84 | }
85 |
86 | .toast-type-warning {
87 | color: white;
88 | border-color: #FCBD57;
89 | }
90 |
91 | .toast-type-error {
92 | color: white;
93 | border-color: #B32B2B;
94 | }
95 |
96 | /**
97 | * positions
98 | *
99 | * pattern: toast-position-[value]
100 | * where 'value' is the real value of the plugin option 'position'
101 | *
102 | */
103 | .toast-position-top-left {
104 | position: fixed;
105 | left: 20px;
106 | top: 20px;
107 | }
108 |
109 | .toast-position-top-center {
110 | position: fixed;
111 | top: 20px;
112 | left: 50%;
113 | margin-left: -140px;
114 | }
115 |
116 | .toast-position-top-right {
117 | position: fixed;
118 | top: 20px;
119 | right: 20px;
120 | }
121 |
122 | .toast-position-middle-left {
123 | position: fixed;
124 | left: 20px;
125 | top: 50%;
126 | margin-top: -40px;
127 | }
128 |
129 | .toast-position-middle-center {
130 | position: fixed;
131 | left: 50%;
132 | margin-left: -140px;
133 | margin-top: -40px;
134 | top: 50%;
135 | }
136 |
137 | .toast-position-middle-right {
138 | position: fixed;
139 | right: 20px;
140 | margin-left: -140px;
141 | margin-top: -40px;
142 | top: 50%;
143 | }
144 |
--------------------------------------------------------------------------------
/public/javascripts/bootstrap-popover.js:
--------------------------------------------------------------------------------
1 | /* ===========================================================
2 | * bootstrap-popover.js v2.0.0
3 | * http://twitter.github.com/bootstrap/javascript.html#popovers
4 | * ===========================================================
5 | * Copyright 2012 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * =========================================================== */
19 |
20 |
21 | !function( $ ) {
22 |
23 | "use strict"
24 |
25 | var Popover = function ( element, options ) {
26 | this.init('popover', element, options)
27 | }
28 |
29 | /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
30 | ========================================== */
31 |
32 | Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
33 |
34 | constructor: Popover
35 |
36 | , setContent: function () {
37 | var $tip = this.tip()
38 | , title = this.getTitle()
39 | , content = this.getContent()
40 |
41 | $tip.find('.popover-title')[ $.type(title) == 'object' ? 'append' : 'html' ](title)
42 | $tip.find('.popover-content > *')[ $.type(content) == 'object' ? 'append' : 'html' ](content)
43 |
44 | $tip.removeClass('fade top bottom left right in')
45 | }
46 |
47 | , hasContent: function () {
48 | return this.getTitle() || this.getContent()
49 | }
50 |
51 | , getContent: function () {
52 | var content
53 | , $e = this.$element
54 | , o = this.options
55 |
56 | content = $e.attr('data-content')
57 | || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
58 |
59 | content = content.toString().replace(/(^\s*|\s*$)/, "")
60 |
61 | return content
62 | }
63 |
64 | , tip: function() {
65 | if (!this.$tip) {
66 | this.$tip = $(this.options.template)
67 | }
68 | return this.$tip
69 | }
70 |
71 | })
72 |
73 |
74 | /* POPOVER PLUGIN DEFINITION
75 | * ======================= */
76 |
77 | $.fn.popover = function ( option ) {
78 | return this.each(function () {
79 | var $this = $(this)
80 | , data = $this.data('popover')
81 | , options = typeof option == 'object' && option
82 | if (!data) $this.data('popover', (data = new Popover(this, options)))
83 | if (typeof option == 'string') data[option]()
84 | })
85 | }
86 |
87 | $.fn.popover.Constructor = Popover
88 |
89 | $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
90 | placement: 'right'
91 | , content: ''
92 | , template: ''
93 | })
94 |
95 | }( window.jQuery )
96 |
--------------------------------------------------------------------------------
/views/admin/layout.jade:
--------------------------------------------------------------------------------
1 | !!! 5
2 | html(lang='en')
3 | head
4 | meta(charset='utf-8')
5 | title PTCoreSec Admin Panel
6 | link(rel='stylesheet', href='/css/layout.css', type='text/css', media='screen')
7 | //if lt IE 9
8 | link(rel='stylesheet', href='/css/ie.css', type='text/css', media='screen')
9 | script(src='http://html5shim.googlecode.com/svn/trunk/html5.js')
10 | script(src='/javascripts/jquery.min.js')
11 | script(src='/javascripts/admin.js')
12 | script(src='/js/hideshow.js', type='text/javascript')
13 | script(src='/js/jquery.tablesorter.min.js', type='text/javascript')
14 | script(type='text/javascript', src='/js/jquery.equalHeight.js')
15 | script(type='text/javascript')
16 | $(document).ready(function()
17 | {
18 | $(".tablesorter").tablesorter();
19 | }
20 | );
21 | $(document).ready(function() {
22 | //When page loads...
23 | $(".tab_content").hide(); //Hide all content
24 | $("ul.tabs li:first").addClass("active").show(); //Activate first tab
25 | $(".tab_content:first").show(); //Show first tab content
26 | //On Click Event
27 | $("ul.tabs li").click(function() {
28 | $("ul.tabs li").removeClass("active"); //Remove any "active" class
29 | $(this).addClass("active"); //Add "active" class to selected tab
30 | $(".tab_content").hide(); //Hide all tab content
31 | var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
32 | $(activeTab).fadeIn(); //Fade in the active ID content
33 | return false;
34 | });
35 | });
36 | script(type='text/javascript')
37 | $(function(){
38 | $('.column').equalHeight();
39 | });
40 | body
41 | header#header
42 | hgroup
43 | h1.site_title
44 | a(href='/dashboard') PTCoreSec Admin
45 | //
46 | h2.section_title Dashboard
47 | //
48 | end of header bar
49 | section#secondary_bar
50 | .user
51 | p #{session.user}
52 | //
53 | Logout
54 | aside#sidebar.column
55 | h3 Manage Teams
56 | ul.toggle
57 | li.icn_add_user
58 | a(href='/addTeam') Add New Team
59 | li.icn_view_users
60 | a(href='/listTeams') List Teams
61 | //
62 | h3 Manage Challenges
63 | ul.toggle
64 | li.icn_new_article
65 | a(href='/addChallenge') Add New Challenge
66 | li.icn_categories
67 | a(href='/listChallenges') List Challenges
68 | h3 Manage Problems
69 | ul.toggle
70 | li.icn_new_article
71 | a(href='/addCategory') Add New Category
72 | li.icn_categories
73 | a(href='/listCategories') List Categories
74 | li.icn_new_article
75 | a(href='/addProblem') Add New Problem
76 | li.icn_categories
77 | a(href='/listProblems') List Problems
78 | h3 Scoreboard
79 | ul.toggle
80 | li.icn_settings
81 | a(href='/') Go back to Scoreboard
82 | h3 Admin
83 | ul.toggle
84 | li.icn_settings
85 | a(href='/options') Options
86 | li.icn_settings
87 | a(href='/comms') Communications
88 | li.icn_jump_back
89 | a(href='/logout') Logout
90 | //end of sidebar
91 | block content
92 |
93 | footer
94 | script(src='/socket.io/socket.io.js')
95 | block footer
--------------------------------------------------------------------------------
/views/layout.jade:
--------------------------------------------------------------------------------
1 | !!! 5
2 | html(lang='pt-PT')
3 | head
4 | title PTCoreSec
5 | link(rel='stylesheet', href='/stylesheets/bootstrap.css')
6 | link(rel='stylesheet', href='/stylesheets/style.css')
7 | link(rel='stylesheet', href='/stylesheets/jquery.countdown.css')
8 | link(rel='stylesheet', href='/stylesheets/jquery.toastmessage.css')
9 | script(src='../javascripts/jquery.min.js')
10 | script(src='/socket.io/socket.io.js')
11 | script(src='../javascripts/jquery.countdown.js')
12 | script(src='../javascripts/bootstrap.min.js')
13 | block scripts
14 | body
15 | #main
16 | div.navbar
17 | div.navbar-inner
18 | div.container(style='height:40px;')
19 | a(href='http://www.ptcoresec.eu/').brand PTCoreSec
20 | div.nav-collapse
21 | ul.nav
22 | if(session.path == '/')
23 | li.active
24 | a(href='/') Public
25 | else
26 | li
27 | a(href='/') Public
28 | - if (session.administrationLevel == 2)
29 | ul.nav
30 | if(session.path == '/dashboard')
31 | li.active
32 | a(href='/dashboard') Administration
33 | else
34 | li
35 | a(href='/dashboard') Administration
36 | - else
37 | - if (session.passport.user)
38 | ul.nav
39 | if(session.path == '/score')
40 | li.active
41 | a(href='/score') My Scoreboard
42 | else
43 | li
44 | a(href='/score') My Scoreboard
45 |
46 |
47 | ul.nav.pull-right
48 | - if (session.passport.user)
49 | ul.nav
50 | li
51 | p
52 | div(id='countdown')
53 | p(id='note')
54 | - var userType = ''
55 | - if (session.administrationLevel == 2)
56 | userType = 'Admin '
57 | - else
58 | userType = 'Team '
59 | li
60 | p.navbar-text #{userType}
61 | a(href='/', id='teamId', team='#{session.passport.user}') #{session.user}
62 | li.divider-vertical
63 | li
64 | p.navbar-text
65 | a(href='/logout') logout
66 | - else
67 | ul.nav
68 | li
69 | p
70 | div(id='countdown')
71 | p(id='note')
72 | ul.nav.nav-tabs.pull-right.signin-menu
73 | li.dropdown(id='menu1')
74 | a.dropdown-toggle(data-toggle='dropdown', href='#menu1') Login
75 | b.caret
76 | div.dropdown-menu
77 | form(style="margin: 0px;", action='/login', method='POST')
78 | fieldset.textbox(style="padding:10px;")
79 | div.clearfix
80 | input(style="margin-top: 8px", type='text', name='username', id='username', placeholder='Username')
81 | div.clearfix
82 | input(style="margin-top: 8px", type='password', name='password', id='password', placeholder='Password')
83 | button.btn.primary(type='submit') Login
84 | block content
85 |
86 | footer
87 | script(src='../javascripts/jquery.toastmessage.js')
88 | script(src='../javascripts/jquery-ui.min.js')
89 | script(src='../javascripts/bootstrap-collapse.js')
90 | script(src='../javascripts/bootstrap-popover.js')
91 | script(src='../javascripts/bootstrap-tooltip.js')
92 | script(src='../javascripts/bootstrap-modal.js')
93 | script(src='../javascripts/bootstrap-alert.js')
94 | script(src='../javascripts/bootstrap-tab.js')
95 | script(src='../javascripts/bootstrap-transition.js')
96 | block footer
--------------------------------------------------------------------------------
/public/javascripts/jquery.countdown.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @name jQuery Countdown Plugin
3 | * @author Martin Angelov
4 | * @version 1.0
5 | * @url http://tutorialzine.com/2011/12/countdown-jquery/
6 | * @license MIT License
7 | */
8 |
9 | (function($){
10 |
11 | // Number of seconds in every time division
12 | var days = 24*60*60,
13 | hours = 60*60,
14 | minutes = 60;
15 |
16 | // Creating the plugin
17 | $.fn.countdown = function(prop){
18 |
19 | var options = $.extend({
20 | callback : function(){},
21 | timestamp : 0
22 | },prop);
23 |
24 | var left, d, h, m, s, positions;
25 |
26 | // Initialize the plugin
27 | init(this, options);
28 |
29 | positions = this.find('.position');
30 |
31 | (function tick(){
32 |
33 | // Time left
34 | left = Math.floor((options.timestamp - (new Date())) / 1000);
35 |
36 | if(left < 0){
37 | left = 0;
38 | }
39 |
40 | // Number of days left
41 | d = Math.floor(left / days);
42 | updateDuo(0, 1, d);
43 | left -= d*days;
44 |
45 | // Number of hours left
46 | h = Math.floor(left / hours);
47 | updateDuo(2, 3, h);
48 | left -= h*hours;
49 |
50 | // Number of minutes left
51 | m = Math.floor(left / minutes);
52 | updateDuo(4, 5, m);
53 | left -= m*minutes;
54 |
55 | // Number of seconds left
56 | s = left;
57 | updateDuo(6, 7, s);
58 |
59 | // Calling an optional user supplied callback
60 | options.callback(d, h, m, s);
61 |
62 | // Scheduling another call of this function in 1s
63 | setTimeout(tick, 1000);
64 | })();
65 |
66 | // This function updates two digit positions at once
67 | function updateDuo(minor,major,value){
68 | switchDigit(positions.eq(minor),Math.floor(value/10)%10);
69 | switchDigit(positions.eq(major),value%10);
70 | }
71 |
72 | return this;
73 | };
74 |
75 |
76 | function init(elem, options){
77 | elem.addClass('countdownHolder');
78 |
79 | // Creating the markup inside the container
80 | $.each(['Days','Hours','Minutes','Seconds'],function(i){
81 | $('').html(
82 | '\
83 | 0\
84 | \
85 | \
86 | 0\
87 | '
88 | ).appendTo(elem);
89 |
90 | if(this!="Seconds"){
91 | elem.append('');
92 | }
93 | });
94 |
95 | }
96 |
97 | // Creates an animated transition between the two numbers
98 | function switchDigit(position,number){
99 |
100 | var digit = position.find('.digit')
101 |
102 | if(digit.is(':animated')){
103 | return false;
104 | }
105 |
106 | if(position.data('digit') == number){
107 | // We are already showing this number
108 | return false;
109 | }
110 |
111 | position.data('digit', number);
112 |
113 | var replacement = $('',{
114 | 'class':'digit',
115 | css:{
116 | top:'-2.1em',
117 | opacity:0
118 | },
119 | html:number
120 | });
121 |
122 | // The .static class is added when the animation
123 | // completes. This makes it run smoother.
124 |
125 | digit
126 | .before(replacement)
127 | .removeClass('static')
128 | .animate({top:'2.5em',opacity:0},'fast',function(){
129 | digit.remove();
130 | })
131 |
132 | replacement
133 | .delay(100)
134 | .animate({top:0,opacity:1},'fast',function(){
135 | replacement.addClass('static');
136 | });
137 | }
138 | })(jQuery);
--------------------------------------------------------------------------------
/BD/salts.sql:
--------------------------------------------------------------------------------
1 | CREATE DATABASE IF NOT EXISTS `torneio` /*!40100 DEFAULT CHARACTER SET latin1 */;
2 | USE `torneio`;
3 | -- MySQL dump 10.13 Distrib 5.5.16, for Win32 (x86)
4 | --
5 | -- Host: zeus.gank.eu Database: torneio
6 | -- ------------------------------------------------------
7 | -- Server version 5.1.63-0ubuntu0.11.04.1
8 |
9 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
10 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
11 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
12 | /*!40101 SET NAMES utf8 */;
13 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
14 | /*!40103 SET TIME_ZONE='+00:00' */;
15 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
16 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
17 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
18 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
19 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
20 |
21 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
22 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
23 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
24 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
25 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
26 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
27 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
28 |
29 | -- Dump completed on 2012-07-14 19:18:42
30 | CREATE DATABASE IF NOT EXISTS `passsalts` /*!40100 DEFAULT CHARACTER SET latin1 */;
31 | USE `passsalts`;
32 | -- MySQL dump 10.13 Distrib 5.5.16, for Win32 (x86)
33 | --
34 | -- Host: zeus.gank.eu Database: torneioHashes
35 | -- ------------------------------------------------------
36 | -- Server version 5.1.63-0ubuntu0.11.04.1
37 |
38 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
39 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
40 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
41 | /*!40101 SET NAMES utf8 */;
42 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
43 | /*!40103 SET TIME_ZONE='+00:00' */;
44 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
45 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
46 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
47 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
48 |
49 | --
50 | -- Table structure for table `userHashes`
51 | --
52 |
53 | DROP TABLE IF EXISTS `userHashes`;
54 | /*!40101 SET @saved_cs_client = @@character_set_client */;
55 | /*!40101 SET character_set_client = utf8 */;
56 | CREATE TABLE `userHashes` (
57 | `idteams` int(11) NOT NULL,
58 | `salt` varchar(100) DEFAULT NULL,
59 | PRIMARY KEY (`idteams`)
60 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
61 | /*!40101 SET character_set_client = @saved_cs_client */;
62 |
63 | --
64 | -- Dumping data for table `userHashes`
65 | --
66 |
67 | LOCK TABLES `userHashes` WRITE;
68 | /*!40000 ALTER TABLE `userHashes` DISABLE KEYS */;
69 | INSERT INTO `userHashes` VALUES (31,'KMq8MCrVe0lPl01qyv8a');
70 | /*!40000 ALTER TABLE `userHashes` ENABLE KEYS */;
71 | UNLOCK TABLES;
72 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
73 |
74 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
75 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
76 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
77 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
78 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
79 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
80 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
81 |
82 | -- Dump completed on 2012-07-14 19:18:43
83 |
--------------------------------------------------------------------------------
/public/javascripts/bootstrap-tab.js:
--------------------------------------------------------------------------------
1 | /* ========================================================
2 | * bootstrap-tab.js v2.0.3
3 | * http://twitter.github.com/bootstrap/javascript.html#tabs
4 | * ========================================================
5 | * Copyright 2012 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ======================================================== */
19 |
20 |
21 | !function ($) {
22 |
23 | "use strict"; // jshint ;_;
24 |
25 |
26 | /* TAB CLASS DEFINITION
27 | * ==================== */
28 |
29 | var Tab = function ( element ) {
30 | this.element = $(element)
31 | }
32 |
33 | Tab.prototype = {
34 |
35 | constructor: Tab
36 |
37 | , show: function () {
38 | var $this = this.element
39 | , $ul = $this.closest('ul:not(.dropdown-menu)')
40 | , selector = $this.attr('data-target')
41 | , previous
42 | , $target
43 | , e
44 |
45 | if (!selector) {
46 | selector = $this.attr('href')
47 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
48 | }
49 |
50 | if ( $this.parent('li').hasClass('active') ) return
51 |
52 | previous = $ul.find('.active a').last()[0]
53 |
54 | e = $.Event('show', {
55 | relatedTarget: previous
56 | })
57 |
58 | $this.trigger(e)
59 |
60 | if (e.isDefaultPrevented()) return
61 |
62 | $target = $(selector)
63 |
64 | this.activate($this.parent('li'), $ul)
65 | this.activate($target, $target.parent(), function () {
66 | $this.trigger({
67 | type: 'shown'
68 | , relatedTarget: previous
69 | })
70 | })
71 | }
72 |
73 | , activate: function ( element, container, callback) {
74 | var $active = container.find('> .active')
75 | , transition = callback
76 | && $.support.transition
77 | && $active.hasClass('fade')
78 |
79 | function next() {
80 | $active
81 | .removeClass('active')
82 | .find('> .dropdown-menu > .active')
83 | .removeClass('active')
84 |
85 | element.addClass('active')
86 |
87 | if (transition) {
88 | element[0].offsetWidth // reflow for transition
89 | element.addClass('in')
90 | } else {
91 | element.removeClass('fade')
92 | }
93 |
94 | if ( element.parent('.dropdown-menu') ) {
95 | element.closest('li.dropdown').addClass('active')
96 | }
97 |
98 | callback && callback()
99 | }
100 |
101 | transition ?
102 | $active.one($.support.transition.end, next) :
103 | next()
104 |
105 | $active.removeClass('in')
106 | }
107 | }
108 |
109 |
110 | /* TAB PLUGIN DEFINITION
111 | * ===================== */
112 |
113 | $.fn.tab = function ( option ) {
114 | return this.each(function () {
115 | var $this = $(this)
116 | , data = $this.data('tab')
117 | if (!data) $this.data('tab', (data = new Tab(this)))
118 | if (typeof option == 'string') data[option]()
119 | })
120 | }
121 |
122 | $.fn.tab.Constructor = Tab
123 |
124 |
125 | /* TAB DATA-API
126 | * ============ */
127 |
128 | $(function () {
129 | $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
130 | e.preventDefault()
131 | $(this).tab('show')
132 | })
133 | })
134 |
135 | }(window.jQuery);
--------------------------------------------------------------------------------
/public/javascripts/bootstrap-transition.js:
--------------------------------------------------------------------------------
1 | /* ===================================================
2 | * bootstrap-transition.js v2.0.4
3 | * http://twitter.github.com/bootstrap/javascript.html#transitions
4 | * ===================================================
5 | * Copyright 2012 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ========================================================== */
19 |
20 |
21 | !function ($) {
22 |
23 | $(function () {
24 |
25 | "use strict"; // jshint ;_;
26 |
27 |
28 | /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
29 | * ======================================================= */
30 |
31 | $.support.transition = (function () {
32 |
33 | var transitionEnd = (function () {
34 |
35 | var el = document.createElement('bootstrap')
36 | , transEndEventNames = {
37 | 'WebkitTransition' : 'webkitTransitionEnd'
38 | , 'MozTransition' : 'transitionend'
39 | , 'OTransition' : 'oTransitionEnd'
40 | , 'msTransition' : 'MSTransitionEnd'
41 | , 'transition' : 'transitionend'
42 | }
43 | , name
44 |
45 | for (name in transEndEventNames){
46 | if (el.style[name] !== undefined) {
47 | return transEndEventNames[name]
48 | }
49 | }
50 |
51 | }())
52 |
53 | return transitionEnd && {
54 | end: transitionEnd
55 | }
56 |
57 | })()
58 |
59 | })
60 |
61 | }(window.jQuery);/* ===================================================
62 | * bootstrap-transition.js v2.0.4
63 | * http://twitter.github.com/bootstrap/javascript.html#transitions
64 | * ===================================================
65 | * Copyright 2012 Twitter, Inc.
66 | *
67 | * Licensed under the Apache License, Version 2.0 (the "License");
68 | * you may not use this file except in compliance with the License.
69 | * You may obtain a copy of the License at
70 | *
71 | * http://www.apache.org/licenses/LICENSE-2.0
72 | *
73 | * Unless required by applicable law or agreed to in writing, software
74 | * distributed under the License is distributed on an "AS IS" BASIS,
75 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
76 | * See the License for the specific language governing permissions and
77 | * limitations under the License.
78 | * ========================================================== */
79 |
80 |
81 | !function ($) {
82 |
83 | $(function () {
84 |
85 | "use strict"; // jshint ;_;
86 |
87 |
88 | /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
89 | * ======================================================= */
90 |
91 | $.support.transition = (function () {
92 |
93 | var transitionEnd = (function () {
94 |
95 | var el = document.createElement('bootstrap')
96 | , transEndEventNames = {
97 | 'WebkitTransition' : 'webkitTransitionEnd'
98 | , 'MozTransition' : 'transitionend'
99 | , 'OTransition' : 'oTransitionEnd'
100 | , 'msTransition' : 'MSTransitionEnd'
101 | , 'transition' : 'transitionend'
102 | }
103 | , name
104 |
105 | for (name in transEndEventNames){
106 | if (el.style[name] !== undefined) {
107 | return transEndEventNames[name]
108 | }
109 | }
110 |
111 | }())
112 |
113 | return transitionEnd && {
114 | end: transitionEnd
115 | }
116 |
117 | })()
118 |
119 | })
120 |
121 | }(window.jQuery);
--------------------------------------------------------------------------------
/routes/score.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * GET home page.
4 | */
5 |
6 | var mysql = require('mysql');
7 | var util = require('util');
8 | var connections = require('../BD/db.js');
9 |
10 |
11 | connections.connection.on('close', function(err) {
12 | if (err) {
13 | // We did not expect this connection to terminate
14 | util.log('ligacao caiu mas vou restabelecer');
15 | connections.connection = mysql.createConnection(connections.connection.config);
16 | } else {
17 | // We expected this to happen, end() was called.
18 | }
19 | });
20 |
21 | connections.connection.on('error', function(err) {
22 | util.log(err.code); // 'ER_BAD_DB_ERROR'
23 | util.log('ligacao caiu mas vou restabelecer');
24 | connections.connection = mysql.createConnection(connections.connection.config);
25 | });
26 |
27 | exports.answer= function(req, res){
28 | console.log('Recebi uma answer');
29 | console.log(req.body);
30 |
31 | }
32 |
33 |
34 |
35 |
36 | exports.score = function(req, res){
37 | var sqlGrupos = 'SELECT * FROM torneio.grupos_problemas';
38 | var problems = new Array;
39 | var groups = new Array;
40 | connections.connection.query(sqlGrupos, function(errGroups, rowsGroups, fieldsGroups) {
41 | if(errGroups){
42 | console.log('err - '+errGroups);
43 | }
44 | if(rowsGroups.length == 0){
45 | console.log('Nao encontrei nada');
46 | callbackRender(req, res, {}, {});
47 | }
48 | else{
49 | groups = rowsGroups;
50 | var totalGroups = 0;
51 | for(var i = 0; rowsGroups[i];i++){
52 | var sqlProblemas = 'SELECT p.*, SUM(t.correct) as correct FROM problemas as p LEFT JOIN teams_log as t '
53 | +' on p.idgrupos_problemas = t.idgrupos_problemas and p.idproblemas = t.idproblemas '
54 | +' and t.idteams = '+req.session.teamId+' '
55 | + 'where p.idgrupos_problemas = '+rowsGroups[i].idgrupos_problemas+' '
56 | +' group by p.idproblemas ORDER by points';
57 | connections.connection.query(sqlProblemas, function(err, rows, fields) {
58 | if(err){
59 | console.log('err - '+err);
60 | totalGroups++;
61 | }
62 | else{
63 | problems[totalGroups] = rows;
64 | totalGroups++;
65 | if(totalGroups == rowsGroups.length){
66 | callbackRender(req, res, groups, problems)
67 | }
68 | }
69 | });
70 | }
71 | }
72 | });
73 | }
74 |
75 |
76 | function callbackRender(req, res, groups, problems){
77 | var teams = new Array;
78 | var sqlConfig = 'SELECT * from config';
79 | var sqlTeams = 'SELECT * FROM teams where administrationLevel = 0';
80 |
81 | var sqlTeamsPoints = 'SELECT t.idteams, name, sum(p.points) as points, (SELECT data from teams_log where teams_log.idteams = t.idteams order by data desc limit 1) as data '
82 | + ', problems_to_open_level_1, problems_to_open_level_2, problems_to_open_level_3, problems_to_open_level_4 '
83 | +'FROM teams '
84 | +'LEFT JOIN teams_log as t on t.idteams = teams.idteams '
85 | +'LEFT JOIN problemas as p ON t.idgrupos_problemas = p.idgrupos_problemas AND t.idproblemas = p.idproblemas '
86 | +'where administrationLevel = 0 and (t.correct = 1 OR t.correct IS NULL) '
87 | +'group by teams.idteams order by points desc, data asc '
88 | connections.connection.query(sqlTeamsPoints, function(errTeams, rowsTeams, fieldsTeams) {
89 | if(errTeams){
90 | console.log('errTeams - '+errTeams);
91 | }
92 | connections.connection.query(sqlConfig, function(errConfig, rowsConfig, fieldsConfig) {
93 | req.session.user = req.user[0].name;
94 | res.cookie('teamid', req.session.teamId);
95 | res.cookie('teamname', req.user[0].name);
96 | req.session.path = req.route.path;
97 | req.session.administrationLevel = req.user[0].administrationLevel;
98 | var open;
99 | var now = new Date();
100 | if(now < rowsConfig[0].start_date){
101 | open = false;
102 | }
103 | else{
104 | open = true;
105 | }
106 | var level1 = 0;
107 | var level2 = 0;
108 | var level3 = 0;
109 | for(var i = 0; rowsTeams[i];i++){
110 | if(rowsTeams[i].idteams == req.session.teamId){
111 | level1 = rowsTeams[i].problems_to_open_level_1;
112 | level2 = rowsTeams[i].problems_to_open_level_2;
113 | level3 = rowsTeams[i].problems_to_open_level_3;
114 | }
115 | }
116 | res.render('score', { title: 'PTCoreSec Scoreboard', thisteam: req.session.teamId, level1: level1, level2: level2, level3: level3, open: open, config: rowsConfig, groups: groups, problems: problems, teams: rowsTeams})
117 | });
118 | });
119 | }
--------------------------------------------------------------------------------
/public/javascripts/bootstrap-collapse.js:
--------------------------------------------------------------------------------
1 | /* =============================================================
2 | * bootstrap-collapse.js v2.0.0
3 | * http://twitter.github.com/bootstrap/javascript.html#collapse
4 | * =============================================================
5 | * Copyright 2012 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ============================================================ */
19 |
20 | !function( $ ){
21 |
22 | "use strict"
23 |
24 | var Collapse = function ( element, options ) {
25 | this.$element = $(element)
26 | this.options = $.extend({}, $.fn.collapse.defaults, options)
27 |
28 | if (this.options["parent"]) {
29 | this.$parent = $(this.options["parent"])
30 | }
31 |
32 | this.options.toggle && this.toggle()
33 | }
34 |
35 | Collapse.prototype = {
36 |
37 | constructor: Collapse
38 |
39 | , dimension: function () {
40 | var hasWidth = this.$element.hasClass('width')
41 | return hasWidth ? 'width' : 'height'
42 | }
43 |
44 | , show: function () {
45 | var dimension = this.dimension()
46 | , scroll = $.camelCase(['scroll', dimension].join('-'))
47 | , actives = this.$parent && this.$parent.find('.in')
48 | , hasData
49 |
50 | if (actives && actives.length) {
51 | hasData = actives.data('collapse')
52 | actives.collapse('hide')
53 | hasData || actives.data('collapse', null)
54 | }
55 |
56 | this.$element[dimension](0)
57 | this.transition('addClass', 'show', 'shown')
58 | this.$element[dimension](this.$element[0][scroll])
59 |
60 | }
61 |
62 | , hide: function () {
63 | var dimension = this.dimension()
64 | this.reset(this.$element[dimension]())
65 | this.transition('removeClass', 'hide', 'hidden')
66 | this.$element[dimension](0)
67 | }
68 |
69 | , reset: function ( size ) {
70 | var dimension = this.dimension()
71 |
72 | this.$element
73 | .removeClass('collapse')
74 | [dimension](size || 'auto')
75 | [0].offsetWidth
76 |
77 | this.$element.addClass('collapse')
78 | }
79 |
80 | , transition: function ( method, startEvent, completeEvent ) {
81 | var that = this
82 | , complete = function () {
83 | if (startEvent == 'show') that.reset()
84 | that.$element.trigger(completeEvent)
85 | }
86 |
87 | this.$element
88 | .trigger(startEvent)
89 | [method]('in')
90 |
91 | $.support.transition && this.$element.hasClass('collapse') ?
92 | this.$element.one($.support.transition.end, complete) :
93 | complete()
94 | }
95 |
96 | , toggle: function () {
97 | this[this.$element.hasClass('in') ? 'hide' : 'show']()
98 | }
99 |
100 | }
101 |
102 | /* COLLAPSIBLE PLUGIN DEFINITION
103 | * ============================== */
104 |
105 | $.fn.collapse = function ( option ) {
106 | return this.each(function () {
107 | var $this = $(this)
108 | , data = $this.data('collapse')
109 | , options = typeof option == 'object' && option
110 | if (!data) $this.data('collapse', (data = new Collapse(this, options)))
111 | if (typeof option == 'string') data[option]()
112 | })
113 | }
114 |
115 | $.fn.collapse.defaults = {
116 | toggle: true
117 | }
118 |
119 | $.fn.collapse.Constructor = Collapse
120 |
121 |
122 | /* COLLAPSIBLE DATA-API
123 | * ==================== */
124 |
125 | $(function () {
126 | $('body').on('click.collapse.data-api', '[data-toggle=collapse]', function ( e ) {
127 | var $this = $(this), href
128 | , target = $this.attr('data-target')
129 | || e.preventDefault()
130 | || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
131 | , option = $(target).data('collapse') ? 'toggle' : $this.data()
132 | $(target).collapse(option)
133 | })
134 | })
135 |
136 | }( window.jQuery )
137 |
--------------------------------------------------------------------------------
/views/admin/list/listChallenges.jade:
--------------------------------------------------------------------------------
1 | extends ../layout
2 |
3 | block content
4 | section#main.column
5 | .clear
6 | article.module.width_full
7 | header
8 | h3.tabs_involved Content Manager
9 | ul.tabs
10 | li
11 | a(href='#tab1') Posts
12 | li
13 | a(href='#tab2') Comments
14 | .tab_container
15 | #tab1.tab_content
16 | table.tablesorter(cellspacing='0')
17 | thead
18 | tr
19 | th
20 | th Entry Name
21 | th Category
22 | th Created On
23 | th Actions
24 | tbody
25 | tr
26 | td
27 | input(type='checkbox')
28 | td Lorem Ipsum Dolor Sit Amet
29 | td Articles
30 | td 5th April 2011
31 | td
32 | input(type='image', src='images/icn_edit.png', title='Edit')
33 | input(type='image', src='images/icn_trash.png', title='Trash')
34 | tr
35 | td
36 | input(type='checkbox')
37 | td Ipsum Lorem Dolor Sit Amet
38 | td Freebies
39 | td 6th April 2011
40 | td
41 | input(type='image', src='images/icn_edit.png', title='Edit')
42 | input(type='image', src='images/icn_trash.png', title='Trash')
43 | tr
44 | td
45 | input(type='checkbox')
46 | td Sit Amet Dolor Ipsum
47 | td Tutorials
48 | td 10th April 2011
49 | td
50 | input(type='image', src='images/icn_edit.png', title='Edit')
51 | input(type='image', src='images/icn_trash.png', title='Trash')
52 | tr
53 | td
54 | input(type='checkbox')
55 | td Dolor Lorem Amet
56 | td Articles
57 | td 16th April 2011
58 | td
59 | input(type='image', src='images/icn_edit.png', title='Edit')
60 | input(type='image', src='images/icn_trash.png', title='Trash')
61 | tr
62 | td
63 | input(type='checkbox')
64 | td Dolor Lorem Amet
65 | td Articles
66 | td 16th April 2011
67 | td
68 | input(type='image', src='images/icn_edit.png', title='Edit')
69 | input(type='image', src='images/icn_trash.png', title='Trash')
70 | //
71 | end of #tab1
72 | #tab2.tab_content
73 | table.tablesorter(cellspacing='0')
74 | thead
75 | tr
76 | th
77 | th Comment
78 | th Posted by
79 | th Posted On
80 | th Actions
81 | tbody
82 | tr
83 | td
84 | input(type='checkbox')
85 | td Lorem Ipsum Dolor Sit Amet
86 | td Mark Corrigan
87 | td 5th April 2011
88 | td
89 | input(type='image', src='images/icn_edit.png', title='Edit')
90 | input(type='image', src='images/icn_trash.png', title='Trash')
91 | tr
92 | td
93 | input(type='checkbox')
94 | td Ipsum Lorem Dolor Sit Amet
95 | td Jeremy Usbourne
96 | td 6th April 2011
97 | td
98 | input(type='image', src='images/icn_edit.png', title='Edit')
99 | input(type='image', src='images/icn_trash.png', title='Trash')
100 | tr
101 | td
102 | input(type='checkbox')
103 | td Sit Amet Dolor Ipsum
104 | td Super Hans
105 | td 10th April 2011
106 | td
107 | input(type='image', src='images/icn_edit.png', title='Edit')
108 | input(type='image', src='images/icn_trash.png', title='Trash')
109 | tr
110 | td
111 | input(type='checkbox')
112 | td Dolor Lorem Amet
113 | td Alan Johnson
114 | td 16th April 2011
115 | td
116 | input(type='image', src='images/icn_edit.png', title='Edit')
117 | input(type='image', src='images/icn_trash.png', title='Trash')
118 | tr
119 | td
120 | input(type='checkbox')
121 | td Dolor Lorem Amet
122 | td Dobby
123 | td 16th April 2011
124 | td
125 | input(type='image', src='images/icn_edit.png', title='Edit')
126 | input(type='image', src='images/icn_trash.png', title='Trash')
127 | //
128 | end of #tab2
129 | //
130 | end of .tab_container
131 | //
132 | end of content manager article
133 | .spacer
134 |
--------------------------------------------------------------------------------
/routes/index.js:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * GET home page.
4 | */
5 |
6 | var mysql = require('mysql');
7 | var util = require('util');
8 | var connections = require('../BD/db.js');
9 |
10 |
11 | connections.connection.on('close', function(err) {
12 | if (err) {
13 | // We did not expect this connection to terminate
14 | util.log('ligacao caiu mas vou restabelecer');
15 | connections.connection = mysql.createConnection(connections.connection.config);
16 | } else {
17 | // We expected this to happen, end() was called.
18 | }
19 | });
20 |
21 | connections.connection.on('error', function(err) {
22 | util.log(err.code); // 'ER_BAD_DB_ERROR'
23 | util.log('ligacao caiu mas vou restabelecer');
24 | connections.connection = mysql.createConnection(connections.connection.config);
25 | });
26 |
27 |
28 | exports.index = function(req, res){
29 | var sqlGrupos = 'SELECT * FROM torneio.grupos_problemas';
30 | var problems = new Array;
31 | var groups = new Array;
32 | connections.connection.query(sqlGrupos, function(errGroups, rowsGroups, fieldsGroups) {
33 | if(errGroups){
34 | console.log('err - '+errGroups);
35 | }
36 | if(rowsGroups.length == 0){
37 | callbackRender(req, res, {}, {})
38 | }
39 | else{
40 | groups = rowsGroups;
41 | var totalGroups = 0;
42 | for(var i = 0; rowsGroups[i];i++){
43 | var sqlProblemas = 'SELECT p.*, SUM(t.correct) as correct FROM problemas as p LEFT JOIN teams_log as t '
44 | +' on p.idgrupos_problemas = t.idgrupos_problemas and p.idproblemas = t.idproblemas '
45 | + 'where p.idgrupos_problemas = '+rowsGroups[i].idgrupos_problemas+' '
46 | +' group by p.idproblemas ORDER by points';
47 | connections.connection.query(sqlProblemas, function(err, rows, fields) {
48 | if(err){
49 | console.log('err - '+err);
50 | totalGroups++;
51 | }
52 | else{
53 | problems[totalGroups] = rows;
54 | totalGroups++;
55 | if(totalGroups == rowsGroups.length){
56 | callbackRender(req, res, groups, problems)
57 | }
58 | }
59 | });
60 | }
61 | }
62 | });
63 | };
64 |
65 | function callbackRender(req, res, groups, problems){
66 | var teams = new Array;
67 | var sqlTeams = 'SELECT * FROM teams where administrationLevel = 0';
68 | var sqlConfig = 'SELECT * from config';
69 | var sqlTeamsPoints = 'SELECT t.idteams, name, sum(p.points) as points, (SELECT data from teams_log where teams_log.idteams = t.idteams order by data desc limit 1) as data '
70 | + ', problems_to_open_level_1, problems_to_open_level_2, problems_to_open_level_3, problems_to_open_level_4 '
71 | +'FROM teams '
72 | +'LEFT JOIN teams_log as t on t.idteams = teams.idteams '
73 | +'LEFT JOIN problemas as p ON t.idgrupos_problemas = p.idgrupos_problemas AND t.idproblemas = p.idproblemas '
74 | +'where administrationLevel = 0 and (t.correct = 1 OR t.correct IS NULL) '
75 | +'group by teams.idteams order by points desc, data asc '
76 | var sqlTeamsPointsLogs = 'SELECT t.idteams, DATE_FORMAT(t.data, \'%Y-%m-%d %H:%i:%s\') as data, t.sum_of_points, gp.name from teams_log as t, teams, grupos_problemas as gp where t.idteams = teams.idteams and t.idgrupos_problemas = gp.idgrupos_problemas order by data';
77 | connections.connection.query(sqlTeamsPoints, function(errTeams, rowsTeams, fieldsTeams) {
78 | connections.connection.query(sqlTeamsPointsLogs, function(err, rowsLogs, fieldsLogs) {
79 | if(req.user){
80 | if(req.user[0]){
81 | req.session.user = req.user[0].name;
82 | res.cookie('teamid', req.session.teamId);
83 | req.session.administrationLevel = req.user[0].administrationLevel;
84 | }
85 | }
86 | req.session.path = req.route.path;
87 | var processLogs = [];
88 | var teamsDataAll = [];
89 | for(var i = 0; rowsLogs[i];i++){
90 | if(teamsDataAll[rowsLogs[i].idteams]){
91 | if(rowsLogs[i].sum_of_points){
92 | var myDate = new Date(rowsLogs[i].data);
93 | var timezone_delay = -myDate.getTimezoneOffset()*60*1000;
94 | myDate = new Date(myDate.getTime() + timezone_delay);
95 | teamsDataAll[rowsLogs[i].idteams].push({name: rowsLogs[i].name, x:(myDate).getTime(), y:rowsLogs[i].sum_of_points});
96 | }
97 | }
98 | else{
99 | teamsDataAll[rowsLogs[i].idteams] = new Array();
100 | var myDate = new Date(rowsLogs[i].data);
101 | var timezone_delay = -myDate.getTimezoneOffset()*60*1000;
102 | myDate = new Date(myDate.getTime() + timezone_delay);
103 |
104 | teamsDataAll[rowsLogs[i].idteams].push({name: rowsLogs[i].name, x: (myDate).getTime(), y:rowsLogs[i].sum_of_points});
105 | }
106 | }
107 |
108 |
109 | connections.connection.query(sqlTeams, function(errTeams, rows, fields) {
110 |
111 | for(var i = 0; rows[i];i++){
112 | var teamid = rows[i].idteams;
113 | if(teamsDataAll[rows[i].idteams]){
114 | processLogs.push({name: rows[i].name, id: teamid, data: teamsDataAll[rows[i].idteams]});
115 | }
116 | else {
117 | if(rows[i].administrationLevel == 0){
118 | processLogs.push({name: rows[i].name, id: teamid, data: []});
119 | }
120 | }
121 | }
122 |
123 | connections.connection.query(sqlConfig, function(errConfig, rowsConfig, fieldsConfig) {
124 | res.render('index', { title: 'PTCoreSec Scoreboard', config: rowsConfig, groups: groups, problems: problems, teams: rowsTeams, logs: processLogs});
125 | });
126 | });
127 |
128 | });
129 | });
130 | }
--------------------------------------------------------------------------------
/views/score.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block scripts
4 | script(src='../javascripts/jquery.scrollTo-1.4.2-min.js')
5 | link(rel='stylesheet', href='/stylesheets/style.css')
6 |
7 | script(type='text/javascript')
8 | $(document).ready(function() {
9 | var level1 = #{level1};
10 | var level2 = #{level2};
11 | var level3 = #{level3};
12 |
13 |
14 | $('div.exampleborderradiusa').each(function(index) {
15 | var level = jQuery(this).attr("level");
16 | if((level == 2 && level1>0) || (level == 3 && level2>0) || (level3>0 && level == 4)){
17 | if(jQuery(this).hasClass('pontuacao_closed')){
18 | jQuery(this).removeClass("pontuacao_closed");
19 | jQuery(this).addClass("pontuacao_can_open");
20 | }
21 | }
22 | });
23 |
24 |
25 |
26 | var start = new Date('#{config[0].start_date}');
27 | var end = new Date('#{config[0].end_date}');
28 | var note = $('#note');
29 | ts = start;
30 | newYear = true;
31 | if(note){
32 | if((new Date()) > ts){
33 | // The new year is here! Count towards something else.
34 | // Notice the *1000 at the end - time must be in milliseconds
35 | ts = end;
36 | newYear = false;
37 | }
38 |
39 | $('#countdown').countdown({
40 | timestamp : ts,
41 | callback : function(days, hours, minutes, seconds){
42 | var message = "";
43 | note.html(message);
44 | }
45 | });
46 | }
47 | });
48 | script(src='../javascripts/script.js')
49 | block content
50 | div(id='page')
51 | - if(!open)
52 | div(style='margin:0 auto;text-align:center;')
53 | //
54 | h3 Soon..
55 | img(src='soon.png', alt='Soon, height='400', width='400')
56 | - else
57 | div(id='conteudoGeral')
58 | div(id='conteudo')
59 | table
60 | tr
61 | td
62 | div(id='left')
63 | - var largura = groups.length*173
64 | - var numProblems = 0
65 | - each problemsFromGroup in problems
66 | -if(problemsFromGroup.length>numProblems)
67 | - numProblems = problemsFromGroup.length
68 | - var altura = (numProblems+1)*80
69 | div.main_pontuacao(id='main_pontuacao', style='width: #{largura}px;height: #{altura}px;')
70 | - each group, i in groups
71 | div.group
72 | div.exampleborderradiusatop.pontuacao_header
73 | span.exampleborderradiusatop(style='font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;') #{group.name}
74 | - var problemsFromGroup = problems[i]
75 | - each problem in problemsFromGroup
76 | - if(problem.correct > 0)
77 | div.exampleborderradiusa.pontuacao_correct(group=problem.idgrupos_problemas, problem=problem.idproblemas, id=problem.idgrupos_problemas+''+problem.idproblemas, level=problem.level)
78 | span.exampleborderradiusa #{problem.points}
79 | - else
80 | - if(problem.open)
81 | div.exampleborderradiusa.pontuacao_no_answer(group=problem.idgrupos_problemas, problem=problem.idproblemas, id=problem.idgrupos_problemas+''+problem.idproblemas, level=problem.level)
82 | span.exampleborderradiusa #{problem.points}
83 | - else
84 | div.exampleborderradiusa.pontuacao_closed(group=problem.idgrupos_problemas, problem=problem.idproblemas, id=problem.idgrupos_problemas+''+problem.idproblemas, level=problem.level)
85 | span.exampleborderradiusa #{problem.points}
86 | div(id='legenda')
87 | div.legenda.pontuacao_correct
88 | div.legenda_text Answered
89 | div.legenda.pontuacao_no_answer
90 | div.legenda_text Open
91 | div.legenda.pontuacao_closed
92 | div.legenda_text Closed
93 | div.legenda.pontuacao_can_open
94 | div.legenda_text You can open me
95 | //
96 | div.legenda_text(style='text-align:right;width:460px;color:red;') U can open X problems
97 | td
98 | div(id='right')
99 | div(id='answer')
100 | h3(style='font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;margin-left:5px;') Problem
101 | div(style='height:240px;')
102 | label(id='problem_description', style='color:black;')
103 | div(style='height:30px;')
104 | form.form-inline
105 | input.span2(id='answerInput', text='text', style='display: none;')
106 | input.button(id='submitAnswer', type='submit', value='Answer', sytle='width:50px;display: none;').btn.btn-primary
107 | span.help-inline(id='feedback')
108 | div(id='leaderboard')
109 | h3(style='font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;margin-left:5px;') Leaderboard
110 | div(id='scores')
111 | table
112 | -each team in teams
113 | -if(team)
114 | -var points = 0
115 | -if(team.points)
116 | - points = team.points
117 | -if(team.idteams == session.passport.user)
118 | tr
119 | td
120 | p(style='color: white;') #{team.name}
121 | td
122 | p(style='color: white;') -
123 | td(style='text-align:right;')
124 | p(style='color: white;') #{points}
125 | -else
126 | tr
127 | td
128 | p #{team.name}
129 | td
130 | p -
131 | td(style='text-align:right;')
132 | p #{points}
133 |
--------------------------------------------------------------------------------
/public/javascripts/themes/dark-blue.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Dark blue theme for Highcharts JS
3 | * @author Torstein Hønsi
4 | */
5 |
6 | Highcharts.theme = {
7 | colors: ["#DDDF0D", "#55BF3B", "#DF5353", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee",
8 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
9 | chart: {
10 | backgroundColor: {
11 | linearGradient: [0, 0, 250, 500],
12 | stops: [
13 | [0, 'rgb(48, 48, 96)'],
14 | [1, 'rgb(0, 0, 0)']
15 | ]
16 | },
17 | borderColor: '#000000',
18 | borderWidth: 2,
19 | className: 'dark-container',
20 | plotBackgroundColor: 'rgba(255, 255, 255, .1)',
21 | plotBorderColor: '#CCCCCC',
22 | plotBorderWidth: 1
23 | },
24 | title: {
25 | style: {
26 | color: '#C0C0C0',
27 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif'
28 | }
29 | },
30 | subtitle: {
31 | style: {
32 | color: '#666666',
33 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif'
34 | }
35 | },
36 | xAxis: {
37 | gridLineColor: '#333333',
38 | gridLineWidth: 1,
39 | labels: {
40 | style: {
41 | color: '#A0A0A0'
42 | }
43 | },
44 | lineColor: '#A0A0A0',
45 | tickColor: '#A0A0A0',
46 | title: {
47 | style: {
48 | color: '#CCC',
49 | fontWeight: 'bold',
50 | fontSize: '12px',
51 | fontFamily: 'Trebuchet MS, Verdana, sans-serif'
52 |
53 | }
54 | }
55 | },
56 | yAxis: {
57 | gridLineColor: '#333333',
58 | labels: {
59 | style: {
60 | color: '#A0A0A0'
61 | }
62 | },
63 | lineColor: '#A0A0A0',
64 | minorTickInterval: null,
65 | tickColor: '#A0A0A0',
66 | tickWidth: 1,
67 | title: {
68 | style: {
69 | color: '#CCC',
70 | fontWeight: 'bold',
71 | fontSize: '12px',
72 | fontFamily: 'Trebuchet MS, Verdana, sans-serif'
73 | }
74 | }
75 | },
76 | tooltip: {
77 | backgroundColor: 'rgba(0, 0, 0, 0.75)',
78 | style: {
79 | color: '#F0F0F0'
80 | }
81 | },
82 | toolbar: {
83 | itemStyle: {
84 | color: 'silver'
85 | }
86 | },
87 | plotOptions: {
88 | line: {
89 | dataLabels: {
90 | color: '#CCC'
91 | },
92 | marker: {
93 | lineColor: '#333'
94 | }
95 | },
96 | spline: {
97 | marker: {
98 | lineColor: '#333'
99 | }
100 | },
101 | scatter: {
102 | marker: {
103 | lineColor: '#333'
104 | }
105 | },
106 | candlestick: {
107 | lineColor: 'white'
108 | }
109 | },
110 | legend: {
111 | itemStyle: {
112 | font: '9pt Trebuchet MS, Verdana, sans-serif',
113 | color: '#A0A0A0'
114 | },
115 | itemHoverStyle: {
116 | color: '#FFF'
117 | },
118 | itemHiddenStyle: {
119 | color: '#444'
120 | }
121 | },
122 | credits: {
123 | style: {
124 | color: '#666'
125 | }
126 | },
127 | labels: {
128 | style: {
129 | color: '#CCC'
130 | }
131 | },
132 |
133 | navigation: {
134 | buttonOptions: {
135 | backgroundColor: {
136 | linearGradient: [0, 0, 0, 20],
137 | stops: [
138 | [0.4, '#606060'],
139 | [0.6, '#333333']
140 | ]
141 | },
142 | borderColor: '#000000',
143 | symbolStroke: '#C0C0C0',
144 | hoverSymbolStroke: '#FFFFFF'
145 | }
146 | },
147 |
148 | exporting: {
149 | buttons: {
150 | exportButton: {
151 | symbolFill: '#55BE3B'
152 | },
153 | printButton: {
154 | symbolFill: '#7797BE'
155 | }
156 | }
157 | },
158 |
159 | // scroll charts
160 | rangeSelector: {
161 | buttonTheme: {
162 | fill: {
163 | linearGradient: [0, 0, 0, 20],
164 | stops: [
165 | [0.4, '#888'],
166 | [0.6, '#555']
167 | ]
168 | },
169 | stroke: '#000000',
170 | style: {
171 | color: '#CCC',
172 | fontWeight: 'bold'
173 | },
174 | states: {
175 | hover: {
176 | fill: {
177 | linearGradient: [0, 0, 0, 20],
178 | stops: [
179 | [0.4, '#BBB'],
180 | [0.6, '#888']
181 | ]
182 | },
183 | stroke: '#000000',
184 | style: {
185 | color: 'white'
186 | }
187 | },
188 | select: {
189 | fill: {
190 | linearGradient: [0, 0, 0, 20],
191 | stops: [
192 | [0.1, '#000'],
193 | [0.3, '#333']
194 | ]
195 | },
196 | stroke: '#000000',
197 | style: {
198 | color: 'yellow'
199 | }
200 | }
201 | }
202 | },
203 | inputStyle: {
204 | backgroundColor: '#333',
205 | color: 'silver'
206 | },
207 | labelStyle: {
208 | color: 'silver'
209 | }
210 | },
211 |
212 | navigator: {
213 | handles: {
214 | backgroundColor: '#666',
215 | borderColor: '#AAA'
216 | },
217 | outlineColor: '#CCC',
218 | maskFill: 'rgba(16, 16, 16, 0.5)',
219 | series: {
220 | color: '#7798BF',
221 | lineColor: '#A6C7ED'
222 | }
223 | },
224 |
225 | scrollbar: {
226 | barBackgroundColor: {
227 | linearGradient: [0, 0, 0, 20],
228 | stops: [
229 | [0.4, '#888'],
230 | [0.6, '#555']
231 | ]
232 | },
233 | barBorderColor: '#CCC',
234 | buttonArrowColor: '#CCC',
235 | buttonBackgroundColor: {
236 | linearGradient: [0, 0, 0, 20],
237 | stops: [
238 | [0.4, '#888'],
239 | [0.6, '#555']
240 | ]
241 | },
242 | buttonBorderColor: '#CCC',
243 | rifleColor: '#FFF',
244 | trackBackgroundColor: {
245 | linearGradient: [0, 0, 0, 10],
246 | stops: [
247 | [0, '#000'],
248 | [1, '#333']
249 | ]
250 | },
251 | trackBorderColor: '#666'
252 | },
253 |
254 | // special colors for some of the
255 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)',
256 | legendBackgroundColorSolid: 'rgb(35, 35, 70)',
257 | dataLabelsColor: '#444',
258 | textColor: '#C0C0C0',
259 | maskColor: 'rgba(255,255,255,0.3)'
260 | };
261 |
262 | // Apply the theme
263 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
264 |
--------------------------------------------------------------------------------
/public/javascripts/themes/dark-green.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Dark blue theme for Highcharts JS
3 | * @author Torstein Hønsi
4 | */
5 |
6 | Highcharts.theme = {
7 | colors: ["#DDDF0D", "#55BF3B", "#DF5353", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee",
8 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
9 | chart: {
10 | backgroundColor: {
11 | linearGradient: [0, 0, 250, 500],
12 | stops: [
13 | [0, 'rgb(48, 96, 48)'],
14 | [1, 'rgb(0, 0, 0)']
15 | ]
16 | },
17 | borderColor: '#000000',
18 | borderWidth: 2,
19 | className: 'dark-container',
20 | plotBackgroundColor: 'rgba(255, 255, 255, .1)',
21 | plotBorderColor: '#CCCCCC',
22 | plotBorderWidth: 1
23 | },
24 | title: {
25 | style: {
26 | color: '#C0C0C0',
27 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif'
28 | }
29 | },
30 | subtitle: {
31 | style: {
32 | color: '#666666',
33 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif'
34 | }
35 | },
36 | xAxis: {
37 | gridLineColor: '#333333',
38 | gridLineWidth: 1,
39 | labels: {
40 | style: {
41 | color: '#A0A0A0'
42 | }
43 | },
44 | lineColor: '#A0A0A0',
45 | tickColor: '#A0A0A0',
46 | title: {
47 | style: {
48 | color: '#CCC',
49 | fontWeight: 'bold',
50 | fontSize: '12px',
51 | fontFamily: 'Trebuchet MS, Verdana, sans-serif'
52 |
53 | }
54 | }
55 | },
56 | yAxis: {
57 | gridLineColor: '#333333',
58 | labels: {
59 | style: {
60 | color: '#A0A0A0'
61 | }
62 | },
63 | lineColor: '#A0A0A0',
64 | minorTickInterval: null,
65 | tickColor: '#A0A0A0',
66 | tickWidth: 1,
67 | title: {
68 | style: {
69 | color: '#CCC',
70 | fontWeight: 'bold',
71 | fontSize: '12px',
72 | fontFamily: 'Trebuchet MS, Verdana, sans-serif'
73 | }
74 | }
75 | },
76 | tooltip: {
77 | backgroundColor: 'rgba(0, 0, 0, 0.75)',
78 | style: {
79 | color: '#F0F0F0'
80 | }
81 | },
82 | toolbar: {
83 | itemStyle: {
84 | color: 'silver'
85 | }
86 | },
87 | plotOptions: {
88 | line: {
89 | dataLabels: {
90 | color: '#CCC'
91 | },
92 | marker: {
93 | lineColor: '#333'
94 | }
95 | },
96 | spline: {
97 | marker: {
98 | lineColor: '#333'
99 | }
100 | },
101 | scatter: {
102 | marker: {
103 | lineColor: '#333'
104 | }
105 | },
106 | candlestick: {
107 | lineColor: 'white'
108 | }
109 | },
110 | legend: {
111 | itemStyle: {
112 | font: '9pt Trebuchet MS, Verdana, sans-serif',
113 | color: '#A0A0A0'
114 | },
115 | itemHoverStyle: {
116 | color: '#FFF'
117 | },
118 | itemHiddenStyle: {
119 | color: '#444'
120 | }
121 | },
122 | credits: {
123 | style: {
124 | color: '#666'
125 | }
126 | },
127 | labels: {
128 | style: {
129 | color: '#CCC'
130 | }
131 | },
132 |
133 | navigation: {
134 | buttonOptions: {
135 | backgroundColor: {
136 | linearGradient: [0, 0, 0, 20],
137 | stops: [
138 | [0.4, '#606060'],
139 | [0.6, '#333333']
140 | ]
141 | },
142 | borderColor: '#000000',
143 | symbolStroke: '#C0C0C0',
144 | hoverSymbolStroke: '#FFFFFF'
145 | }
146 | },
147 |
148 | exporting: {
149 | buttons: {
150 | exportButton: {
151 | symbolFill: '#55BE3B'
152 | },
153 | printButton: {
154 | symbolFill: '#7797BE'
155 | }
156 | }
157 | },
158 |
159 | // scroll charts
160 | rangeSelector: {
161 | buttonTheme: {
162 | fill: {
163 | linearGradient: [0, 0, 0, 20],
164 | stops: [
165 | [0.4, '#888'],
166 | [0.6, '#555']
167 | ]
168 | },
169 | stroke: '#000000',
170 | style: {
171 | color: '#CCC',
172 | fontWeight: 'bold'
173 | },
174 | states: {
175 | hover: {
176 | fill: {
177 | linearGradient: [0, 0, 0, 20],
178 | stops: [
179 | [0.4, '#BBB'],
180 | [0.6, '#888']
181 | ]
182 | },
183 | stroke: '#000000',
184 | style: {
185 | color: 'white'
186 | }
187 | },
188 | select: {
189 | fill: {
190 | linearGradient: [0, 0, 0, 20],
191 | stops: [
192 | [0.1, '#000'],
193 | [0.3, '#333']
194 | ]
195 | },
196 | stroke: '#000000',
197 | style: {
198 | color: 'yellow'
199 | }
200 | }
201 | }
202 | },
203 | inputStyle: {
204 | backgroundColor: '#333',
205 | color: 'silver'
206 | },
207 | labelStyle: {
208 | color: 'silver'
209 | }
210 | },
211 |
212 | navigator: {
213 | handles: {
214 | backgroundColor: '#666',
215 | borderColor: '#AAA'
216 | },
217 | outlineColor: '#CCC',
218 | maskFill: 'rgba(16, 16, 16, 0.5)',
219 | series: {
220 | color: '#7798BF',
221 | lineColor: '#A6C7ED'
222 | }
223 | },
224 |
225 | scrollbar: {
226 | barBackgroundColor: {
227 | linearGradient: [0, 0, 0, 20],
228 | stops: [
229 | [0.4, '#888'],
230 | [0.6, '#555']
231 | ]
232 | },
233 | barBorderColor: '#CCC',
234 | buttonArrowColor: '#CCC',
235 | buttonBackgroundColor: {
236 | linearGradient: [0, 0, 0, 20],
237 | stops: [
238 | [0.4, '#888'],
239 | [0.6, '#555']
240 | ]
241 | },
242 | buttonBorderColor: '#CCC',
243 | rifleColor: '#FFF',
244 | trackBackgroundColor: {
245 | linearGradient: [0, 0, 0, 10],
246 | stops: [
247 | [0, '#000'],
248 | [1, '#333']
249 | ]
250 | },
251 | trackBorderColor: '#666'
252 | },
253 |
254 | // special colors for some of the
255 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)',
256 | legendBackgroundColorSolid: 'rgb(35, 35, 70)',
257 | dataLabelsColor: '#444',
258 | textColor: '#C0C0C0',
259 | maskColor: 'rgba(255,255,255,0.3)'
260 | };
261 |
262 | // Apply the theme
263 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
264 |
--------------------------------------------------------------------------------
/public/javascripts/themes/gray.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Gray theme for Highcharts JS
3 | * @author Torstein Hønsi
4 | */
5 |
6 | Highcharts.theme = {
7 | colors: ["#DDDF0D", "#7798BF", "#55BF3B", "#DF5353", "#aaeeee", "#ff0066", "#eeaaee",
8 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
9 | chart: {
10 | backgroundColor: {
11 | linearGradient: [0, 0, 0, 400],
12 | stops: [
13 | [0, 'rgb(96, 96, 96)'],
14 | [1, 'rgb(16, 16, 16)']
15 | ]
16 | },
17 | borderWidth: 0,
18 | borderRadius: 15,
19 | plotBackgroundColor: null,
20 | plotShadow: false,
21 | plotBorderWidth: 0
22 | },
23 | title: {
24 | style: {
25 | color: '#FFF',
26 | font: '16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
27 | }
28 | },
29 | subtitle: {
30 | style: {
31 | color: '#DDD',
32 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
33 | }
34 | },
35 | xAxis: {
36 | gridLineWidth: 0,
37 | lineColor: '#999',
38 | tickColor: '#999',
39 | labels: {
40 | style: {
41 | color: '#999',
42 | fontWeight: 'bold'
43 | }
44 | },
45 | title: {
46 | style: {
47 | color: '#AAA',
48 | font: 'bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
49 | }
50 | }
51 | },
52 | yAxis: {
53 | alternateGridColor: null,
54 | minorTickInterval: null,
55 | gridLineColor: 'rgba(255, 255, 255, .1)',
56 | lineWidth: 0,
57 | tickWidth: 0,
58 | labels: {
59 | style: {
60 | color: '#999',
61 | fontWeight: 'bold'
62 | }
63 | },
64 | title: {
65 | style: {
66 | color: '#AAA',
67 | font: 'bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
68 | }
69 | }
70 | },
71 | legend: {
72 | itemStyle: {
73 | color: '#CCC'
74 | },
75 | itemHoverStyle: {
76 | color: '#FFF'
77 | },
78 | itemHiddenStyle: {
79 | color: '#333'
80 | }
81 | },
82 | labels: {
83 | style: {
84 | color: '#CCC'
85 | }
86 | },
87 | tooltip: {
88 | backgroundColor: {
89 | linearGradient: [0, 0, 0, 50],
90 | stops: [
91 | [0, 'rgba(96, 96, 96, .8)'],
92 | [1, 'rgba(16, 16, 16, .8)']
93 | ]
94 | },
95 | borderWidth: 0,
96 | style: {
97 | color: '#FFF'
98 | }
99 | },
100 |
101 |
102 | plotOptions: {
103 | line: {
104 | dataLabels: {
105 | color: '#CCC'
106 | },
107 | marker: {
108 | lineColor: '#333'
109 | }
110 | },
111 | spline: {
112 | marker: {
113 | lineColor: '#333'
114 | }
115 | },
116 | scatter: {
117 | marker: {
118 | lineColor: '#333'
119 | }
120 | },
121 | candlestick: {
122 | lineColor: 'white'
123 | }
124 | },
125 |
126 | toolbar: {
127 | itemStyle: {
128 | color: '#CCC'
129 | }
130 | },
131 |
132 | navigation: {
133 | buttonOptions: {
134 | backgroundColor: {
135 | linearGradient: [0, 0, 0, 20],
136 | stops: [
137 | [0.4, '#606060'],
138 | [0.6, '#333333']
139 | ]
140 | },
141 | borderColor: '#000000',
142 | symbolStroke: '#C0C0C0',
143 | hoverSymbolStroke: '#FFFFFF'
144 | }
145 | },
146 |
147 | exporting: {
148 | buttons: {
149 | exportButton: {
150 | symbolFill: '#55BE3B'
151 | },
152 | printButton: {
153 | symbolFill: '#7797BE'
154 | }
155 | }
156 | },
157 |
158 | // scroll charts
159 | rangeSelector: {
160 | buttonTheme: {
161 | fill: {
162 | linearGradient: [0, 0, 0, 20],
163 | stops: [
164 | [0.4, '#888'],
165 | [0.6, '#555']
166 | ]
167 | },
168 | stroke: '#000000',
169 | style: {
170 | color: '#CCC',
171 | fontWeight: 'bold'
172 | },
173 | states: {
174 | hover: {
175 | fill: {
176 | linearGradient: [0, 0, 0, 20],
177 | stops: [
178 | [0.4, '#BBB'],
179 | [0.6, '#888']
180 | ]
181 | },
182 | stroke: '#000000',
183 | style: {
184 | color: 'white'
185 | }
186 | },
187 | select: {
188 | fill: {
189 | linearGradient: [0, 0, 0, 20],
190 | stops: [
191 | [0.1, '#000'],
192 | [0.3, '#333']
193 | ]
194 | },
195 | stroke: '#000000',
196 | style: {
197 | color: 'yellow'
198 | }
199 | }
200 | }
201 | },
202 | inputStyle: {
203 | backgroundColor: '#333',
204 | color: 'silver'
205 | },
206 | labelStyle: {
207 | color: 'silver'
208 | }
209 | },
210 |
211 | navigator: {
212 | handles: {
213 | backgroundColor: '#666',
214 | borderColor: '#AAA'
215 | },
216 | outlineColor: '#CCC',
217 | maskFill: 'rgba(16, 16, 16, 0.5)',
218 | series: {
219 | color: '#7798BF',
220 | lineColor: '#A6C7ED'
221 | }
222 | },
223 |
224 | scrollbar: {
225 | barBackgroundColor: {
226 | linearGradient: [0, 0, 0, 20],
227 | stops: [
228 | [0.4, '#888'],
229 | [0.6, '#555']
230 | ]
231 | },
232 | barBorderColor: '#CCC',
233 | buttonArrowColor: '#CCC',
234 | buttonBackgroundColor: {
235 | linearGradient: [0, 0, 0, 20],
236 | stops: [
237 | [0.4, '#888'],
238 | [0.6, '#555']
239 | ]
240 | },
241 | buttonBorderColor: '#CCC',
242 | rifleColor: '#FFF',
243 | trackBackgroundColor: {
244 | linearGradient: [0, 0, 0, 10],
245 | stops: [
246 | [0, '#000'],
247 | [1, '#333']
248 | ]
249 | },
250 | trackBorderColor: '#666'
251 | },
252 |
253 | // special colors for some of the demo examples
254 | legendBackgroundColor: 'rgba(48, 48, 48, 0.8)',
255 | legendBackgroundColorSolid: 'rgb(70, 70, 70)',
256 | dataLabelsColor: '#444',
257 | textColor: '#E0E0E0',
258 | maskColor: 'rgba(255,255,255,0.3)'
259 | };
260 |
261 | // Apply the theme
262 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
263 |
--------------------------------------------------------------------------------
/public/javascripts/bootstrap-modal.js:
--------------------------------------------------------------------------------
1 | /* =========================================================
2 | * bootstrap-modal.js v2.0.2
3 | * http://twitter.github.com/bootstrap/javascript.html#modals
4 | * =========================================================
5 | * Copyright 2012 Twitter, Inc.
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS,
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 | * See the License for the specific language governing permissions and
17 | * limitations under the License.
18 | * ========================================================= */
19 |
20 |
21 | !function( $ ){
22 |
23 | "use strict"
24 |
25 | /* MODAL CLASS DEFINITION
26 | * ====================== */
27 |
28 | var Modal = function ( content, options ) {
29 | this.options = options
30 | this.$element = $(content)
31 | .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
32 | }
33 |
34 | Modal.prototype = {
35 |
36 | constructor: Modal
37 |
38 | , toggle: function () {
39 | return this[!this.isShown ? 'show' : 'hide']()
40 | }
41 |
42 | , show: function () {
43 | var that = this
44 |
45 | if (this.isShown) return
46 |
47 | $('body').addClass('modal-open')
48 |
49 | this.isShown = true
50 | this.$element.trigger('show')
51 |
52 | escape.call(this)
53 | backdrop.call(this, function () {
54 | var transition = $.support.transition && that.$element.hasClass('fade')
55 |
56 | !that.$element.parent().length && that.$element.appendTo(document.body) //don't move modals dom position
57 |
58 | that.$element
59 | .show()
60 |
61 | if (transition) {
62 | that.$element[0].offsetWidth // force reflow
63 | }
64 |
65 | that.$element.addClass('in')
66 |
67 | transition ?
68 | that.$element.one($.support.transition.end, function () { that.$element.trigger('shown') }) :
69 | that.$element.trigger('shown')
70 |
71 | })
72 | }
73 |
74 | , hide: function ( e ) {
75 | e && e.preventDefault()
76 |
77 | if (!this.isShown) return
78 |
79 | var that = this
80 | this.isShown = false
81 |
82 | $('body').removeClass('modal-open')
83 |
84 | escape.call(this)
85 |
86 | this.$element
87 | .trigger('hide')
88 | .removeClass('in')
89 |
90 | $.support.transition && this.$element.hasClass('fade') ?
91 | hideWithTransition.call(this) :
92 | hideModal.call(this)
93 | }
94 |
95 | }
96 |
97 |
98 | /* MODAL PRIVATE METHODS
99 | * ===================== */
100 |
101 | function hideWithTransition() {
102 | var that = this
103 | , timeout = setTimeout(function () {
104 | that.$element.off($.support.transition.end)
105 | hideModal.call(that)
106 | }, 500)
107 |
108 | this.$element.one($.support.transition.end, function () {
109 | clearTimeout(timeout)
110 | hideModal.call(that)
111 | })
112 | }
113 |
114 | function hideModal( that ) {
115 | this.$element
116 | .hide()
117 | .trigger('hidden')
118 |
119 | backdrop.call(this)
120 | }
121 |
122 | function backdrop( callback ) {
123 | var that = this
124 | , animate = this.$element.hasClass('fade') ? 'fade' : ''
125 |
126 | if (this.isShown && this.options.backdrop) {
127 | var doAnimate = $.support.transition && animate
128 |
129 | this.$backdrop = $('')
130 | .appendTo(document.body)
131 |
132 | if (this.options.backdrop != 'static') {
133 | this.$backdrop.click($.proxy(this.hide, this))
134 | }
135 |
136 | if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
137 |
138 | this.$backdrop.addClass('in')
139 |
140 | doAnimate ?
141 | this.$backdrop.one($.support.transition.end, callback) :
142 | callback()
143 |
144 | } else if (!this.isShown && this.$backdrop) {
145 | this.$backdrop.removeClass('in')
146 |
147 | $.support.transition && this.$element.hasClass('fade')?
148 | this.$backdrop.one($.support.transition.end, $.proxy(removeBackdrop, this)) :
149 | removeBackdrop.call(this)
150 |
151 | } else if (callback) {
152 | callback()
153 | }
154 | }
155 |
156 | function removeBackdrop() {
157 | this.$backdrop.remove()
158 | this.$backdrop = null
159 | }
160 |
161 | function escape() {
162 | var that = this
163 | if (this.isShown && this.options.keyboard) {
164 | $(document).on('keyup.dismiss.modal', function ( e ) {
165 | e.which == 27 && that.hide()
166 | })
167 | } else if (!this.isShown) {
168 | $(document).off('keyup.dismiss.modal')
169 | }
170 | }
171 |
172 |
173 | /* MODAL PLUGIN DEFINITION
174 | * ======================= */
175 |
176 | $.fn.modal = function ( option ) {
177 | return this.each(function () {
178 | var $this = $(this)
179 | , data = $this.data('modal')
180 | , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
181 | if (!data) $this.data('modal', (data = new Modal(this, options)))
182 | if (typeof option == 'string') data[option]()
183 | else if (options.show) data.show()
184 | })
185 | }
186 |
187 | $.fn.modal.defaults = {
188 | backdrop: true
189 | , keyboard: true
190 | , show: true
191 | }
192 |
193 | $.fn.modal.Constructor = Modal
194 |
195 |
196 | /* MODAL DATA-API
197 | * ============== */
198 |
199 | $(function () {
200 | $('body').on('click.modal.data-api', '[data-toggle="modal"]', function ( e ) {
201 | var $this = $(this), href
202 | , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
203 | , option = $target.data('modal') ? 'toggle' : $.extend({}, $target.data(), $this.data())
204 |
205 | e.preventDefault()
206 | $target.modal(option)
207 | })
208 | })
209 |
210 | }( window.jQuery );
--------------------------------------------------------------------------------
/views/index.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block scripts
4 | script(src='/socket.io/socket.io.js')
5 | script(src='../javascripts/jquery.scrollTo-1.4.2-min.js')
6 | script(src='../javascripts/jquery.countdown.js')
7 | link(rel='stylesheet', href='/stylesheets/style.css')
8 | link(rel='stylesheet', href='/stylesheets/jquery.countdown.css')
9 | script(src='../javascripts/highcharts.js')
10 | script(src='../javascripts/index.js')
11 | script(type='text/javascript')
12 | var chart;
13 | var datas = !{JSON.stringify(logs)};
14 | var config = !{JSON.stringify(config)};
15 | var teams = !{JSON.stringify(teams)};
16 |
17 |
18 | $(document).ready(function() {
19 | //Countdown
20 | var start = new Date('#{config[0].start_date}');
21 | var end = new Date('#{config[0].end_date}');
22 | var note = $('#note');
23 | ts = start;
24 | newYear = true;
25 | if(note){
26 | if((new Date()) > ts){
27 | // The new year is here! Count towards something else.
28 | // Notice the *1000 at the end - time must be in milliseconds
29 | ts = end;
30 | newYear = false;
31 | }
32 |
33 | $('#countdown').countdown({
34 | timestamp : ts,
35 | callback : function(days, hours, minutes, seconds){
36 | var message = "";
37 | note.html(message);
38 | }
39 | });
40 | }
41 | //Chart
42 | chart = new Highcharts.Chart({
43 | chart: {
44 | renderTo: 'container',
45 | marginRight: 200,
46 | type: 'scatter',
47 | zoomType: 'x'
48 | },
49 | title: {
50 | text: 'Timeline'
51 | },
52 | subtitle: {
53 | text: 'Click and drag to zoom'
54 | },
55 | xAxis: {
56 | type: 'datetime',
57 | tickPixelInterval: 150
58 | },
59 | yAxis: {
60 | title: {
61 | text: 'Points'
62 | },
63 | minPadding: 0.2,
64 | maxPadding: 0.2,
65 | maxZoom: 60,
66 | plotLines: [{
67 | value: 0,
68 | width: 1,
69 | color: '#808080'
70 | }] ,
71 | min: 0,
72 | tickInterval: 200
73 | },
74 | legend: {
75 | layout: 'vertical',
76 | align: 'right',
77 | verticalAlign: 'top',
78 | x: -10,
79 | y: 0,
80 | floating: true,
81 | borderWidth: 0,
82 | labelFormatter: function() {
83 | var points = 0;
84 | if(this.yData.length > 0){
85 | for(var i in this.yData){
86 | console.log(this.yData[i]);
87 | if( this.yData[i] > points){
88 | points = this.yData[i];
89 | }
90 | }
91 | }
92 | return this.name +' - '+points;
93 | }
94 | },
95 | exporting: {
96 | enabled: false
97 | },
98 | plotOptions: {
99 | series: {
100 | lineWidth: 1
101 | }
102 | },
103 | tooltip: {
104 | formatter: function() {
105 | var myDate = new Date(this.x);
106 | var timezone_delay = -myDate.getTimezoneOffset()*60*1000;
107 | myDate = new Date(myDate.getTime() - timezone_delay);
108 | var date = myDate.toString('dd/mm/yyyy HH:mm:ss');
109 | return ' '+ this.series.name +''+
110 | '
category: '+this.point.name+'' +
111 | '
points: '+this.y+'';
112 | }
113 | },
114 | series: datas
115 | });
116 | });
117 |
118 | block content
119 | div(id='page')
120 | div(id='conteudoGeral')
121 | div(id='conteudo')
122 | ul.nav.nav-tabs.active(id='myTab')
123 | li.active
124 | a(href='#timeline', data-toggle='tab') Timeline
125 | li
126 | a(href='#scoreboard', data-toggle='tab') Scoreboard
127 | div.tab-content
128 | div.tab-pane.active(id='timeline', style='width: 1000px; height: 500px; margin: 0 auto;')
129 | div(id='container', style='width: 1000px; height: 400px; margin: 0 auto;')
130 | div.tab-pane(id='scoreboard')
131 | div(id='conteudoGeral')
132 | div(id='conteudo')
133 | table
134 | tr
135 | td
136 | div(id='left')
137 | - var largura = groups.length*173
138 | - var numProblems = 0
139 | - each problemsFromGroup in problems
140 | -if(problemsFromGroup.length>numProblems)
141 | - numProblems = problemsFromGroup.length
142 | - var altura = (numProblems+1)*80
143 | div.main_pontuacao(id='main_pontuacao', style='width: #{largura}px;height: #{altura}px;')
144 | - each group, i in groups
145 | div.group
146 | div.exampleborderradiusatop.pontuacao_header
147 | span.exampleborderradiusatop #{group.name}
148 | - var problemsFromGroup = problems[i]
149 | - each problem in problemsFromGroup
150 | if(problem.correct > 0)
151 | div.exampleborderradiusa.pontuacao_correct(group=problem.idgrupos_problemas, problem=problem.idproblemas, id=problem.idgrupos_problemas+''+problem.idproblemas)
152 | span.exampleborderradiusa #{problem.points}
153 | - else
154 | - if(problem.open)
155 | div.exampleborderradiusa.pontuacao_no_answer(group=problem.idgrupos_problemas, problem=problem.idproblemas, id=problem.idgrupos_problemas+''+problem.idproblemas)
156 | span.exampleborderradiusa #{problem.points}
157 | - else
158 | div.exampleborderradiusa.pontuacao_closed(group=problem.idgrupos_problemas, problem=problem.idproblemas, id=problem.idgrupos_problemas+''+problem.idproblemas)
159 | span.exampleborderradiusa #{problem.points}
160 | div.legenda.pontuacao_correct
161 | div.legenda_text Answered
162 | div.legenda.pontuacao_no_answer
163 | div.legenda_text Open
164 | div.legenda.pontuacao_closed
165 | div.legenda_text Closed
166 | td
167 | div(id='right')
168 | div(id='leaderboard_public')
169 | h1(style='font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;margin-left:5px;') Leaderboard
170 | div(id='scores')
171 | table
172 | -each team in teams
173 | -if(team)
174 | -var points = 0
175 | -if(team.points)
176 | - points = team.points
177 | -if(team.idteams == session.passport.user)
178 | tr
179 | td
180 | p(style='color: white;') #{team.name}
181 | td
182 | p(style='color: white;') -
183 | td
184 | p(style='color: white;') #{points}
185 | -else
186 | tr
187 | td
188 | p #{team.name}
189 | td
190 | p -
191 | td
192 | p #{points}
--------------------------------------------------------------------------------
/public/javascripts/script.js:
--------------------------------------------------------------------------------
1 | $(document).ready(function() {
2 |
3 | //console.log('consigo aceder var level1 - '+level1);
4 |
5 | var level1 = 0;
6 | var level2 = 0;
7 | var level3 = 0;
8 |
9 | var selectedGroup =-1;
10 | var selectedProblem =-1;
11 | var selectedId;
12 |
13 | var socket = io.connect(null, {
14 | 'reconnect': true,
15 | 'reconnection delay': 250,
16 | 'max reconnection attempts': 100
17 | });
18 |
19 | var snd; // buffers automatically when created
20 | //var no = new Audio("yes.mp3"); // buffers automatically when created
21 |
22 |
23 | $('#problem_description').hide();
24 | $('#answerInput').hide();
25 | $('#submitAnswer').hide();
26 | $('#feedback').hide();
27 |
28 | socket.on('reconnect', function (data) {
29 | window.location.reload(true);
30 | });
31 |
32 | socket.on('start', function (data) {
33 | window.location.reload(true);
34 | });
35 |
36 | socket.on('uCanOpen', function (data) {
37 | //console.log(data);
38 | level1 = data.level1;
39 | level2 = data.level2;
40 | level3 = data.level3;
41 | checkWhatICanOpenz();
42 | });
43 |
44 | function checkWhatICanOpenz(){
45 | $('div.exampleborderradiusa').each(function(index) {
46 | var level = jQuery(this).attr("level");
47 | if((level == 2 && level1>0) || (level == 3 && level2>0) || (level3>0 && level == 4)){
48 | if(jQuery(this).hasClass('pontuacao_closed')){
49 | jQuery(this).removeClass("pontuacao_closed");
50 | jQuery(this).addClass("pontuacao_can_open");
51 | }
52 | }
53 | if((level == 2 && level1==0) || (level == 3 && level2==0) || (level3==0 && level == 4)){
54 | if(jQuery(this).hasClass('pontuacao_can_open')){
55 | jQuery(this).removeClass("pontuacao_can_open");
56 | jQuery(this).addClass("pontuacao_closed");
57 | }
58 | }
59 |
60 | });
61 | }
62 |
63 | socket.on('globalMessage', function (data) {
64 | $().toastmessage('showToast', {
65 | text : data.message,
66 | sticky : data.sticky,
67 | type : 'notice'
68 | });
69 | });
70 |
71 | socket.on('answers', function (data) {
72 | if(snd){
73 | snd.pause();
74 | }
75 | $('#newstext').append(''+data.correct+'
');
76 | $('#newsscroll').scrollTo( '100%', 10 , {
77 | axis:'y'
78 | });
79 |
80 | var teamid = data.teamid;
81 | var group = data.group;
82 | var problema = data.problem;
83 | var correct = data.correct;
84 | if(teamid == $('#teamId').attr("team")){
85 | if(correct){
86 | document.getElementById("feedback").innerHTML ='Correct.
';
87 | $('#feedback').addClass("success");
88 | //$("#myModal").effect("highlight", {color: 'green'}, 3000);
89 | $("div#"+group+''+problema).removeClass("pontuacao_no_answer");
90 | $("div#"+group+''+problema).removeClass("pontuacao_selected");
91 | $("div#"+group+''+problema).addClass("pontuacao_correct");
92 |
93 | snd = new Audio("yes.mp3");
94 | snd.play();
95 | }
96 | else{
97 | $('#submitAnswer').attr("disabled", false);
98 | document.getElementById("feedback").innerHTML ='Computer says No.
';
99 | $('#feedback').addClass("error");
100 | snd = new Audio("no5s.ogg");
101 | //snd.play();
102 | //setInterval(snd.pause(),2000);
103 | }
104 | }
105 | });
106 |
107 |
108 | socket.on('leader', function (data) {
109 | var leaderBoard = "";
110 | for(var i = 0; data.teams[i]; i++){
111 | var name = data.teams[i].name;
112 | var points = 0;
113 | if(data.teams[i].points){
114 | points = data.teams[i].points;
115 | }
116 | if(data.teams[i].idteams == $('#teamId').attr("team")){
117 | leaderBoard +=''+name+' - '+points+'
';
118 | }
119 | else{
120 | leaderBoard +=''+name+' - '+points+'
';
121 | }
122 | }
123 |
124 | document.getElementById("scores").innerHTML = leaderBoard;
125 | });
126 |
127 | socket.on('activateProblem', function (data) {
128 | $("div#"+data.group+''+data.problem).removeClass("pontuacao_can_open");
129 | $("div#"+data.group+''+data.problem).removeClass("pontuacao_closed");
130 | $('#'+data.group+''+data.problem).addClass("pontuacao_no_answer");
131 | problemClick(data.group+''+data.problem, data.group, data.problem);
132 | $().toastmessage('showToast', {
133 | text : 'le wild problem appeared..',
134 | sticky : false,
135 | type : 'notice'
136 | });
137 | });
138 |
139 | socket.on('problemDefinition', function (data) {
140 | var group = data.group;
141 | var problema = data.problem;
142 | var open = data.open;
143 | if(group == selectedGroup && problema == selectedProblem){
144 | var description = data.description;
145 | document.getElementById("feedback").innerHTML ='';
146 | document.getElementById("problem_description").innerHTML = description;
147 | $('#answerInput').val("");
148 | $('#problem_description').show();
149 | if(open){
150 | $('#answerInput').show();
151 | $('#submitAnswer').show();
152 | $('#feedback').show();
153 | $('#submitAnswer').attr("disabled", false);
154 | $('#answerInput').focus();
155 | }
156 | else{
157 | $('#answerInput').hide();
158 | $('#submitAnswer').hide();
159 | $('#feedback').hide();
160 | }
161 | }
162 | });
163 |
164 |
165 | $('div.exampleborderradiusa').each(function(index) {
166 | var id = jQuery(this).attr("id");
167 | var group = jQuery(this).attr("group");
168 | var problem = jQuery(this).attr("problem");
169 | problemClick(id, group, problem);
170 | });
171 |
172 | function problemClick(id, group, problem){
173 | $('#'+id).click(function(event) {
174 | $('#answerInput').hide();
175 | $('#submitAnswer').hide();
176 | $('#feedback').hide();
177 | if($('#'+id).hasClass('pontuacao_no_answer')){
178 | selectedGroup = group;
179 | selectedProblem = problem;
180 | socket.emit('getProblem', {'group': selectedGroup,'problem': selectedProblem});
181 | clearSelected();
182 | document.getElementById("feedback").innerHTML ='';
183 | document.getElementById("problem_description").innerHTML = 'Loading..';
184 | $('#answerInput').val("");
185 | $("#"+id).addClass("pontuacao_selected");
186 | }
187 | if($('#'+id).hasClass('pontuacao_closed') || $('#'+id).hasClass('pontuacao_can_open')){
188 | selectedGroup = group;
189 | selectedProblem = problem;
190 | socket.emit('openProblem', {'group': selectedGroup,'problem': selectedProblem});
191 | }
192 | });
193 | }
194 |
195 | $("#submitAnswer").click(function(event) {
196 | event.preventDefault();
197 | document.getElementById("feedback").innerHTML ='Waiting Response.
';
198 | socket.emit('answer', {'group': selectedGroup,'problem': selectedProblem, 'answer': $('#answerInput').val()});
199 | $('#submitAnswer').attr("disabled", true);
200 | });
201 |
202 |
203 | function clearSelected(){
204 | $('div.exampleborderradiusa').each(function(index) {
205 | var thisId = jQuery(this).attr("id");
206 | jQuery(this).removeClass("pontuacao_selected");
207 | });
208 | }
209 | });
210 |
211 |
212 |
213 |
--------------------------------------------------------------------------------
/public/javascripts/jquery.toastmessage.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2010 akquinet
3 | * Licensed under the Apache License, Version 2.0 (the "License");
4 | * you may not use this file except in compliance with the License.
5 | * You may obtain a copy of the License at
6 | *
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software
10 | * distributed under the License is distributed on an "AS IS" BASIS,
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | * See the License for the specific language governing permissions and
13 | * limitations under the License.
14 | */
15 |
16 | /**
17 | * This JQuery Plugin will help you in showing some nice Toast-Message like notification messages. The behavior is
18 | * similar to the android Toast class.
19 | * You have 4 different toast types you can show. Each type comes with its own icon and colored border. The types are:
20 | * - notice
21 | * - success
22 | * - warning
23 | * - error
24 | *
25 | * The following methods will display a toast message:
26 | *
27 | * $().toastmessage('showNoticeToast', 'some message here');
28 | * $().toastmessage('showSuccessToast', "some message here");
29 | * $().toastmessage('showWarningToast', "some message here");
30 | * $().toastmessage('showErrorToast', "some message here");
31 | *
32 | * // user configured toastmessage:
33 | * $().toastmessage('showToast', {
34 | * text : 'Hello World',
35 | * sticky : true,
36 | * position : 'top-right',
37 | * type : 'success',
38 | * close : function () {console.log("toast is closed ...");}
39 | * });
40 | *
41 | * To see some more examples please have a look into the Tests in src/test/javascript/ToastmessageTest.js
42 | *
43 | * For further style configuration please see corresponding css file: jquery-toastmessage.css
44 | *
45 | * This plugin is based on the jquery-notice (http://sandbox.timbenniks.com/projects/jquery-notice/)
46 | * but is enhanced in several ways:
47 | *
48 | * configurable positioning
49 | * convenience methods for different message types
50 | * callback functionality when closing the toast
51 | * included some nice free icons
52 | * reimplemented to follow jquery plugin good practices rules
53 | *
54 | * Author: Daniel Bremer-Tonn
55 | **/
56 | (function($)
57 | {
58 | var settings = {
59 | inEffect: {opacity: 'show'}, // in effect
60 | inEffectDuration: 600, // in effect duration in miliseconds
61 | stayTime: 3000, // time in miliseconds before the item has to disappear
62 | text: '', // content of the item. Might be a string or a jQuery object. Be aware that any jQuery object which is acting as a message will be deleted when the toast is fading away.
63 | sticky: false, // should the toast item sticky or not?
64 | type: 'notice', // notice, warning, error, success
65 | position: 'top-right', // top-left, top-center, top-right, middle-left, middle-center, middle-right ... Position of the toast container holding different toast. Position can be set only once at the very first call, changing the position after the first call does nothing
66 | closeText: '', // text which will be shown as close button, set to '' when you want to introduce an image via css
67 | close: null // callback function when the toastmessage is closed
68 | };
69 |
70 | var methods = {
71 | init : function(options)
72 | {
73 | if (options) {
74 | $.extend( settings, options );
75 | }
76 | },
77 |
78 | showToast : function(options)
79 | {
80 | var localSettings = {};
81 | $.extend(localSettings, settings, options);
82 |
83 | // declare variables
84 | var toastWrapAll, toastItemOuter, toastItemInner, toastItemClose, toastItemImage;
85 |
86 | toastWrapAll = (!$('.toast-container').length) ? $('').addClass('toast-container').addClass('toast-position-' + localSettings.position).appendTo('body') : $('.toast-container');
87 | toastItemOuter = $('').addClass('toast-item-wrapper');
88 | toastItemInner = $('').hide().addClass('toast-item toast-type-' + localSettings.type).appendTo(toastWrapAll).html($('').append (localSettings.text)).animate(localSettings.inEffect, localSettings.inEffectDuration).wrap(toastItemOuter);
89 | toastItemClose = $('
').addClass('toast-item-close').prependTo(toastItemInner).html(localSettings.closeText).click(function() { $().toastmessage('removeToast',toastItemInner, localSettings) });
90 | toastItemImage = $('').addClass('toast-item-image').addClass('toast-item-image-' + localSettings.type).prependTo(toastItemInner);
91 |
92 | if(navigator.userAgent.match(/MSIE 6/i))
93 | {
94 | toastWrapAll.css({top: document.documentElement.scrollTop});
95 | }
96 |
97 | if(!localSettings.sticky)
98 | {
99 | setTimeout(function()
100 | {
101 | $().toastmessage('removeToast', toastItemInner, localSettings);
102 | },
103 | localSettings.stayTime);
104 | }
105 | return toastItemInner;
106 | },
107 |
108 | showNoticeToast : function (message)
109 | {
110 | var options = {text : message, type : 'notice'};
111 | return $().toastmessage('showToast', options);
112 | },
113 |
114 | showSuccessToast : function (message)
115 | {
116 | var options = {text : message, type : 'success'};
117 | return $().toastmessage('showToast', options);
118 | },
119 |
120 | showErrorToast : function (message)
121 | {
122 | var options = {text : message, type : 'error'};
123 | return $().toastmessage('showToast', options);
124 | },
125 |
126 | showWarningToast : function (message)
127 | {
128 | var options = {text : message, type : 'warning'};
129 | return $().toastmessage('showToast', options);
130 | },
131 |
132 | removeToast: function(obj, options)
133 | {
134 | obj.animate({opacity: '0'}, 600, function()
135 | {
136 | obj.parent().animate({height: '0px'}, 300, function()
137 | {
138 | obj.parent().remove();
139 | });
140 | });
141 | // callback
142 | if (options && options.close !== null)
143 | {
144 | options.close();
145 | }
146 | }
147 | };
148 |
149 | $.fn.toastmessage = function( method ) {
150 |
151 | // Method calling logic
152 | if ( methods[method] ) {
153 | return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
154 | } else if ( typeof method === 'object' || ! method ) {
155 | return methods.init.apply( this, arguments );
156 | } else {
157 | $.error( 'Method ' + method + ' does not exist on jQuery.toastmessage' );
158 | }
159 | };
160 |
161 | })(jQuery);
--------------------------------------------------------------------------------
/public/javascripts/bootstrap-tooltip.js:
--------------------------------------------------------------------------------
1 | /* ===========================================================
2 | * bootstrap-tooltip.js v2.0.0
3 | * http://twitter.github.com/bootstrap/javascript.html#tooltips
4 | * Inspired by the original jQuery.tipsy by Jason Frame
5 | * ===========================================================
6 | * Copyright 2012 Twitter, Inc.
7 | *
8 | * Licensed under the Apache License, Version 2.0 (the "License");
9 | * you may not use this file except in compliance with the License.
10 | * You may obtain a copy of the License at
11 | *
12 | * http://www.apache.org/licenses/LICENSE-2.0
13 | *
14 | * Unless required by applicable law or agreed to in writing, software
15 | * distributed under the License is distributed on an "AS IS" BASIS,
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 | * See the License for the specific language governing permissions and
18 | * limitations under the License.
19 | * ========================================================== */
20 |
21 | !function( $ ) {
22 |
23 | "use strict"
24 |
25 | /* TOOLTIP PUBLIC CLASS DEFINITION
26 | * =============================== */
27 |
28 | var Tooltip = function ( element, options ) {
29 | this.init('tooltip', element, options)
30 | }
31 |
32 | Tooltip.prototype = {
33 |
34 | constructor: Tooltip
35 |
36 | , init: function ( type, element, options ) {
37 | var eventIn
38 | , eventOut
39 |
40 | this.type = type
41 | this.$element = $(element)
42 | this.options = this.getOptions(options)
43 | this.enabled = true
44 |
45 | if (this.options.trigger != 'manual') {
46 | eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
47 | eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
48 | this.$element.on(eventIn, this.options.selector, $.proxy(this.enter, this))
49 | this.$element.on(eventOut, this.options.selector, $.proxy(this.leave, this))
50 | }
51 |
52 | this.options.selector ?
53 | (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
54 | this.fixTitle()
55 | }
56 |
57 | , getOptions: function ( options ) {
58 | options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
59 |
60 | if (options.delay && typeof options.delay == 'number') {
61 | options.delay = {
62 | show: options.delay
63 | , hide: options.delay
64 | }
65 | }
66 |
67 | return options
68 | }
69 |
70 | , enter: function ( e ) {
71 | var self = $(e.currentTarget)[this.type](this._options).data(this.type)
72 |
73 | if (!self.options.delay || !self.options.delay.show) {
74 | self.show()
75 | } else {
76 | self.hoverState = 'in'
77 | setTimeout(function() {
78 | if (self.hoverState == 'in') {
79 | self.show()
80 | }
81 | }, self.options.delay.show)
82 | }
83 | }
84 |
85 | , leave: function ( e ) {
86 | var self = $(e.currentTarget)[this.type](this._options).data(this.type)
87 |
88 | if (!self.options.delay || !self.options.delay.hide) {
89 | self.hide()
90 | } else {
91 | self.hoverState = 'out'
92 | setTimeout(function() {
93 | if (self.hoverState == 'out') {
94 | self.hide()
95 | }
96 | }, self.options.delay.hide)
97 | }
98 | }
99 |
100 | , show: function () {
101 | var $tip
102 | , inside
103 | , pos
104 | , actualWidth
105 | , actualHeight
106 | , placement
107 | , tp
108 |
109 | if (this.hasContent() && this.enabled) {
110 | $tip = this.tip()
111 | this.setContent()
112 |
113 | if (this.options.animation) {
114 | $tip.addClass('fade')
115 | }
116 |
117 | placement = typeof this.options.placement == 'function' ?
118 | this.options.placement.call(this, $tip[0], this.$element[0]) :
119 | this.options.placement
120 |
121 | inside = /in/.test(placement)
122 |
123 | $tip
124 | .remove()
125 | .css({ top: 0, left: 0, display: 'block' })
126 | .appendTo(inside ? this.$element : document.body)
127 |
128 | pos = this.getPosition(inside)
129 |
130 | actualWidth = $tip[0].offsetWidth
131 | actualHeight = $tip[0].offsetHeight
132 |
133 | switch (inside ? placement.split(' ')[1] : placement) {
134 | case 'bottom':
135 | tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
136 | break
137 | case 'top':
138 | tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
139 | break
140 | case 'left':
141 | tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
142 | break
143 | case 'right':
144 | tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
145 | break
146 | }
147 |
148 | $tip
149 | .css(tp)
150 | .addClass(placement)
151 | .addClass('in')
152 | }
153 | }
154 |
155 | , setContent: function () {
156 | var $tip = this.tip()
157 | $tip.find('.tooltip-inner').html(this.getTitle())
158 | $tip.removeClass('fade in top bottom left right')
159 | }
160 |
161 | , hide: function () {
162 | var that = this
163 | , $tip = this.tip()
164 |
165 | $tip.removeClass('in')
166 |
167 | function removeWithAnimation() {
168 | var timeout = setTimeout(function () {
169 | $tip.off($.support.transition.end).remove()
170 | }, 500)
171 |
172 | $tip.one($.support.transition.end, function () {
173 | clearTimeout(timeout)
174 | $tip.remove()
175 | })
176 | }
177 |
178 | $.support.transition && this.$tip.hasClass('fade') ?
179 | removeWithAnimation() :
180 | $tip.remove()
181 | }
182 |
183 | , fixTitle: function () {
184 | var $e = this.$element
185 | if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
186 | $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
187 | }
188 | }
189 |
190 | , hasContent: function () {
191 | return this.getTitle()
192 | }
193 |
194 | , getPosition: function (inside) {
195 | return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
196 | width: this.$element[0].offsetWidth
197 | , height: this.$element[0].offsetHeight
198 | })
199 | }
200 |
201 | , getTitle: function () {
202 | var title
203 | , $e = this.$element
204 | , o = this.options
205 |
206 | title = $e.attr('data-original-title')
207 | || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
208 |
209 | title = title.toString().replace(/(^\s*|\s*$)/, "")
210 |
211 | return title
212 | }
213 |
214 | , tip: function () {
215 | return this.$tip = this.$tip || $(this.options.template)
216 | }
217 |
218 | , validate: function () {
219 | if (!this.$element[0].parentNode) {
220 | this.hide()
221 | this.$element = null
222 | this.options = null
223 | }
224 | }
225 |
226 | , enable: function () {
227 | this.enabled = true
228 | }
229 |
230 | , disable: function () {
231 | this.enabled = false
232 | }
233 |
234 | , toggleEnabled: function () {
235 | this.enabled = !this.enabled
236 | }
237 |
238 | , toggle: function () {
239 | this[this.tip().hasClass('in') ? 'hide' : 'show']()
240 | }
241 |
242 | }
243 |
244 |
245 | /* TOOLTIP PLUGIN DEFINITION
246 | * ========================= */
247 |
248 | $.fn.tooltip = function ( option ) {
249 | return this.each(function () {
250 | var $this = $(this)
251 | , data = $this.data('tooltip')
252 | , options = typeof option == 'object' && option
253 | if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
254 | if (typeof option == 'string') data[option]()
255 | })
256 | }
257 |
258 | $.fn.tooltip.Constructor = Tooltip
259 |
260 | $.fn.tooltip.defaults = {
261 | animation: true
262 | , delay: 0
263 | , selector: false
264 | , placement: 'top'
265 | , trigger: 'hover'
266 | , title: ''
267 | , template: ''
268 | }
269 |
270 | }( window.jQuery )
271 |
--------------------------------------------------------------------------------
/views/admin/index.jade:
--------------------------------------------------------------------------------
1 | extends layout
2 |
3 | block content
4 | section#main.column
5 | h4.alert_info
6 | | Welcome to the free MediaLoot admin panel template, this could be an informative message.
7 | article.module.width_full
8 | header
9 | h3 Stats
10 | .module_content
11 | article.stats_graph
12 | img(src='http://chart.apis.google.com/chart?chxr=0,0,3000&chxt=y&chs=520x140&cht=lc&chco=76A4FB,80C65A&chd=s:Tdjpsvyvttmiihgmnrst,OTbdcfhhggcTUTTUadfk&chls=2|2&chma=40,20,20,30', width='520', height='140', alt='')
13 | article.stats_overview
14 | .overview_today
15 | p.overview_day Today
16 | p.overview_count 1,876
17 | p.overview_type Hits
18 | p.overview_count 2,103
19 | p.overview_type Views
20 | .overview_previous
21 | p.overview_day Yesterday
22 | p.overview_count 1,646
23 | p.overview_type Hits
24 | p.overview_count 2,054
25 | p.overview_type Views
26 | .clear
27 | //
28 | end of stats article
29 | article.module.width_3_quarter
30 | header
31 | h3.tabs_involved Content Manager
32 | ul.tabs
33 | li
34 | a(href='#tab1') Posts
35 | li
36 | a(href='#tab2') Comments
37 | .tab_container
38 | #tab1.tab_content
39 | table.tablesorter(cellspacing='0')
40 | thead
41 | tr
42 | th
43 | th Entry Name
44 | th Category
45 | th Created On
46 | th Actions
47 | tbody
48 | tr
49 | td
50 | input(type='checkbox')
51 | td Lorem Ipsum Dolor Sit Amet
52 | td Articles
53 | td 5th April 2011
54 | td
55 | input(type='image', src='images/icn_edit.png', title='Edit')
56 | input(type='image', src='images/icn_trash.png', title='Trash')
57 | tr
58 | td
59 | input(type='checkbox')
60 | td Ipsum Lorem Dolor Sit Amet
61 | td Freebies
62 | td 6th April 2011
63 | td
64 | input(type='image', src='images/icn_edit.png', title='Edit')
65 | input(type='image', src='images/icn_trash.png', title='Trash')
66 | tr
67 | td
68 | input(type='checkbox')
69 | td Sit Amet Dolor Ipsum
70 | td Tutorials
71 | td 10th April 2011
72 | td
73 | input(type='image', src='images/icn_edit.png', title='Edit')
74 | input(type='image', src='images/icn_trash.png', title='Trash')
75 | tr
76 | td
77 | input(type='checkbox')
78 | td Dolor Lorem Amet
79 | td Articles
80 | td 16th April 2011
81 | td
82 | input(type='image', src='images/icn_edit.png', title='Edit')
83 | input(type='image', src='images/icn_trash.png', title='Trash')
84 | tr
85 | td
86 | input(type='checkbox')
87 | td Dolor Lorem Amet
88 | td Articles
89 | td 16th April 2011
90 | td
91 | input(type='image', src='images/icn_edit.png', title='Edit')
92 | input(type='image', src='images/icn_trash.png', title='Trash')
93 | //
94 | end of #tab1
95 | #tab2.tab_content
96 | table.tablesorter(cellspacing='0')
97 | thead
98 | tr
99 | th
100 | th Comment
101 | th Posted by
102 | th Posted On
103 | th Actions
104 | tbody
105 | tr
106 | td
107 | input(type='checkbox')
108 | td Lorem Ipsum Dolor Sit Amet
109 | td Mark Corrigan
110 | td 5th April 2011
111 | td
112 | input(type='image', src='images/icn_edit.png', title='Edit')
113 | input(type='image', src='images/icn_trash.png', title='Trash')
114 | tr
115 | td
116 | input(type='checkbox')
117 | td Ipsum Lorem Dolor Sit Amet
118 | td Jeremy Usbourne
119 | td 6th April 2011
120 | td
121 | input(type='image', src='images/icn_edit.png', title='Edit')
122 | input(type='image', src='images/icn_trash.png', title='Trash')
123 | tr
124 | td
125 | input(type='checkbox')
126 | td Sit Amet Dolor Ipsum
127 | td Super Hans
128 | td 10th April 2011
129 | td
130 | input(type='image', src='images/icn_edit.png', title='Edit')
131 | input(type='image', src='images/icn_trash.png', title='Trash')
132 | tr
133 | td
134 | input(type='checkbox')
135 | td Dolor Lorem Amet
136 | td Alan Johnson
137 | td 16th April 2011
138 | td
139 | input(type='image', src='images/icn_edit.png', title='Edit')
140 | input(type='image', src='images/icn_trash.png', title='Trash')
141 | tr
142 | td
143 | input(type='checkbox')
144 | td Dolor Lorem Amet
145 | td Dobby
146 | td 16th April 2011
147 | td
148 | input(type='image', src='images/icn_edit.png', title='Edit')
149 | input(type='image', src='images/icn_trash.png', title='Trash')
150 | //
151 | end of #tab2
152 | //
153 | end of .tab_container
154 | //
155 | end of content manager article
156 | article.module.width_quarter
157 | header
158 | h3 Messages
159 | .message_list
160 | .module_content
161 | .message
162 | p Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor.
163 | p
164 | strong John Doe
165 | .message
166 | p Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor.
167 | p
168 | strong John Doe
169 | .message
170 | p Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor.
171 | p
172 | strong John Doe
173 | .message
174 | p Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor.
175 | p
176 | strong John Doe
177 | .message
178 | p Vivamus sagittis lacus vel augue laoreet rutrum faucibus dolor.
179 | p
180 | strong John Doe
181 | footer
182 | form.post_message
183 | input(type='text', value='Message', onfocus='if(!this._haschanged){this.value=\'\'};this._haschanged=true;')
184 | input.btn_post_message(type='submit', value='')
185 | //
186 | end of messages article
187 | .clear
188 | article.module.width_full
189 | header
190 | h3 Post New Article
191 | .module_content
192 | fieldset
193 | label Post Title
194 | input(type='text')
195 | fieldset
196 | label Content
197 | textarea(rows='12')
198 | fieldset(style='width: 48%; float: left; margin-right: 3%;')
199 | //
200 | to make two field float next to one another, adjust values accordingly
201 | label Category
202 | select(style='width: 92%;')
203 | option Articles
204 | option Tutorials
205 | option Freebies
206 | fieldset(style='width: 48%; float: left;')
207 | //
208 | to make two field float next to one another, adjust values accordingly
209 | label Tags
210 | input(type='text', style='width: 92%;')
211 | .clear
212 | footer
213 | .submit_link
214 | select
215 | option Draft
216 | option Published
217 | input.alt_btn(type='submit', value='Publish')
218 | input(type='submit', value='Reset')
219 | //
220 | end of post new article
221 | h4.alert_warning A Warning Alert
222 | h4.alert_error An Error Message
223 | h4.alert_success A Success Message
224 | article.module.width_full
225 | header
226 | h3 Basic Styles
227 | .module_content
228 | h1 Header 1
229 | h2 Header 2
230 | h3 Header 3
231 | h4 Header 4
232 | p
233 | | Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras mattis consectetur purus sit amet fermentum. Maecenas faucibus mollis interdum. Maecenas faucibus mollis interdum. Cras justo odio, dapibus ac facilisis in, egestas eget quam.
234 | p
235 | | Donec id elit non mi porta
236 | a(href='#') link text
237 | | gravida at eget metus. Donec ullamcorper nulla non metus auctor fringilla. Cras mattis consectetur purus sit amet fermentum. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum.
238 | ul
239 | li Donec ullamcorper nulla non metus auctor fringilla.
240 | li Cras mattis consectetur purus sit amet fermentum.
241 | li Donec ullamcorper nulla non metus auctor fringilla.
242 | li Cras mattis consectetur purus sit amet fermentum.
243 | //
244 | end of styles article
245 | .spacer
246 |
--------------------------------------------------------------------------------
/BD/tournament.sql:
--------------------------------------------------------------------------------
1 | CREATE DATABASE IF NOT EXISTS `torneio` /*!40100 DEFAULT CHARACTER SET latin1 */;
2 | USE `torneio`;
3 | -- MySQL dump 10.13 Distrib 5.5.16, for Win32 (x86)
4 | --
5 | -- Host: zeus.gank.eu Database: torneio
6 | -- ------------------------------------------------------
7 | -- Server version 5.1.63-0ubuntu0.11.04.1
8 |
9 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
10 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
11 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
12 | /*!40101 SET NAMES utf8 */;
13 | /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
14 | /*!40103 SET TIME_ZONE='+00:00' */;
15 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
16 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
17 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
18 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
19 |
20 | --
21 | -- Table structure for table `grupos_problemas`
22 | --
23 |
24 | DROP TABLE IF EXISTS `grupos_problemas`;
25 | /*!40101 SET @saved_cs_client = @@character_set_client */;
26 | /*!40101 SET character_set_client = utf8 */;
27 | CREATE TABLE `grupos_problemas` (
28 | `idgrupos_problemas` bigint(20) NOT NULL AUTO_INCREMENT,
29 | `name` varchar(45) NOT NULL,
30 | `desc` varchar(200) DEFAULT NULL,
31 | PRIMARY KEY (`idgrupos_problemas`),
32 | UNIQUE KEY `idgrupos_problemas_UNIQUE` (`idgrupos_problemas`)
33 | ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=latin1;
34 | /*!40101 SET character_set_client = @saved_cs_client */;
35 |
36 | --
37 | -- Dumping data for table `grupos_problemas`
38 | --
39 |
40 | LOCK TABLES `grupos_problemas` WRITE;
41 | /*!40000 ALTER TABLE `grupos_problemas` DISABLE KEYS */;
42 | /*!40000 ALTER TABLE `grupos_problemas` ENABLE KEYS */;
43 | UNLOCK TABLES;
44 |
45 | --
46 | -- Table structure for table `teams_log`
47 | --
48 |
49 | DROP TABLE IF EXISTS `teams_log`;
50 | /*!40101 SET @saved_cs_client = @@character_set_client */;
51 | /*!40101 SET character_set_client = utf8 */;
52 | CREATE TABLE `teams_log` (
53 | `idteams_log` bigint(20) NOT NULL AUTO_INCREMENT,
54 | `idteams` bigint(20) NOT NULL,
55 | `data` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
56 | `resposta` varchar(200) NOT NULL,
57 | `correct` tinyint(1) NOT NULL,
58 | `idgrupos_problemas` bigint(20) NOT NULL,
59 | `idproblemas` bigint(20) NOT NULL,
60 | `sum_of_points` int(11) NOT NULL,
61 | PRIMARY KEY (`idteams_log`),
62 | UNIQUE KEY `idteams_log_UNIQUE` (`idteams_log`),
63 | KEY `fk_teams_log_teams` (`idteams`),
64 | KEY `fk_teams_log_problemas1` (`idgrupos_problemas`,`idproblemas`),
65 | CONSTRAINT `fk_teams_log_problemas1` FOREIGN KEY (`idgrupos_problemas`, `idproblemas`) REFERENCES `problemas` (`idgrupos_problemas`, `idproblemas`) ON DELETE NO ACTION ON UPDATE NO ACTION,
66 | CONSTRAINT `fk_teams_log_teams` FOREIGN KEY (`idteams`) REFERENCES `teams` (`idteams`) ON DELETE NO ACTION ON UPDATE NO ACTION
67 | ) ENGINE=InnoDB AUTO_INCREMENT=1919 DEFAULT CHARSET=latin1;
68 | /*!40101 SET character_set_client = @saved_cs_client */;
69 |
70 | --
71 | -- Dumping data for table `teams_log`
72 | --
73 |
74 | LOCK TABLES `teams_log` WRITE;
75 | /*!40000 ALTER TABLE `teams_log` DISABLE KEYS */;
76 | /*!40000 ALTER TABLE `teams_log` ENABLE KEYS */;
77 | UNLOCK TABLES;
78 |
79 | --
80 | -- Table structure for table `teams`
81 | --
82 |
83 | DROP TABLE IF EXISTS `teams`;
84 | /*!40101 SET @saved_cs_client = @@character_set_client */;
85 | /*!40101 SET character_set_client = utf8 */;
86 | CREATE TABLE `teams` (
87 | `idteams` bigint(20) NOT NULL AUTO_INCREMENT,
88 | `name` varchar(100) NOT NULL,
89 | `description` varchar(200) NOT NULL,
90 | `password` varchar(200) NOT NULL,
91 | `administrationLevel` tinyint(4) DEFAULT '0',
92 | `problems_to_open_level_1` int(2) DEFAULT '0',
93 | `problems_to_open_level_2` int(2) DEFAULT '0',
94 | `problems_to_open_level_3` int(2) DEFAULT '0',
95 | `problems_to_open_level_4` int(2) DEFAULT '0',
96 | PRIMARY KEY (`idteams`),
97 | UNIQUE KEY `idteams_UNIQUE` (`idteams`)
98 | ) ENGINE=InnoDB AUTO_INCREMENT=32 DEFAULT CHARSET=latin1;
99 | /*!40101 SET character_set_client = @saved_cs_client */;
100 |
101 | --
102 | -- Dumping data for table `teams`
103 | --
104 |
105 | LOCK TABLES `teams` WRITE;
106 | /*!40000 ALTER TABLE `teams` DISABLE KEYS */;
107 | INSERT INTO `teams` VALUES (31,'Administrator','Application Administrator','e071d8624c930dd2412ba7a5d20a0a2098a546747d901add852d47520adeb7875e8b1256b64eb4e6d4d3fc45857032c1701c14f74af2bb01a12d78484e2849ef',2,0,0,0,0);
108 | /*!40000 ALTER TABLE `teams` ENABLE KEYS */;
109 | UNLOCK TABLES;
110 |
111 | --
112 | -- Table structure for table `torneio_problems`
113 | --
114 |
115 | DROP TABLE IF EXISTS `torneio_problems`;
116 | /*!40101 SET @saved_cs_client = @@character_set_client */;
117 | /*!40101 SET character_set_client = utf8 */;
118 | CREATE TABLE `torneio_problems` (
119 | `idtorneio_problems` bigint(20) NOT NULL AUTO_INCREMENT,
120 | `idtorneio` bigint(20) NOT NULL,
121 | `idgrupos_problemas` bigint(20) NOT NULL,
122 | PRIMARY KEY (`idtorneio_problems`),
123 | KEY `fk_torneio_problems_torneio1` (`idtorneio`),
124 | KEY `fk_torneio_problems_grupos_problemas1` (`idgrupos_problemas`),
125 | CONSTRAINT `fk_torneio_problems_grupos_problemas1` FOREIGN KEY (`idgrupos_problemas`) REFERENCES `grupos_problemas` (`idgrupos_problemas`) ON DELETE NO ACTION ON UPDATE NO ACTION,
126 | CONSTRAINT `fk_torneio_problems_torneio1` FOREIGN KEY (`idtorneio`) REFERENCES `torneio` (`idtorneio`) ON DELETE NO ACTION ON UPDATE NO ACTION
127 | ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
128 | /*!40101 SET character_set_client = @saved_cs_client */;
129 |
130 | --
131 | -- Dumping data for table `torneio_problems`
132 | --
133 |
134 | LOCK TABLES `torneio_problems` WRITE;
135 | /*!40000 ALTER TABLE `torneio_problems` DISABLE KEYS */;
136 | /*!40000 ALTER TABLE `torneio_problems` ENABLE KEYS */;
137 | UNLOCK TABLES;
138 |
139 | --
140 | -- Table structure for table `members`
141 | --
142 |
143 | DROP TABLE IF EXISTS `members`;
144 | /*!40101 SET @saved_cs_client = @@character_set_client */;
145 | /*!40101 SET character_set_client = utf8 */;
146 | CREATE TABLE `members` (
147 | `idmembers` bigint(20) NOT NULL AUTO_INCREMENT,
148 | `name` varchar(100) NOT NULL,
149 | `idteams` bigint(20) NOT NULL,
150 | `description` varchar(200) DEFAULT NULL,
151 | PRIMARY KEY (`idmembers`),
152 | UNIQUE KEY `idmembers_UNIQUE` (`idmembers`),
153 | KEY `fk_members_teams1` (`idteams`),
154 | CONSTRAINT `fk_members_teams1` FOREIGN KEY (`idteams`) REFERENCES `teams` (`idteams`) ON DELETE NO ACTION ON UPDATE NO ACTION
155 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
156 | /*!40101 SET character_set_client = @saved_cs_client */;
157 |
158 | --
159 | -- Dumping data for table `members`
160 | --
161 |
162 | LOCK TABLES `members` WRITE;
163 | /*!40000 ALTER TABLE `members` DISABLE KEYS */;
164 | /*!40000 ALTER TABLE `members` ENABLE KEYS */;
165 | UNLOCK TABLES;
166 |
167 | --
168 | -- Table structure for table `problemas`
169 | --
170 |
171 | DROP TABLE IF EXISTS `problemas`;
172 | /*!40101 SET @saved_cs_client = @@character_set_client */;
173 | /*!40101 SET character_set_client = utf8 */;
174 | CREATE TABLE `problemas` (
175 | `idproblemas` bigint(20) NOT NULL AUTO_INCREMENT,
176 | `idgrupos_problemas` bigint(20) NOT NULL,
177 | `resposta` varchar(200) NOT NULL,
178 | `description` varchar(5000) DEFAULT NULL,
179 | `points` int(11) NOT NULL,
180 | `open` int(1) DEFAULT '0',
181 | `level` int(2) DEFAULT '1',
182 | PRIMARY KEY (`idproblemas`),
183 | KEY `fk_problemas_grupos_problemas1` (`idgrupos_problemas`),
184 | CONSTRAINT `fk_problemas_grupos_problemas1` FOREIGN KEY (`idgrupos_problemas`) REFERENCES `grupos_problemas` (`idgrupos_problemas`) ON DELETE NO ACTION ON UPDATE NO ACTION
185 | ) ENGINE=InnoDB AUTO_INCREMENT=37 DEFAULT CHARSET=latin1;
186 | /*!40101 SET character_set_client = @saved_cs_client */;
187 |
188 | --
189 | -- Dumping data for table `problemas`
190 | --
191 |
192 | LOCK TABLES `problemas` WRITE;
193 | /*!40000 ALTER TABLE `problemas` DISABLE KEYS */;
194 | /*!40000 ALTER TABLE `problemas` ENABLE KEYS */;
195 | UNLOCK TABLES;
196 |
197 | --
198 | -- Table structure for table `torneio`
199 | --
200 |
201 | DROP TABLE IF EXISTS `torneio`;
202 | /*!40101 SET @saved_cs_client = @@character_set_client */;
203 | /*!40101 SET character_set_client = utf8 */;
204 | CREATE TABLE `torneio` (
205 | `idtorneio` bigint(20) NOT NULL AUTO_INCREMENT,
206 | `name` varchar(45) NOT NULL,
207 | `description` varchar(200) DEFAULT NULL,
208 | PRIMARY KEY (`idtorneio`)
209 | ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;
210 | /*!40101 SET character_set_client = @saved_cs_client */;
211 |
212 | --
213 | -- Dumping data for table `torneio`
214 | --
215 |
216 | LOCK TABLES `torneio` WRITE;
217 | /*!40000 ALTER TABLE `torneio` DISABLE KEYS */;
218 | INSERT INTO `torneio` VALUES (1,'Demo','Demo Tournament');
219 | /*!40000 ALTER TABLE `torneio` ENABLE KEYS */;
220 | UNLOCK TABLES;
221 |
222 | --
223 | -- Table structure for table `config`
224 | --
225 |
226 | DROP TABLE IF EXISTS `config`;
227 | /*!40101 SET @saved_cs_client = @@character_set_client */;
228 | /*!40101 SET character_set_client = utf8 */;
229 | CREATE TABLE `config` (
230 | `idconfig` int(11) NOT NULL AUTO_INCREMENT,
231 | `idtorneio` bigint(20) NOT NULL,
232 | `start_date` datetime NOT NULL,
233 | `end_date` datetime NOT NULL,
234 | `random_problem_opening_interval` int(11) DEFAULT NULL,
235 | PRIMARY KEY (`idconfig`),
236 | KEY `fk_config_torneio1` (`idtorneio`),
237 | CONSTRAINT `fk_config_torneio1` FOREIGN KEY (`idtorneio`) REFERENCES `torneio` (`idtorneio`) ON DELETE NO ACTION ON UPDATE NO ACTION
238 | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
239 | /*!40101 SET character_set_client = @saved_cs_client */;
240 |
241 | --
242 | -- Dumping data for table `config`
243 | --
244 |
245 | LOCK TABLES `config` WRITE;
246 | /*!40000 ALTER TABLE `config` DISABLE KEYS */;
247 | INSERT INTO `config` VALUES (3,1,'2012-07-07 19:45:00','2012-07-20 21:30:00',20000);
248 | /*!40000 ALTER TABLE `config` ENABLE KEYS */;
249 | UNLOCK TABLES;
250 |
251 | --
252 | -- Table structure for table `torneio_teams`
253 | --
254 |
255 | DROP TABLE IF EXISTS `torneio_teams`;
256 | /*!40101 SET @saved_cs_client = @@character_set_client */;
257 | /*!40101 SET character_set_client = utf8 */;
258 | CREATE TABLE `torneio_teams` (
259 | `idtorneio_teams` bigint(20) NOT NULL AUTO_INCREMENT,
260 | `idteams` bigint(20) NOT NULL,
261 | `idtorneio` bigint(20) NOT NULL,
262 | PRIMARY KEY (`idtorneio_teams`),
263 | KEY `fk_torneio_teams_teams1` (`idteams`),
264 | KEY `fk_torneio_teams_torneio1` (`idtorneio`),
265 | CONSTRAINT `fk_torneio_teams_teams1` FOREIGN KEY (`idteams`) REFERENCES `teams` (`idteams`) ON DELETE NO ACTION ON UPDATE NO ACTION,
266 | CONSTRAINT `fk_torneio_teams_torneio1` FOREIGN KEY (`idtorneio`) REFERENCES `torneio` (`idtorneio`) ON DELETE NO ACTION ON UPDATE NO ACTION
267 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
268 | /*!40101 SET character_set_client = @saved_cs_client */;
269 |
270 | --
271 | -- Dumping data for table `torneio_teams`
272 | --
273 |
274 | LOCK TABLES `torneio_teams` WRITE;
275 | /*!40000 ALTER TABLE `torneio_teams` DISABLE KEYS */;
276 | /*!40000 ALTER TABLE `torneio_teams` ENABLE KEYS */;
277 | UNLOCK TABLES;
278 | /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
279 |
280 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
281 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
282 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
283 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
284 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
285 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
286 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
287 |
288 | -- Dump completed on 2012-07-14 19:18:15
289 |
--------------------------------------------------------------------------------
/routes/administration.js:
--------------------------------------------------------------------------------
1 | var hash = require('node_hash');
2 | var randomstring = require("randomstring");
3 | var util = require('util');
4 | var mysql = require('mysql');
5 | var connections = require('../BD/db.js');
6 |
7 |
8 |
9 | connections.connection.on('close', function(err) {
10 | if (err) {
11 | // We did not expect this connection to terminate
12 | util.log('ligacao caiu mas vou restabelecer');
13 | connections.connection = mysql.createConnection(connections.connection.config);
14 | } else {
15 | // We expected this to happen, end() was called.
16 | }
17 | });
18 |
19 | connections.connectionHashes.on('close', function(err) {
20 | if (err) {
21 | // We did not expect this connection to terminate
22 | util.log('ligacao caiu mas vou restabelecer');
23 | connections.connectionHashes = mysql.createConnection(connections.connectionHashes.config);
24 | } else {
25 | // We expected this to happen, end() was called.
26 | }
27 | });
28 |
29 | connections.connection.on('error', function(err) {
30 | util.log(err.code); // 'ER_BAD_DB_ERROR'
31 | util.log('ligacao caiu mas vou restabelecer');
32 | connections.connection = mysql.createConnection(connections.connection.config);
33 | });
34 |
35 | connections.connectionHashes.on('error', function(err) {
36 | util.log(err.code); // 'ER_BAD_DB_ERROR'
37 | util.log('ligacao caiu mas vou restabelecer');
38 | connections.connectionHashes = mysql.createConnection(connections.connectionHashes.config);
39 | });
40 |
41 |
42 |
43 |
44 | exports.dashTemplate = function(req, res) {
45 | res.render('admin/dashboard');
46 | }
47 |
48 | exports.addTeam = function(req, res) {
49 | res.render('admin/insert/addTeam');
50 | }
51 |
52 | exports.insertTeam = function(req, res) {
53 | var teamName = req.body.teamName;
54 | var teamPassword = req.body.teamPassword;
55 | var type = req.body.type;
56 |
57 | var salt = randomstring.generate(20);
58 | var password = hash.sha512(teamPassword, salt);
59 |
60 | connections.connection.query('INSERT INTO teams SET ?', {name: teamName, description: req.body.description, password: password, administrationLevel: type}, function(err, result) {
61 | if (err) console.log(err);
62 | connections.connectionHashes.query('INSERT INTO userHashes SET ?', {idteams: result.insertId, salt: salt}, function(err, result2){
63 | if(err) console.log(err);
64 | res.render('admin/insert/addTeam');
65 | });
66 | });
67 | }
68 |
69 | exports.listTeams = function(req, res) {
70 | connections.connection.query('Select * from teams', function(err, result){
71 | if(err) console.log(err);
72 | res.render('admin/list/listTeams', {teams: result});
73 | });
74 | }
75 |
76 | exports.showEditTeam = function(req, res) {
77 | var sqlQuery = 'SELECT * FROM teams WHERE idteams = ' + connections.connection.escape(req.params.id);
78 |
79 | connections.connection.query(sqlQuery, function(err, result) {
80 | if(err) console.log(err);
81 |
82 | res.render('admin/edit/editTeam', {team: result[0]});
83 | });
84 | }
85 |
86 | exports.editTeam = function(req, res) {
87 | var sqlUpdate = 'UPDATE teams tm SET tm.name = ' + connections.connection.escape(req.body.teamName) + ', tm.description = ' + connections.connection.escape(req.body.description) + ' WHERE tm.idteams = ' + connections.connection.escape(req.params.id);
88 |
89 | connections.connection.query(sqlUpdate, function(err, result) {
90 | if(err) console.log(err);
91 |
92 | res.redirect('/editTeam/'+req.params.id);
93 | });
94 | }
95 |
96 | exports.deleteTeam = function(req, res) {
97 | var sqlDeleteTeam = 'DELETE FROM teams WHERE idteams = ' + connections.connection.escape(req.params.id);
98 | var sqlDeleteTeamLog = 'DELETE FROM teams_log WHERE idteams = ' + connections.connection.escape(req.params.id);
99 |
100 | connections.connection.query(sqlDeleteTeamLog, function(err, result) {
101 | if (err) console.log(err);
102 |
103 | connections.connection.query(sqlDeleteTeam, function(err, result) {
104 | if (err) console.log(err);
105 |
106 | res.redirect('/listTeams');
107 | });
108 | });
109 | }
110 |
111 | exports.addChallenge = function(req, res) {
112 | res.render('admin/insert/addChallenge');
113 | }
114 |
115 | exports.addCategory = function(req, res) {
116 | res.render('admin/insert/addCategory');
117 | }
118 |
119 | exports.insertCategory = function(req, res) {
120 | connections.connection.query('INSERT INTO torneio.grupos_problemas SET ?', {name: req.body.categoryName, desc: req.body.description}, function(err, result) {
121 | if (err) console.log(err);
122 |
123 | res.render('admin/insert/addCategory');
124 | });
125 | }
126 |
127 | exports.showEditCategory = function(req, res) {
128 | var sqlQuery = 'SELECT * FROM grupos_problemas WHERE idgrupos_problemas = ' + connections.connection.escape(req.params.id);
129 |
130 | connections.connection.query(sqlQuery, function(err, result) {
131 | if (err) console.log(err);
132 |
133 | res.render('admin/edit/editCategory', {category: result[0]});
134 | });
135 | }
136 |
137 | exports.editCategory = function(req, res) {
138 | var sqlUpdate = 'UPDATE grupos_problemas gp SET gp.name = ' + connections.connection.escape(req.body.categoryName) + ', gp.desc = ' + connections.connection.escape(req.body.description) + ' WHERE gp.idgrupos_problemas = ' + connections.connection.escape(req.params.id);
139 | //console.log(sqlUpdate);
140 | connections.connection.query(sqlUpdate, function(err, result) {
141 | if (err) console.log(err);
142 |
143 | //console.log(result);
144 | res.redirect('/editCategory/'+req.params.id);
145 | });
146 | }
147 |
148 | exports.listCategories = function(req, res) {
149 | connections.connection.query('select * from grupos_problemas order by idgrupos_problemas', function(err, result){
150 | if(err) console.log(err);
151 | //console.log(result);
152 | res.render('admin/list/listCategories', {categories: result});
153 | });
154 |
155 | }
156 |
157 | exports.deleteCategory = function(req, res) {
158 | var sqlDeleteCategory = 'DELETE FROM grupos_problemas WHERE idgrupos_problemas = ' + connections.connection.escape(req.params.id);
159 | var sqlDeleteCategoryProblems = 'DELETE FROM problemas WHERE idgrupos_problemas = ' + connections.connection.escape(req.params.id);
160 |
161 | connections.connection.query(sqlDeleteCategoryProblems, function(err, result) {
162 | if (err) console.log(err);
163 |
164 | //console.log(result);
165 |
166 | connections.connection.query(sqlDeleteCategory, function(err, result) {
167 | if (err) console.log(err);
168 |
169 | //console.log(result);
170 |
171 | res.redirect('/listCategories');
172 | });
173 | });
174 | }
175 |
176 |
177 | exports.addProblem = function(req, res) {
178 | connections.connection.query('select * from grupos_problemas', function(err, result){
179 | if(err) console.log(err);
180 | res.render('admin/insert/addProblem', {categories: result});
181 | });
182 | }
183 |
184 | exports.insertProblem = function(req, res) {
185 | //console.log(req.body.category);
186 |
187 | connections.connection.query('INSERT INTO problemas SET ?', {idgrupos_problemas: req.body.category, resposta: req.body.answer, description: req.body.description, points: req.body.points, level: req.body.level}, function(err, result) {
188 | if(err) console.log(err);
189 |
190 | connections.connection.query('select * from grupos_problemas', function(err, result){
191 | if(err) console.log(err);
192 | res.render('admin/insert/addProblem', {categories: result});
193 | });
194 | });
195 | }
196 |
197 | exports.showEditProblem = function(req, res) {
198 | var sqlQuery = 'SELECT * FROM problemas WHERE idproblemas = ' + connections.connection.escape(req.params.id);
199 | var problema;
200 | var categorias;
201 |
202 | //console.log(sqlQuery);
203 | connections.connection.query(sqlQuery, function(err, result) {
204 | if (err) console.log(err);
205 | problema = result[0];
206 | connections.connection.query('select * from grupos_problemas order by idgrupos_problemas', function(err, result){
207 | if(err) console.log(err);
208 | categorias = result;
209 | //console.log(problema);
210 | //console.log(categorias);
211 | res.render('admin/edit/editProblem', {problem: problema, categories: categorias});
212 | });
213 | });
214 | }
215 |
216 | exports.editProblem = function(req, res) {
217 | var sqlUpdate = 'UPDATE problemas prob SET prob.idgrupos_problemas = ' + connections.connection.escape(req.body.category) + ', prob.resposta = ' + connections.connection.escape(req.body.answer) + ', prob.points = ' + connections.connection.escape(req.body.points) + ', prob.description = ' + connections.connection.escape(req.body.description) + ', prob.level = '+ connections.connection.escape(req.body.level)+' WHERE prob.idproblemas = ' + connections.connection.escape(req.params.id);
218 |
219 | connections.connection.query(sqlUpdate, function(err, result) {
220 | if(err) console.log(err);
221 |
222 | res.redirect('/editProblem/'+req.params.id);
223 | });
224 | }
225 |
226 |
227 | exports.listProblems = function(req, res) {
228 | var query = 'select * from problemas, grupos_problemas where problemas.idgrupos_problemas = grupos_problemas.idgrupos_problemas order by problemas.idgrupos_problemas';
229 | connections.connection.query(query, function(err, result){
230 | if(err) console.log(err);
231 | //console.log(result);
232 | res.render('admin/list/listProblems', {problems: result});
233 | });
234 | }
235 |
236 | exports.deleteProblem = function(req, res) {
237 | var sqlDeleteProblem = 'DELETE FROM problemas WHERE idproblemas = ' + connections.connection.escape(req.params.id);
238 | var sqlDeleteProblemTeamLog = 'DELETE FROM teams_log WHERE idproblemas = ' + connections.connection.escape(req.params.id);
239 |
240 | connections.connection.query(sqlDeleteProblemTeamLog, function(err, result) {
241 | if (err) console.log(err);
242 |
243 | //console.log(result);
244 |
245 | connections.connection.query(sqlDeleteProblem, function(err, result) {
246 | if (err) console.log(err);
247 |
248 | //console.log(result);
249 |
250 | res.redirect('/listProblems');
251 | });
252 | });
253 | }
254 |
255 |
256 | exports.options = function(req, res) {
257 | var sqlConfig = 'SELECT DATE_FORMAT(start_date, \'%Y-%m-%d %H:%i:%s\') as start_date, DATE_FORMAT(end_date, \'%Y-%m-%d %H:%i:%s\') as end_date, random_problem_opening_interval FROM config';
258 | connections.connection.query(sqlConfig, function(errConfig, rowsConfig, fieldsConfig) {
259 | if(errConfig) console.log(errConfig);
260 | connections.connection.query('select * from grupos_problemas, problemas where grupos_problemas.idgrupos_problemas = problemas.idgrupos_problemas and problemas.open = false', function(err, result){
261 | if(err) console.log(err);
262 | //console.log(result);
263 | res.render('admin/config/options', {categories: result, config: rowsConfig[0]});
264 | });
265 | });
266 | }
267 |
268 | exports.editOptions = function(req, res) {
269 | var sqlConfig = 'SELECT DATE_FORMAT(start_date, \'%Y-%m-%d %H:%i:%s\') as start_date, DATE_FORMAT(end_date, \'%Y-%m-%d %H:%i:%s\') as end_date, random_problem_opening_interval FROM config';
270 | //console.log(req.body.category);
271 |
272 | connections.connection.query('UPDATE config SET ?', {start_date: req.body.startDate, end_date: req.body.endDate, random_problem_opening_interval: req.body.random_problem_opening_interval}, function(err, result) {
273 | if(err) console.log(err);
274 | connections.connection.query(sqlConfig, function(errConfig, rowsConfig, fieldsConfig) {
275 | if(errConfig) throw errConfig;
276 | connections.connection.query('select * from grupos_problemas, problemas where grupos_problemas.idgrupos_problemas = problemas.idgrupos_problemas and problemas.open = false', function(err, result){
277 | if(err) console.log(err);
278 | //console.log(result);
279 | res.render('admin/config/options', {categories: result, config: rowsConfig[0]});
280 | });
281 |
282 | });
283 | });
284 | }
285 |
286 | exports.resetTeamlogs = function(req, res) {
287 | var sqlConfig = 'SELECT DATE_FORMAT(start_date, \'%Y-%m-%d %H:%i:%s\') as start_date, DATE_FORMAT(end_date, \'%Y-%m-%d %H:%i:%s\') as end_date, random_problem_opening_interval FROM config';
288 | var sqlResetTeamlogs = 'Delete from teams_log';
289 | var sqlResetProblems = 'UPDATE problemas set open = 0 where level > 1';
290 | var sqlResetTeamsOpenProblemsLevels = 'UPDATE teams SET problems_to_open_level_1 = 0, problems_to_open_level_2 = 0, problems_to_open_level_3 = 0, problems_to_open_level_4 = 0';
291 | connections.connection.query(sqlResetTeamsOpenProblemsLevels, function(err, result) {
292 | if(err) console.log(err);
293 | connections.connection.query(sqlResetProblems, function(err, result) {
294 | if(err) console.log(err);
295 | connections.connection.query(sqlResetTeamlogs, function(err, result) {
296 | if(err) console.log(err);
297 | connections.connection.query(sqlConfig, function(errConfig, rowsConfig, fieldsConfig) {
298 | if(errConfig) console.log(errConfig);
299 | connections.connection.query('select * from grupos_problemas, problemas where grupos_problemas.idgrupos_problemas = problemas.idgrupos_problemas and problemas.open = false', function(err, result){
300 | if(err) console.log(err);
301 | //console.log(result);
302 | res.render('admin/config/options', {categories: result, config: rowsConfig[0]});
303 | });
304 | });
305 | });
306 | });
307 | });
308 | }
309 |
310 | exports.comms = function(req, res) {
311 | /*var sqlConfig = 'SELECT DATE_FORMAT(start_date, \'%Y-%m-%d %h:%i:%s\') as start_date, DATE_FORMAT(end_date, \'%Y-%m-%d %h:%i:%s\') as end_date FROM config';
312 | console.log(req.body.category);
313 |
314 | connection.query('UPDATE config SET ?', {start_date: req.body.startDate, end_date: req.body.endDate}, function(err, result) {
315 | if(err) throw err;
316 | connection.query(sqlConfig, function(errConfig, rowsConfig, fieldsConfig) {
317 | if(errConfig) throw errConfig;*/
318 | res.render('admin/config/comms');
319 |
320 | /*});
321 | });*/
322 | }
323 |
--------------------------------------------------------------------------------
/public/js/jquery.tablesorter.min.js:
--------------------------------------------------------------------------------
1 |
2 | (function($){$.extend({tablesorter:new
3 | function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",cssChildRow:"expand-child",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,sortAppend:null,sortLocaleCompare:true,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",decimal:'/\.|\,/g',onRenderHeader:null,selectorHeaders:'thead th',debug:false};function benchmark(s,d){log(s+","+(new Date().getTime()-d.getTime())+"ms");}this.benchmark=benchmark;function log(s){if(typeof console!="undefined"&&typeof console.debug!="undefined"){console.log(s);}else{alert(s);}}function buildParserCache(table,$headers){if(table.config.debug){var parsersDebug="";}if(table.tBodies.length==0)return;var rows=table.tBodies[0].rows;if(rows[0]){var list=[],cells=rows[0].cells,l=cells.length;for(var i=0;i1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.metadata)&&($(cell).metadata().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function checkHeaderOptionsSortingLocked(table,i){if((table.config.headers[i])&&(table.config.headers[i].lockedOrder))return table.config.headers[i].lockedOrder;return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;i b["+i+"]) ? 1 : 0));";};function makeSortTextDesc(i){return"((b["+i+"] < a["+i+"]) ? -1 : ((b["+i+"] > a["+i+"]) ? 1 : 0));";};function makeSortNumeric(i){return"a["+i+"]-b["+i+"];";};function makeSortNumericDesc(i){return"b["+i+"]-a["+i+"];";};function sortText(a,b){if(table.config.sortLocaleCompare)return a.localeCompare(b);return((ab)?1:0));};function sortTextDesc(a,b){if(table.config.sortLocaleCompare)return b.localeCompare(a);return((ba)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$.data(this,"tablesorter",config);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){$this.trigger("sortStart");var $cell=$(this);var i=this.column;this.order=this.count++%2;if(this.lockedOrder)this.order=this.lockedOrder;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i