|
@@ -4,6 +4,15 @@ main.mapShareKey = 'map-shares'; |
|
|
|
|
|
main.ga = window.ga || function() {};
|
|
|
|
|
|
+main.challengeTypes = {
|
|
|
+ 'HTML_CSS_JQ': '0',
|
|
|
+ 'JAVASCRIPT': '1',
|
|
|
+ 'VIDEO': '2',
|
|
|
+ 'ZIPLINE': '3',
|
|
|
+ 'BASEJUMP': '4',
|
|
|
+ 'BONFIRE': '5'
|
|
|
+};
|
|
|
+
|
|
|
main = (function(main) {
|
|
|
|
|
|
// should be set before gitter script loads
|
|
@@ -103,6 +112,44 @@ main = (function(main) { |
|
|
return main;
|
|
|
}(main));
|
|
|
|
|
|
+main.lockTop = function lockTop() {
|
|
|
+ var magiVal;
|
|
|
+
|
|
|
+ if ($(window).width() >= 990) {
|
|
|
+ if ($('.editorScrollDiv').html()) {
|
|
|
+
|
|
|
+ magiVal = $(window).height() -
|
|
|
+ $('.navbar').height() +
|
|
|
+ $('.footer').height();
|
|
|
+
|
|
|
+ if (magiVal < 0) {
|
|
|
+ magiVal = 0;
|
|
|
+ }
|
|
|
+ $('.editorScrollDiv').css('height', magiVal - 85 + 'px');
|
|
|
+ }
|
|
|
+
|
|
|
+ magiVal = $(window).height() -
|
|
|
+ $('.navbar').height() +
|
|
|
+ $('.footer').height();
|
|
|
+
|
|
|
+ if (magiVal < 0) {
|
|
|
+ magiVal = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ $('.scroll-locker')
|
|
|
+ .css('min-height', $('.editorScrollDiv').height())
|
|
|
+ .css('height', magiVal - 185);
|
|
|
+ } else {
|
|
|
+ $('.editorScrollDiv').css('max-height', 500 + 'px');
|
|
|
+
|
|
|
+ $('.scroll-locker')
|
|
|
+ .css('position', 'inherit')
|
|
|
+ .css('top', 'inherit')
|
|
|
+ .css('width', '100%')
|
|
|
+ .css('max-height', '85%');
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
var lastCompleted = typeof lastCompleted !== 'undefined' ?
|
|
|
lastCompleted :
|
|
|
'';
|
|
@@ -143,11 +190,11 @@ $(document).ready(function() { |
|
|
'';
|
|
|
|
|
|
if (challengeName) {
|
|
|
- ga('send', 'event', 'Challenge', 'load', challengeName);
|
|
|
+ ga('send', 'event', 'Challenge', 'load', challengeName);
|
|
|
}
|
|
|
|
|
|
if (typeof editor !== 'undefined') {
|
|
|
- $('#reset-button').on('click', resetEditor);
|
|
|
+ $('#reset-button').on('click', window.resetEditor);
|
|
|
}
|
|
|
|
|
|
var CSRF_HEADER = 'X-CSRF-Token';
|
|
@@ -164,7 +211,7 @@ $(document).ready(function() { |
|
|
|
|
|
$('.checklist-element').each(function() {
|
|
|
var checklistElementId = $(this).attr('id');
|
|
|
- if(!!localStorage[checklistElementId]) {
|
|
|
+ if (localStorage[checklistElementId]) {
|
|
|
$(this).children().children('li').addClass('faded');
|
|
|
$(this).children().children('input').trigger('click');
|
|
|
}
|
|
@@ -179,13 +226,14 @@ $(document).ready(function() { |
|
|
|
|
|
$('.challenge-list-checkbox').on('change', function() {
|
|
|
var checkboxId = $(this).parent().parent().attr('id');
|
|
|
- if ($(this).is(":checked")) {
|
|
|
+ if ($(this).is(':checked')) {
|
|
|
$(this).parent().siblings().children().addClass('faded');
|
|
|
if (!localStorage || !localStorage[checkboxId]) {
|
|
|
localStorage[checkboxId] = true;
|
|
|
}
|
|
|
}
|
|
|
- if (!$(this).is(":checked")) {
|
|
|
+
|
|
|
+ if (!$(this).is(':checked')) {
|
|
|
$(this).parent().siblings().children().removeClass('faded');
|
|
|
if (localStorage[checkboxId]) {
|
|
|
localStorage.removeItem(checkboxId);
|
|
@@ -193,271 +241,294 @@ $(document).ready(function() { |
|
|
}
|
|
|
});
|
|
|
|
|
|
- $("img").error(function () {
|
|
|
- $(this).unbind("error").attr("src", "https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png");
|
|
|
+ $('img').error(function() {
|
|
|
+ $(this)
|
|
|
+ .unbind('error')
|
|
|
+ .attr(
|
|
|
+ 'src',
|
|
|
+ 'https://s3.amazonaws.com/freecodecamp/camper-image-placeholder.png'
|
|
|
+ );
|
|
|
});
|
|
|
|
|
|
- function reBindModals(){
|
|
|
+ function reBindModals() {
|
|
|
+ if (!window.common) {
|
|
|
+ throw new Error('common framework should be loaded.');
|
|
|
+ }
|
|
|
+ var common = window.common;
|
|
|
|
|
|
- $('.close-modal').unbind('click');
|
|
|
- $('.close-modal').on('click', function(){
|
|
|
- setTimeout(function() {
|
|
|
- $('.close-modal').parent().parent().parent().parent().modal('hide');
|
|
|
- }, 200);
|
|
|
- });
|
|
|
+ $('.close-modal').unbind('click');
|
|
|
+ $('.close-modal').on('click', function() {
|
|
|
+ setTimeout(function() {
|
|
|
+ $('.close-modal').parent().parent().parent().parent().modal('hide');
|
|
|
+ }, 200);
|
|
|
+ });
|
|
|
|
|
|
- $('#search-issue').unbind('click');
|
|
|
- $('#search-issue').on('click', function() {
|
|
|
- var queryIssue = window.location.href.toString().split('#?')[0];
|
|
|
- window.open('https://github.com/FreeCodeCamp/FreeCodeCamp/issues?q=' +
|
|
|
- 'is:issue is:all ' + (challenge_Name || challengeName) + ' OR ' +
|
|
|
- queryIssue.substr(queryIssue.lastIndexOf('challenges/') + 11)
|
|
|
- .replace('/', ''), '_blank');
|
|
|
- });
|
|
|
+ $('#search-issue').unbind('click');
|
|
|
+ $('#search-issue').on('click', function() {
|
|
|
+ var queryIssue = window.location.href.toString();
|
|
|
+ window.open(
|
|
|
+ 'https://github.com/FreeCodeCamp/FreeCodeCamp/issues?q=' +
|
|
|
+ 'is:issue is:all ' +
|
|
|
+ (common.challengeName) +
|
|
|
+ ' OR ' +
|
|
|
+ queryIssue
|
|
|
+ .substr(queryIssue.lastIndexOf('challenges/') + 11)
|
|
|
+ .replace('/', ''), '_blank');
|
|
|
+ });
|
|
|
|
|
|
- $('#gist-share').unbind('click');
|
|
|
- $('#gist-share').on('click', function() {
|
|
|
- var gistWindow = window.open('', '_blank');
|
|
|
-
|
|
|
- $('#gist-share')
|
|
|
- .attr('disabled', 'true')
|
|
|
- .removeClass('btn-danger')
|
|
|
- .addClass('btn-warning disabled');
|
|
|
-
|
|
|
- function createCORSRequest(method, url) {
|
|
|
- var xhr = new XMLHttpRequest();
|
|
|
- if ('withCredentials' in xhr) {
|
|
|
- xhr.open(method, url, true);
|
|
|
- } else if (typeof XDomainRequest !== 'undefined') {
|
|
|
- xhr = new XDomainRequest();
|
|
|
- xhr.open(method, url);
|
|
|
- } else {
|
|
|
- xhr = null;
|
|
|
- }
|
|
|
- xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8');
|
|
|
- return xhr;
|
|
|
+ $('#gist-share').unbind('click');
|
|
|
+ $('#gist-share').on('click', function() {
|
|
|
+ var gistWindow = window.open('', '_blank');
|
|
|
+
|
|
|
+ $('#gist-share')
|
|
|
+ .attr('disabled', 'true')
|
|
|
+ .removeClass('btn-danger')
|
|
|
+ .addClass('btn-warning disabled');
|
|
|
+
|
|
|
+ function createCORSRequest(method, url) {
|
|
|
+ var xhr = new XMLHttpRequest();
|
|
|
+ if ('withCredentials' in xhr) {
|
|
|
+ xhr.open(method, url, true);
|
|
|
+ } else if (typeof XDomainRequest !== 'undefined') {
|
|
|
+ xhr = new XDomainRequest();
|
|
|
+ xhr.open(method, url);
|
|
|
+ } else {
|
|
|
+ xhr = null;
|
|
|
}
|
|
|
+ xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8');
|
|
|
+ return xhr;
|
|
|
+ }
|
|
|
|
|
|
- var request = createCORSRequest('post', 'https://api.github.com/gists');
|
|
|
- if (request) {
|
|
|
- request.onload = function() {
|
|
|
- if (request.readyState === 4 &&
|
|
|
- request.status === 201 &&
|
|
|
- request.statusText === 'Created') {
|
|
|
- gistWindow.location.href = JSON.parse(request.responseText)['html_url'];
|
|
|
- }
|
|
|
- };
|
|
|
- var data = {
|
|
|
- description: (username ? 'http://www.freecodecamp.com/' + username +
|
|
|
- ' \'s s' : 'S') + 'olution for ' + (challenge_Name || challengeName),
|
|
|
- public: true,
|
|
|
- files: {}
|
|
|
- },
|
|
|
- queryIssue = window.location.href.toString().split('#?')[0],
|
|
|
- filename = queryIssue
|
|
|
- .substr(queryIssue.lastIndexOf('challenges/') + 11)
|
|
|
- .replace('/', '') + '.js';
|
|
|
- data['files'][filename] = {
|
|
|
- content: '// ' + (challenge_Name || challengeName) + '\n' +
|
|
|
- (username ? '// Author: @' + username + '\n' : '') +
|
|
|
- '// Challenge: ' + queryIssue + '\n' +
|
|
|
- '// Learn to Code at Free Code Camp (www.freecodecamp.com)' +
|
|
|
- '\n\n' + editor.getValue().trim()
|
|
|
- };
|
|
|
-
|
|
|
- request.send(JSON.stringify(data));
|
|
|
- }
|
|
|
- });
|
|
|
+ var request = createCORSRequest('post', 'https://api.github.com/gists');
|
|
|
+ if (request) {
|
|
|
+ request.onload = function() {
|
|
|
+ if (request.readyState === 4 &&
|
|
|
+ request.status === 201 &&
|
|
|
+ request.statusText === 'Created') {
|
|
|
+ gistWindow.location.href = JSON.parse(request.responseText)['html_url'];
|
|
|
+ }
|
|
|
+ };
|
|
|
+ var data = {
|
|
|
+ description: (username ? 'http://www.freecodecamp.com/' + username +
|
|
|
+ ' \'s s' : 'S') + 'olution for ' + (challenge_Name || challengeName),
|
|
|
+ public: true,
|
|
|
+ files: {}
|
|
|
+ },
|
|
|
+ queryIssue = window.location.href.toString().split('#?')[0],
|
|
|
+ filename = queryIssue
|
|
|
+ .substr(queryIssue.lastIndexOf('challenges/') + 11)
|
|
|
+ .replace('/', '') + '.js';
|
|
|
+ data['files'][filename] = {
|
|
|
+ content: '// ' + (challenge_Name || challengeName) + '\n' +
|
|
|
+ (username ? '// Author: @' + username + '\n' : '') +
|
|
|
+ '// Challenge: ' + queryIssue + '\n' +
|
|
|
+ '// Learn to Code at Free Code Camp (www.freecodecamp.com)' +
|
|
|
+ '\n\n' + editor.getValue().trim()
|
|
|
+ };
|
|
|
|
|
|
- $('#help-ive-found-a-bug-wiki-article').unbind('click');
|
|
|
- $('#help-ive-found-a-bug-wiki-article').on('click', function() {
|
|
|
- window.open("https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Help-I've-Found-a-Bug", '_blank');
|
|
|
- });
|
|
|
+ request.send(JSON.stringify(data));
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
- $('#report-issue').unbind('click');
|
|
|
- $('#report-issue').on('click', function() {
|
|
|
- var textMessage = [
|
|
|
- 'Challenge [',
|
|
|
- (challenge_Name || challengeName || window.location.href),
|
|
|
- '](',
|
|
|
- window.location.href,
|
|
|
- ') has an issue.\n',
|
|
|
- 'User Agent is: <code>',
|
|
|
- navigator.userAgent,
|
|
|
- '</code>.\n',
|
|
|
- 'Please describe how to reproduce this issue, and include ',
|
|
|
- 'links to screenshots if possible.\n\n'
|
|
|
- ].join('');
|
|
|
-
|
|
|
- if (typeof editor !== 'undefined' && editor.getValue().trim()) {
|
|
|
- var type;
|
|
|
- switch (challengeType) {
|
|
|
- case challengeTypes.HTML_CSS_JQ:
|
|
|
- type = 'html';
|
|
|
- break;
|
|
|
- case challengeTypes.JAVASCRIPT:
|
|
|
- case challengeTypes.BONFIRE:
|
|
|
- type = 'javascript';
|
|
|
- break;
|
|
|
- default:
|
|
|
- type = '';
|
|
|
- }
|
|
|
+ $('#help-ive-found-a-bug-wiki-article').unbind('click');
|
|
|
+ $('#help-ive-found-a-bug-wiki-article').on('click', function() {
|
|
|
+ window.open(
|
|
|
+ 'https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/' +
|
|
|
+ "Help-I've-Found-a-Bug",
|
|
|
+ '_blank'
|
|
|
+ );
|
|
|
+ });
|
|
|
|
|
|
- textMessage += [
|
|
|
- 'My code:\n```',
|
|
|
- type,
|
|
|
- '\n',
|
|
|
- editor.getValue(),
|
|
|
- '\n```\n\n'
|
|
|
- ].join('');
|
|
|
- }
|
|
|
+ $('#report-issue').unbind('click');
|
|
|
+ $('#report-issue').on('click', function() {
|
|
|
+ var textMessage = [
|
|
|
+ 'Challenge [',
|
|
|
+ (common.challengeName || window.location.href),
|
|
|
+ '](',
|
|
|
+ window.location.href,
|
|
|
+ ') has an issue.\n',
|
|
|
+ 'User Agent is: <code>',
|
|
|
+ navigator.userAgent,
|
|
|
+ '</code>.\n',
|
|
|
+ 'Please describe how to reproduce this issue, and include ',
|
|
|
+ 'links to screenshots if possible.\n\n'
|
|
|
+ ].join('');
|
|
|
+
|
|
|
+ if (
|
|
|
+ window.editor &&
|
|
|
+ typeof window.editor.getValue === 'function' &&
|
|
|
+ window.editor.getValue().trim()
|
|
|
+ ) {
|
|
|
+ var type;
|
|
|
+ switch (common.challengeType) {
|
|
|
+ case main.challengeTypes.HTML_CSS_JQ:
|
|
|
+ type = 'html';
|
|
|
+ break;
|
|
|
+ case main.challengeTypes.JAVASCRIPT:
|
|
|
+ case main.challengeTypes.BONFIRE:
|
|
|
+ type = 'javascript';
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ type = '';
|
|
|
+ }
|
|
|
|
|
|
- textMessage = encodeURIComponent(textMessage);
|
|
|
+ textMessage += [
|
|
|
+ 'My code:\n```',
|
|
|
+ type,
|
|
|
+ '\n',
|
|
|
+ window.editor.getValue(),
|
|
|
+ '\n```\n\n'
|
|
|
+ ].join('');
|
|
|
+ }
|
|
|
|
|
|
- $('#issue-modal').modal('hide');
|
|
|
- window.open(
|
|
|
- 'https://github.com/freecodecamp/freecodecamp/issues/new?&body=' +
|
|
|
- textMessage, '_blank'
|
|
|
- );
|
|
|
- });
|
|
|
+ textMessage = encodeURIComponent(textMessage);
|
|
|
|
|
|
- $('#completed-courseware').unbind('click');
|
|
|
- $('#completed-courseware').on('click', function() {
|
|
|
- $('#complete-courseware-dialog').modal('show');
|
|
|
- });
|
|
|
+ $('#issue-modal').modal('hide');
|
|
|
+ window.open(
|
|
|
+ 'https://github.com/freecodecamp/freecodecamp/issues/new?&body=' +
|
|
|
+ textMessage, '_blank'
|
|
|
+ );
|
|
|
+ });
|
|
|
|
|
|
- $('#completed-courseware-editorless').unbind('click');
|
|
|
- $('#completed-courseware-editorless').on('click', function() {
|
|
|
- $('#complete-courseware-editorless-dialog').modal('show');
|
|
|
- });
|
|
|
+ $('#completed-courseware').unbind('click');
|
|
|
+ $('#completed-courseware').on('click', function() {
|
|
|
+ $('#complete-courseware-dialog').modal('show');
|
|
|
+ });
|
|
|
|
|
|
- $('#trigger-pair-modal').unbind('click');
|
|
|
- $('#trigger-pair-modal').on('click', function() {
|
|
|
- $('#pair-modal').modal('show');
|
|
|
- });
|
|
|
+ $('#completed-courseware-editorless').unbind('click');
|
|
|
+ $('#completed-courseware-editorless').on('click', function() {
|
|
|
+ $('#complete-courseware-editorless-dialog').modal('show');
|
|
|
+ });
|
|
|
|
|
|
- $('#trigger-reset-modal').unbind('click');
|
|
|
- $('#trigger-reset-modal').on('click', function() {
|
|
|
- $('#reset-modal').modal('show');
|
|
|
- });
|
|
|
+ $('#trigger-pair-modal').unbind('click');
|
|
|
+ $('#trigger-pair-modal').on('click', function() {
|
|
|
+ $('#pair-modal').modal('show');
|
|
|
+ });
|
|
|
|
|
|
- $('#trigger-help-modal').unbind('click');
|
|
|
- $('#trigger-help-modal').on('click', function() {
|
|
|
- $('#help-modal').modal('show');
|
|
|
- });
|
|
|
+ $('#trigger-reset-modal').unbind('click');
|
|
|
+ $('#trigger-reset-modal').on('click', function() {
|
|
|
+ $('#reset-modal').modal('show');
|
|
|
+ });
|
|
|
|
|
|
- $('#trigger-issue-modal').unbind('click');
|
|
|
- $('#trigger-issue-modal').on('click', function() {
|
|
|
- $('#issue-modal').modal('show');
|
|
|
- });
|
|
|
+ $('#trigger-help-modal').unbind('click');
|
|
|
+ $('#trigger-help-modal').on('click', function() {
|
|
|
+ $('#help-modal').modal('show');
|
|
|
+ });
|
|
|
|
|
|
- $('#completed-zipline-or-basejump').unbind('click');
|
|
|
- $('#completed-zipline-or-basejump').on('click', function() {
|
|
|
- $('#complete-zipline-or-basejump-dialog').modal('show');
|
|
|
- });
|
|
|
+ $('#trigger-issue-modal').unbind('click');
|
|
|
+ $('#trigger-issue-modal').on('click', function() {
|
|
|
+ $('#issue-modal').modal('show');
|
|
|
+ });
|
|
|
+
|
|
|
+ $('#completed-zipline-or-basejump').unbind('click');
|
|
|
+ $('#completed-zipline-or-basejump').on('click', function() {
|
|
|
+ $('#complete-zipline-or-basejump-dialog').modal('show');
|
|
|
+ });
|
|
|
|
|
|
+ $('#next-courseware-button').unbind('click');
|
|
|
+ $('#next-courseware-button').on('click', function() {
|
|
|
$('#next-courseware-button').unbind('click');
|
|
|
- $('#next-courseware-button').on('click', function() {
|
|
|
- $('#next-courseware-button').unbind('click');
|
|
|
- if ($('.signup-btn-nav').length < 1) {
|
|
|
- switch (challengeType) {
|
|
|
- case challengeTypes.HTML_CSS_JQ:
|
|
|
- case challengeTypes.JAVASCRIPT:
|
|
|
- case challengeTypes.VIDEO:
|
|
|
- $.post(
|
|
|
- '/completed-challenge/',
|
|
|
- {
|
|
|
- challengeInfo: {
|
|
|
- challengeId: challenge_Id,
|
|
|
- challengeName: challenge_Name
|
|
|
- }
|
|
|
- }).success(
|
|
|
- function(res) {
|
|
|
- if (res) {
|
|
|
- window.location.href = '/challenges/next-challenge?id=' + challenge_Id;
|
|
|
- }
|
|
|
- }).fail(
|
|
|
- function() {
|
|
|
- window.location.href="/challenges";
|
|
|
- }
|
|
|
- );
|
|
|
- break;
|
|
|
- case challengeTypes.ZIPLINE:
|
|
|
- var didCompleteWith = $('#completed-with').val() || null;
|
|
|
- var publicURL = $('#public-url').val() || null;
|
|
|
- $.post(
|
|
|
- '/completed-zipline-or-basejump/',
|
|
|
- {
|
|
|
- challengeInfo: {
|
|
|
- challengeId: challenge_Id,
|
|
|
- challengeName: challenge_Name,
|
|
|
- completedWith: didCompleteWith,
|
|
|
- publicURL: publicURL,
|
|
|
- challengeType: challengeType
|
|
|
- }
|
|
|
- }).success(
|
|
|
- function() {
|
|
|
- window.location.href = '/challenges/next-challenge?id=' + challenge_Id;
|
|
|
- }).fail(
|
|
|
- function() {
|
|
|
- window.location.href = '/challenges';
|
|
|
- });
|
|
|
- break;
|
|
|
- case challengeTypes.BASEJUMP:
|
|
|
- var didCompleteWith = $('#completed-with').val() || null;
|
|
|
- var publicURL = $('#public-url').val() || null;
|
|
|
- var githubURL = $('#github-url').val() || null;
|
|
|
- $.post(
|
|
|
- '/completed-zipline-or-basejump/',
|
|
|
- {
|
|
|
- challengeInfo: {
|
|
|
- challengeId: challenge_Id,
|
|
|
- challengeName: challenge_Name,
|
|
|
- completedWith: didCompleteWith,
|
|
|
- publicURL: publicURL,
|
|
|
- githubURL: githubURL,
|
|
|
- challengeType: challengeType,
|
|
|
- verified: false
|
|
|
- }
|
|
|
- }).success(function() {
|
|
|
- window.location.href = '/challenges/next-challenge?id=' + challenge_Id;
|
|
|
- }).fail(function() {
|
|
|
- window.location.replace(window.location.href);
|
|
|
- });
|
|
|
- break;
|
|
|
- case challengeTypes.BONFIRE:
|
|
|
- window.location.href = '/challenges/next-challenge?id=' + challenge_Id;
|
|
|
- default:
|
|
|
- break;
|
|
|
+ if ($('.signup-btn-nav').length < 1) {
|
|
|
+ var data;
|
|
|
+ var completedWith;
|
|
|
+ var publicURL;
|
|
|
+ switch (common.challengeType) {
|
|
|
+ case main.challengeTypes.HTML_CSS_JQ:
|
|
|
+ case main.challengeTypes.JAVASCRIPT:
|
|
|
+ case main.challengeTypes.VIDEO:
|
|
|
+ data = {
|
|
|
+ challengeInfo: {
|
|
|
+ challengeId: common.challengeId,
|
|
|
+ challengeName: common.challengeName
|
|
|
}
|
|
|
- }
|
|
|
- });
|
|
|
+ };
|
|
|
+ $.post('/completed-challenge/', data)
|
|
|
+ .success(function(res) {
|
|
|
+ if (!res) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ window.location.href = '/challenges/next-challenge?id=' +
|
|
|
+ common.challengeId;
|
|
|
+ })
|
|
|
+ .fail(function() {
|
|
|
+ window.location.href = '/challenges';
|
|
|
+ });
|
|
|
|
|
|
- $('#complete-courseware-dialog').on('hidden.bs.modal', function() {
|
|
|
- editor.focus();
|
|
|
- });
|
|
|
+ break;
|
|
|
+ case main.challengeTypes.ZIPLINE:
|
|
|
+ completedWith = $('#completed-with').val() || null;
|
|
|
+ publicURL = $('#public-url').val() || null;
|
|
|
+ data = {
|
|
|
+ challengeInfo: {
|
|
|
+ challengeId: common.challengeId,
|
|
|
+ challengeName: common.challengeName,
|
|
|
+ completedWith: completedWith,
|
|
|
+ publicURL: publicURL,
|
|
|
+ challengeType: common.challengeType
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ $.post('/completed-zipline-or-basejump/', data)
|
|
|
+ .success(function() {
|
|
|
+ window.location.href = '/challenges/next-challenge?id=' +
|
|
|
+ common.challengeId;
|
|
|
+ })
|
|
|
+ .fail(function() {
|
|
|
+ window.location.href = '/challenges';
|
|
|
+ });
|
|
|
+ break;
|
|
|
+
|
|
|
+ case main.challengeTypes.BASEJUMP:
|
|
|
+ completedWith = $('#completed-with').val() || null;
|
|
|
+ publicURL = $('#public-url').val() || null;
|
|
|
+ var githubURL = $('#github-url').val() || null;
|
|
|
+ data = {
|
|
|
+ challengeInfo: {
|
|
|
+ challengeId: common.challengeId,
|
|
|
+ challengeName: common.challengeName,
|
|
|
+ completedWith: completedWith,
|
|
|
+ publicURL: publicURL,
|
|
|
+ githubURL: githubURL,
|
|
|
+ challengeType: common.challengeType,
|
|
|
+ verified: false
|
|
|
+ }
|
|
|
+ };
|
|
|
+ $.post('/completed-zipline-or-basejump/', data)
|
|
|
+ .success(function() {
|
|
|
+ window.location.href = '/challenges/next-challenge?id=' +
|
|
|
+ common.challengeId;
|
|
|
+ })
|
|
|
+ .fail(function() {
|
|
|
+ window.location.replace(window.location.href);
|
|
|
+ });
|
|
|
+ break;
|
|
|
|
|
|
- $('#complete-zipline-or-basejump').on('hidden.bs.modal', function() {
|
|
|
- editor.focus();
|
|
|
- });
|
|
|
- };
|
|
|
+ case main.challengeTypes.BONFIRE:
|
|
|
+ window.location.href = '/challenges/next-challenge?id=' +
|
|
|
+ common.challengeId;
|
|
|
+ break;
|
|
|
|
|
|
+ default:
|
|
|
+ console.log('Happy Coding!');
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
+ $('#complete-courseware-dialog').on('hidden.bs.modal', function() {
|
|
|
+ window.editor.focus();
|
|
|
+ });
|
|
|
|
|
|
- $(window).resize(function(){
|
|
|
- reBindModals();
|
|
|
+ $('#complete-zipline-or-basejump').on('hidden.bs.modal', function() {
|
|
|
+ window.editor.focus();
|
|
|
});
|
|
|
+ }
|
|
|
|
|
|
+ $(window).resize(function() {
|
|
|
reBindModals();
|
|
|
+ });
|
|
|
|
|
|
- var challengeTypes = {
|
|
|
- 'HTML_CSS_JQ': '0',
|
|
|
- 'JAVASCRIPT': '1',
|
|
|
- 'VIDEO': '2',
|
|
|
- 'ZIPLINE': '3',
|
|
|
- 'BASEJUMP': '4',
|
|
|
- 'BONFIRE': '5'
|
|
|
- };
|
|
|
+ reBindModals();
|
|
|
|
|
|
function upvoteHandler(e) {
|
|
|
e.preventDefault();
|
|
@@ -474,16 +545,19 @@ $(document).ready(function() { |
|
|
}
|
|
|
if (!alreadyUpvoted) {
|
|
|
$.post('/stories/upvote', { id: id })
|
|
|
- .fail(function(xhr, textStatus, errorThrown) {
|
|
|
+ .fail(function() {
|
|
|
$(upvoteBtn).bind('click', upvoteHandler);
|
|
|
})
|
|
|
- .done(function(data, textStatus, xhr) {
|
|
|
- $(upvoteBtn).text('Upvoted!').addClass('disabled');
|
|
|
+ .done(function(data) {
|
|
|
+ $(upvoteBtn)
|
|
|
+ .text('Upvoted!')
|
|
|
+ .addClass('disabled');
|
|
|
|
|
|
- $('#storyRank').text(data.rank + " points");
|
|
|
+ $('#storyRank').text(data.rank + ' points');
|
|
|
});
|
|
|
}
|
|
|
- };
|
|
|
+ }
|
|
|
+
|
|
|
$('#story-list').on('click', 'button.btn-upvote', upvoteHandler);
|
|
|
|
|
|
var storySubmitButtonHandler = function storySubmitButtonHandler() {
|
|
@@ -491,91 +565,121 @@ $(document).ready(function() { |
|
|
var link = $('#story-url').val();
|
|
|
var headline = $('#story-title').val();
|
|
|
var description = $('#description-box').val();
|
|
|
+ var data = {
|
|
|
+ data: {
|
|
|
+ link: link,
|
|
|
+ headline: headline,
|
|
|
+ timePosted: Date.now(),
|
|
|
+ description: description,
|
|
|
+ storyMetaDescription: main.storyMetaDescription,
|
|
|
+ rank: 1,
|
|
|
+ image: main.storyImage
|
|
|
+ }
|
|
|
+ };
|
|
|
|
|
|
$('#story-submit').unbind('click');
|
|
|
- $.post('/stories/',
|
|
|
- {
|
|
|
- data: {
|
|
|
- link: link,
|
|
|
- headline: headline,
|
|
|
- timePosted: Date.now(),
|
|
|
- description: description,
|
|
|
- storyMetaDescription: storyMetaDescription,
|
|
|
- rank: 1,
|
|
|
- image: storyImage
|
|
|
- }
|
|
|
- })
|
|
|
- .fail(function (xhr, textStatus, errorThrown) {
|
|
|
+ $.post('/stories/', data)
|
|
|
+ .fail(function() {
|
|
|
$('#story-submit').bind('click', storySubmitButtonHandler);
|
|
|
})
|
|
|
- .done(function(data, textStatus, xhr) {
|
|
|
+ .done(function(data) {
|
|
|
window.location = '/stories/' + data.storyLink;
|
|
|
});
|
|
|
};
|
|
|
|
|
|
$('#story-submit').on('click', storySubmitButtonHandler);
|
|
|
- //fakeiphone positioning hotfix
|
|
|
- if($('.iphone-position').html() !==undefined || $('.iphone').html() !== undefined){
|
|
|
- var startIphonePosition = parseInt($('.iphone-position').css('top').replace('px', ''));
|
|
|
- var startIphone = parseInt($('.iphone').css('top').replace('px', ''));
|
|
|
- $(window).on('scroll', function(){
|
|
|
- if((($('.courseware-height').height() + $('.courseware-height').offset().top)-$(window).scrollTop()-$('.iphone-position').height()) <= 0){
|
|
|
- $('.iphone-position').css('top', startIphonePosition+(($('.courseware-height').height() + $('.courseware-height').offset().top)-$(window).scrollTop()-$('.iphone-position').height()));
|
|
|
- $('.iphone').css('top', startIphonePosition+(($('.courseware-height').height() + $('.courseware-height').offset().top)-$(window).scrollTop()-$('.iphone-position').height())+120);
|
|
|
- }
|
|
|
- else{
|
|
|
- $('.iphone-position').css('top', startIphonePosition);
|
|
|
- $('.iphone').css('top', startIphone);
|
|
|
- }
|
|
|
- });
|
|
|
+
|
|
|
+ // fakeiphone positioning hotfix
|
|
|
+ if (
|
|
|
+ $('.iphone-position').html() ||
|
|
|
+ $('.iphone').html()
|
|
|
+ ) {
|
|
|
+ var startIphonePosition = parseInt(
|
|
|
+ $('.iphone-position')
|
|
|
+ .css('top')
|
|
|
+ .replace('px', ''),
|
|
|
+ 10
|
|
|
+ );
|
|
|
+
|
|
|
+ var startIphone = parseInt(
|
|
|
+ $('.iphone')
|
|
|
+ .css('top')
|
|
|
+ .replace('px', ''),
|
|
|
+ 10
|
|
|
+ );
|
|
|
+
|
|
|
+ $(window).on('scroll', function() {
|
|
|
+ var courseHeight = $('.courseware-height').height();
|
|
|
+ var courseTop = $('.courseware-height').offset().top;
|
|
|
+ var windowScrollTop = $(window).scrollTop();
|
|
|
+ var phoneHeight = $('.iphone-position').height();
|
|
|
+
|
|
|
+ if (courseHeight + courseTop - windowScrollTop - phoneHeight <= 0) {
|
|
|
+ $('.iphone-position').css(
|
|
|
+ 'top',
|
|
|
+ startIphonePosition +
|
|
|
+ courseHeight +
|
|
|
+ courseTop -
|
|
|
+ windowScrollTop -
|
|
|
+ phoneHeight
|
|
|
+ );
|
|
|
+
|
|
|
+ $('.iphone').css(
|
|
|
+ 'top',
|
|
|
+ startIphonePosition +
|
|
|
+ courseHeight +
|
|
|
+ courseTop -
|
|
|
+ windowScrollTop -
|
|
|
+ phoneHeight +
|
|
|
+ 120
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ $('.iphone-position').css('top', startIphonePosition);
|
|
|
+ $('.iphone').css('top', startIphone);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ if ($('.scroll-locker').html()) {
|
|
|
+
|
|
|
+ if ($('.scroll-locker').html()) {
|
|
|
+ main.lockTop();
|
|
|
+ $(window).on('resize', function() {
|
|
|
+ main.lockTop();
|
|
|
+ });
|
|
|
+ $(window).on('scroll', function() {
|
|
|
+ main.lockTop();
|
|
|
+ });
|
|
|
}
|
|
|
- if($('.scroll-locker').html() != undefined){
|
|
|
- function lockTop(){
|
|
|
- if ($(window).width() >= 990) {
|
|
|
- if($('.editorScrollDiv').html() !== 'undefined'){
|
|
|
- var magiVal = $(window).height()-($('.navbar').height()+$('.footer').height());
|
|
|
- if(magiVal < 0){
|
|
|
- magiVal = 0;
|
|
|
- }
|
|
|
- $('.editorScrollDiv').css("height", (magiVal-85) + "px");
|
|
|
- }
|
|
|
- magiVal = $(window).height()-($('.navbar').height()+$('.footer').height());
|
|
|
- if(magiVal < 0){
|
|
|
- magiVal = 0;
|
|
|
- }
|
|
|
|
|
|
- $('.scroll-locker').css("min-height", $('.editorScrollDiv').height()).css("height",magiVal-185);
|
|
|
- }
|
|
|
- else {
|
|
|
- $('.editorScrollDiv').css("max-height", 500 + "px");
|
|
|
- $('.scroll-locker').css('position', 'inherit').css('top', 'inherit').css('width', '100%').css('max-height', '85%');
|
|
|
+ var execInProgress = false;
|
|
|
+
|
|
|
+ // why is this not $???
|
|
|
+ document
|
|
|
+ .getElementById('scroll-locker')
|
|
|
+ .addEventListener(
|
|
|
+ 'previewUpdateSpy',
|
|
|
+ function(e) {
|
|
|
+ if (execInProgress) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ execInProgress = true;
|
|
|
+ setTimeout(function() {
|
|
|
+ if (
|
|
|
+ $($('.scroll-locker').children()[0]).height() - 800 > e.detail
|
|
|
+ ) {
|
|
|
+ $('.scroll-locker').scrollTop(e.detail);
|
|
|
+ } else {
|
|
|
+ var scrollTop = $($('.scroll-locker').children()[0]).height();
|
|
|
+
|
|
|
+ $('.scroll-locker').animate({ scrollTop: scrollTop }, 175);
|
|
|
}
|
|
|
- }
|
|
|
- if ($('.scroll-locker').html()){
|
|
|
- lockTop();
|
|
|
- $(window).on('resize', function(){
|
|
|
- lockTop();
|
|
|
- });
|
|
|
- $(window).on('scroll', function() {
|
|
|
- lockTop();
|
|
|
- });
|
|
|
- }
|
|
|
- var execInProgress = false;
|
|
|
- document.getElementById('scroll-locker').addEventListener('previewUpdateSpy', function(e){
|
|
|
- if (!execInProgress){
|
|
|
- execInProgress = true;
|
|
|
- setTimeout(function(){
|
|
|
- if($($('.scroll-locker').children()[0]).height()-800 > e.detail){
|
|
|
- $('.scroll-locker').scrollTop(e.detail);
|
|
|
- }
|
|
|
- else {
|
|
|
- $('.scroll-locker').animate({"scrollTop":$($('.scroll-locker').children()[0]).height()}, 175);
|
|
|
- }
|
|
|
- execInProgress = false;
|
|
|
- }, 750);
|
|
|
- }
|
|
|
- }, false);
|
|
|
- }
|
|
|
+ execInProgress = false;
|
|
|
+ }, 750);
|
|
|
+ },
|
|
|
+ false
|
|
|
+ );
|
|
|
+ }
|
|
|
|
|
|
|
|
|
// map sharing
|
|
@@ -613,141 +717,153 @@ $(document).ready(function() { |
|
|
});
|
|
|
});
|
|
|
|
|
|
-function defCheck(a){
|
|
|
- if(a !== 'undefined'){return(true);}else{return(false);}
|
|
|
-}
|
|
|
-
|
|
|
-var profileValidation = angular.module('profileValidation',
|
|
|
- ['ui.bootstrap']);
|
|
|
-profileValidation.controller('profileValidationController', ['$scope', '$http',
|
|
|
- function($scope, $http) {
|
|
|
- $http.get('/account/api').success(function(data) {
|
|
|
- $scope.user = data.user;
|
|
|
- $scope.user.username = $scope.user.username ? $scope.user.username.toLowerCase() : undefined;
|
|
|
- $scope.storedUsername = data.user.username;
|
|
|
- $scope.storedEmail = data.user.email;
|
|
|
- $scope.user.email = $scope.user.email ? $scope.user.email.toLowerCase() : undefined;
|
|
|
- $scope.user.twitterHandle = $scope.user.twitterHandle ? $scope.user.twitterHandle.toLowerCase() : undefined;
|
|
|
- $scope.asyncComplete = true;
|
|
|
- });
|
|
|
- }
|
|
|
-]);
|
|
|
-
|
|
|
-profileValidation.controller('pairedWithController', ['$scope',
|
|
|
- function($scope) {
|
|
|
- $scope.existingUser = null;
|
|
|
- }
|
|
|
-]);
|
|
|
-
|
|
|
-profileValidation.controller('emailSignUpController', ['$scope',
|
|
|
- function($scope) {
|
|
|
-
|
|
|
- }
|
|
|
-]);
|
|
|
-
|
|
|
-profileValidation.controller('emailSignInController', ['$scope',
|
|
|
- function($scope) {
|
|
|
-
|
|
|
- }
|
|
|
-]);
|
|
|
-
|
|
|
-profileValidation.controller('URLSubmitController', ['$scope',
|
|
|
- function($scope) {
|
|
|
-
|
|
|
- }
|
|
|
-]);
|
|
|
-
|
|
|
-profileValidation.controller('nonprofitFormController', ['$scope',
|
|
|
- function($scope) {
|
|
|
-
|
|
|
- }
|
|
|
-]);
|
|
|
-
|
|
|
-profileValidation.controller('doneWithFirst100HoursFormController', ['$scope',
|
|
|
- function($scope) {
|
|
|
-
|
|
|
- }
|
|
|
-]);
|
|
|
-
|
|
|
-profileValidation.controller('submitStoryController', ['$scope',
|
|
|
- function($scope) {
|
|
|
-
|
|
|
- }
|
|
|
-]);
|
|
|
-
|
|
|
-profileValidation.directive('uniqueUsername', ['$http', function($http) {
|
|
|
- return {
|
|
|
- restrict: 'A',
|
|
|
- require: 'ngModel',
|
|
|
- link: function (scope, element, attrs, ngModel) {
|
|
|
- element.bind("keyup", function (event) {
|
|
|
- ngModel.$setValidity('unique', true);
|
|
|
- var username = element.val();
|
|
|
- if (username) {
|
|
|
- var config = { params: { username: username } };
|
|
|
- $http
|
|
|
- .get('/api/users/exists', config)
|
|
|
- .success(function (result) {
|
|
|
- if (username === scope.storedUsername) {
|
|
|
- ngModel.$setValidity('unique', true);
|
|
|
- } else if (result.exists) {
|
|
|
- ngModel.$setValidity('unique', false);
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
+var profileValidation =
|
|
|
+ window.angular.module('profileValidation', ['ui.bootstrap']);
|
|
|
+
|
|
|
+profileValidation.controller(
|
|
|
+ 'profileValidationController',
|
|
|
+ [
|
|
|
+ '$scope',
|
|
|
+ '$http',
|
|
|
+ function($scope, $http) {
|
|
|
+ $http.get('/account/api').success(function(data) {
|
|
|
+ $scope.user = data.user;
|
|
|
+
|
|
|
+ $scope.user.username = $scope.user.username ?
|
|
|
+ $scope.user.username.toLowerCase() :
|
|
|
+ null;
|
|
|
+
|
|
|
+ $scope.storedUsername = data.user.username;
|
|
|
+ $scope.storedEmail = data.user.email;
|
|
|
+ $scope.user.email = $scope.user.email ?
|
|
|
+ $scope.user.email.toLowerCase() :
|
|
|
+ null;
|
|
|
+
|
|
|
+ $scope.user.twitterHandle = $scope.user.twitterHandle ?
|
|
|
+ $scope.user.twitterHandle.toLowerCase() :
|
|
|
+ null;
|
|
|
+
|
|
|
+ $scope.asyncComplete = true;
|
|
|
});
|
|
|
}
|
|
|
- };
|
|
|
-}]);
|
|
|
+ ]
|
|
|
+);
|
|
|
+
|
|
|
+profileValidation.controller(
|
|
|
+ 'pairedWithController',
|
|
|
+ [
|
|
|
+ '$scope',
|
|
|
+ function($scope) { $scope.existingUser = null; }
|
|
|
+ ]
|
|
|
+);
|
|
|
+
|
|
|
+profileValidation.controller('emailSignUpController', function() {});
|
|
|
+
|
|
|
+profileValidation.controller('emailSignInController', function() {});
|
|
|
+
|
|
|
+profileValidation.controller('URLSubmitController', function() {});
|
|
|
+
|
|
|
+profileValidation.controller('nonprofitFormController', function() {});
|
|
|
+
|
|
|
+profileValidation.controller(
|
|
|
+ 'doneWithFirst100HoursFormController',
|
|
|
+ function() {}
|
|
|
+);
|
|
|
+
|
|
|
+profileValidation.controller('submitStoryController', function() {});
|
|
|
+
|
|
|
+profileValidation.directive(
|
|
|
+ 'uniqueUsername',
|
|
|
+ [
|
|
|
+ '$http',
|
|
|
+ function($http) {
|
|
|
+ return {
|
|
|
+ restrict: 'A',
|
|
|
+ require: 'ngModel',
|
|
|
+ link: function(scope, element, attrs, ngModel) {
|
|
|
+
|
|
|
+ element.bind('keyup', function() {
|
|
|
+
|
|
|
+ ngModel.$setValidity('unique', true);
|
|
|
+ var username = element.val();
|
|
|
+ if (username) {
|
|
|
+ var config = { params: { username: username } };
|
|
|
+ $http
|
|
|
+ .get('/api/users/exists', config)
|
|
|
+ .success(function(result) {
|
|
|
+ if (username === scope.storedUsername) {
|
|
|
+ ngModel.$setValidity('unique', true);
|
|
|
+ } else if (result.exists) {
|
|
|
+ ngModel.$setValidity('unique', false);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ };
|
|
|
+ }
|
|
|
+ ]
|
|
|
+);
|
|
|
|
|
|
profileValidation.directive('existingUsername',
|
|
|
- ['$http', function($http) {
|
|
|
- return {
|
|
|
- restrict: 'A',
|
|
|
- require: 'ngModel',
|
|
|
- link: function (scope, element, attrs, ngModel) {
|
|
|
- element.bind('keyup', function (event) {
|
|
|
- if (element.val().length > 0) {
|
|
|
- ngModel.$setValidity('exists', false);
|
|
|
- } else {
|
|
|
- element.removeClass('ng-dirty');
|
|
|
- ngModel.$setPristine();
|
|
|
- }
|
|
|
- var username = element.val();
|
|
|
- if (username) {
|
|
|
- var config = { params: { username: username } };
|
|
|
- $http
|
|
|
- .get('/api/users/exists', config)
|
|
|
- .success(function(result) {
|
|
|
- ngModel.$setValidity('exists', result.exists);
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- };
|
|
|
+ [
|
|
|
+ '$http',
|
|
|
+ function($http) {
|
|
|
+ return {
|
|
|
+ restrict: 'A',
|
|
|
+ require: 'ngModel',
|
|
|
+ link: function(scope, element, attrs, ngModel) {
|
|
|
+
|
|
|
+ element.bind('keyup', function() {
|
|
|
+
|
|
|
+ if (element.val().length > 0) {
|
|
|
+ ngModel.$setValidity('exists', false);
|
|
|
+ } else {
|
|
|
+ element.removeClass('ng-dirty');
|
|
|
+ ngModel.$setPristine();
|
|
|
+ }
|
|
|
+
|
|
|
+ var username = element.val();
|
|
|
+ if (username) {
|
|
|
+ var config = { params: { username: username } };
|
|
|
+ $http
|
|
|
+ .get('/api/users/exists', config)
|
|
|
+ .success(function(result) {
|
|
|
+ ngModel.$setValidity('exists', result.exists);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ };
|
|
|
}]);
|
|
|
|
|
|
-profileValidation.directive('uniqueEmail', ['$http', function($http) {
|
|
|
- return {
|
|
|
- restrict: 'A',
|
|
|
- require: 'ngModel',
|
|
|
- link: function getUnique (scope, element, attrs, ngModel) {
|
|
|
- element.bind("keyup", function (event) {
|
|
|
- ngModel.$setValidity('unique', true);
|
|
|
- var email = element.val();
|
|
|
- if (email) {
|
|
|
- var config = { params: { email: email } };
|
|
|
- $http
|
|
|
- .get('/api/users/exists', config)
|
|
|
- .success(function(result) {
|
|
|
- if (email === scope.storedEmail) {
|
|
|
- ngModel.$setValidity('unique', true);
|
|
|
- } else if (result.exists) {
|
|
|
- ngModel.$setValidity('unique', false);
|
|
|
- }
|
|
|
- });
|
|
|
- };
|
|
|
- });
|
|
|
+profileValidation.directive(
|
|
|
+ 'uniqueEmail',
|
|
|
+ [
|
|
|
+ '$http',
|
|
|
+ function($http) {
|
|
|
+ return {
|
|
|
+ restrict: 'A',
|
|
|
+ require: 'ngModel',
|
|
|
+ link: function getUnique(scope, element, attrs, ngModel) {
|
|
|
+ element.bind('keyup', function() {
|
|
|
+ ngModel.$setValidity('unique', true);
|
|
|
+ var email = element.val();
|
|
|
+ if (email) {
|
|
|
+ var config = { params: { email: email } };
|
|
|
+ $http
|
|
|
+ .get('/api/users/exists', config)
|
|
|
+ .success(function(result) {
|
|
|
+ if (email === scope.storedEmail) {
|
|
|
+ ngModel.$setValidity('unique', true);
|
|
|
+ } else if (result.exists) {
|
|
|
+ ngModel.$setValidity('unique', false);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ };
|
|
|
}
|
|
|
- }
|
|
|
-}]);
|
|
|
+ ]
|
|
|
+);
|
0 comments on commit
5dbfbfc