├── README.md ├── Views ├── _ViewStart.cshtml ├── _ViewImports.cshtml ├── Shared │ ├── Error.cshtml │ └── _Layout.cshtml └── Home │ └── Index.cshtml ├── archive └── hq1 │ ├── global.json │ ├── src │ └── HabraQuest │ │ ├── Properties │ │ └── debugSettings.json │ │ ├── Views │ │ ├── _ViewStart.cshtml │ │ ├── Home │ │ │ ├── About.cshtml │ │ │ ├── Contact.cshtml │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ ├── Error.cshtml │ │ │ ├── _LoginPartial.cshtml │ │ │ └── _Layout.cshtml │ │ └── Account │ │ │ ├── Manage.cshtml │ │ │ ├── _ChangePasswordPartial.cshtml │ │ │ ├── Register.cshtml │ │ │ └── Login.cshtml │ │ ├── package.json │ │ ├── wwwroot │ │ ├── lib │ │ │ ├── bootstrap │ │ │ │ ├── fonts │ │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ │ └── glyphicons-halflings-regular.woff │ │ │ │ └── css │ │ │ │ │ ├── bootstrap-theme.min.css │ │ │ │ │ └── bootstrap-theme.css │ │ │ └── jquery-validation-unobtrusive │ │ │ │ ├── jquery.validate.unobtrusive.min.js │ │ │ │ └── jquery.validate.unobtrusive.js │ │ ├── app │ │ │ ├── app.js │ │ │ ├── home │ │ │ │ ├── home.html │ │ │ │ └── home.js │ │ │ ├── services │ │ │ │ └── mainQuest.js │ │ │ ├── config.route.js │ │ │ └── start │ │ │ │ ├── start.html │ │ │ │ └── start.js │ │ ├── _references.js │ │ ├── css │ │ │ └── site.css │ │ └── index.html │ │ ├── Models │ │ ├── Progress.cs │ │ ├── Finisher.cs │ │ ├── QuestTask.cs │ │ ├── AccountViewModels.cs │ │ └── IdentityModels.cs │ │ ├── config.json │ │ ├── bower.json │ │ ├── Controllers │ │ ├── HomeController.cs │ │ ├── StatisticsController.cs │ │ ├── AccountController.cs │ │ └── QuestController.cs │ │ ├── gruntfile.js │ │ ├── Migrations │ │ ├── 201502110941236_Finisher.cs │ │ ├── 201502110941236_Finisher.Designer.cs │ │ ├── ApplicationDbContextModelSnapshot.cs │ │ ├── 000000000000001_HQ.cs │ │ └── 000000000000000_CreateIdentitySchema.cs │ │ ├── HabraQuest.kproj │ │ ├── project.json │ │ └── Startup.cs │ └── HabraQuest.sln ├── webpack.config.dev.js ├── typings ├── tsd.d.ts ├── url-workaround.d.ts └── requirejs │ └── require.d.ts ├── ClientApp ├── components │ ├── nav-menu │ │ ├── nav-menu.ts │ │ └── nav-menu.html │ ├── app │ │ ├── app.html │ │ └── app.ts │ ├── home │ │ ├── home.ts │ │ └── home.html │ ├── results │ │ ├── results.ts │ │ └── results.html │ └── quest │ │ ├── quest.ts │ │ └── quest.html ├── routes.ts ├── boot-client.ts ├── boot-server.ts └── styles │ └── site.css ├── tsconfig.json ├── Dockerfile ├── appsettings.json ├── wwwroot └── web.config ├── webpack.config.prod.js ├── tsd.json ├── Model ├── DataContext.cs ├── Player.cs └── QuestTask.cs ├── web.config ├── Migrations ├── 20160728063831_PlayerEmail.cs ├── 20160725063832_Initial.Designer.cs ├── 20160725063832_Initial.cs ├── 20160726131042_AddQuestTask.cs ├── 20160726131042_AddQuestTask.Designer.cs ├── DataContextModelSnapshot.cs └── 20160728063831_PlayerEmail.Designer.cs ├── HabraQuest.sln ├── Controllers ├── ResultsController.cs └── HomeController.cs ├── HabraQuest.xproj ├── webpack.config.js ├── package.json ├── webpack.config.vendor.js ├── .gitattributes ├── Startup.cs ├── project.json └── .gitignore /README.md: -------------------------------------------------------------------------------- 1 | # HabraQuest 2 | https://habrahabr.ru/post/306292/ 3 | -------------------------------------------------------------------------------- /Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /archive/hq1/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sources": [ "src", "test" ] 3 | } 4 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Properties/debugSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Profiles": [] 3 | } -------------------------------------------------------------------------------- /webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | devtool: 'inline-source-map' 3 | }; 4 | -------------------------------------------------------------------------------- /typings/tsd.d.ts: -------------------------------------------------------------------------------- 1 | 2 | /// 3 | /// 4 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @using HabraQuest; 2 | @{ 3 | Layout = "/Views/Shared/_Layout.cshtml"; 4 | } 5 | -------------------------------------------------------------------------------- /Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using HabraQuest 2 | @addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers" 3 | @addTagHelper "*, Microsoft.AspNetCore.SpaServices" 4 | -------------------------------------------------------------------------------- /Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Error"; 3 | } 4 | 5 |

Error.

6 |

An error occurred while processing your request.

7 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "About"; 3 | } 4 |

@ViewBag.Title.

5 |

@ViewBag.Message

6 | 7 |

Use this area to provide additional information.

-------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.0.0", 3 | "name": "HabraQuest", 4 | "devDependencies": { 5 | "grunt": "^0.4.5", 6 | "grunt-bower-task": "^0.4.0" 7 | } 8 | } -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Error"; 3 | } 4 | 5 |

Error.

6 |

An error occurred while processing your request.

-------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbdrm/HabraQuest/HEAD/archive/hq1/src/HabraQuest/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbdrm/HabraQuest/HEAD/archive/hq1/src/HabraQuest/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gbdrm/HabraQuest/HEAD/archive/hq1/src/HabraQuest/wwwroot/lib/bootstrap/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Models/Progress.cs: -------------------------------------------------------------------------------- 1 | namespace HabraQuest.Models 2 | { 3 | public class Progress 4 | { 5 | public int Id { get; set; } 6 | public string Token { get; set; } 7 | public int TaskNumber { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Models/Finisher.cs: -------------------------------------------------------------------------------- 1 | namespace HabraQuest.Models 2 | { 3 | public class Finisher 4 | { 5 | public int Id { get; set; } 6 | public string Token { get; set; } 7 | public string Name { get; set; } 8 | public string Time { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /ClientApp/components/nav-menu/nav-menu.ts: -------------------------------------------------------------------------------- 1 | import * as ng from '@angular/core'; 2 | import { ROUTER_DIRECTIVES } from '@angular/router'; 3 | 4 | @ng.Component({ 5 | selector: 'nav-menu', 6 | template: require('./nav-menu.html'), 7 | directives: [...ROUTER_DIRECTIVES] 8 | }) 9 | export class NavMenu { 10 | } 11 | -------------------------------------------------------------------------------- /Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | Loading... 3 | 4 | 5 | @section scripts { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "node", 4 | "target": "es5", 5 | "sourceMap": true, 6 | "experimentalDecorators": true, 7 | "emitDecoratorMetadata": true, 8 | "skipDefaultLibCheck": true 9 | }, 10 | "exclude": [ 11 | "node_modules" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /ClientApp/components/app/app.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 | 8 |
9 |
10 |
11 | -------------------------------------------------------------------------------- /typings/url-workaround.d.ts: -------------------------------------------------------------------------------- 1 | // This file is a workaround for angular2-universal-preview version 0.84.2 relying on the declaration of 2 | // Node's 'url' module. Ideally it would not declare dependencies on Node APIs except where it also supplies 3 | // the definitions itself. 4 | 5 | declare module 'url' { 6 | export interface Url {} 7 | } 8 | -------------------------------------------------------------------------------- /ClientApp/components/app/app.ts: -------------------------------------------------------------------------------- 1 | import * as ng from '@angular/core'; 2 | import { ROUTER_DIRECTIVES } from '@angular/router'; 3 | import { NavMenu } from '../nav-menu/nav-menu'; 4 | 5 | @ng.Component({ 6 | selector: 'app', 7 | template: require('./app.html'), 8 | directives: [...ROUTER_DIRECTIVES, NavMenu] 9 | }) 10 | export class App { 11 | } 12 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Models/QuestTask.cs: -------------------------------------------------------------------------------- 1 | namespace HabraQuest.Models 2 | { 3 | public class QuestTask 4 | { 5 | public int Id { get; set; } 6 | public string Title { get; set; } 7 | public string Content { get; set; } 8 | public int Number { get; set; } 9 | public string Answer { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /ClientApp/components/home/home.ts: -------------------------------------------------------------------------------- 1 | import * as ng from '@angular/core'; 2 | import { ROUTER_DIRECTIVES } from '@angular/router'; 3 | import { Cookie } from 'ng2-cookies/ng2-cookies'; 4 | 5 | @ng.Component({ 6 | selector: 'home', 7 | template: require('./home.html'), 8 | directives: [...ROUTER_DIRECTIVES] 9 | }) 10 | export class Home { 11 | constructor() { 12 | } 13 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/aspnet:1.0.0-rc1-update1 2 | 3 | RUN printf "deb http://ftp.us.debian.org/debian jessie main\n" >> /etc/apt/sources.list 4 | RUN apt-get -qq update && apt-get install -qqy sqlite3 libsqlite3-dev && rm -rf /var/lib/apt/lists/* 5 | 6 | COPY . /app 7 | WORKDIR /app 8 | RUN ["dnu", "restore"] 9 | 10 | EXPOSE 5000/tcp 11 | ENTRYPOINT ["dnx", "-p", "project.json", "web"] 12 | -------------------------------------------------------------------------------- /appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-HabraQuest;Trusted_Connection=True;MultipleActiveResultSets=true" 4 | }, 5 | "Logging": { 6 | "IncludeScopes": false, 7 | "LogLevel": { 8 | "Default": "Verbose", 9 | "System": "Information", 10 | "Microsoft": "Information" 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /wwwroot/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/app/app.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | var app = angular.module('app', [ 5 | 'ngAnimate', // animations 6 | 'ngRoute', // routing 7 | 'ngResource', 8 | 'ngCookies', 9 | 'ui.bootstrap', // ui-bootstrap (ex: carousel, pagination, dialog) 10 | 'angular-loading-bar' 11 | ]); 12 | })(); -------------------------------------------------------------------------------- /webpack.config.prod.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | 3 | module.exports = { 4 | plugins: [ 5 | new webpack.optimize.OccurenceOrderPlugin(), 6 | new webpack.optimize.UglifyJsPlugin({ 7 | compress: { warnings: false }, 8 | minimize: true, 9 | mangle: false // Due to https://github.com/angular/angular/issues/6678 10 | }) 11 | ] 12 | }; 13 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/app/home/home.html: -------------------------------------------------------------------------------- 1 |
2 |

Привет

3 |

Все задания квеста - логические. 4 | Всего заданий - 12. 5 | До 10 задания никаких особых умений в программировании или матиматике не требуется. 6 | Ответ - всегда одно слово.

7 |
8 |

Начать квест

9 |
-------------------------------------------------------------------------------- /tsd.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "v4", 3 | "repo": "borisyankov/DefinitelyTyped", 4 | "ref": "master", 5 | "path": "typings", 6 | "bundle": "typings/tsd.d.ts", 7 | "installed": { 8 | "requirejs/require.d.ts": { 9 | "commit": "dade4414712ce84e3c63393f1aae407e9e7e6af7" 10 | }, 11 | "es6-shim/es6-shim.d.ts": { 12 | "commit": "c0d876601e0f8236fd6b57626eb62c4e485f1563" 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Model/DataContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | 3 | namespace HabraQuest.Model 4 | { 5 | public class DataContext : DbContext 6 | { 7 | public DataContext(DbContextOptions options) 8 | : base(options) 9 | { 10 | } 11 | 12 | 13 | public DbSet Players { get; set; } 14 | public DbSet Tasks{ get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Model/Player.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace HabraQuest.Model 4 | { 5 | public class Player 6 | { 7 | public int Id { get; set; } 8 | public Guid Token { get; set; } 9 | public int TaskNumber { get; set; } 10 | public string Name { get; set; } 11 | public string Comment { get; set; } 12 | public bool HasFinished { get; set; } 13 | public string Email { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/app/home/home.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | var controllerId = 'home'; 4 | angular.module('app').controller(controllerId, home); 5 | 6 | home.$inject = ['$location']; 7 | 8 | function home($location) { 9 | /* jshint validthis:true */ 10 | var vm = this; 11 | vm.title = controllerId; 12 | 13 | activate(); 14 | 15 | function activate() { } 16 | } 17 | })(); 18 | -------------------------------------------------------------------------------- /ClientApp/components/home/home.html: -------------------------------------------------------------------------------- 1 |

Привет

2 |

3 | Все задания квеста - логические. 4 |
5 | Всего заданий - 10. 6 |
7 | Для прохождения квеста никаких особых умений в программировании или матиматике не требуется. 8 |
9 | Ответ - всегда одно слово. 10 |

11 |
12 |

Начать квест

13 | -------------------------------------------------------------------------------- /Model/QuestTask.cs: -------------------------------------------------------------------------------- 1 | namespace HabraQuest.Model 2 | { 3 | public class QuestTask 4 | { 5 | public int Id { get; set; } 6 | public string Title { get; set; } 7 | public string Content { get; set; } 8 | public int Watched { get; set; } 9 | public int Done { get; set; } 10 | 11 | /// 12 | /// Lower case answers, separated by ',' 13 | /// 14 | public string Answers { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /ClientApp/routes.ts: -------------------------------------------------------------------------------- 1 | import { RouterConfig } from '@angular/router'; 2 | import { Home } from './components/home/home'; 3 | import { Results } from './components/results/results'; 4 | import { Quest } from './components/quest/quest'; 5 | 6 | export const routes: RouterConfig = [ 7 | { path: '', redirectTo: 'home' }, 8 | { path: 'home', component: Home }, 9 | { path: 'quest', component: Quest }, 10 | { path: 'results', component: Results }, 11 | { path: '**', redirectTo: 'home' } 12 | ]; 13 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Contact"; 3 | } 4 |

@ViewBag.Title.

5 |

@ViewBag.Message

6 | 7 |
8 | One Microsoft Way
9 | Redmond, WA 98052-6399
10 | P: 11 | 425.555.0100 12 |
13 | 14 |
15 | Support: Support@example.com
16 | Marketing: Marketing@example.com 17 |
-------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "Data": { 3 | "DefaultConnection": { 4 | //"ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=aspnet5-HabraQuest-7a07e396-c53a-48e2-8538-11bb6329e68a;Trusted_Connection=True;MultipleActiveResultSets=true" 5 | "ConnectionString": "Data Source=(LocalDb)\\v12.0;Initial Catalog=habraquest;Integrated Security=True" 6 | } 7 | }, 8 | "EntityFramework": { 9 | "ApplicationDbContext": { 10 | "ConnectionStringKey": "Data:DefaultConnection:ConnectionString" 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | HabraQuest 7 | 8 | 9 | 10 | 11 | 12 | @RenderBody() 13 | 14 | @RenderSection("scripts", required: false) 15 | 16 | 17 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Views/Account/Manage.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Manage Account"; 3 | } 4 | 5 |

@ViewBag.Title.

6 |

@ViewBag.StatusMessage

7 | 8 |
9 |
10 | @await Html.PartialAsync("_ChangePasswordPartial") 11 |
12 |
13 | 14 | @section Scripts { 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/_references.js: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | /// 7 | /// 8 | /// 9 | /// 10 | /// 11 | /// 12 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/app/services/mainQuest.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | angular 5 | .module('app') 6 | .factory('mainQuest', mainQuestService); 7 | 8 | mainQuestService.$inject = ['$resource']; 9 | 10 | function mainQuestService($resource) { 11 | var service = { 12 | submitAnswer: submitAnswer, 13 | Statistics: getStatistics 14 | }; 15 | 16 | return service; 17 | 18 | function submitAnswer() { 19 | return $resource('api/quest'); 20 | } 21 | 22 | function getStatistics() { 23 | return $resource('api/statistics'); 24 | } 25 | } 26 | })(); -------------------------------------------------------------------------------- /Migrations/20160728063831_PlayerEmail.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.EntityFrameworkCore.Migrations; 4 | 5 | namespace HabraQuest.Migrations 6 | { 7 | public partial class PlayerEmail : Migration 8 | { 9 | protected override void Up(MigrationBuilder migrationBuilder) 10 | { 11 | migrationBuilder.AddColumn( 12 | name: "Email", 13 | table: "Players", 14 | nullable: true); 15 | } 16 | 17 | protected override void Down(MigrationBuilder migrationBuilder) 18 | { 19 | migrationBuilder.DropColumn( 20 | name: "Email", 21 | table: "Players"); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ClientApp/components/results/results.ts: -------------------------------------------------------------------------------- 1 | import * as ng from '@angular/core'; 2 | import { Http } from '@angular/http'; 3 | import { Cookie } from 'ng2-cookies/ng2-cookies'; 4 | 5 | @ng.Component({ 6 | selector: 'results', 7 | template: require('./results.html') 8 | }) 9 | export class Results { 10 | private showres = false; 11 | private results: IResultItem[]; 12 | 13 | constructor(http: Http) { 14 | this.showres = Cookie.get('q_finished') === 'yes'; 15 | 16 | http.get('/api/Results/Fetch').subscribe(result => { 17 | this.results = result.json(); 18 | }); 19 | } 20 | } 21 | 22 | interface IResultItem { 23 | rank: number; 24 | dateFormatted: string; 25 | name: string; 26 | summary: string; 27 | } 28 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | /* Move down content because we have a fixed navbar that is 50px tall */ 2 | body { 3 | padding-top: 50px; 4 | padding-bottom: 20px; 5 | } 6 | 7 | /* Wrapping element */ 8 | /* Set some basic padding to keep content from hitting the edges */ 9 | .body-content { 10 | padding-left: 15px; 11 | padding-right: 15px; 12 | } 13 | 14 | /* Set widths on the form inputs since otherwise they're 100% wide */ 15 | input, 16 | select, 17 | textarea { 18 | max-width: 280px; 19 | } 20 | 21 | 22 | /* Responsive: Portrait tablets and up */ 23 | @media screen and (min-width: 768px) { 24 | .jumbotron { 25 | margin-top: 20px; 26 | } 27 | 28 | .body-content { 29 | padding: 0; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HabraQuest", 3 | "private": true, 4 | "dependencies": { 5 | "bootstrap": "~3.0.0", 6 | "jquery": "~1.10.2", 7 | "jquery-validation": "~1.11.1", 8 | "jquery-validation-unobtrusive": "~3.2.2" 9 | }, 10 | "exportsOverride": { 11 | "bootstrap": { 12 | "js": "dist/js/*.*", 13 | "css": "dist/css/*.*", 14 | "fonts": "dist/fonts/*.*" 15 | }, 16 | "jquery": { 17 | "js": "jquery.{js,min.js,min.map}" 18 | }, 19 | "jquery-validation": { 20 | "": "jquery.validate.js" 21 | }, 22 | "jquery-validation-unobtrusive": { 23 | "": "jquery.validate.unobtrusive.{js,min.js}" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ClientApp/components/results/results.html: -------------------------------------------------------------------------------- 1 |

Loading...

2 |
3 |

4 | Для того, чтобы посмотреть результаты нужно пройти все уровни. 5 |

6 |
7 |
8 |

9 | Поздравлям, вы прошли все уровни. 10 |

11 | 12 |

Уже финишировали

13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
ИмяКомментарии
{{ result.name }}{{ result.summary }}
28 |
-------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.AspNet.Mvc; 5 | 6 | namespace HabraQuest.Controllers 7 | { 8 | public class HomeController : Controller 9 | { 10 | public IActionResult Index() 11 | { 12 | return View(); 13 | } 14 | 15 | public IActionResult About() 16 | { 17 | ViewBag.Message = "Your application description page."; 18 | 19 | return View(); 20 | } 21 | 22 | public IActionResult Contact() 23 | { 24 | ViewBag.Message = "Your contact page."; 25 | 26 | return View(); 27 | } 28 | 29 | public IActionResult Error() 30 | { 31 | return View("~/Views/Shared/Error.cshtml"); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/gruntfile.js: -------------------------------------------------------------------------------- 1 | // This file in the main entry point for defining grunt tasks and using grunt plugins. 2 | // Click here to learn more. http://go.microsoft.com/fwlink/?LinkID=513275&clcid=0x409 3 | 4 | module.exports = function (grunt) { 5 | grunt.initConfig({ 6 | bower: { 7 | install: { 8 | options: { 9 | targetDir: "wwwroot/lib", 10 | layout: "byComponent", 11 | cleanTargetDir: false 12 | } 13 | } 14 | } 15 | }); 16 | 17 | // This command registers the default task which will install bower packages into wwwroot/lib 18 | grunt.registerTask("default", ["bower:install"]); 19 | 20 | // The following line loads the grunt plugins. 21 | // This line needs to be at the end of this this file. 22 | grunt.loadNpmTasks("grunt-bower-task"); 23 | }; -------------------------------------------------------------------------------- /ClientApp/boot-client.ts: -------------------------------------------------------------------------------- 1 | require('zone.js'); 2 | import 'bootstrap'; 3 | import 'reflect-metadata'; 4 | import './styles/site.css'; 5 | 6 | import { bootstrap } from '@angular/platform-browser-dynamic'; 7 | import { FormBuilder } from '@angular/common'; 8 | import { provideRouter } from '@angular/router'; 9 | import { HTTP_PROVIDERS } from '@angular/http'; 10 | import { App } from './components/app/app'; 11 | import { routes } from './routes'; 12 | import { disableDeprecatedForms, provideForms } from '@angular/forms'; 13 | 14 | bootstrap(App, [ 15 | ...HTTP_PROVIDERS, 16 | FormBuilder, 17 | provideRouter(routes), 18 | provideForms() 19 | ]); 20 | 21 | // Basic hot reloading support. Automatically reloads and restarts the Angular 2 app each time 22 | // you modify source files. This will not preserve any application state other than the URL. 23 | declare var module: any; 24 | if (module.hot) { 25 | module.hot.accept(); 26 | } 27 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Migrations/201502110941236_Finisher.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Data.Entity.Migrations; 2 | using Microsoft.Data.Entity.Migrations.Builders; 3 | using Microsoft.Data.Entity.Migrations.Model; 4 | using System; 5 | 6 | namespace HabraQuest.Migrations 7 | { 8 | public partial class Finisher : Migration 9 | { 10 | public override void Up(MigrationBuilder migrationBuilder) 11 | { 12 | migrationBuilder.CreateTable("Finisher", 13 | c => new 14 | { 15 | Id = c.Int(nullable: false, identity: true), 16 | Name = c.String(), 17 | Token = c.String(), 18 | Time = c.String() 19 | }) 20 | .PrimaryKey("PK_Finisher", t => t.Id); 21 | } 22 | 23 | public override void Down(MigrationBuilder migrationBuilder) 24 | { 25 | migrationBuilder.DropTable("Finisher"); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /HabraQuest.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "HabraQuest", "HabraQuest.xproj", "{F5AA1B4D-DFE8-4E38-B074-32AD0ED09023}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {F5AA1B4D-DFE8-4E38-B074-32AD0ED09023}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {F5AA1B4D-DFE8-4E38-B074-32AD0ED09023}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {F5AA1B4D-DFE8-4E38-B074-32AD0ED09023}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {F5AA1B4D-DFE8-4E38-B074-32AD0ED09023}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Views/Shared/_LoginPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Security.Principal 2 | 3 | @if (User.Identity.IsAuthenticated) 4 | { 5 | using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" })) 6 | { 7 | @Html.AntiForgeryToken() 8 | 14 | } 15 | } 16 | else 17 | { 18 | 22 | } 23 | -------------------------------------------------------------------------------- /Controllers/ResultsController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using HabraQuest.Model; 4 | using Microsoft.AspNetCore.Mvc; 5 | 6 | namespace HabraQuest.Controllers 7 | { 8 | [Route("api/[controller]")] 9 | public class Results : Controller 10 | { 11 | private readonly DataContext dataContext; 12 | public Results(DataContext db) 13 | { 14 | dataContext = db; 15 | } 16 | 17 | [HttpGet("[action]")] 18 | public IEnumerable Fetch() 19 | { 20 | var finieshed = dataContext.Players.Where(p => p.HasFinished).Take(100).Select(item => new ResultItem 21 | { 22 | Summary = item.Comment.Length>160? item.Comment.Substring(0, 150) + "..." : item.Comment, 23 | Name = item.Name 24 | }); 25 | 26 | return finieshed; 27 | } 28 | 29 | public class ResultItem 30 | { 31 | public int Rank { get; set; } 32 | public string DateFormatted { get; set; } 33 | public string Name { get; set; } 34 | public string Summary { get; set; } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/app/config.route.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | 4 | var app = angular.module('app'); 5 | 6 | app.constant('routes', getRoutes()); 7 | app.config(['$routeProvider', 'routes', routeConfigurator]); 8 | function routeConfigurator($routeProvider, routes) { 9 | routes.forEach(function (r) { 10 | $routeProvider.when(r.url, r.config); 11 | }); 12 | $routeProvider.otherwise({ redirectTo: '/' }); 13 | } 14 | function getRoutes() { 15 | return [ 16 | { 17 | url: '/', 18 | config: { 19 | templateUrl: 'app/home/home.html', 20 | title: 'home', 21 | settings: { 22 | nav: 3 23 | } 24 | } 25 | }, { 26 | url: '/start', 27 | config: { 28 | title: 'start', 29 | templateUrl: 'app/start/start.html', 30 | settings: { 31 | nav: 2, 32 | } 33 | } 34 | } 35 | ]; 36 | } 37 | })(); -------------------------------------------------------------------------------- /HabraQuest.xproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | true 7 | 8 | 9 | 10 | f5aa1b4d-dfe8-4e38-b074-32ad0ed09023 11 | HabraQuest 12 | 13 | 14 | 2.0 15 | 2018 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Migrations/20160725063832_Initial.Designer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | using Microsoft.EntityFrameworkCore.Migrations; 6 | using HabraQuest.Model; 7 | 8 | namespace HabraQuest.Migrations 9 | { 10 | [DbContext(typeof(DataContext))] 11 | [Migration("20160725063832_Initial")] 12 | partial class Initial 13 | { 14 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 15 | { 16 | modelBuilder 17 | .HasAnnotation("ProductVersion", "1.0.0-rtm-21431") 18 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 19 | 20 | modelBuilder.Entity("HabraQuest.Model.Player", b => 21 | { 22 | b.Property("Id") 23 | .ValueGeneratedOnAdd(); 24 | 25 | b.Property("Comment"); 26 | 27 | b.Property("Name"); 28 | 29 | b.Property("TaskNumber"); 30 | 31 | b.Property("Token"); 32 | 33 | b.HasKey("Id"); 34 | 35 | b.ToTable("Players"); 36 | }); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var merge = require('extendify')({ isDeep: true, arrays: 'concat' }); 4 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 5 | var extractCSS = new ExtractTextPlugin('styles.css'); 6 | var devConfig = require('./webpack.config.dev'); 7 | var prodConfig = require('./webpack.config.prod'); 8 | var isDevelopment = process.env.ASPNETCORE_ENVIRONMENT === 'Development'; 9 | 10 | module.exports = merge({ 11 | resolve: { 12 | extensions: [ '', '.js', '.ts' ] 13 | }, 14 | module: { 15 | loaders: [ 16 | { test: /\.ts$/, include: /ClientApp/, loader: 'ts-loader' }, 17 | { test: /\.html$/, loader: 'raw-loader' }, 18 | { test: /\.css/, loader: extractCSS.extract(['css']) } 19 | ] 20 | }, 21 | entry: { 22 | main: ['./ClientApp/boot-client.ts'] 23 | }, 24 | output: { 25 | path: path.join(__dirname, 'wwwroot', 'dist'), 26 | filename: '[name].js', 27 | publicPath: '/dist/' 28 | }, 29 | plugins: [ 30 | extractCSS, 31 | new webpack.DllReferencePlugin({ 32 | context: __dirname, 33 | manifest: require('./wwwroot/dist/vendor-manifest.json') 34 | }) 35 | ] 36 | }, isDevelopment ? devConfig : prodConfig); 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "habraquest", 3 | "version": "0.0.0", 4 | "devDependencies": { 5 | "bootstrap": "^3.3.6", 6 | "css-loader": "^0.23.1", 7 | "expose-loader": "^0.7.1", 8 | "extendify": "^1.0.0", 9 | "extract-text-webpack-plugin": "^1.0.1", 10 | "file-loader": "^0.8.5", 11 | "jquery": "^2.2.1", 12 | "raw-loader": "^0.5.1", 13 | "style-loader": "^0.13.0", 14 | "ts-loader": "^0.8.1", 15 | "typescript": "^1.8.2", 16 | "url-loader": "^0.5.7", 17 | "webpack": "^1.12.14", 18 | "webpack-hot-middleware": "^2.10.0" 19 | }, 20 | "dependencies": { 21 | "@angular/common": "2.0.0-rc.4", 22 | "@angular/compiler": "2.0.0-rc.4", 23 | "@angular/core": "2.0.0-rc.4", 24 | "@angular/forms": "^0.2.0", 25 | "@angular/http": "2.0.0-rc.4", 26 | "@angular/platform-browser": "2.0.0-rc.4", 27 | "@angular/platform-browser-dynamic": "2.0.0-rc.4", 28 | "@angular/platform-server": "2.0.0-rc.4", 29 | "@angular/router": "3.0.0-alpha.8", 30 | "angular2-universal": "^0.104.1", 31 | "aspnet-prerendering": "^1.0.2", 32 | "aspnet-webpack": "^1.0.1", 33 | "css": "^2.2.1", 34 | "isomorphic-fetch": "^2.2.1", 35 | "ng2-cookies": "^1.0.1", 36 | "preboot": "^2.0.10", 37 | "rxjs": "5.0.0-beta.6", 38 | "webpack-externals-plugin": "^1.0.0", 39 | "zone.js": "^0.6.12" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Migrations/20160725063832_Initial.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.EntityFrameworkCore.Migrations; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | 6 | namespace HabraQuest.Migrations 7 | { 8 | public partial class Initial : Migration 9 | { 10 | protected override void Up(MigrationBuilder migrationBuilder) 11 | { 12 | migrationBuilder.CreateTable( 13 | name: "Players", 14 | columns: table => new 15 | { 16 | Id = table.Column(nullable: false) 17 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 18 | Comment = table.Column(nullable: true), 19 | Name = table.Column(nullable: true), 20 | TaskNumber = table.Column(nullable: false), 21 | Token = table.Column(nullable: false) 22 | }, 23 | constraints: table => 24 | { 25 | table.PrimaryKey("PK_Players", x => x.Id); 26 | }); 27 | } 28 | 29 | protected override void Down(MigrationBuilder migrationBuilder) 30 | { 31 | migrationBuilder.DropTable( 32 | name: "Players"); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ClientApp/boot-server.ts: -------------------------------------------------------------------------------- 1 | import 'angular2-universal/polyfills'; 2 | import * as ngCore from '@angular/core'; 3 | import { APP_BASE_HREF } from '@angular/common'; 4 | import { provideRouter } from '@angular/router'; 5 | import * as ngUniversal from 'angular2-universal'; 6 | import { BASE_URL, ORIGIN_URL, REQUEST_URL } from 'angular2-universal/common'; 7 | import { App } from './components/app/app'; 8 | import { routes } from './routes'; 9 | 10 | const bootloader = ngUniversal.bootloader({ 11 | async: true, 12 | preboot: false, 13 | platformProviders: [ 14 | ngCore.provide(APP_BASE_HREF, { useValue: '/' }), 15 | ] 16 | }); 17 | 18 | export default function (params: any): Promise<{ html: string, globals?: any }> { 19 | const config: ngUniversal.AppConfig = { 20 | directives: [App], 21 | providers: [ 22 | ngCore.provide(ORIGIN_URL, { useValue: params.origin }), 23 | ngCore.provide(REQUEST_URL, { useValue: params.url }), 24 | ...ngUniversal.NODE_HTTP_PROVIDERS, 25 | provideRouter(routes), 26 | ...ngUniversal.NODE_LOCATION_PROVIDERS, 27 | ], 28 | // TODO: Render just the component instead of wrapping it inside an extra HTML document 29 | // Waiting on https://github.com/angular/universal/issues/347 30 | template: '\n' 31 | }; 32 | 33 | return bootloader.serializeApplication(config).then(html => { 34 | return { html }; 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Migrations/201502110941236_Finisher.Designer.cs: -------------------------------------------------------------------------------- 1 | using HabraQuest.Models; 2 | using Microsoft.Data.Entity; 3 | using Microsoft.Data.Entity.Metadata; 4 | using Microsoft.Data.Entity.Migrations.Infrastructure; 5 | using System; 6 | 7 | namespace HabraQuest.Migrations 8 | { 9 | [ContextType(typeof(HabraQuest.Models.ApplicationDbContext))] 10 | public partial class Finisher : IMigrationMetadata 11 | { 12 | string IMigrationMetadata.MigrationId 13 | { 14 | get 15 | { 16 | return "201502110941236_Finisher"; 17 | } 18 | } 19 | 20 | string IMigrationMetadata.ProductVersion 21 | { 22 | get 23 | { 24 | return "7.0.0-beta2-11909"; 25 | } 26 | } 27 | 28 | IModel IMigrationMetadata.TargetModel 29 | { 30 | get 31 | { 32 | var builder = new BasicModelBuilder(); 33 | 34 | builder.Entity("HabraQuest.Models.Finisher", b => 35 | { 36 | b.Property("Id") 37 | .GenerateValueOnAdd(); 38 | b.Property("Name"); 39 | b.Property("Token"); 40 | b.Property("Time"); 41 | b.Key("Id"); 42 | }); 43 | 44 | return builder.Model; 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /ClientApp/components/nav-menu/nav-menu.html: -------------------------------------------------------------------------------- 1 | 34 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Views/Account/_ChangePasswordPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Security.Principal 2 | @model HabraQuest.Models.ManageUserViewModel 3 | 4 |

You're logged in as @User.Identity.GetUserName().

5 | 6 | @using (Html.BeginForm("Manage", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 7 | { 8 | @Html.AntiForgeryToken() 9 |

Change Password Form

10 |
11 | @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 12 |
13 | @Html.LabelFor(m => m.OldPassword, new { @class = "col-md-2 control-label" }) 14 |
15 | @Html.PasswordFor(m => m.OldPassword, new { @class = "form-control" }) 16 |
17 |
18 |
19 | @Html.LabelFor(m => m.NewPassword, new { @class = "col-md-2 control-label" }) 20 |
21 | @Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" }) 22 |
23 |
24 |
25 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 26 |
27 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 28 |
29 |
30 | 31 |
32 |
33 | 34 |
35 |
36 | } 37 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/HabraQuest.kproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 1589982c-e9b5-4932-bd07-1e9e7e1c4313 10 | HabraQuest 11 | ..\..\artifacts\obj\$(MSBuildProjectName) 12 | ..\..\artifacts\bin\$(MSBuildProjectName)\ 13 | 14 | 15 | 2.0 16 | 38216 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /archive/hq1/HabraQuest.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.22512.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{61C7ED3E-9B2B-4190-A473-92B6754E3DB3}" 7 | EndProject 8 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "HabraQuest", "src\HabraQuest\HabraQuest.kproj", "{1589982C-E9B5-4932-BD07-1E9E7E1C4313}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1A96108B-EDE4-45F4-8962-F5FD72EBC4B2}" 11 | ProjectSection(SolutionItems) = preProject 12 | global.json = global.json 13 | EndProjectSection 14 | ProjectSection(FolderGlobals) = preProject 15 | global_1json__JSONSchema = http://json.schemastore.org/global 16 | EndProjectSection 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|Any CPU = Debug|Any CPU 21 | Release|Any CPU = Release|Any CPU 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {1589982C-E9B5-4932-BD07-1E9E7E1C4313}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {1589982C-E9B5-4932-BD07-1E9E7E1C4313}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {1589982C-E9B5-4932-BD07-1E9E7E1C4313}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {1589982C-E9B5-4932-BD07-1E9E7E1C4313}.Release|Any CPU.Build.0 = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | GlobalSection(NestedProjects) = preSolution 33 | {1589982C-E9B5-4932-BD07-1E9E7E1C4313} = {61C7ED3E-9B2B-4190-A473-92B6754E3DB3} 34 | EndGlobalSection 35 | EndGlobal 36 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Views/Account/Register.cshtml: -------------------------------------------------------------------------------- 1 | @model HabraQuest.Models.RegisterViewModel 2 | 3 | @{ 4 | ViewBag.Title = "Register"; 5 | } 6 | 7 |

@ViewBag.Title.

8 | 9 | @using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 10 | { 11 | @Html.AntiForgeryToken() 12 |

Create a new account.

13 |
14 | @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 15 |
16 | @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" }) 17 |
18 | @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" }) 19 |
20 |
21 |
22 | @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) 23 |
24 | @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) 25 |
26 |
27 |
28 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 29 |
30 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 31 |
32 |
33 |
34 |
35 | 36 |
37 |
38 | } 39 | 40 | @section Scripts { 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /ClientApp/styles/site.css: -------------------------------------------------------------------------------- 1 | @media (max-width: 767px) { 2 | /* On small screens, the nav menu spans the full width of the screen. Leave a space for it. */ 3 | .body-content { 4 | padding-top: 50px; 5 | } 6 | } 7 | 8 | .main-nav li .glyphicon { 9 | margin-right: 10px; 10 | } 11 | 12 | /* Highlighting rules for nav menu items */ 13 | .main-nav li.link-active a, 14 | .main-nav li.link-active a:hover, 15 | .main-nav li.link-active a:focus { 16 | background-color: #4189C7; 17 | color: white; 18 | } 19 | 20 | /* Keep the nav menu independent of scrolling and on top of other items */ 21 | .main-nav { 22 | position: fixed; 23 | top: 0; 24 | left: 0; 25 | right: 0; 26 | z-index: 1; 27 | } 28 | 29 | @media (min-width: 768px) { 30 | /* On small screens, convert the nav menu to a vertical sidebar */ 31 | .main-nav { 32 | height: 100%; 33 | width: calc(25% - 20px); 34 | } 35 | .main-nav .navbar { 36 | border-radius: 0px; 37 | border-width: 0px; 38 | height: 100%; 39 | } 40 | .main-nav .navbar-header { 41 | float: none; 42 | } 43 | .main-nav .navbar-collapse { 44 | border-top: 1px solid #444; 45 | padding: 0px; 46 | } 47 | .main-nav .navbar ul { 48 | float: none; 49 | } 50 | .main-nav .navbar li { 51 | float: none; 52 | font-size: 15px; 53 | margin: 6px; 54 | } 55 | .main-nav .navbar li a { 56 | padding: 10px 16px; 57 | border-radius: 4px; 58 | } 59 | .main-nav .navbar a { 60 | /* If a menu item's text is too long, truncate it */ 61 | width: 100%; 62 | white-space: nowrap; 63 | overflow: hidden; 64 | text-overflow: ellipsis; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Migrations/20160726131042_AddQuestTask.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Microsoft.EntityFrameworkCore.Migrations; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | 6 | namespace HabraQuest.Migrations 7 | { 8 | public partial class AddQuestTask : Migration 9 | { 10 | protected override void Up(MigrationBuilder migrationBuilder) 11 | { 12 | migrationBuilder.CreateTable( 13 | name: "Tasks", 14 | columns: table => new 15 | { 16 | Id = table.Column(nullable: false) 17 | .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn), 18 | Answers = table.Column(nullable: true), 19 | Content = table.Column(nullable: true), 20 | Done = table.Column(nullable: false), 21 | Title = table.Column(nullable: true), 22 | Watched = table.Column(nullable: false) 23 | }, 24 | constraints: table => 25 | { 26 | table.PrimaryKey("PK_Tasks", x => x.Id); 27 | }); 28 | 29 | migrationBuilder.AddColumn( 30 | name: "HasFinished", 31 | table: "Players", 32 | nullable: false, 33 | defaultValue: false); 34 | } 35 | 36 | protected override void Down(MigrationBuilder migrationBuilder) 37 | { 38 | migrationBuilder.DropColumn( 39 | name: "HasFinished", 40 | table: "Players"); 41 | 42 | migrationBuilder.DropTable( 43 | name: "Tasks"); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/project.json: -------------------------------------------------------------------------------- 1 | { 2 | /* Click to learn more about project.json http://go.microsoft.com/fwlink/?LinkID=517074 */ 3 | "webroot": "wwwroot", 4 | "version": "1.0.0-*", 5 | "dependencies": { 6 | "EntityFramework.SqlServer": "7.0.0-beta2", 7 | "EntityFramework.Commands": "7.0.0-beta2", 8 | "Microsoft.AspNet.Mvc": "6.0.0-beta2", 9 | /* "Microsoft.AspNet.Mvc.WebApiCompatShim": "6.0.0-beta2", */ 10 | "Microsoft.AspNet.Diagnostics": "1.0.0-beta2", 11 | "Microsoft.AspNet.Diagnostics.Entity": "7.0.0-beta2", 12 | "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-beta2", 13 | "Microsoft.AspNet.Security.Cookies": "1.0.0-beta2", 14 | "Microsoft.AspNet.Server.IIS": "1.0.0-beta2", 15 | "Microsoft.AspNet.Server.WebListener": "1.0.0-beta2", 16 | "Microsoft.AspNet.StaticFiles": "1.0.0-beta2", 17 | "Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta2", 18 | "Microsoft.Framework.CodeGenerators.Mvc": "1.0.0-beta2", 19 | "Microsoft.Framework.Logging": "1.0.0-beta2", 20 | "Microsoft.Framework.Logging.Console": "1.0.0-beta2", 21 | "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-beta1" 22 | }, 23 | "commands": { 24 | /* Change the port number when you are self hosting this application */ 25 | "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000", 26 | "gen": "Microsoft.Framework.CodeGeneration", 27 | "ef": "EntityFramework.Commands" 28 | }, 29 | "frameworks": { 30 | "aspnet50": { }, 31 | "aspnetcore50": { 32 | "dependencies": { 33 | } 34 | } 35 | }, 36 | "exclude": [ 37 | "wwwroot", 38 | "node_modules", 39 | "bower_components" 40 | ], 41 | "packExclude": [ 42 | "node_modules", 43 | "bower_components", 44 | "**.kproj", 45 | "**.user", 46 | "**.vspscc" 47 | ], 48 | "scripts": { 49 | "postrestore": [ "npm install" ], 50 | "prepare": [ "grunt bower:install" ] 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | @ViewBag.Title - My ASP.NET Application 7 | 8 | 9 | 10 | 11 | 12 | 32 |
33 | @RenderBody() 34 |
35 |
36 |

© @DateTime.Now.Year - My ASP.NET Application

37 |
38 |
39 | 40 | 41 | @RenderSection("scripts", required: false) 42 | 43 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Migrations/ApplicationDbContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | using HabraQuest.Models; 2 | using Microsoft.Data.Entity; 3 | using Microsoft.Data.Entity.Metadata; 4 | using Microsoft.Data.Entity.Migrations.Infrastructure; 5 | using System; 6 | 7 | namespace HabraQuest.Migrations 8 | { 9 | [ContextType(typeof(HabraQuest.Models.ApplicationDbContext))] 10 | public class ApplicationDbContextModelSnapshot : ModelSnapshot 11 | { 12 | public override IModel Model 13 | { 14 | get 15 | { 16 | var builder = new BasicModelBuilder(); 17 | 18 | builder.Entity("HabraQuest.Models.Finisher", b => 19 | { 20 | b.Property("Id") 21 | .GenerateValueOnAdd(); 22 | b.Property("Name"); 23 | b.Property("Token"); 24 | b.Key("Id"); 25 | }); 26 | 27 | builder.Entity("HabraQuest.Models.Progress", b => 28 | { 29 | b.Property("Id") 30 | .GenerateValueOnAdd(); 31 | b.Property("TaskNumber"); 32 | b.Property("Token"); 33 | b.Key("Id"); 34 | }); 35 | 36 | builder.Entity("HabraQuest.Models.QuestTask", b => 37 | { 38 | b.Property("Answer"); 39 | b.Property("Content"); 40 | b.Property("Id") 41 | .GenerateValueOnAdd(); 42 | b.Property("Number"); 43 | b.Property("Title"); 44 | b.Key("Id"); 45 | }); 46 | 47 | return builder.Model; 48 | } 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /Migrations/20160726131042_AddQuestTask.Designer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | using Microsoft.EntityFrameworkCore.Migrations; 6 | using HabraQuest.Model; 7 | 8 | namespace HabraQuest.Migrations 9 | { 10 | [DbContext(typeof(DataContext))] 11 | [Migration("20160726131042_AddQuestTask")] 12 | partial class AddQuestTask 13 | { 14 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 15 | { 16 | modelBuilder 17 | .HasAnnotation("ProductVersion", "1.0.0-rtm-21431") 18 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 19 | 20 | modelBuilder.Entity("HabraQuest.Model.Player", b => 21 | { 22 | b.Property("Id") 23 | .ValueGeneratedOnAdd(); 24 | 25 | b.Property("Comment"); 26 | 27 | b.Property("HasFinished"); 28 | 29 | b.Property("Name"); 30 | 31 | b.Property("TaskNumber"); 32 | 33 | b.Property("Token"); 34 | 35 | b.HasKey("Id"); 36 | 37 | b.ToTable("Players"); 38 | }); 39 | 40 | modelBuilder.Entity("HabraQuest.Model.QuestTask", b => 41 | { 42 | b.Property("Id") 43 | .ValueGeneratedOnAdd(); 44 | 45 | b.Property("Answers"); 46 | 47 | b.Property("Content"); 48 | 49 | b.Property("Done"); 50 | 51 | b.Property("Title"); 52 | 53 | b.Property("Watched"); 54 | 55 | b.HasKey("Id"); 56 | 57 | b.ToTable("Tasks"); 58 | }); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /webpack.config.vendor.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var webpack = require('webpack'); 3 | var ExtractTextPlugin = require('extract-text-webpack-plugin'); 4 | var extractCSS = new ExtractTextPlugin('vendor.css'); 5 | var isDevelopment = process.env.ASPNETCORE_ENVIRONMENT === 'Development'; 6 | 7 | module.exports = { 8 | resolve: { 9 | extensions: [ '', '.js' ] 10 | }, 11 | module: { 12 | loaders: [ 13 | { test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000' }, 14 | { test: /\.css/, loader: extractCSS.extract(['css']) } 15 | ] 16 | }, 17 | entry: { 18 | vendor: [ 19 | 'bootstrap', 20 | 'bootstrap/dist/css/bootstrap.css', 21 | 'style-loader', 22 | 'jquery', 23 | '@angular/common', 24 | '@angular/compiler', 25 | '@angular/core', 26 | '@angular/http', 27 | '@angular/platform-browser', 28 | '@angular/platform-browser-dynamic', 29 | '@angular/router', 30 | '@angular/platform-server', 31 | ] 32 | }, 33 | output: { 34 | path: path.join(__dirname, 'wwwroot', 'dist'), 35 | filename: '[name].js', 36 | library: '[name]_[hash]', 37 | }, 38 | plugins: [ 39 | extractCSS, 40 | new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' }), // Maps these identifiers to the jQuery package (because Bootstrap expects it to be a global variable) 41 | new webpack.optimize.OccurenceOrderPlugin(), 42 | new webpack.DllPlugin({ 43 | path: path.join(__dirname, 'wwwroot', 'dist', '[name]-manifest.json'), 44 | name: '[name]_[hash]' 45 | }) 46 | ].concat(isDevelopment ? [] : [ 47 | new webpack.optimize.UglifyJsPlugin({ 48 | compress: { warnings: false }, 49 | minimize: true, 50 | mangle: false // Due to https://github.com/angular/angular/issues/6678 51 | }) 52 | ]) 53 | }; 54 | -------------------------------------------------------------------------------- /Migrations/DataContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | using Microsoft.EntityFrameworkCore.Migrations; 6 | using HabraQuest.Model; 7 | 8 | namespace HabraQuest.Migrations 9 | { 10 | [DbContext(typeof(DataContext))] 11 | partial class DataContextModelSnapshot : ModelSnapshot 12 | { 13 | protected override void BuildModel(ModelBuilder modelBuilder) 14 | { 15 | modelBuilder 16 | .HasAnnotation("ProductVersion", "1.0.0-rtm-21431") 17 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 18 | 19 | modelBuilder.Entity("HabraQuest.Model.Player", b => 20 | { 21 | b.Property("Id") 22 | .ValueGeneratedOnAdd(); 23 | 24 | b.Property("Comment"); 25 | 26 | b.Property("Email"); 27 | 28 | b.Property("HasFinished"); 29 | 30 | b.Property("Name"); 31 | 32 | b.Property("TaskNumber"); 33 | 34 | b.Property("Token"); 35 | 36 | b.HasKey("Id"); 37 | 38 | b.ToTable("Players"); 39 | }); 40 | 41 | modelBuilder.Entity("HabraQuest.Model.QuestTask", b => 42 | { 43 | b.Property("Id") 44 | .ValueGeneratedOnAdd(); 45 | 46 | b.Property("Answers"); 47 | 48 | b.Property("Content"); 49 | 50 | b.Property("Done"); 51 | 52 | b.Property("Title"); 53 | 54 | b.Property("Watched"); 55 | 56 | b.HasKey("Id"); 57 | 58 | b.ToTable("Tasks"); 59 | }); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Migrations/20160728063831_PlayerEmail.Designer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | using Microsoft.EntityFrameworkCore.Migrations; 6 | using HabraQuest.Model; 7 | 8 | namespace HabraQuest.Migrations 9 | { 10 | [DbContext(typeof(DataContext))] 11 | [Migration("20160728063831_PlayerEmail")] 12 | partial class PlayerEmail 13 | { 14 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 15 | { 16 | modelBuilder 17 | .HasAnnotation("ProductVersion", "1.0.0-rtm-21431") 18 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 19 | 20 | modelBuilder.Entity("HabraQuest.Model.Player", b => 21 | { 22 | b.Property("Id") 23 | .ValueGeneratedOnAdd(); 24 | 25 | b.Property("Comment"); 26 | 27 | b.Property("Email"); 28 | 29 | b.Property("HasFinished"); 30 | 31 | b.Property("Name"); 32 | 33 | b.Property("TaskNumber"); 34 | 35 | b.Property("Token"); 36 | 37 | b.HasKey("Id"); 38 | 39 | b.ToTable("Players"); 40 | }); 41 | 42 | modelBuilder.Entity("HabraQuest.Model.QuestTask", b => 43 | { 44 | b.Property("Id") 45 | .ValueGeneratedOnAdd(); 46 | 47 | b.Property("Answers"); 48 | 49 | b.Property("Content"); 50 | 51 | b.Property("Done"); 52 | 53 | b.Property("Title"); 54 | 55 | b.Property("Watched"); 56 | 57 | b.HasKey("Id"); 58 | 59 | b.ToTable("Tasks"); 60 | }); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/app/start/start.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |

5 | {{vm.taskTitle}} 6 |

7 | 8 |

{{vm.taskContent}}

9 |
10 |
11 |
12 | 13 |
14 | Отправить 15 |
16 |
17 |
18 |
19 | {{vm.hints}} 20 |
21 |
22 |
23 | Загрузка.... 24 |
25 |
26 |
Просмотрено - {{vm.watched}}
27 |
Пройдено - {{vm.done}}
28 |
29 |
30 |

Поздравляем, вы прошли все задания.

31 |
32 |
Вы можете вписать свое имя на доску почета
33 | 34 |
35 |
36 | 37 | 38 | Отправить 39 | 40 |
41 |
42 | 43 |
44 |
45 | Уже финишировали: 46 |
47 |
48 |
    49 |
  • [{{user.time}}] - {{user.name}}
  • 50 |
51 |
52 |
53 | Начать сначала 54 |
55 |
-------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Models/AccountViewModels.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.DataAnnotations; 2 | 3 | namespace HabraQuest.Models 4 | { 5 | public class ExternalLoginConfirmationViewModel 6 | { 7 | [Required] 8 | [Display(Name = "User name")] 9 | public string UserName { get; set; } 10 | } 11 | 12 | public class ManageUserViewModel 13 | { 14 | [Required] 15 | [DataType(DataType.Password)] 16 | [Display(Name = "Current password")] 17 | public string OldPassword { get; set; } 18 | 19 | [Required] 20 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 21 | [DataType(DataType.Password)] 22 | [Display(Name = "New password")] 23 | public string NewPassword { get; set; } 24 | 25 | [DataType(DataType.Password)] 26 | [Display(Name = "Confirm new password")] 27 | [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] 28 | public string ConfirmPassword { get; set; } 29 | } 30 | 31 | public class LoginViewModel 32 | { 33 | [Required] 34 | [Display(Name = "User name")] 35 | public string UserName { get; set; } 36 | 37 | [Required] 38 | [DataType(DataType.Password)] 39 | [Display(Name = "Password")] 40 | public string Password { get; set; } 41 | 42 | [Display(Name = "Remember me?")] 43 | public bool RememberMe { get; set; } 44 | } 45 | 46 | public class RegisterViewModel 47 | { 48 | [Required] 49 | [Display(Name = "User name")] 50 | public string UserName { get; set; } 51 | 52 | [Required] 53 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 54 | [DataType(DataType.Password)] 55 | [Display(Name = "Password")] 56 | public string Password { get; set; } 57 | 58 | [DataType(DataType.Password)] 59 | [Display(Name = "Confirm password")] 60 | [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 61 | public string ConfirmPassword { get; set; } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Models/IdentityModels.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNet.Identity; 3 | using Microsoft.AspNet.Identity.EntityFramework; 4 | using Microsoft.Data.Entity; 5 | using Microsoft.Data.Entity.Metadata; 6 | using Microsoft.Framework.ConfigurationModel; 7 | using Microsoft.Framework.OptionsModel; 8 | 9 | namespace HabraQuest.Models 10 | { 11 | // Add profile data for application users by adding properties to the ApplicationUser class 12 | public class ApplicationUser : IdentityUser 13 | { 14 | 15 | } 16 | 17 | public class ApplicationDbContext : DbContext // IdentityDbContext 18 | { 19 | public DbSet QuestTask { get; set; } 20 | public DbSet Progress { get; set; } 21 | public DbSet Finishers { get; set; } 22 | 23 | 24 | private static bool _created = false; 25 | public ApplicationDbContext() 26 | { 27 | // Create the database and schema if it doesn't exist 28 | // This is a temporary workaround to create database until Entity Framework database migrations 29 | // are supported in ASP.NET 5 30 | if (!_created) 31 | { 32 | var xx = Database.AsMigrationsEnabled(); 33 | 34 | Database.AsMigrationsEnabled().ApplyMigrations(); 35 | _created = true; 36 | } 37 | } 38 | 39 | protected override void OnConfiguring(DbContextOptions options) 40 | { 41 | var xConfiguration = new Microsoft.Framework.ConfigurationModel.Configuration() 42 | .AddJsonFile("config.json") 43 | .AddEnvironmentVariables(); 44 | options.UseSqlServer(xConfiguration.Get("Data:DefaultConnection:ConnectionString")); 45 | } 46 | 47 | protected override void OnModelCreating(ModelBuilder builder) 48 | { 49 | base.OnModelCreating(builder); 50 | // Customize the ASP.NET Identity model and override the defaults if needed. 51 | // For example, you can rename the ASP.NET Identity table names and more. 52 | // Add your customizations after calling base.OnModelCreating(builder); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Home Page"; 3 | } 4 | 5 |
6 |

ASP.NET 5

7 |

ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.

8 |

Learn more »

9 |
10 | 11 |
12 |
13 |

This application consists of:

14 |
    15 |
  • Sample pages showing basic nav
  • 16 |
  • Theming using Bootstrap
  • 17 |
18 |
19 | 32 | 41 |
-------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Views/Account/Login.cshtml: -------------------------------------------------------------------------------- 1 | @model HabraQuest.Models.LoginViewModel 2 | 3 | @{ 4 | ViewBag.Title = "Log in"; 5 | } 6 | 7 |

@ViewBag.Title.

8 |
9 |
10 |
11 | @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 12 | { 13 | @Html.AntiForgeryToken() 14 |

Use a local account to log in.

15 |
16 | @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 17 |
18 | @Html.LabelFor(m => m.UserName, new { @class = "col-md-2 control-label" }) 19 |
20 | @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" }) 21 | @Html.ValidationMessageFor(m => m.UserName, "", new { @class = "text-danger" }) 22 |
23 |
24 |
25 | @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) 26 |
27 | @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) 28 | @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" }) 29 |
30 |
31 |
32 |
33 |
34 | @Html.CheckBoxFor(m => m.RememberMe) 35 | @Html.LabelFor(m => m.RememberMe) 36 |
37 |
38 |
39 |
40 |
41 | 42 |
43 |
44 |

45 | @Html.ActionLink("Register", "Register") if you don't have a local account. 46 |

47 | } 48 |
49 |
50 |
51 | @section Scripts { 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Controllers/StatisticsController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | using System.Linq; 4 | using HabraQuest.Models; 5 | using Microsoft.AspNet.Mvc; 6 | 7 | namespace HabraQuest.Controllers 8 | { 9 | [AllowAnonymous] 10 | [Route("api/[controller]")] 11 | public class StatisticsController : Controller 12 | { 13 | // GET api/Statistics 14 | [HttpGet] 15 | public StatisticsResult Get(string token) 16 | { 17 | using (ApplicationDbContext db = new ApplicationDbContext()) 18 | { 19 | var current = db.Progress.FirstOrDefault(_ => _.Token == token); 20 | int taskNumber = current?.TaskNumber ?? 1; 21 | 22 | return new StatisticsResult 23 | { 24 | Watched = db.Progress.Count(_ => _.TaskNumber >= taskNumber), 25 | Done = db.Progress.Count(_ => _.TaskNumber > taskNumber) 26 | }; 27 | 28 | } 29 | } 30 | 31 | // POST api/Statistics 32 | [HttpPost] 33 | public Finisher[] Post([FromBody]SaveNameRequest data) 34 | { 35 | if (data == null) return Array.Empty(); 36 | var name = data.Name; 37 | var token = data.Token; 38 | using (ApplicationDbContext db = new ApplicationDbContext()) 39 | { 40 | var current = db.Progress.FirstOrDefault(_ => _.Token == token); 41 | if (current != null && current.TaskNumber == 999) 42 | { 43 | var alreadyAdded = db.Finishers.Any(_ => _.Token == token); 44 | if (!alreadyAdded) 45 | { 46 | var finisher = new Finisher() 47 | { 48 | Name = name, 49 | Token = token, 50 | Time = DateTime.UtcNow.ToString(CultureInfo.InvariantCulture) 51 | }; 52 | db.Finishers.Add(finisher); 53 | db.SaveChanges(); 54 | } 55 | 56 | return db.Finishers.ToArray(); 57 | } 58 | return null; 59 | } 60 | } 61 | } 62 | 63 | public class SaveNameRequest 64 | { 65 | public string Token { get; set; } 66 | public string Name { get; set; } 67 | } 68 | 69 | public class StatisticsResult 70 | { 71 | public string Ok { get; } = "OK"; 72 | public int Watched { get; set; } 73 | public int Done { get; set; } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /ClientApp/components/quest/quest.ts: -------------------------------------------------------------------------------- 1 | import * as ng from '@angular/core'; 2 | import {Inject} from '@angular/core'; 3 | import { Http } from '@angular/http'; 4 | import { Cookie } from 'ng2-cookies/ng2-cookies'; 5 | import {Router} from '@angular/router'; 6 | 7 | @ng.Component({ 8 | selector: 'quest', 9 | template: require('./quest.html') 10 | }) 11 | export class Quest { 12 | private task: any = {}; 13 | private answer: string = ''; 14 | 15 | private feedback = ''; 16 | private hintColor = '#34bb34'; 17 | 18 | private hasFinished = false; 19 | private finishForm; 20 | 21 | constructor( @Inject(Http) private http: Http, private router: Router) { 22 | const showres = Cookie.get('q_finished') === 'yes'; 23 | if (showres) this.router.navigateByUrl('results'); 24 | else 25 | this.http.get('/home/getcurrentstate', { withCredentials: true }) 26 | .subscribe(result => { 27 | const res = result.json(); 28 | this.hasFinished = res.player.hasFinished; 29 | this.task = res.task ? res.task : {}; 30 | let token = Cookie.get('playerToken'); 31 | if (!token) { 32 | token = res.player.token; 33 | Cookie.set('playerToken', token); 34 | } 35 | }); 36 | } 37 | 38 | submit() { 39 | this.http.get('/home/submitanswer?answer=' + this.answer, { withCredentials: true }) 40 | .subscribe(result => { 41 | const res = result.json(); 42 | if (res.player.hasFinished) { 43 | this.hasFinished = true; 44 | this.answer = ''; 45 | this.task = {}; 46 | this.feedback = ''; 47 | return; 48 | } 49 | this.task = res.task; 50 | this.feedback = res.feedback; 51 | this.answer = ''; 52 | }); 53 | this.refreshHintStyle() 54 | } 55 | 56 | // set random color to hint 57 | refreshHintStyle() { 58 | var letters = '0123456789ABC'.split(''); 59 | var color = '#'; 60 | for (var i = 0; i < 6; i++) { 61 | color += letters[Math.floor(Math.random() * 13)]; 62 | } 63 | this.hintColor = color; 64 | }; 65 | 66 | finish(form): void { 67 | this.http.post('/home/finish', form, { withCredentials: true }) 68 | .subscribe(result => { 69 | if (result.json().statusCode == 200) { 70 | Cookie.set('q_finished', 'yes'); 71 | this.router.navigateByUrl('results'); 72 | } 73 | else if (this.hasFinished) { 74 | Cookie.set('playerToken', ''); 75 | this.hasFinished = false; 76 | } 77 | }); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Startup.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using HabraQuest.Model; 3 | using Microsoft.AspNetCore.Builder; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.AspNetCore.SpaServices.Webpack; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.Extensions.Logging; 8 | using Newtonsoft.Json.Serialization; 9 | using Microsoft.EntityFrameworkCore; 10 | using Microsoft.Extensions.Configuration; 11 | 12 | 13 | namespace HabraQuest 14 | { 15 | public class Startup 16 | { 17 | public Startup(IHostingEnvironment env) 18 | { 19 | var builder = new ConfigurationBuilder() 20 | .SetBasePath(env.ContentRootPath) 21 | .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 22 | .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); 23 | 24 | builder.AddEnvironmentVariables(); 25 | Configuration = builder.Build(); 26 | } 27 | 28 | public IConfigurationRoot Configuration { get; } 29 | 30 | // This method gets called by the runtime. Use this method to add services to the container. 31 | public void ConfigureServices(IServiceCollection services) 32 | { 33 | services.AddDbContext(options => 34 | options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); 35 | 36 | services.AddMvc().AddJsonOptions(options => 37 | { 38 | options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 39 | }); 40 | } 41 | 42 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 43 | public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IHostingEnvironment env) 44 | { 45 | app.UseDeveloperExceptionPage(); 46 | 47 | if (env.IsDevelopment()) { 48 | app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions { 49 | HotModuleReplacement = true 50 | }); 51 | } 52 | 53 | app.UseStaticFiles(); 54 | loggerFactory.AddConsole(); 55 | app.UseMvc(routes => 56 | { 57 | routes.MapRoute( 58 | name: "default", 59 | template: "{controller=Home}/{action=Index}/{id?}"); 60 | 61 | routes.MapSpaFallbackRoute( 62 | name: "spa-fallback", 63 | defaults: new { controller = "Home", action = "Index" }); 64 | }); 65 | } 66 | 67 | public static void Main(string[] args) 68 | { 69 | var host = new WebHostBuilder() 70 | .UseContentRoot(Directory.GetCurrentDirectory()) 71 | .UseIISIntegration() 72 | .UseKestrel() 73 | .UseStartup() 74 | .Build(); 75 | 76 | host.Run(); 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Migrations/000000000000001_HQ.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Data.Entity; 2 | using Microsoft.Data.Entity.Metadata; 3 | using Microsoft.Data.Entity.Migrations; 4 | using Microsoft.Data.Entity.Migrations.Builders; 5 | using Microsoft.Data.Entity.Migrations.Infrastructure; 6 | 7 | namespace HabraQuest.Migrations 8 | { 9 | public partial class HQ : Migration 10 | { 11 | public override void Up(MigrationBuilder migrationBuilder) 12 | { 13 | migrationBuilder.CreateTable( 14 | "Progress", 15 | c => new 16 | { 17 | Id = c.Int(nullable: false, identity: true), 18 | Token = c.String(), 19 | TaskNumber = c.Int(nullable: false), 20 | }) 21 | .PrimaryKey("PK_Progress", t => t.Id); 22 | 23 | migrationBuilder.CreateTable( 24 | "QuestTask", 25 | c => new 26 | { 27 | Id = c.Int(nullable: false, identity: true), 28 | Title = c.String(), 29 | Content = c.String(), 30 | Number = c.Int(nullable: false), 31 | Answer = c.String(), 32 | }) 33 | .PrimaryKey("PK_QuestTask", t => t.Id); 34 | 35 | } 36 | 37 | public override void Down(MigrationBuilder migrationBuilder) 38 | { 39 | migrationBuilder.DropTable("QuestTask"); 40 | migrationBuilder.DropTable("Progress"); 41 | } 42 | } 43 | 44 | [ContextType(typeof (Models.ApplicationDbContext))] 45 | public partial class HQ : IMigrationMetadata 46 | { 47 | string IMigrationMetadata.MigrationId 48 | { 49 | get { return "000000000000001_HQ"; } 50 | } 51 | 52 | string IMigrationMetadata.ProductVersion 53 | { 54 | get { return "7.0.0-beta2"; } 55 | } 56 | 57 | IModel IMigrationMetadata.TargetModel 58 | { 59 | get 60 | { 61 | var builder = new BasicModelBuilder(); 62 | 63 | builder.Entity("HabraQuest.Models.Progress", b => 64 | { 65 | b.Property("Id"); 66 | b.Property("Token"); 67 | b.Property("TaskNumber"); 68 | b.Key("Id"); 69 | b.ForRelational().Table("Progress"); 70 | }); 71 | 72 | builder.Entity("HabraQuest.Models.QuestTask", b => 73 | { 74 | b.Property("Id"); 75 | b.Property("Title"); 76 | b.Property("Content"); 77 | b.Property("Number"); 78 | b.Property("Answer"); 79 | b.Key("Id"); 80 | b.ForRelational().Table("QuestTask"); 81 | }); 82 | 83 | return builder.Model; 84 | } 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | HabraQuest 9 | 10 | 25 | 26 | 27 | 28 | 48 |
49 |
50 |
51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /ClientApp/components/quest/quest.html: -------------------------------------------------------------------------------- 1 |
2 |

Loading...

3 |
4 |

5 | {{task.title}} 6 |

7 | 8 |

{{task.content}}

9 |
10 |
11 |
12 | 13 |
14 | Отправить 15 |
16 |
17 |
18 |
19 | {{feedback}} 20 |
21 |
22 |
23 |
24 |
25 |

Поздравляем, вы прошли все задания.

26 |
27 |
28 |
29 |
Вы можете вписать свое имя на доску почета
30 |
31 | 32 |
33 | 34 | 35 |
36 |
37 | 38 |
39 | 40 |
41 | 42 | 43 |
44 |
45 | 46 |
47 | 48 |
49 | 50 | 51 |
52 |
53 | 54 | Отправить 55 |
56 |
57 | 58 |
59 | 60 |
61 |
62 |
-------------------------------------------------------------------------------- /project.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "Microsoft.NETCore.App": { 4 | "version": "1.0.0", 5 | "type": "platform" 6 | }, 7 | "Microsoft.AspNetCore.Authentication.Cookies": "1.0.0", 8 | "Microsoft.AspNetCore.AngularServices": "1.0.0-*", 9 | "Microsoft.AspNetCore.Diagnostics": "1.0.0", 10 | "Microsoft.AspNetCore.Mvc": "1.0.0", 11 | "Microsoft.AspNetCore.Razor.Tools": { 12 | "version": "1.0.0-preview2-final", 13 | "type": "build" 14 | }, 15 | "Microsoft.AspNetCore.Server.IISIntegration": "1.0.0", 16 | "Microsoft.AspNetCore.Server.Kestrel": "1.0.0", 17 | "Microsoft.AspNetCore.StaticFiles": "1.0.0", 18 | "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", 19 | "Microsoft.Extensions.Configuration.Json": "1.0.0", 20 | "Microsoft.Extensions.Logging": "1.0.0", 21 | "Microsoft.Extensions.Logging.Console": "1.0.0", 22 | "Microsoft.Extensions.Logging.Debug": "1.0.0", 23 | "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { 24 | "version": "1.0.0-preview2-final", 25 | "type": "build" 26 | }, 27 | "Microsoft.VisualStudio.Web.CodeGenerators.Mvc": { 28 | "version": "1.0.0-preview2-final", 29 | "type": "build" 30 | }, 31 | "Microsoft.EntityFrameworkCore.SqlServer": "1.0.0", 32 | "Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final" 33 | }, 34 | 35 | "tools": { 36 | "Microsoft.AspNetCore.Razor.Tools": { 37 | "version": "1.0.0-preview2-final", 38 | "imports": "portable-net45+win8+dnxcore50" 39 | }, 40 | "Microsoft.AspNetCore.Server.IISIntegration.Tools": { 41 | "version": "1.0.0-preview2-final", 42 | "imports": "portable-net45+win8+dnxcore50" 43 | }, 44 | "Microsoft.EntityFrameworkCore.Tools": { 45 | "version": "1.0.0-preview2-final", 46 | "imports": [ 47 | "portable-net45+win8+dnxcore50", 48 | "portable-net45+win8" 49 | ] 50 | }, 51 | "Microsoft.Extensions.SecretManager.Tools": { 52 | "version": "1.0.0-preview2-final", 53 | "imports": "portable-net45+win8+dnxcore50" 54 | }, 55 | "Microsoft.VisualStudio.Web.CodeGeneration.Tools": { 56 | "version": "1.0.0-preview2-final", 57 | "imports": [ 58 | "portable-net45+win8+dnxcore50", 59 | "portable-net45+win8" 60 | ] 61 | }, 62 | "Microsoft.DotNet.Watcher.Tools": "1.0.0-preview2-final" 63 | }, 64 | 65 | "frameworks": { 66 | "netcoreapp1.0": { 67 | "imports": [ 68 | "dotnet5.6", 69 | "dnxcore50", 70 | "portable-net45+win8" 71 | ] 72 | } 73 | }, 74 | 75 | 76 | "exclude": ["archive"], 77 | 78 | "buildOptions": { 79 | "debugType": "portable", 80 | "emitEntryPoint": true, 81 | "preserveCompilationContext": true 82 | }, 83 | 84 | "runtimeOptions": { 85 | "configProperties": { 86 | "System.GC.Server": true 87 | } 88 | }, 89 | 90 | "publishOptions": { 91 | "include": [ 92 | "appsettings.json", 93 | "ClientApp", 94 | "node_modules", 95 | "typings", 96 | "Views", 97 | "tsconfig.json", 98 | "tsd.json", 99 | "web.config", 100 | "webpack.*.js", 101 | "wwwroot" 102 | ] 103 | }, 104 | 105 | "scripts": { 106 | "prepublish": [ 107 | "npm install", 108 | "node node_modules/webpack/bin/webpack.js --config webpack.config.vendor.js", 109 | "node node_modules/webpack/bin/webpack.js" 110 | ], 111 | "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] 112 | }, 113 | 114 | "tooling": { 115 | "defaultNamespace": "HabraQuest" 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Microsoft.AspNet.Builder; 4 | using Microsoft.AspNet.Diagnostics; 5 | using Microsoft.AspNet.Diagnostics.Entity; 6 | using Microsoft.AspNet.Hosting; 7 | using Microsoft.AspNet.Http; 8 | using Microsoft.AspNet.Identity; 9 | using Microsoft.AspNet.Routing; 10 | using Microsoft.AspNet.Security.Cookies; 11 | using Microsoft.Data.Entity; 12 | using Microsoft.Framework.ConfigurationModel; 13 | using Microsoft.Framework.DependencyInjection; 14 | using Microsoft.Framework.Logging; 15 | using Microsoft.Framework.Logging.Console; 16 | using HabraQuest.Models; 17 | using Microsoft.AspNet.Mvc; 18 | using Newtonsoft.Json.Serialization; 19 | 20 | namespace HabraQuest 21 | { 22 | public class Startup 23 | { 24 | public Startup(IHostingEnvironment env) 25 | { 26 | // Setup configuration sources. 27 | Configuration = new Configuration() 28 | .AddJsonFile("config.json") 29 | .AddEnvironmentVariables(); 30 | } 31 | 32 | public static IConfiguration Configuration { get; set; } 33 | 34 | // This method gets called by the runtime. 35 | public void ConfigureServices(IServiceCollection services) 36 | { 37 | // Add EF services to the services container. 38 | services.AddEntityFramework(Configuration) 39 | .AddSqlServer() 40 | .AddDbContext(options => options.UseSqlServer( 41 | Configuration.Get("Data:DefaultConnection:ConnectionString"))); 42 | 43 | // Add Identity services to the services container. 44 | services.AddIdentity(Configuration) 45 | .AddEntityFrameworkStores(); 46 | 47 | // Add MVC services to the services container. 48 | services.AddMvc().Configure(options => 49 | { 50 | options.OutputFormatters 51 | .Where(f => f.Instance is JsonOutputFormatter) 52 | .Select(f => f.Instance as JsonOutputFormatter) 53 | .First() 54 | .SerializerSettings 55 | .ContractResolver = new CamelCasePropertyNamesContractResolver(); 56 | }); 57 | 58 | // Uncomment the following line to add Web API servcies which makes it easier to port Web API 2 controllers. 59 | // You need to add Microsoft.AspNet.Mvc.WebApiCompatShim package to project.json 60 | // services.AddWebApiConventions(); 61 | 62 | } 63 | 64 | // Configure is called after ConfigureServices is called. 65 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory) 66 | { 67 | // Configure the HTTP request pipeline. 68 | // Add the console logger. 69 | loggerfactory.AddConsole(); 70 | 71 | // Add the following to the request pipeline only in development environment. 72 | if (string.Equals(env.EnvironmentName, "Development", StringComparison.OrdinalIgnoreCase)) 73 | { 74 | app.UseBrowserLink(); 75 | app.UseErrorPage(ErrorPageOptions.ShowAll); 76 | app.UseDatabaseErrorPage(DatabaseErrorPageOptions.ShowAll); 77 | } 78 | else 79 | { 80 | // Add Error handling middleware which catches all application specific errors and 81 | // send the request to the following path or controller action. 82 | app.UseErrorHandler("/Home/Error"); 83 | } 84 | 85 | // Add static files to the request pipeline. 86 | app.UseStaticFiles(); 87 | 88 | // Add cookie-based authentication to the request pipeline. 89 | app.UseIdentity(); 90 | 91 | // Add MVC to the request pipeline. 92 | app.UseMvc(routes => 93 | { 94 | routes.MapRoute( 95 | name: "default", 96 | template: "{controller}/{action}/{id?}" 97 | //defaults: new { controller = "Home", action = "Index" } 98 | ); 99 | 100 | // Uncomment the following line to add a route for porting Web API 2 controllers. 101 | // routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}"); 102 | }); 103 | } 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /Properties/launchSettings.json 2 | 3 | ## Ignore Visual Studio temporary files, build results, and 4 | ## files generated by popular Visual Studio add-ons. 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | build/ 23 | bld/ 24 | bin/ 25 | Bin/ 26 | obj/ 27 | Obj/ 28 | 29 | # Visual Studio 2015 cache/options directory 30 | .vs/ 31 | /wwwroot/dist/ 32 | 33 | # MSTest test Results 34 | [Tt]est[Rr]esult*/ 35 | [Bb]uild[Ll]og.* 36 | 37 | # NUNIT 38 | *.VisualState.xml 39 | TestResult.xml 40 | 41 | # Build Results of an ATL Project 42 | [Dd]ebugPS/ 43 | [Rr]eleasePS/ 44 | dlldata.c 45 | 46 | # DNX 47 | project.lock.json 48 | artifacts/ 49 | 50 | *_i.c 51 | *_p.c 52 | *_i.h 53 | *.ilk 54 | *.meta 55 | *.obj 56 | *.pch 57 | *.pdb 58 | *.pgc 59 | *.pgd 60 | *.rsp 61 | *.sbr 62 | *.tlb 63 | *.tli 64 | *.tlh 65 | *.tmp 66 | *.tmp_proj 67 | *.log 68 | *.vspscc 69 | *.vssscc 70 | .builds 71 | *.pidb 72 | *.svclog 73 | *.scc 74 | 75 | # Chutzpah Test files 76 | _Chutzpah* 77 | 78 | # Visual C++ cache files 79 | ipch/ 80 | *.aps 81 | *.ncb 82 | *.opendb 83 | *.opensdf 84 | *.sdf 85 | *.cachefile 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | *.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | 158 | # Microsoft Azure Build Output 159 | csx/ 160 | *.build.csdef 161 | 162 | # Microsoft Azure Emulator 163 | ecf/ 164 | rcf/ 165 | 166 | # Microsoft Azure ApplicationInsights config file 167 | ApplicationInsights.config 168 | 169 | # Windows Store app package directory 170 | AppPackages/ 171 | BundleArtifacts/ 172 | 173 | # Visual Studio cache files 174 | # files ending in .cache can be ignored 175 | *.[Cc]ache 176 | # but keep track of directories ending in .cache 177 | !*.[Cc]ache/ 178 | 179 | # Others 180 | ClientBin/ 181 | ~$* 182 | *~ 183 | *.dbmdl 184 | *.dbproj.schemaview 185 | *.pfx 186 | *.publishsettings 187 | node_modules/ 188 | orleans.codegen.cs 189 | 190 | # RIA/Silverlight projects 191 | Generated_Code/ 192 | 193 | # Backup & report files from converting an old project file 194 | # to a newer Visual Studio version. Backup files are not needed, 195 | # because we have git ;-) 196 | _UpgradeReport_Files/ 197 | Backup*/ 198 | UpgradeLog*.XML 199 | UpgradeLog*.htm 200 | 201 | # SQL Server files 202 | *.mdf 203 | *.ldf 204 | 205 | # Business Intelligence projects 206 | *.rdl.data 207 | *.bim.layout 208 | *.bim_*.settings 209 | 210 | # Microsoft Fakes 211 | FakesAssemblies/ 212 | 213 | # GhostDoc plugin setting file 214 | *.GhostDoc.xml 215 | 216 | # Node.js Tools for Visual Studio 217 | .ntvs_analysis.dat 218 | 219 | # Visual Studio 6 build log 220 | *.plg 221 | 222 | # Visual Studio 6 workspace options file 223 | *.opt 224 | 225 | # Visual Studio LightSwitch build output 226 | **/*.HTMLClient/GeneratedArtifacts 227 | **/*.DesktopClient/GeneratedArtifacts 228 | **/*.DesktopClient/ModelManifest.xml 229 | **/*.Server/GeneratedArtifacts 230 | **/*.Server/ModelManifest.xml 231 | _Pvt_Extensions 232 | 233 | # Paket dependency manager 234 | .paket/paket.exe 235 | 236 | # FAKE - F# Make 237 | .fake/ 238 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/app/start/start.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 'use strict'; 3 | var controllerId = 'start'; 4 | angular.module('app').controller(controllerId, ['$cookies', '$http', 'mainQuest', start]); 5 | 6 | function start($cookies, $http, mainQuestSvc) { 7 | var vm = this; 8 | vm.hints = ""; 9 | vm.answer = ""; 10 | vm.lastTask = false; 11 | vm.userToken = ""; 12 | vm.watched = "?"; 13 | vm.done = "?"; 14 | 15 | // set random color to hint 16 | var refreshHintStyle = function () { 17 | var letters = '0123456789ABC'.split(''); 18 | var color = '#'; 19 | for (var i = 0; i < 6; i++) { 20 | color += letters[Math.floor(Math.random() * 13)]; 21 | } 22 | vm.hintColor = color; 23 | }; 24 | 25 | function activate() { 26 | var tokenCookie = $cookies.token; 27 | if (tokenCookie) { 28 | vm.userToken = tokenCookie; 29 | } 30 | 31 | mainQuestSvc.Statistics().get({ token: vm.userToken }, function (result) { 32 | if (result && result.ok === "OK") { 33 | vm.watched = result.watched; 34 | vm.done = result.done; 35 | } 36 | }); 37 | 38 | mainQuestSvc.submitAnswer().get({ token: vm.userToken, taskNumberString: "-1" }, function (result) { 39 | if (result) { 40 | if (!result.task && result.isAnswerRight) { 41 | vm.lastTask = true; 42 | return; 43 | } 44 | if (result.task) { 45 | vm.taskId = result.task.number; 46 | vm.taskTitle = result.task.title; 47 | vm.taskContent = result.task.content; 48 | } 49 | vm.answer = ""; 50 | $cookies.token = result.token; 51 | vm.userToken = result.token; 52 | } 53 | }); 54 | }; 55 | 56 | activate(); 57 | 58 | vm.sendName = function () { 59 | var data = { "token": vm.userToken, "name": vm.name }; 60 | $http.post( 61 | '/api/statistics', 62 | JSON.stringify(data), 63 | { 64 | headers: { 65 | 'Content-Type': 'application/json' 66 | } 67 | } 68 | ).success(function (data) { 69 | vm.users = data; 70 | }); 71 | } 72 | 73 | vm.startAgain = function () { 74 | mainQuestSvc.submitAnswer().save({ token: vm.userToken, startAgaing: 'true' }); 75 | $cookies.token = null; 76 | vm.userToken = null; 77 | vm.taskId = 1; 78 | vm.taskTitle = "Первый"; 79 | vm.taskContent = "Какой уровень следующий?"; 80 | vm.hints = ""; 81 | vm.answer = ""; 82 | vm.lastTask = false; 83 | vm.userToken = ""; 84 | 85 | mainQuestSvc.Statistics().get({ token: vm.userToken }, function (result) { 86 | if (result && result.ok === "OK") { 87 | vm.watched = result.watched; 88 | vm.done = result.done; 89 | } else { 90 | alert('error'); 91 | } 92 | }); 93 | } 94 | 95 | vm.submit = function () { 96 | mainQuestSvc.submitAnswer().get({ token: vm.userToken, taskNumberString: vm.taskId, answer: vm.answer }, function (result) { 97 | if (result) { 98 | if (result.isAnswerRight) { 99 | if (!result.task) { 100 | vm.lastTask = true; 101 | return; 102 | } 103 | vm.taskId = result.task.number; 104 | vm.taskTitle = result.task.title; 105 | vm.taskContent = result.task.content; 106 | 107 | mainQuestSvc.Statistics().get({ token: vm.userToken }, function (result) { 108 | if (result && result.ok === "OK") { 109 | vm.watched = result.watched; 110 | vm.done = result.done; 111 | } else { 112 | alert('error'); 113 | } 114 | }); 115 | } else { 116 | vm.hints = "Ответ неверный."; 117 | refreshHintStyle(); 118 | } 119 | vm.answer = ""; 120 | } 121 | }); 122 | } 123 | } 124 | })(); 125 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | ** Unobtrusive validation support library for jQuery and jQuery Validate 3 | ** Copyright (C) Microsoft Corporation. All rights reserved. 4 | */ 5 | (function(a){var d=a.validator,b,e="unobtrusiveValidation";function c(a,b,c){a.rules[b]=c;if(a.message)a.messages[b]=a.message}function j(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function f(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function h(a){return a.substr(0,a.lastIndexOf(".")+1)}function g(a,b){if(a.indexOf("*.")===0)a=a.replace("*.",b);return a}function m(c,e){var b=a(this).find("[data-valmsg-for='"+f(e[0].name)+"']"),d=b.attr("data-valmsg-replace"),g=d?a.parseJSON(d)!==false:null;b.removeClass("field-validation-valid").addClass("field-validation-error");c.data("unobtrusiveContainer",b);if(g){b.empty();c.removeClass("input-validation-error").appendTo(b)}else c.hide()}function l(e,d){var c=a(this).find("[data-valmsg-summary=true]"),b=c.find("ul");if(b&&b.length&&d.errorList.length){b.empty();c.addClass("validation-summary-errors").removeClass("validation-summary-valid");a.each(d.errorList,function(){a("
  • ").html(this.message).appendTo(b)})}}function k(d){var b=d.data("unobtrusiveContainer"),c=b.attr("data-valmsg-replace"),e=c?a.parseJSON(c):null;if(b){b.addClass("field-validation-valid").removeClass("field-validation-error");d.removeData("unobtrusiveContainer");e&&b.empty()}}function n(){var b=a(this);b.data("validator").resetForm();b.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors");b.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}function i(b){var c=a(b),f=c.data(e),i=a.proxy(n,b),g=d.unobtrusive.options||{},h=function(e,d){var c=g[e];c&&a.isFunction(c)&&c.apply(b,d)};if(!f){f={options:{errorClass:g.errorClass||"input-validation-error",errorElement:g.errorElement||"span",errorPlacement:function(){m.apply(b,arguments);h("errorPlacement",arguments)},invalidHandler:function(){l.apply(b,arguments);h("invalidHandler",arguments)},messages:{},rules:{},success:function(){k.apply(b,arguments);h("success",arguments)}},attachValidation:function(){c.off("reset."+e,i).on("reset."+e,i).validate(this.options)},validate:function(){c.validate();return c.valid()}};c.data(e,f)}return f}d.unobtrusive={adapters:[],parseElement:function(b,h){var d=a(b),f=d.parents("form")[0],c,e,g;if(!f)return;c=i(f);c.options.rules[b.name]=e={};c.options.messages[b.name]=g={};a.each(this.adapters,function(){var c="data-val-"+this.name,i=d.attr(c),h={};if(i!==undefined){c+="-";a.each(this.params,function(){h[this]=d.attr(c+this)});this.adapt({element:b,form:f,message:i,params:h,rules:e,messages:g})}});a.extend(e,{__dummy__:true});!h&&c.attachValidation()},parse:function(c){var b=a(c),e=b.parents().addBack().filter("form").add(b.find("form")).has("[data-val=true]");b.find("[data-val=true]").each(function(){d.unobtrusive.parseElement(this,true)});e.each(function(){var a=i(this);a&&a.attachValidation()})}};b=d.unobtrusive.adapters;b.add=function(c,a,b){if(!b){b=a;a=[]}this.push({name:c,params:a,adapt:b});return this};b.addBool=function(a,b){return this.add(a,function(d){c(d,b||a,true)})};b.addMinMax=function(e,g,f,a,d,b){return this.add(e,[d||"min",b||"max"],function(b){var e=b.params.min,d=b.params.max;if(e&&d)c(b,a,[e,d]);else if(e)c(b,g,e);else d&&c(b,f,d)})};b.addSingleVal=function(a,b,d){return this.add(a,[b||"val"],function(e){c(e,d||a,e.params[b])})};d.addMethod("__dummy__",function(){return true});d.addMethod("regex",function(b,c,d){var a;if(this.optional(c))return true;a=(new RegExp(d)).exec(b);return a&&a.index===0&&a[0].length===b.length});d.addMethod("nonalphamin",function(c,d,b){var a;if(b){a=c.match(/\W/g);a=a&&a.length>=b}return a});if(d.methods.extension){b.addSingleVal("accept","mimtype");b.addSingleVal("extension","extension")}else b.addSingleVal("extension","extension","accept");b.addSingleVal("regex","pattern");b.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");b.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range");b.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength");b.add("equalto",["other"],function(b){var i=h(b.element.name),j=b.params.other,d=g(j,i),e=a(b.form).find(":input").filter("[name='"+f(d)+"']")[0];c(b,"equalTo",e)});b.add("required",function(a){(a.element.tagName.toUpperCase()!=="INPUT"||a.element.type.toUpperCase()!=="CHECKBOX")&&c(a,"required",true)});b.add("remote",["url","type","additionalfields"],function(b){var d={url:b.params.url,type:b.params.type||"GET",data:{}},e=h(b.element.name);a.each(j(b.params.additionalfields||b.element.name),function(i,h){var c=g(h,e);d.data[c]=function(){return a(b.form).find(":input").filter("[name='"+f(c)+"']").val()}});c(b,"remote",d)});b.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&c(a,"minlength",a.params.min);a.params.nonalphamin&&c(a,"nonalphamin",a.params.nonalphamin);a.params.regex&&c(a,"regex",a.params.regex)});a(function(){d.unobtrusive.parse(document)})})(jQuery); -------------------------------------------------------------------------------- /Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using HabraQuest.Model; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace HabraQuest.Controllers 8 | { 9 | public class HomeController : Controller 10 | { 11 | private readonly DataContext dataContext; 12 | 13 | public HomeController(DataContext db) 14 | { 15 | dataContext = db; 16 | } 17 | 18 | public IActionResult Index() 19 | { 20 | return View(); 21 | } 22 | 23 | public IActionResult Error() 24 | { 25 | return View(); 26 | } 27 | 28 | [HttpPost] 29 | public dynamic Finish([FromBody]FinishForm form) 30 | { 31 | var token = Request.Cookies["playerToken"]; 32 | if (token == null) 33 | { 34 | return BadRequest("something went wrong"); 35 | } 36 | 37 | var player = dataContext.Players.SingleOrDefault(p => p.Token.ToString() == token); 38 | if (player == null || !player.HasFinished || !string.IsNullOrEmpty(player.Name)) 39 | { 40 | return BadRequest("something went wrong"); 41 | } 42 | 43 | player.Name = form.Name; 44 | player.Comment = form.Message; 45 | player.Email = form.Email; 46 | dataContext.SaveChanges(); 47 | 48 | return new OkResult(); 49 | } 50 | 51 | public dynamic GetCurrentState() 52 | { 53 | try 54 | { 55 | Player player = GetOrInitPlayer(); 56 | var task = dataContext.Tasks.Single(t => t.Id == player.TaskNumber); 57 | 58 | return new ReturnResult(task, player); 59 | } 60 | catch (Exception ex) 61 | { 62 | //to do: log error 63 | return Json(new { status = "error", message = ex.Message }); 64 | } 65 | 66 | } 67 | 68 | public dynamic SubmitAnswer(string answer) 69 | { 70 | var token = Request.Cookies["playerToken"]; 71 | if (token == null) 72 | { 73 | return BadRequest("something went wrong"); 74 | } 75 | 76 | var player = dataContext.Players.Single(p => p.Token.ToString() == token); 77 | var task = dataContext.Tasks.Single(t => t.Id == player.TaskNumber); 78 | if (!string.IsNullOrEmpty(answer) && task.Answers.Split(',').Contains(answer.ToLower())) 79 | { 80 | var nextTask = dataContext.Tasks.SingleOrDefault(t => t.Id == task.Id + 1); 81 | if (nextTask == null) 82 | { 83 | player.HasFinished = true; 84 | dataContext.SaveChanges(); 85 | 86 | return new ReturnResult(task, player); 87 | } 88 | 89 | player.TaskNumber++; 90 | dataContext.SaveChanges(); 91 | 92 | return new ReturnResult(nextTask, player, GetPositiveFeedback()); 93 | } 94 | 95 | return new ReturnResult(task, player, GetNegativeFeedback()); 96 | } 97 | 98 | readonly Random rnd = new Random(); 99 | private readonly string[] negatives = { "Нет.", "неа", "не верно", "Ответ не правильный", "Мимо" }; 100 | private readonly string[] positives = { "Да!", "Правильно", "Верно", "Ответ принят", "Правильно" }; 101 | private string GetNegativeFeedback() 102 | { 103 | return negatives[rnd.Next(0, 5)]; 104 | } 105 | 106 | private string GetPositiveFeedback() 107 | { 108 | return positives[rnd.Next(0, 5)]; 109 | } 110 | 111 | private Player GetOrInitPlayer(string token = null) 112 | { 113 | Player player = null; 114 | if (token == null) token = Request.Cookies["playerToken"]; 115 | if (token == null) 116 | { 117 | player = new Player 118 | { 119 | Token = Guid.NewGuid(), 120 | TaskNumber = 1 121 | }; 122 | 123 | dataContext.Add(player); 124 | dataContext.SaveChanges(); 125 | } 126 | 127 | return player ?? dataContext.Players.Single(p => p.Token.ToString() == token); 128 | } 129 | } 130 | 131 | public class ReturnResult 132 | { 133 | public dynamic Task { get; set; } 134 | public dynamic Player { get; set; } 135 | public string Feedback { get; set; } 136 | public ReturnResult(QuestTask task, Player player, string feedback = "") 137 | { 138 | Task = new 139 | { 140 | task.Content, task.Title 141 | }; 142 | 143 | Player = new 144 | { 145 | player.Name, 146 | player.Comment, 147 | player.HasFinished, 148 | player.TaskNumber, 149 | player.Token 150 | }; 151 | 152 | Feedback = feedback; 153 | } 154 | } 155 | 156 | public class FinishForm 157 | { 158 | public string Name { get; set; } 159 | public string Message { get; set; } 160 | public string Email { get; set; } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Controllers/AccountController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Security.Principal; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNet.Identity; 7 | using Microsoft.AspNet.Mvc; 8 | using HabraQuest.Models; 9 | 10 | namespace HabraQuest.Controllers 11 | { 12 | [Authorize] 13 | public class AccountController : Controller 14 | { 15 | public AccountController(UserManager userManager, SignInManager signInManager) 16 | { 17 | UserManager = userManager; 18 | SignInManager = signInManager; 19 | } 20 | 21 | public UserManager UserManager { get; private set; } 22 | public SignInManager SignInManager { get; private set; } 23 | 24 | // GET: /Account/Login 25 | [HttpGet] 26 | [AllowAnonymous] 27 | public IActionResult Login(string returnUrl = null) 28 | { 29 | ViewBag.ReturnUrl = returnUrl; 30 | return View(); 31 | } 32 | 33 | // 34 | // POST: /Account/Login 35 | [HttpPost] 36 | [AllowAnonymous] 37 | [ValidateAntiForgeryToken] 38 | public async Task Login(LoginViewModel model, string returnUrl = null) 39 | { 40 | if (ModelState.IsValid) 41 | { 42 | var signInStatus = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false); 43 | switch (signInStatus) 44 | { 45 | case SignInStatus.Success: 46 | return RedirectToLocal(returnUrl); 47 | case SignInStatus.Failure: 48 | default: 49 | ModelState.AddModelError("", "Invalid username or password."); 50 | return View(model); 51 | } 52 | } 53 | 54 | // If we got this far, something failed, redisplay form 55 | return View(model); 56 | } 57 | 58 | // 59 | // GET: /Account/Register 60 | [AllowAnonymous] 61 | [HttpGet] 62 | public IActionResult Register() 63 | { 64 | return View(); 65 | } 66 | 67 | // 68 | // POST: /Account/Register 69 | [HttpPost] 70 | [AllowAnonymous] 71 | [ValidateAntiForgeryToken] 72 | public async Task Register(RegisterViewModel model) 73 | { 74 | if (ModelState.IsValid) 75 | { 76 | var user = new ApplicationUser { UserName = model.UserName }; 77 | var result = await UserManager.CreateAsync(user, model.Password); 78 | if (result.Succeeded) 79 | { 80 | await SignInManager.SignInAsync(user, isPersistent: false); 81 | return RedirectToAction("Index", "Home"); 82 | } 83 | else 84 | { 85 | AddErrors(result); 86 | } 87 | } 88 | 89 | // If we got this far, something failed, redisplay form 90 | return View(model); 91 | } 92 | 93 | // 94 | // GET: /Account/Manage 95 | [HttpGet] 96 | public IActionResult Manage(ManageMessageId? message = null) 97 | { 98 | ViewBag.StatusMessage = 99 | message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed." 100 | : message == ManageMessageId.Error ? "An error has occurred." 101 | : ""; 102 | ViewBag.ReturnUrl = Url.Action("Manage"); 103 | return View(); 104 | } 105 | 106 | // 107 | // POST: /Account/Manage 108 | [HttpPost] 109 | [ValidateAntiForgeryToken] 110 | public async Task Manage(ManageUserViewModel model) 111 | { 112 | ViewBag.ReturnUrl = Url.Action("Manage"); 113 | if (ModelState.IsValid) 114 | { 115 | var user = await GetCurrentUserAsync(); 116 | var result = await UserManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword); 117 | if (result.Succeeded) 118 | { 119 | return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess }); 120 | } 121 | else 122 | { 123 | AddErrors(result); 124 | } 125 | } 126 | 127 | // If we got this far, something failed, redisplay form 128 | return View(model); 129 | } 130 | 131 | // 132 | // POST: /Account/LogOff 133 | [HttpPost] 134 | [ValidateAntiForgeryToken] 135 | public IActionResult LogOff() 136 | { 137 | SignInManager.SignOut(); 138 | return RedirectToAction("Index", "Home"); 139 | } 140 | 141 | #region Helpers 142 | 143 | private void AddErrors(IdentityResult result) 144 | { 145 | foreach (var error in result.Errors) 146 | { 147 | ModelState.AddModelError("", error); 148 | } 149 | } 150 | 151 | private async Task GetCurrentUserAsync() 152 | { 153 | return await UserManager.FindByIdAsync(Context.User.Identity.GetUserId()); 154 | } 155 | 156 | public enum ManageMessageId 157 | { 158 | ChangePasswordSuccess, 159 | Error 160 | } 161 | 162 | private IActionResult RedirectToLocal(string returnUrl) 163 | { 164 | if (Url.IsLocalUrl(returnUrl)) 165 | { 166 | return Redirect(returnUrl); 167 | } 168 | else 169 | { 170 | return RedirectToAction("Index", "Home"); 171 | } 172 | } 173 | #endregion 174 | } 175 | } -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Controllers/QuestController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using HabraQuest.Models; 4 | using Microsoft.AspNet.Mvc; 5 | 6 | namespace HabraQuest.Controllers 7 | { 8 | [AllowAnonymous] 9 | [Route("api/[controller]")] 10 | public class QuestController : Controller 11 | { 12 | // GET api/MainQuest 13 | [HttpGet] 14 | public MainQuestViewModel Get(string token, string taskNumberString, string answer) 15 | { 16 | int taskNumber; 17 | if (token == "null") token = null; 18 | if (!string.IsNullOrEmpty(taskNumberString) && int.TryParse(taskNumberString, out taskNumber)) 19 | { 20 | using (var db = new ApplicationDbContext()) 21 | { 22 | if (taskNumber == -1) 23 | { 24 | if (string.IsNullOrEmpty(token)) 25 | { 26 | token = Guid.NewGuid().ToString(); 27 | db.Progress.Add(new Progress { TaskNumber = 1, Token = token }); 28 | db.SaveChanges(); 29 | 30 | return new MainQuestViewModel 31 | { 32 | Task = new Task 33 | { 34 | Number = 1, 35 | Title = "Первый", 36 | Content = "Какой уровень следующий?" 37 | }, 38 | Token = token 39 | }; 40 | } 41 | } 42 | 43 | if (string.IsNullOrEmpty(token)) return null; 44 | 45 | var current = db.Progress.FirstOrDefault(_ => _.Token == token); 46 | if (current == null || (current.TaskNumber != taskNumber && taskNumber != -1)) 47 | { 48 | return new MainQuestViewModel 49 | { 50 | IsAnswerRight = false, 51 | Task = null, 52 | Token = null 53 | }; 54 | } 55 | 56 | // if user already finished 57 | if (current.TaskNumber == 999) 58 | return new MainQuestViewModel 59 | { 60 | IsAnswerRight = true, 61 | Task = null, 62 | Token = token 63 | }; 64 | 65 | // check if the answer is right or get last task for user 66 | var isRight = taskNumber == -1; 67 | if (!isRight) 68 | { 69 | var task = db.QuestTask.SingleOrDefault(_ => _.Number == taskNumber); 70 | if (task != null) 71 | { 72 | isRight = task.Answer.Split(',').Contains(answer?.ToLower() ?? ""); 73 | } 74 | } 75 | 76 | var nextTask = GetNextTask(db, isRight, taskNumber, current); 77 | 78 | var progress = db.Progress.SingleOrDefault(_ => _.Token == token); 79 | if (progress == null) return null; 80 | 81 | // save user progress 82 | if (isRight) 83 | { 84 | progress.TaskNumber = nextTask?.Number ?? 999; 85 | db.SaveChanges(); 86 | } 87 | 88 | return new MainQuestViewModel 89 | { 90 | IsAnswerRight = isRight, 91 | Task = nextTask, 92 | Token = token 93 | }; 94 | } 95 | } 96 | 97 | return null; 98 | } 99 | 100 | // POST api/MainQuest 101 | [HttpPost] 102 | public void Post([FromBody]StartAgainRequest startAgainRequest) 103 | { 104 | if (startAgainRequest != null && startAgainRequest.StartAgaing) 105 | { 106 | using (var db = new ApplicationDbContext()) 107 | { 108 | var progress = db.Progress.SingleOrDefault(_ => startAgainRequest != null && _.Token == startAgainRequest.Token); 109 | if (progress != null) 110 | { 111 | progress.TaskNumber = 1; 112 | db.SaveChanges(); 113 | } 114 | } 115 | } 116 | } 117 | 118 | private Task GetNextTask(ApplicationDbContext db, bool isRight, int taskNumber, Progress current) 119 | { 120 | QuestTask nextTask = null; 121 | if (taskNumber == -1) 122 | { 123 | nextTask = db.QuestTask.SingleOrDefault(_ => _.Number == current.TaskNumber); 124 | } 125 | else if (isRight) 126 | { 127 | nextTask = db.QuestTask.FirstOrDefault(t => t.Id > taskNumber); 128 | } 129 | 130 | return nextTask != null 131 | ? new Task 132 | { 133 | Number = nextTask.Number, 134 | Title = nextTask.Title, 135 | Content = nextTask.Content 136 | } 137 | : null; 138 | } 139 | } 140 | 141 | public class StartAgainRequest 142 | { 143 | public string Token { get; set; } 144 | public bool StartAgaing { get; set; } 145 | } 146 | 147 | public class MainQuestViewModel 148 | { 149 | public bool IsAnswerRight { get; set; } 150 | public Task Task { get; set; } 151 | public string Token { get; set; } 152 | } 153 | 154 | public class Task 155 | { 156 | public int Number { get; set; } 157 | public string Title { get; set; } 158 | public string Content { get; set; } 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/Migrations/000000000000000_CreateIdentitySchema.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.Data.Entity; 3 | using Microsoft.Data.Entity.Metadata; 4 | using Microsoft.Data.Entity.Migrations; 5 | using Microsoft.Data.Entity.Migrations.Builders; 6 | using Microsoft.Data.Entity.Migrations.Infrastructure; 7 | 8 | namespace HabraQuest.Migrations 9 | { 10 | public partial class CreateIdentitySchema : Migration 11 | { 12 | public override void Up(MigrationBuilder migrationBuilder) 13 | { 14 | migrationBuilder.CreateTable("AspNetRoles", 15 | c => new 16 | { 17 | Id = c.String(), 18 | Name = c.String() 19 | }) 20 | .PrimaryKey("PK_AspNetRoles", t => t.Id); 21 | 22 | migrationBuilder.CreateTable("AspNetRoleClaims", 23 | c => new 24 | { 25 | Id = c.Int(nullable: false, identity: true), 26 | ClaimType = c.String(), 27 | ClaimValue = c.String(), 28 | RoleId = c.String() 29 | }) 30 | .PrimaryKey("PK_AspNetRoleClaims", t => t.Id); 31 | 32 | migrationBuilder.CreateTable("AspNetUserClaims", 33 | c => new 34 | { 35 | Id = c.Int(nullable: false, identity: true), 36 | ClaimType = c.String(), 37 | ClaimValue = c.String(), 38 | UserId = c.String() 39 | }) 40 | .PrimaryKey("PK_AspNetUserClaims", t => t.Id); 41 | 42 | migrationBuilder.CreateTable("AspNetUserLogins", 43 | c => new 44 | { 45 | LoginProvider = c.String(), 46 | ProviderKey = c.String(), 47 | ProviderDisplayName = c.String(), 48 | UserId = c.String() 49 | }) 50 | .PrimaryKey("PK_AspNetUserLogins", t => new { t.LoginProvider, t.ProviderKey }); 51 | 52 | migrationBuilder.CreateTable("AspNetUserRoles", 53 | c => new 54 | { 55 | UserId = c.String(), 56 | RoleId = c.String() 57 | }) 58 | .PrimaryKey("PK_AspNetUserRoles", t => new { t.UserId, t.RoleId }); 59 | 60 | migrationBuilder.CreateTable("AspNetUsers", 61 | c => new 62 | { 63 | Id = c.String(), 64 | AccessFailedCount = c.Int(nullable: false), 65 | Email = c.String(), 66 | EmailConfirmed = c.Boolean(nullable: false), 67 | LockoutEnabled = c.Boolean(nullable: false), 68 | LockoutEnd = c.DateTimeOffset(), 69 | NormalizedUserName = c.String(), 70 | PasswordHash = c.String(), 71 | PhoneNumber = c.String(), 72 | PhoneNumberConfirmed = c.Boolean(nullable: false), 73 | SecurityStamp = c.String(), 74 | TwoFactorEnabled = c.Boolean(nullable: false), 75 | UserName = c.String() 76 | }) 77 | .PrimaryKey("PK_AspNetUsers", t => t.Id); 78 | 79 | migrationBuilder.AddForeignKey( 80 | "AspNetRoleClaims", 81 | "FK_AspNetRoleClaims_AspNetRoles_RoleId", 82 | new[] { "RoleId" }, 83 | "AspNetRoles", 84 | new[] { "Id" }, 85 | cascadeDelete: false); 86 | 87 | migrationBuilder.AddForeignKey( 88 | "AspNetUserClaims", 89 | "FK_AspNetUserClaims_AspNetUsers_UserId", 90 | new[] { "UserId" }, "AspNetUsers", 91 | new[] { "Id" }, 92 | cascadeDelete: false); 93 | 94 | migrationBuilder.AddForeignKey( 95 | "AspNetUserLogins", 96 | "FK_AspNetUserLogins_AspNetUsers_UserId", 97 | new[] { "UserId" }, 98 | "AspNetUsers", 99 | new[] { "Id" }, 100 | cascadeDelete: false); 101 | } 102 | 103 | public override void Down(MigrationBuilder migrationBuilder) 104 | { 105 | migrationBuilder.DropForeignKey("AspNetRoleClaims", "FK_AspNetRoleClaims_AspNetRoles_RoleId"); 106 | 107 | migrationBuilder.DropForeignKey("AspNetUserClaims", "FK_AspNetUserClaims_AspNetUsers_UserId"); 108 | 109 | migrationBuilder.DropForeignKey("AspNetUserLogins", "FK_AspNetUserLogins_AspNetUsers_UserId"); 110 | 111 | migrationBuilder.DropTable("AspNetRoles"); 112 | 113 | migrationBuilder.DropTable("AspNetRoleClaims"); 114 | 115 | migrationBuilder.DropTable("AspNetUserClaims"); 116 | 117 | migrationBuilder.DropTable("AspNetUserLogins"); 118 | 119 | migrationBuilder.DropTable("AspNetUserRoles"); 120 | 121 | migrationBuilder.DropTable("AspNetUsers"); 122 | } 123 | } 124 | 125 | [ContextType(typeof(Models.ApplicationDbContext))] 126 | public partial class CreateIdentitySchema : IMigrationMetadata 127 | { 128 | string IMigrationMetadata.MigrationId 129 | { 130 | get 131 | { 132 | return "000000000000000_CreateIdentitySchema"; 133 | } 134 | } 135 | 136 | string IMigrationMetadata.ProductVersion 137 | { 138 | get 139 | { 140 | return "7.0.0-beta2"; 141 | } 142 | } 143 | 144 | IModel IMigrationMetadata.TargetModel 145 | { 146 | get 147 | { 148 | var builder = new BasicModelBuilder(); 149 | 150 | builder.Entity("Microsoft.AspNet.Identity.IdentityRole", b => 151 | { 152 | b.Property("Id"); 153 | b.Property("Name"); 154 | b.Key("Id"); 155 | b.ForRelational().Table("AspNetRoles"); 156 | }); 157 | 158 | builder.Entity("Microsoft.AspNet.Identity.IdentityRoleClaim`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", b => 159 | { 160 | b.Property("ClaimType"); 161 | b.Property("ClaimValue"); 162 | b.Property("Id") 163 | .GenerateValueOnAdd(); 164 | b.Property("RoleId"); 165 | b.Key("Id"); 166 | b.ForRelational().Table("AspNetRoleClaims"); 167 | }); 168 | 169 | builder.Entity("Microsoft.AspNet.Identity.IdentityUserClaim`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", b => 170 | { 171 | b.Property("ClaimType"); 172 | b.Property("ClaimValue"); 173 | b.Property("Id") 174 | .GenerateValueOnAdd(); 175 | b.Property("UserId"); 176 | b.Key("Id"); 177 | b.ForRelational().Table("AspNetUserClaims"); 178 | }); 179 | 180 | builder.Entity("Microsoft.AspNet.Identity.IdentityUserLogin`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", b => 181 | { 182 | b.Property("LoginProvider"); 183 | b.Property("ProviderDisplayName"); 184 | b.Property("ProviderKey"); 185 | b.Property("UserId"); 186 | b.Key("LoginProvider", "ProviderKey"); 187 | b.ForRelational().Table("AspNetUserLogins"); 188 | }); 189 | 190 | builder.Entity("Microsoft.AspNet.Identity.IdentityUserRole`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", b => 191 | { 192 | b.Property("RoleId"); 193 | b.Property("UserId"); 194 | b.Key("UserId", "RoleId"); 195 | b.ForRelational().Table("AspNetUserRoles"); 196 | }); 197 | 198 | builder.Entity("HabraQuest.Models.ApplicationUser", b => 199 | { 200 | b.Property("AccessFailedCount"); 201 | b.Property("Email"); 202 | b.Property("EmailConfirmed"); 203 | b.Property("Id"); 204 | b.Property("LockoutEnabled"); 205 | b.Property("LockoutEnd"); 206 | b.Property("NormalizedUserName"); 207 | b.Property("PasswordHash"); 208 | b.Property("PhoneNumber"); 209 | b.Property("PhoneNumberConfirmed"); 210 | b.Property("SecurityStamp"); 211 | b.Property("TwoFactorEnabled"); 212 | b.Property("UserName"); 213 | b.Key("Id"); 214 | b.ForRelational().Table("AspNetUsers"); 215 | }); 216 | 217 | builder.Entity("Microsoft.AspNet.Identity.IdentityRoleClaim`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", b => 218 | { 219 | b.ForeignKey("Microsoft.AspNet.Identity.IdentityRole", "RoleId"); 220 | }); 221 | 222 | builder.Entity("Microsoft.AspNet.Identity.IdentityUserClaim`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", b => 223 | { 224 | b.ForeignKey("HabraQuest.Models.ApplicationUser", "UserId"); 225 | }); 226 | 227 | builder.Entity("Microsoft.AspNet.Identity.IdentityUserLogin`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", b => 228 | { 229 | b.ForeignKey("HabraQuest.Models.ApplicationUser", "UserId"); 230 | }); 231 | 232 | return builder.Model; 233 | } 234 | } 235 | } 236 | } -------------------------------------------------------------------------------- /typings/requirejs/require.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for RequireJS 2.1.20 2 | // Project: http://requirejs.org/ 3 | // Definitions by: Josh Baldwin 4 | // Definitions: https://github.com/borisyankov/DefinitelyTyped 5 | 6 | /* 7 | require-2.1.8.d.ts may be freely distributed under the MIT license. 8 | 9 | Copyright (c) 2013 Josh Baldwin https://github.com/jbaldwin/require.d.ts 10 | 11 | Permission is hereby granted, free of charge, to any person 12 | obtaining a copy of this software and associated documentation 13 | files (the "Software"), to deal in the Software without 14 | restriction, including without limitation the rights to use, 15 | copy, modify, merge, publish, distribute, sublicense, and/or sell 16 | copies of the Software, and to permit persons to whom the 17 | Software is furnished to do so, subject to the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be 20 | included in all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 24 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 26 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 27 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 28 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 29 | OTHER DEALINGS IN THE SOFTWARE. 30 | */ 31 | 32 | declare module 'module' { 33 | var mod: { 34 | config: () => any; 35 | id: string; 36 | uri: string; 37 | } 38 | export = mod; 39 | } 40 | 41 | interface RequireError extends Error { 42 | 43 | /** 44 | * The error ID that maps to an ID on a web page. 45 | **/ 46 | requireType: string; 47 | 48 | /** 49 | * Required modules. 50 | **/ 51 | requireModules: string[]; 52 | 53 | /** 54 | * The original error, if there is one (might be null). 55 | **/ 56 | originalError: Error; 57 | } 58 | 59 | interface RequireShim { 60 | 61 | /** 62 | * List of dependencies. 63 | **/ 64 | deps?: string[]; 65 | 66 | /** 67 | * Name the module will be exported as. 68 | **/ 69 | exports?: string; 70 | 71 | /** 72 | * Initialize function with all dependcies passed in, 73 | * if the function returns a value then that value is used 74 | * as the module export value instead of the object 75 | * found via the 'exports' string. 76 | * @param dependencies 77 | * @return 78 | **/ 79 | init?: (...dependencies: any[]) => any; 80 | } 81 | 82 | interface RequireConfig { 83 | 84 | // The root path to use for all module lookups. 85 | baseUrl?: string; 86 | 87 | // Path mappings for module names not found directly under 88 | // baseUrl. 89 | paths?: { [key: string]: any; }; 90 | 91 | 92 | // Dictionary of Shim's. 93 | // does not cover case of key->string[] 94 | shim?: { [key: string]: RequireShim; }; 95 | 96 | /** 97 | * For the given module prefix, instead of loading the 98 | * module with the given ID, substitude a different 99 | * module ID. 100 | * 101 | * @example 102 | * requirejs.config({ 103 | * map: { 104 | * 'some/newmodule': { 105 | * 'foo': 'foo1.2' 106 | * }, 107 | * 'some/oldmodule': { 108 | * 'foo': 'foo1.0' 109 | * } 110 | * } 111 | * }); 112 | **/ 113 | map?: { 114 | [id: string]: { 115 | [id: string]: string; 116 | }; 117 | }; 118 | 119 | /** 120 | * Allows pointing multiple module IDs to a module ID that contains a bundle of modules. 121 | * 122 | * @example 123 | * requirejs.config({ 124 | * bundles: { 125 | * 'primary': ['main', 'util', 'text', 'text!template.html'], 126 | * 'secondary': ['text!secondary.html'] 127 | * } 128 | * }); 129 | **/ 130 | bundles?: { [key: string]: string[]; }; 131 | 132 | /** 133 | * AMD configurations, use module.config() to access in 134 | * define() functions 135 | **/ 136 | config?: { [id: string]: {}; }; 137 | 138 | /** 139 | * Configures loading modules from CommonJS packages. 140 | **/ 141 | packages?: {}; 142 | 143 | /** 144 | * The number of seconds to wait before giving up on loading 145 | * a script. The default is 7 seconds. 146 | **/ 147 | waitSeconds?: number; 148 | 149 | /** 150 | * A name to give to a loading context. This allows require.js 151 | * to load multiple versions of modules in a page, as long as 152 | * each top-level require call specifies a unique context string. 153 | **/ 154 | context?: string; 155 | 156 | /** 157 | * An array of dependencies to load. 158 | **/ 159 | deps?: string[]; 160 | 161 | /** 162 | * A function to pass to require that should be require after 163 | * deps have been loaded. 164 | * @param modules 165 | **/ 166 | callback?: (...modules: any[]) => void; 167 | 168 | /** 169 | * If set to true, an error will be thrown if a script loads 170 | * that does not call define() or have shim exports string 171 | * value that can be checked. 172 | **/ 173 | enforceDefine?: boolean; 174 | 175 | /** 176 | * If set to true, document.createElementNS() will be used 177 | * to create script elements. 178 | **/ 179 | xhtml?: boolean; 180 | 181 | /** 182 | * Extra query string arguments appended to URLs that RequireJS 183 | * uses to fetch resources. Most useful to cache bust when 184 | * the browser or server is not configured correctly. 185 | * 186 | * @example 187 | * urlArgs: "bust= + (new Date()).getTime() 188 | **/ 189 | urlArgs?: string; 190 | 191 | /** 192 | * Specify the value for the type="" attribute used for script 193 | * tags inserted into the document by RequireJS. Default is 194 | * "text/javascript". To use Firefox's JavasScript 1.8 195 | * features, use "text/javascript;version=1.8". 196 | **/ 197 | scriptType?: string; 198 | 199 | /** 200 | * If set to true, skips the data-main attribute scanning done 201 | * to start module loading. Useful if RequireJS is embedded in 202 | * a utility library that may interact with other RequireJS 203 | * library on the page, and the embedded version should not do 204 | * data-main loading. 205 | **/ 206 | skipDataMain?: boolean; 207 | 208 | /** 209 | * Allow extending requirejs to support Subresource Integrity 210 | * (SRI). 211 | **/ 212 | onNodeCreated?: (node: HTMLScriptElement, config: RequireConfig, moduleName: string, url: string) => void; 213 | } 214 | 215 | // todo: not sure what to do with this guy 216 | interface RequireModule { 217 | 218 | /** 219 | * 220 | **/ 221 | config(): {}; 222 | 223 | } 224 | 225 | /** 226 | * 227 | **/ 228 | interface RequireMap { 229 | 230 | /** 231 | * 232 | **/ 233 | prefix: string; 234 | 235 | /** 236 | * 237 | **/ 238 | name: string; 239 | 240 | /** 241 | * 242 | **/ 243 | parentMap: RequireMap; 244 | 245 | /** 246 | * 247 | **/ 248 | url: string; 249 | 250 | /** 251 | * 252 | **/ 253 | originalName: string; 254 | 255 | /** 256 | * 257 | **/ 258 | fullName: string; 259 | } 260 | 261 | interface Require { 262 | 263 | /** 264 | * Configure require.js 265 | **/ 266 | config(config: RequireConfig): Require; 267 | 268 | /** 269 | * CommonJS require call 270 | * @param module Module to load 271 | * @return The loaded module 272 | */ 273 | (module: string): any; 274 | 275 | /** 276 | * Start the main app logic. 277 | * Callback is optional. 278 | * Can alternatively use deps and callback. 279 | * @param modules Required modules to load. 280 | **/ 281 | (modules: string[]): void; 282 | 283 | /** 284 | * @see Require() 285 | * @param ready Called when required modules are ready. 286 | **/ 287 | (modules: string[], ready: Function): void; 288 | 289 | /** 290 | * @see http://requirejs.org/docs/api.html#errbacks 291 | * @param ready Called when required modules are ready. 292 | **/ 293 | (modules: string[], ready: Function, errback: Function): void; 294 | 295 | /** 296 | * Generate URLs from require module 297 | * @param module Module to URL 298 | * @return URL string 299 | **/ 300 | toUrl(module: string): string; 301 | 302 | /** 303 | * Returns true if the module has already been loaded and defined. 304 | * @param module Module to check 305 | **/ 306 | defined(module: string): boolean; 307 | 308 | /** 309 | * Returns true if the module has already been requested or is in the process of loading and should be available at some point. 310 | * @param module Module to check 311 | **/ 312 | specified(module: string): boolean; 313 | 314 | /** 315 | * On Error override 316 | * @param err 317 | **/ 318 | onError(err: RequireError, errback?: (err: RequireError) => void): void; 319 | 320 | /** 321 | * Undefine a module 322 | * @param module Module to undefine. 323 | **/ 324 | undef(module: string): void; 325 | 326 | /** 327 | * Semi-private function, overload in special instance of undef() 328 | **/ 329 | onResourceLoad(context: Object, map: RequireMap, depArray: RequireMap[]): void; 330 | } 331 | 332 | interface RequireDefine { 333 | 334 | /** 335 | * Define Simple Name/Value Pairs 336 | * @param config Dictionary of Named/Value pairs for the config. 337 | **/ 338 | (config: { [key: string]: any; }): void; 339 | 340 | /** 341 | * Define function. 342 | * @param func: The function module. 343 | **/ 344 | (func: () => any): void; 345 | 346 | /** 347 | * Define function with dependencies. 348 | * @param deps List of dependencies module IDs. 349 | * @param ready Callback function when the dependencies are loaded. 350 | * callback param deps module dependencies 351 | * callback return module definition 352 | **/ 353 | (deps: string[], ready: Function): void; 354 | 355 | /** 356 | * Define module with simplified CommonJS wrapper. 357 | * @param ready 358 | * callback require requirejs instance 359 | * callback exports exports object 360 | * callback module module 361 | * callback return module definition 362 | **/ 363 | (ready: (require: Require, exports: { [key: string]: any; }, module: RequireModule) => any): void; 364 | 365 | /** 366 | * Define a module with a name and dependencies. 367 | * @param name The name of the module. 368 | * @param deps List of dependencies module IDs. 369 | * @param ready Callback function when the dependencies are loaded. 370 | * callback deps module dependencies 371 | * callback return module definition 372 | **/ 373 | (name: string, deps: string[], ready: Function): void; 374 | 375 | /** 376 | * Define a module with a name. 377 | * @param name The name of the module. 378 | * @param ready Callback function when the dependencies are loaded. 379 | * callback return module definition 380 | **/ 381 | (name: string, ready: Function): void; 382 | 383 | /** 384 | * Used to allow a clear indicator that a global define function (as needed for script src browser loading) conforms 385 | * to the AMD API, any global define function SHOULD have a property called "amd" whose value is an object. 386 | * This helps avoid conflict with any other existing JavaScript code that could have defined a define() function 387 | * that does not conform to the AMD API. 388 | * define.amd.jQuery is specific to jQuery and indicates that the loader is able to account for multiple version 389 | * of jQuery being loaded simultaneously. 390 | */ 391 | amd: Object; 392 | } 393 | 394 | // Ambient declarations for 'require' and 'define' 395 | declare var requirejs: Require; 396 | declare var require: Require; 397 | declare var define: RequireDefine; 398 | -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/lib/bootstrap/css/bootstrap-theme.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.0.3 (http://getbootstrap.com) 3 | * Copyright 2013 Twitter, Inc. 4 | * Licensed under http://www.apache.org/licenses/LICENSE-2.0 5 | */ 6 | 7 | .btn-default,.btn-primary,.btn-success,.btn-info,.btn-warning,.btn-danger{text-shadow:0 -1px 0 rgba(0,0,0,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 1px rgba(0,0,0,0.075)}.btn-default:active,.btn-primary:active,.btn-success:active,.btn-info:active,.btn-warning:active,.btn-danger:active,.btn-default.active,.btn-primary.active,.btn-success.active,.btn-info.active,.btn-warning.active,.btn-danger.active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:active,.btn.active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe0e0e0',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-default:hover,.btn-default:focus{background-color:#e0e0e0;background-position:0 -15px}.btn-default:active,.btn-default.active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-primary{background-image:-webkit-linear-gradient(top,#428bca 0,#2d6ca2 100%);background-image:linear-gradient(to bottom,#428bca 0,#2d6ca2 100%);background-repeat:repeat-x;border-color:#2b669a;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff2d6ca2',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-primary:hover,.btn-primary:focus{background-color:#2d6ca2;background-position:0 -15px}.btn-primary:active,.btn-primary.active{background-color:#2d6ca2;border-color:#2b669a}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);background-repeat:repeat-x;border-color:#3e8f3e;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c',endColorstr='#ff419641',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-success:hover,.btn-success:focus{background-color:#419641;background-position:0 -15px}.btn-success:active,.btn-success.active{background-color:#419641;border-color:#3e8f3e}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);background-repeat:repeat-x;border-color:#e38d13;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e',endColorstr='#ffeb9316',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-warning:hover,.btn-warning:focus{background-color:#eb9316;background-position:0 -15px}.btn-warning:active,.btn-warning.active{background-color:#eb9316;border-color:#e38d13}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);background-repeat:repeat-x;border-color:#b92c28;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f',endColorstr='#ffc12e2a',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-danger:hover,.btn-danger:focus{background-color:#c12e2a;background-position:0 -15px}.btn-danger:active,.btn-danger.active{background-color:#c12e2a;border-color:#b92c28}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);background-repeat:repeat-x;border-color:#28a4c9;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff2aabd2',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.btn-info:hover,.btn-info:focus{background-color:#2aabd2;background-position:0 -15px}.btn-info:active,.btn-info.active{background-color:#2aabd2;border-color:#28a4c9}.thumbnail,.img-thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#ffe8e8e8',GradientType=0)}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{background-color:#357ebd;background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff357ebd',GradientType=0)}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);background-repeat:repeat-x;border-radius:4px;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#fff8f8f8',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075);box-shadow:inset 0 1px 0 rgba(255,255,255,0.15),0 1px 5px rgba(0,0,0,0.075)}.navbar-default .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f3f3f3 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f3f3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb',endColorstr='#fff3f3f3',GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.075);box-shadow:inset 0 3px 9px rgba(0,0,0,0.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,0.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c',endColorstr='#ff222222',GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.navbar-inverse .navbar-nav>.active>a{background-image:-webkit-linear-gradient(top,#222 0,#282828 100%);background-image:linear-gradient(to bottom,#222 0,#282828 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222',endColorstr='#ff282828',GradientType=0);-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,0.25);box-shadow:inset 0 3px 9px rgba(0,0,0,0.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,0.25)}.navbar-static-top,.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}.alert{text-shadow:0 1px 0 rgba(255,255,255,0.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05);box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 2px rgba(0,0,0,0.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);background-repeat:repeat-x;border-color:#b2dba1;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8',endColorstr='#ffc8e5bc',GradientType=0)}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);background-repeat:repeat-x;border-color:#9acfea;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7',endColorstr='#ffb9def0',GradientType=0)}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);background-repeat:repeat-x;border-color:#f5e79e;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3',endColorstr='#fff8efc0',GradientType=0)}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);background-repeat:repeat-x;border-color:#dca7a7;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede',endColorstr='#ffe7c3c3',GradientType=0)}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb',endColorstr='#fff5f5f5',GradientType=0)}.progress-bar{background-image:-webkit-linear-gradient(top,#428bca 0,#3071a9 100%);background-image:linear-gradient(to bottom,#428bca 0,#3071a9 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3071a9',GradientType=0)}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c',endColorstr='#ff449d44',GradientType=0)}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de',endColorstr='#ff31b0d5',GradientType=0)}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e',endColorstr='#ffec971f',GradientType=0)}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f',endColorstr='#ffc9302c',GradientType=0)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.075);box-shadow:0 1px 2px rgba(0,0,0,0.075)}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{text-shadow:0 -1px 0 #3071a9;background-image:-webkit-linear-gradient(top,#428bca 0,#3278b3 100%);background-image:linear-gradient(to bottom,#428bca 0,#3278b3 100%);background-repeat:repeat-x;border-color:#3278b3;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff3278b3',GradientType=0)}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.05);box-shadow:0 1px 2px rgba(0,0,0,0.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5',endColorstr='#ffe8e8e8',GradientType=0)}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#428bca 0,#357ebd 100%);background-image:linear-gradient(to bottom,#428bca 0,#357ebd 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca',endColorstr='#ff357ebd',GradientType=0)}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8',endColorstr='#ffd0e9c6',GradientType=0)}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7',endColorstr='#ffc4e3f3',GradientType=0)}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3',endColorstr='#fffaf2cc',GradientType=0)}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede',endColorstr='#ffebcccc',GradientType=0)}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);background-repeat:repeat-x;border-color:#dcdcdc;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8',endColorstr='#fff5f5f5',GradientType=0);-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 3px rgba(0,0,0,0.05),0 1px 0 rgba(255,255,255,0.1)} -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/lib/bootstrap/css/bootstrap-theme.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v3.0.3 (http://getbootstrap.com) 3 | * Copyright 2013 Twitter, Inc. 4 | * Licensed under http://www.apache.org/licenses/LICENSE-2.0 5 | */ 6 | 7 | .btn-default, 8 | .btn-primary, 9 | .btn-success, 10 | .btn-info, 11 | .btn-warning, 12 | .btn-danger { 13 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); 14 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); 15 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075); 16 | } 17 | 18 | .btn-default:active, 19 | .btn-primary:active, 20 | .btn-success:active, 21 | .btn-info:active, 22 | .btn-warning:active, 23 | .btn-danger:active, 24 | .btn-default.active, 25 | .btn-primary.active, 26 | .btn-success.active, 27 | .btn-info.active, 28 | .btn-warning.active, 29 | .btn-danger.active { 30 | -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); 31 | box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); 32 | } 33 | 34 | .btn:active, 35 | .btn.active { 36 | background-image: none; 37 | } 38 | 39 | .btn-default { 40 | text-shadow: 0 1px 0 #fff; 41 | background-image: -webkit-linear-gradient(top, #ffffff 0%, #e0e0e0 100%); 42 | background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%); 43 | background-repeat: repeat-x; 44 | border-color: #dbdbdb; 45 | border-color: #ccc; 46 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0); 47 | filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); 48 | } 49 | 50 | .btn-default:hover, 51 | .btn-default:focus { 52 | background-color: #e0e0e0; 53 | background-position: 0 -15px; 54 | } 55 | 56 | .btn-default:active, 57 | .btn-default.active { 58 | background-color: #e0e0e0; 59 | border-color: #dbdbdb; 60 | } 61 | 62 | .btn-primary { 63 | background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%); 64 | background-image: linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%); 65 | background-repeat: repeat-x; 66 | border-color: #2b669a; 67 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0); 68 | filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); 69 | } 70 | 71 | .btn-primary:hover, 72 | .btn-primary:focus { 73 | background-color: #2d6ca2; 74 | background-position: 0 -15px; 75 | } 76 | 77 | .btn-primary:active, 78 | .btn-primary.active { 79 | background-color: #2d6ca2; 80 | border-color: #2b669a; 81 | } 82 | 83 | .btn-success { 84 | background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%); 85 | background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%); 86 | background-repeat: repeat-x; 87 | border-color: #3e8f3e; 88 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0); 89 | filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); 90 | } 91 | 92 | .btn-success:hover, 93 | .btn-success:focus { 94 | background-color: #419641; 95 | background-position: 0 -15px; 96 | } 97 | 98 | .btn-success:active, 99 | .btn-success.active { 100 | background-color: #419641; 101 | border-color: #3e8f3e; 102 | } 103 | 104 | .btn-warning { 105 | background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%); 106 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%); 107 | background-repeat: repeat-x; 108 | border-color: #e38d13; 109 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0); 110 | filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); 111 | } 112 | 113 | .btn-warning:hover, 114 | .btn-warning:focus { 115 | background-color: #eb9316; 116 | background-position: 0 -15px; 117 | } 118 | 119 | .btn-warning:active, 120 | .btn-warning.active { 121 | background-color: #eb9316; 122 | border-color: #e38d13; 123 | } 124 | 125 | .btn-danger { 126 | background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%); 127 | background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%); 128 | background-repeat: repeat-x; 129 | border-color: #b92c28; 130 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0); 131 | filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); 132 | } 133 | 134 | .btn-danger:hover, 135 | .btn-danger:focus { 136 | background-color: #c12e2a; 137 | background-position: 0 -15px; 138 | } 139 | 140 | .btn-danger:active, 141 | .btn-danger.active { 142 | background-color: #c12e2a; 143 | border-color: #b92c28; 144 | } 145 | 146 | .btn-info { 147 | background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%); 148 | background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%); 149 | background-repeat: repeat-x; 150 | border-color: #28a4c9; 151 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0); 152 | filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); 153 | } 154 | 155 | .btn-info:hover, 156 | .btn-info:focus { 157 | background-color: #2aabd2; 158 | background-position: 0 -15px; 159 | } 160 | 161 | .btn-info:active, 162 | .btn-info.active { 163 | background-color: #2aabd2; 164 | border-color: #28a4c9; 165 | } 166 | 167 | .thumbnail, 168 | .img-thumbnail { 169 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); 170 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); 171 | } 172 | 173 | .dropdown-menu > li > a:hover, 174 | .dropdown-menu > li > a:focus { 175 | background-color: #e8e8e8; 176 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 177 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); 178 | background-repeat: repeat-x; 179 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); 180 | } 181 | 182 | .dropdown-menu > .active > a, 183 | .dropdown-menu > .active > a:hover, 184 | .dropdown-menu > .active > a:focus { 185 | background-color: #357ebd; 186 | background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%); 187 | background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); 188 | background-repeat: repeat-x; 189 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); 190 | } 191 | 192 | .navbar-default { 193 | background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%); 194 | background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%); 195 | background-repeat: repeat-x; 196 | border-radius: 4px; 197 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0); 198 | filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); 199 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075); 200 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075); 201 | } 202 | 203 | .navbar-default .navbar-nav > .active > a { 204 | background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%); 205 | background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%); 206 | background-repeat: repeat-x; 207 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0); 208 | -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075); 209 | box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075); 210 | } 211 | 212 | .navbar-brand, 213 | .navbar-nav > li > a { 214 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25); 215 | } 216 | 217 | .navbar-inverse { 218 | background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222222 100%); 219 | background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%); 220 | background-repeat: repeat-x; 221 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0); 222 | filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); 223 | } 224 | 225 | .navbar-inverse .navbar-nav > .active > a { 226 | background-image: -webkit-linear-gradient(top, #222222 0%, #282828 100%); 227 | background-image: linear-gradient(to bottom, #222222 0%, #282828 100%); 228 | background-repeat: repeat-x; 229 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0); 230 | -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25); 231 | box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25); 232 | } 233 | 234 | .navbar-inverse .navbar-brand, 235 | .navbar-inverse .navbar-nav > li > a { 236 | text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); 237 | } 238 | 239 | .navbar-static-top, 240 | .navbar-fixed-top, 241 | .navbar-fixed-bottom { 242 | border-radius: 0; 243 | } 244 | 245 | .alert { 246 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2); 247 | -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); 248 | box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05); 249 | } 250 | 251 | .alert-success { 252 | background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%); 253 | background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%); 254 | background-repeat: repeat-x; 255 | border-color: #b2dba1; 256 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0); 257 | } 258 | 259 | .alert-info { 260 | background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%); 261 | background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%); 262 | background-repeat: repeat-x; 263 | border-color: #9acfea; 264 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0); 265 | } 266 | 267 | .alert-warning { 268 | background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%); 269 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%); 270 | background-repeat: repeat-x; 271 | border-color: #f5e79e; 272 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0); 273 | } 274 | 275 | .alert-danger { 276 | background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%); 277 | background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%); 278 | background-repeat: repeat-x; 279 | border-color: #dca7a7; 280 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0); 281 | } 282 | 283 | .progress { 284 | background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%); 285 | background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%); 286 | background-repeat: repeat-x; 287 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0); 288 | } 289 | 290 | .progress-bar { 291 | background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%); 292 | background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%); 293 | background-repeat: repeat-x; 294 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0); 295 | } 296 | 297 | .progress-bar-success { 298 | background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%); 299 | background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%); 300 | background-repeat: repeat-x; 301 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0); 302 | } 303 | 304 | .progress-bar-info { 305 | background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%); 306 | background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%); 307 | background-repeat: repeat-x; 308 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0); 309 | } 310 | 311 | .progress-bar-warning { 312 | background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%); 313 | background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%); 314 | background-repeat: repeat-x; 315 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0); 316 | } 317 | 318 | .progress-bar-danger { 319 | background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%); 320 | background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%); 321 | background-repeat: repeat-x; 322 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0); 323 | } 324 | 325 | .list-group { 326 | border-radius: 4px; 327 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); 328 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075); 329 | } 330 | 331 | .list-group-item.active, 332 | .list-group-item.active:hover, 333 | .list-group-item.active:focus { 334 | text-shadow: 0 -1px 0 #3071a9; 335 | background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%); 336 | background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%); 337 | background-repeat: repeat-x; 338 | border-color: #3278b3; 339 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0); 340 | } 341 | 342 | .panel { 343 | -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); 344 | box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); 345 | } 346 | 347 | .panel-default > .panel-heading { 348 | background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%); 349 | background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%); 350 | background-repeat: repeat-x; 351 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0); 352 | } 353 | 354 | .panel-primary > .panel-heading { 355 | background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%); 356 | background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%); 357 | background-repeat: repeat-x; 358 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0); 359 | } 360 | 361 | .panel-success > .panel-heading { 362 | background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%); 363 | background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%); 364 | background-repeat: repeat-x; 365 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0); 366 | } 367 | 368 | .panel-info > .panel-heading { 369 | background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%); 370 | background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%); 371 | background-repeat: repeat-x; 372 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0); 373 | } 374 | 375 | .panel-warning > .panel-heading { 376 | background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%); 377 | background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%); 378 | background-repeat: repeat-x; 379 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0); 380 | } 381 | 382 | .panel-danger > .panel-heading { 383 | background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%); 384 | background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%); 385 | background-repeat: repeat-x; 386 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0); 387 | } 388 | 389 | .well { 390 | background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%); 391 | background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%); 392 | background-repeat: repeat-x; 393 | border-color: #dcdcdc; 394 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0); 395 | -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1); 396 | box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1); 397 | } -------------------------------------------------------------------------------- /archive/hq1/src/HabraQuest/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js: -------------------------------------------------------------------------------- 1 | /*! 2 | ** Unobtrusive validation support library for jQuery and jQuery Validate 3 | ** Copyright (C) Microsoft Corporation. All rights reserved. 4 | */ 5 | 6 | /*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */ 7 | /*global document: false, jQuery: false */ 8 | 9 | (function ($) { 10 | var $jQval = $.validator, 11 | adapters, 12 | data_validation = "unobtrusiveValidation"; 13 | 14 | function setValidationValues(options, ruleName, value) { 15 | options.rules[ruleName] = value; 16 | if (options.message) { 17 | options.messages[ruleName] = options.message; 18 | } 19 | } 20 | 21 | function splitAndTrim(value) { 22 | return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g); 23 | } 24 | 25 | function escapeAttributeValue(value) { 26 | // As mentioned on http://api.jquery.com/category/selectors/ 27 | return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1"); 28 | } 29 | 30 | function getModelPrefix(fieldName) { 31 | return fieldName.substr(0, fieldName.lastIndexOf(".") + 1); 32 | } 33 | 34 | function appendModelPrefix(value, prefix) { 35 | if (value.indexOf("*.") === 0) { 36 | value = value.replace("*.", prefix); 37 | } 38 | return value; 39 | } 40 | 41 | function onError(error, inputElement) { // 'this' is the form element 42 | var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"), 43 | replaceAttrValue = container.attr("data-valmsg-replace"), 44 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null; 45 | 46 | container.removeClass("field-validation-valid").addClass("field-validation-error"); 47 | error.data("unobtrusiveContainer", container); 48 | 49 | if (replace) { 50 | container.empty(); 51 | error.removeClass("input-validation-error").appendTo(container); 52 | } 53 | else { 54 | error.hide(); 55 | } 56 | } 57 | 58 | function onErrors(event, validator) { // 'this' is the form element 59 | var container = $(this).find("[data-valmsg-summary=true]"), 60 | list = container.find("ul"); 61 | 62 | if (list && list.length && validator.errorList.length) { 63 | list.empty(); 64 | container.addClass("validation-summary-errors").removeClass("validation-summary-valid"); 65 | 66 | $.each(validator.errorList, function () { 67 | $("
  • ").html(this.message).appendTo(list); 68 | }); 69 | } 70 | } 71 | 72 | function onSuccess(error) { // 'this' is the form element 73 | var container = error.data("unobtrusiveContainer"), 74 | replaceAttrValue = container.attr("data-valmsg-replace"), 75 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null; 76 | 77 | if (container) { 78 | container.addClass("field-validation-valid").removeClass("field-validation-error"); 79 | error.removeData("unobtrusiveContainer"); 80 | 81 | if (replace) { 82 | container.empty(); 83 | } 84 | } 85 | } 86 | 87 | function onReset(event) { // 'this' is the form element 88 | var $form = $(this); 89 | $form.data("validator").resetForm(); 90 | $form.find(".validation-summary-errors") 91 | .addClass("validation-summary-valid") 92 | .removeClass("validation-summary-errors"); 93 | $form.find(".field-validation-error") 94 | .addClass("field-validation-valid") 95 | .removeClass("field-validation-error") 96 | .removeData("unobtrusiveContainer") 97 | .find(">*") // If we were using valmsg-replace, get the underlying error 98 | .removeData("unobtrusiveContainer"); 99 | } 100 | 101 | function validationInfo(form) { 102 | var $form = $(form), 103 | result = $form.data(data_validation), 104 | onResetProxy = $.proxy(onReset, form), 105 | defaultOptions = $jQval.unobtrusive.options || {}, 106 | execInContext = function (name, args) { 107 | var func = defaultOptions[name]; 108 | func && $.isFunction(func) && func.apply(form, args); 109 | } 110 | 111 | if (!result) { 112 | result = { 113 | options: { // options structure passed to jQuery Validate's validate() method 114 | errorClass: defaultOptions.errorClass || "input-validation-error", 115 | errorElement: defaultOptions.errorElement || "span", 116 | errorPlacement: function () { 117 | onError.apply(form, arguments); 118 | execInContext("errorPlacement", arguments); 119 | }, 120 | invalidHandler: function () { 121 | onErrors.apply(form, arguments); 122 | execInContext("invalidHandler", arguments); 123 | }, 124 | messages: {}, 125 | rules: {}, 126 | success: function () { 127 | onSuccess.apply(form, arguments); 128 | execInContext("success", arguments); 129 | } 130 | }, 131 | attachValidation: function () { 132 | $form 133 | .off("reset." + data_validation, onResetProxy) 134 | .on("reset." + data_validation, onResetProxy) 135 | .validate(this.options); 136 | }, 137 | validate: function () { // a validation function that is called by unobtrusive Ajax 138 | $form.validate(); 139 | return $form.valid(); 140 | } 141 | }; 142 | $form.data(data_validation, result); 143 | } 144 | 145 | return result; 146 | } 147 | 148 | $jQval.unobtrusive = { 149 | adapters: [], 150 | 151 | parseElement: function (element, skipAttach) { 152 | /// 153 | /// Parses a single HTML element for unobtrusive validation attributes. 154 | /// 155 | /// The HTML element to be parsed. 156 | /// [Optional] true to skip attaching the 157 | /// validation to the form. If parsing just this single element, you should specify true. 158 | /// If parsing several elements, you should specify false, and manually attach the validation 159 | /// to the form when you are finished. The default is false. 160 | var $element = $(element), 161 | form = $element.parents("form")[0], 162 | valInfo, rules, messages; 163 | 164 | if (!form) { // Cannot do client-side validation without a form 165 | return; 166 | } 167 | 168 | valInfo = validationInfo(form); 169 | valInfo.options.rules[element.name] = rules = {}; 170 | valInfo.options.messages[element.name] = messages = {}; 171 | 172 | $.each(this.adapters, function () { 173 | var prefix = "data-val-" + this.name, 174 | message = $element.attr(prefix), 175 | paramValues = {}; 176 | 177 | if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy) 178 | prefix += "-"; 179 | 180 | $.each(this.params, function () { 181 | paramValues[this] = $element.attr(prefix + this); 182 | }); 183 | 184 | this.adapt({ 185 | element: element, 186 | form: form, 187 | message: message, 188 | params: paramValues, 189 | rules: rules, 190 | messages: messages 191 | }); 192 | } 193 | }); 194 | 195 | $.extend(rules, { "__dummy__": true }); 196 | 197 | if (!skipAttach) { 198 | valInfo.attachValidation(); 199 | } 200 | }, 201 | 202 | parse: function (selector) { 203 | /// 204 | /// Parses all the HTML elements in the specified selector. It looks for input elements decorated 205 | /// with the [data-val=true] attribute value and enables validation according to the data-val-* 206 | /// attribute values. 207 | /// 208 | /// Any valid jQuery selector. 209 | 210 | // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one 211 | // element with data-val=true 212 | var $selector = $(selector), 213 | $forms = $selector.parents() 214 | .addBack() 215 | .filter("form") 216 | .add($selector.find("form")) 217 | .has("[data-val=true]"); 218 | 219 | $selector.find("[data-val=true]").each(function () { 220 | $jQval.unobtrusive.parseElement(this, true); 221 | }); 222 | 223 | $forms.each(function () { 224 | var info = validationInfo(this); 225 | if (info) { 226 | info.attachValidation(); 227 | } 228 | }); 229 | } 230 | }; 231 | 232 | adapters = $jQval.unobtrusive.adapters; 233 | 234 | adapters.add = function (adapterName, params, fn) { 235 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation. 236 | /// The name of the adapter to be added. This matches the name used 237 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 238 | /// [Optional] An array of parameter names (strings) that will 239 | /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and 240 | /// mmmm is the parameter name). 241 | /// The function to call, which adapts the values from the HTML 242 | /// attributes into jQuery Validate rules and/or messages. 243 | /// 244 | if (!fn) { // Called with no params, just a function 245 | fn = params; 246 | params = []; 247 | } 248 | this.push({ name: adapterName, params: params, adapt: fn }); 249 | return this; 250 | }; 251 | 252 | adapters.addBool = function (adapterName, ruleName) { 253 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 254 | /// the jQuery Validate validation rule has no parameter values. 255 | /// The name of the adapter to be added. This matches the name used 256 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 257 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value 258 | /// of adapterName will be used instead. 259 | /// 260 | return this.add(adapterName, function (options) { 261 | setValidationValues(options, ruleName || adapterName, true); 262 | }); 263 | }; 264 | 265 | adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) { 266 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 267 | /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and 268 | /// one for min-and-max). The HTML parameters are expected to be named -min and -max. 269 | /// The name of the adapter to be added. This matches the name used 270 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 271 | /// The name of the jQuery Validate rule to be used when you only 272 | /// have a minimum value. 273 | /// The name of the jQuery Validate rule to be used when you only 274 | /// have a maximum value. 275 | /// The name of the jQuery Validate rule to be used when you 276 | /// have both a minimum and maximum value. 277 | /// [Optional] The name of the HTML attribute that 278 | /// contains the minimum value. The default is "min". 279 | /// [Optional] The name of the HTML attribute that 280 | /// contains the maximum value. The default is "max". 281 | /// 282 | return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) { 283 | var min = options.params.min, 284 | max = options.params.max; 285 | 286 | if (min && max) { 287 | setValidationValues(options, minMaxRuleName, [min, max]); 288 | } 289 | else if (min) { 290 | setValidationValues(options, minRuleName, min); 291 | } 292 | else if (max) { 293 | setValidationValues(options, maxRuleName, max); 294 | } 295 | }); 296 | }; 297 | 298 | adapters.addSingleVal = function (adapterName, attribute, ruleName) { 299 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 300 | /// the jQuery Validate validation rule has a single value. 301 | /// The name of the adapter to be added. This matches the name used 302 | /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name). 303 | /// [Optional] The name of the HTML attribute that contains the value. 304 | /// The default is "val". 305 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value 306 | /// of adapterName will be used instead. 307 | /// 308 | return this.add(adapterName, [attribute || "val"], function (options) { 309 | setValidationValues(options, ruleName || adapterName, options.params[attribute]); 310 | }); 311 | }; 312 | 313 | $jQval.addMethod("__dummy__", function (value, element, params) { 314 | return true; 315 | }); 316 | 317 | $jQval.addMethod("regex", function (value, element, params) { 318 | var match; 319 | if (this.optional(element)) { 320 | return true; 321 | } 322 | 323 | match = new RegExp(params).exec(value); 324 | return (match && (match.index === 0) && (match[0].length === value.length)); 325 | }); 326 | 327 | $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) { 328 | var match; 329 | if (nonalphamin) { 330 | match = value.match(/\W/g); 331 | match = match && match.length >= nonalphamin; 332 | } 333 | return match; 334 | }); 335 | 336 | if ($jQval.methods.extension) { 337 | adapters.addSingleVal("accept", "mimtype"); 338 | adapters.addSingleVal("extension", "extension"); 339 | } else { 340 | // for backward compatibility, when the 'extension' validation method does not exist, such as with versions 341 | // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for 342 | // validating the extension, and ignore mime-type validations as they are not supported. 343 | adapters.addSingleVal("extension", "extension", "accept"); 344 | } 345 | 346 | adapters.addSingleVal("regex", "pattern"); 347 | adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"); 348 | adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range"); 349 | adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength"); 350 | adapters.add("equalto", ["other"], function (options) { 351 | var prefix = getModelPrefix(options.element.name), 352 | other = options.params.other, 353 | fullOtherName = appendModelPrefix(other, prefix), 354 | element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0]; 355 | 356 | setValidationValues(options, "equalTo", element); 357 | }); 358 | adapters.add("required", function (options) { 359 | // jQuery Validate equates "required" with "mandatory" for checkbox elements 360 | if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") { 361 | setValidationValues(options, "required", true); 362 | } 363 | }); 364 | adapters.add("remote", ["url", "type", "additionalfields"], function (options) { 365 | var value = { 366 | url: options.params.url, 367 | type: options.params.type || "GET", 368 | data: {} 369 | }, 370 | prefix = getModelPrefix(options.element.name); 371 | 372 | $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) { 373 | var paramName = appendModelPrefix(fieldName, prefix); 374 | value.data[paramName] = function () { 375 | return $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']").val(); 376 | }; 377 | }); 378 | 379 | setValidationValues(options, "remote", value); 380 | }); 381 | adapters.add("password", ["min", "nonalphamin", "regex"], function (options) { 382 | if (options.params.min) { 383 | setValidationValues(options, "minlength", options.params.min); 384 | } 385 | if (options.params.nonalphamin) { 386 | setValidationValues(options, "nonalphamin", options.params.nonalphamin); 387 | } 388 | if (options.params.regex) { 389 | setValidationValues(options, "regex", options.params.regex); 390 | } 391 | }); 392 | 393 | $(function () { 394 | $jQval.unobtrusive.parse(document); 395 | }); 396 | }(jQuery)); --------------------------------------------------------------------------------