Initial commit
17
.browserslistrc
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
||||||
|
# For additional information regarding the format and rule options, please see:
|
||||||
|
# https://github.com/browserslist/browserslist#queries
|
||||||
|
|
||||||
|
# For the full list of supported browsers by the Angular framework, please see:
|
||||||
|
# https://angular.io/guide/browser-support
|
||||||
|
|
||||||
|
# You can see what browsers were selected by your queries by running:
|
||||||
|
# npx browserslist
|
||||||
|
|
||||||
|
last 1 Chrome version
|
||||||
|
last 1 Firefox version
|
||||||
|
last 2 Edge major versions
|
||||||
|
last 2 Safari major versions
|
||||||
|
last 2 iOS major versions
|
||||||
|
Firefox ESR
|
||||||
|
not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line.
|
||||||
16
.editorconfig
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Editor configuration, see https://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.ts]
|
||||||
|
quote_type = single
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
max_line_length = off
|
||||||
|
trim_trailing_whitespace = false
|
||||||
45
.gitignore
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# compiled output
|
||||||
|
/dist
|
||||||
|
/tmp
|
||||||
|
/out-tsc
|
||||||
|
# Only exists if Bazel was run
|
||||||
|
/bazel-out
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# profiling files
|
||||||
|
chrome-profiler-events*.json
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
/.idea
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# IDE - VSCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.history/*
|
||||||
|
|
||||||
|
# misc
|
||||||
|
/.sass-cache
|
||||||
|
/connect.lock
|
||||||
|
/coverage
|
||||||
|
/libpeerconnection.log
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
testem.log
|
||||||
|
/typings
|
||||||
|
|
||||||
|
# System Files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
10
LICENSE
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
This is free and unencumbered software released into the public domain.
|
||||||
|
|
||||||
|
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.
|
||||||
|
|
||||||
|
In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and
|
||||||
|
successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
For more information, please refer to <http://unlicense.org/>
|
||||||
113
angular.json
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
{
|
||||||
|
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||||
|
"version": 1,
|
||||||
|
"newProjectRoot": "projects",
|
||||||
|
"projects": {
|
||||||
|
"testowy": {
|
||||||
|
"projectType": "application",
|
||||||
|
"schematics": {
|
||||||
|
"@schematics/angular:component": {
|
||||||
|
"style": "scss"
|
||||||
|
},
|
||||||
|
"@schematics/angular:application": {
|
||||||
|
"strict": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "",
|
||||||
|
"sourceRoot": "src",
|
||||||
|
"prefix": "app",
|
||||||
|
"architect": {
|
||||||
|
"build": {
|
||||||
|
"builder": "@angular-devkit/build-angular:browser",
|
||||||
|
"options": {
|
||||||
|
"outputPath": "dist/testowy",
|
||||||
|
"index": "src/index.html",
|
||||||
|
"main": "src/main.ts",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "tsconfig.app.json",
|
||||||
|
"inlineStyleLanguage": "scss",
|
||||||
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/assets"
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
||||||
|
"src/styles.scss"
|
||||||
|
],
|
||||||
|
"scripts": []
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"budgets": [
|
||||||
|
{
|
||||||
|
"type": "initial",
|
||||||
|
"maximumWarning": "500kb",
|
||||||
|
"maximumError": "1mb"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "anyComponentStyle",
|
||||||
|
"maximumWarning": "2kb",
|
||||||
|
"maximumError": "4kb"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"fileReplacements": [
|
||||||
|
{
|
||||||
|
"replace": "src/environments/environment.ts",
|
||||||
|
"with": "src/environments/environment.prod.ts"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"outputHashing": "all"
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"buildOptimizer": false,
|
||||||
|
"optimization": false,
|
||||||
|
"vendorChunk": true,
|
||||||
|
"extractLicenses": false,
|
||||||
|
"sourceMap": true,
|
||||||
|
"namedChunks": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "production"
|
||||||
|
},
|
||||||
|
"serve": {
|
||||||
|
"builder": "@angular-devkit/build-angular:dev-server",
|
||||||
|
"configurations": {
|
||||||
|
"production": {
|
||||||
|
"browserTarget": "testowy:build:production"
|
||||||
|
},
|
||||||
|
"development": {
|
||||||
|
"browserTarget": "testowy:build:development"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultConfiguration": "development"
|
||||||
|
},
|
||||||
|
"extract-i18n": {
|
||||||
|
"builder": "@angular-devkit/build-angular:extract-i18n",
|
||||||
|
"options": {
|
||||||
|
"browserTarget": "testowy:build"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"builder": "@angular-devkit/build-angular:karma",
|
||||||
|
"options": {
|
||||||
|
"main": "src/test.ts",
|
||||||
|
"polyfills": "src/polyfills.ts",
|
||||||
|
"tsConfig": "tsconfig.spec.json",
|
||||||
|
"karmaConfig": "karma.conf.js",
|
||||||
|
"inlineStyleLanguage": "scss",
|
||||||
|
"assets": [
|
||||||
|
"src/favicon.ico",
|
||||||
|
"src/assets"
|
||||||
|
],
|
||||||
|
"styles": [
|
||||||
|
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
||||||
|
"src/styles.scss"
|
||||||
|
],
|
||||||
|
"scripts": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"defaultProject": "testowy"
|
||||||
|
}
|
||||||
44
karma.conf.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
// Karma configuration file, see link for more information
|
||||||
|
// https://karma-runner.github.io/1.0/config/configuration-file.html
|
||||||
|
|
||||||
|
module.exports = function (config) {
|
||||||
|
config.set({
|
||||||
|
basePath: '',
|
||||||
|
frameworks: ['jasmine', '@angular-devkit/build-angular'],
|
||||||
|
plugins: [
|
||||||
|
require('karma-jasmine'),
|
||||||
|
require('karma-chrome-launcher'),
|
||||||
|
require('karma-jasmine-html-reporter'),
|
||||||
|
require('karma-coverage'),
|
||||||
|
require('@angular-devkit/build-angular/plugins/karma')
|
||||||
|
],
|
||||||
|
client: {
|
||||||
|
jasmine: {
|
||||||
|
// you can add configuration options for Jasmine here
|
||||||
|
// the possible options are listed at https://jasmine.github.io/api/edge/Configuration.html
|
||||||
|
// for example, you can disable the random execution with `random: false`
|
||||||
|
// or set a specific seed with `seed: 4321`
|
||||||
|
},
|
||||||
|
clearContext: false // leave Jasmine Spec Runner output visible in browser
|
||||||
|
},
|
||||||
|
jasmineHtmlReporter: {
|
||||||
|
suppressAll: true // removes the duplicated traces
|
||||||
|
},
|
||||||
|
coverageReporter: {
|
||||||
|
dir: require('path').join(__dirname, './coverage/testowy'),
|
||||||
|
subdir: '.',
|
||||||
|
reporters: [
|
||||||
|
{ type: 'html' },
|
||||||
|
{ type: 'text-summary' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
reporters: ['progress', 'kjhtml'],
|
||||||
|
port: 9876,
|
||||||
|
colors: true,
|
||||||
|
logLevel: config.LOG_INFO,
|
||||||
|
autoWatch: true,
|
||||||
|
browsers: ['Chrome'],
|
||||||
|
singleRun: false,
|
||||||
|
restartOnFileChange: true
|
||||||
|
});
|
||||||
|
};
|
||||||
28552
package-lock.json
generated
Normal file
46
package.json
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
{
|
||||||
|
"name": "testowy",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"ng": "ng",
|
||||||
|
"start": "ng serve",
|
||||||
|
"build": "ng build",
|
||||||
|
"brainman": "ng build --base-href /szkolenie/ --output-hashing all",
|
||||||
|
"watch": "ng build --watch --configuration development",
|
||||||
|
"test": "ng test"
|
||||||
|
},
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/animations": "~12.2.0",
|
||||||
|
"@angular/cdk": "^12.2.6",
|
||||||
|
"@angular/common": "~12.2.0",
|
||||||
|
"@angular/compiler": "~12.2.0",
|
||||||
|
"@angular/core": "~12.2.0",
|
||||||
|
"@angular/forms": "~12.2.0",
|
||||||
|
"@angular/material": "^12.2.6",
|
||||||
|
"@angular/localize": "^12.2.6",
|
||||||
|
"@angular/platform-browser": "~12.2.0",
|
||||||
|
"@angular/platform-browser-dynamic": "~12.2.0",
|
||||||
|
"@angular/router": "~12.2.0",
|
||||||
|
"date-fns": "~2.24.0",
|
||||||
|
"rxjs": "~6.6.0",
|
||||||
|
"tslib": "^2.3.0",
|
||||||
|
"zone.js": "~0.11.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@angular-devkit/build-angular": "~12.2.6",
|
||||||
|
"@angular/cli": "~12.2.6",
|
||||||
|
"@angular/compiler-cli": "~12.2.0",
|
||||||
|
"@angular/localize": "^12.2.6",
|
||||||
|
"@types/jasmine": "~3.8.0",
|
||||||
|
"@types/node": "^12.11.1",
|
||||||
|
"date-fns": "~2.24.0",
|
||||||
|
"jasmine-core": "~3.8.0",
|
||||||
|
"karma": "~6.3.0",
|
||||||
|
"karma-chrome-launcher": "~3.1.0",
|
||||||
|
"karma-coverage": "~2.0.3",
|
||||||
|
"karma-jasmine": "~4.0.0",
|
||||||
|
"karma-jasmine-html-reporter": "~1.7.0",
|
||||||
|
"typescript": "~4.3.5"
|
||||||
|
}
|
||||||
|
}
|
||||||
41
src/app/app.module.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
|
import { AppComponent } from './components/app/app.component';
|
||||||
|
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
import { MatInputModule } from '@angular/material/input';
|
||||||
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
|
import { MatGridListModule } from '@angular/material/grid-list';
|
||||||
|
import { ClipboardModule } from '@angular/cdk/clipboard';
|
||||||
|
import { MatSnackBarModule} from '@angular/material/snack-bar';
|
||||||
|
import { TranslatePipe } from './translate-pipe';
|
||||||
|
import { PeselComponent } from './components/pesel/pesel.component';
|
||||||
|
import { NipComponent } from './components/nip/nip.component';
|
||||||
|
import { RegonComponent } from './components/regon/regon.component';
|
||||||
|
import { IbanComponent } from './components/iban/iban.component';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AppComponent,
|
||||||
|
TranslatePipe,
|
||||||
|
PeselComponent,
|
||||||
|
NipComponent,
|
||||||
|
RegonComponent,
|
||||||
|
IbanComponent
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
BrowserModule,
|
||||||
|
FormsModule,
|
||||||
|
BrowserAnimationsModule,
|
||||||
|
MatInputModule,
|
||||||
|
MatIconModule,
|
||||||
|
MatGridListModule,
|
||||||
|
ClipboardModule,
|
||||||
|
MatSnackBarModule,
|
||||||
|
ReactiveFormsModule,
|
||||||
|
],
|
||||||
|
providers: [TranslatePipe],
|
||||||
|
bootstrap: [AppComponent]
|
||||||
|
})
|
||||||
|
export class AppModule {
|
||||||
|
}
|
||||||
1
src/app/components/app/app.component.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/* No CSS *//*# sourceMappingURL=app.component.css.map */
|
||||||
9
src/app/components/app/app.component.css.map
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"mappings": "",
|
||||||
|
"sources": [
|
||||||
|
"app.component.scss"
|
||||||
|
],
|
||||||
|
"names": [],
|
||||||
|
"file": "app.component.css"
|
||||||
|
}
|
||||||
7
src/app/components/app/app.component.html
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<div class="gradient"></div>
|
||||||
|
<div class="generators">
|
||||||
|
<app-regon></app-regon>
|
||||||
|
<app-nip></app-nip>
|
||||||
|
<app-pesel></app-pesel>
|
||||||
|
<app-iban></app-iban>
|
||||||
|
</div>
|
||||||
0
src/app/components/app/app.component.scss
Normal file
15
src/app/components/app/app.component.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-root',
|
||||||
|
templateUrl: './app.component.html',
|
||||||
|
styleUrls: ['./app.component.scss']
|
||||||
|
})
|
||||||
|
export class AppComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/app/components/iban/iban.component.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/* No CSS *//*# sourceMappingURL=iban.component.css.map */
|
||||||
9
src/app/components/iban/iban.component.css.map
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"mappings": "",
|
||||||
|
"sources": [
|
||||||
|
"iban.component.scss"
|
||||||
|
],
|
||||||
|
"names": [],
|
||||||
|
"file": "iban.component.css"
|
||||||
|
}
|
||||||
19
src/app/components/iban/iban.component.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<div class="generator">
|
||||||
|
<div class="title">
|
||||||
|
<span>IBAN</span>
|
||||||
|
<div class="titleButtons">
|
||||||
|
<img id="lettersPrefixButton" src="assets/format_color_text_black_24dp.svg" title="Prefiks literowy" alt="Czy umieścić prefiks literowy PL" (click)="toggleLettersPrefix()" class="smaller" [style.background] = "lettersPrefix ? 'rgba(0, 0, 0, 0.35)' : ''" />
|
||||||
|
<div style="width: 20px;"></div>
|
||||||
|
<img id="separatorButton" src="assets/space_bar_black_24dp.svg" title="Separatory między grupami cyfr" alt="Czy umieścić separatory między grupami cyfr" (click)="toggleSeparators()" [style.background] = "separators ? 'rgba(0, 0, 0, 0.35)' : ''" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<input type="text" [formControl]="valueField" style="width: 380px;"/>
|
||||||
|
|
||||||
|
<div class="buttons">
|
||||||
|
<img id="ibanGenerateButton" src="assets/autorenew_black_24dp.svg" title="Generuj numer IBAN" alt="Generuj numer IBAN" style="margin-left: 1em;" (click)="generate()"/>
|
||||||
|
<img id="ibanCopyButton" src="assets/content_copy_black_24dp.svg" title="Skopiuj numer IBAN do schowka" alt="Skopiuj numer IBAN do schowka" style="margin: auto 1em;" (click)="copyToClipboard()"/>
|
||||||
|
<img id="ibanHelpButton" src="assets/info_black_24dp.svg" title="Definicja numeru IBAN na Wikipedii" alt="Definicja numeru IBAN na Wikipedii" (click)="navigateToDocs()" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
0
src/app/components/iban/iban.component.scss
Normal file
112
src/app/components/iban/iban.component.ts
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { AbstractControl, FormControl } from '@angular/forms';
|
||||||
|
import { ClipboardService } from '../../service/gui/clipboard.service';
|
||||||
|
import { IbanService } from '../../service/iban.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-iban',
|
||||||
|
templateUrl: './iban.component.html',
|
||||||
|
styleUrls: ['./iban.component.scss']
|
||||||
|
})
|
||||||
|
export class IbanComponent implements OnInit {
|
||||||
|
public valueField: FormControl;
|
||||||
|
|
||||||
|
public lettersPrefix: boolean;
|
||||||
|
public separators: boolean;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(private ibanService: IbanService, private clipboardService: ClipboardService) {
|
||||||
|
this.valueField = new FormControl('iban');
|
||||||
|
this.valueField.setValidators([(control: AbstractControl) => this.ibanService.validateIban(control.value)]);
|
||||||
|
|
||||||
|
this.lettersPrefix = false;
|
||||||
|
this.separators = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
generate(): void {
|
||||||
|
let iban: string = this.ibanService.generateIban();
|
||||||
|
|
||||||
|
let formattedIban = iban;
|
||||||
|
|
||||||
|
if (this.separators) {
|
||||||
|
formattedIban = iban.substring(0, 2);
|
||||||
|
|
||||||
|
for (let i: number = 2; i < iban.length; i+=4) {
|
||||||
|
formattedIban += " " + iban.substring(i, i + 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.lettersPrefix) {
|
||||||
|
formattedIban = 'PL' + (this.separators ? " " : "") + formattedIban;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.valueField.setValue(formattedIban);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleLettersPrefix(): void {
|
||||||
|
this.lettersPrefix = !this.lettersPrefix;
|
||||||
|
|
||||||
|
if (this.valueField.valid) {
|
||||||
|
var formattedValue: string;
|
||||||
|
|
||||||
|
if (this.lettersPrefix) {
|
||||||
|
formattedValue = this.addLetterPrefix(this.valueField.value);
|
||||||
|
} else {
|
||||||
|
formattedValue = this.removeLetterPrefix(this.valueField.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.valueField.setValue(formattedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleSeparators(): void {
|
||||||
|
this.separators = !this.separators;
|
||||||
|
|
||||||
|
if (this.valueField.valid) {
|
||||||
|
var formattedValue: string;
|
||||||
|
|
||||||
|
if (this.separators) {
|
||||||
|
formattedValue = this.addSeparators(this.valueField.value);
|
||||||
|
} else {
|
||||||
|
formattedValue = this.removeSeparators(this.valueField.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.valueField.setValue(formattedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addLetterPrefix(iban: string): string {
|
||||||
|
return 'PL' + (this.separators ? " " : "") + iban;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeLetterPrefix(iban: string): string {
|
||||||
|
return iban.replace(/[a-zA-Z]*/g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
addSeparators(iban: string): string {
|
||||||
|
var formattedIban = iban.substring(0, 2);
|
||||||
|
|
||||||
|
for (let i: number = 2; i < iban.length; i+=4) {
|
||||||
|
formattedIban += " " + iban.substring(i, i + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return formattedIban;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeSeparators(iban: string) : string {
|
||||||
|
return iban.replace(/ /g, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
copyToClipboard(): void {
|
||||||
|
this.clipboardService.copyToClipboard(this.valueField.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
navigateToDocs(): void {
|
||||||
|
window.open('https://pl.wikipedia.org/wiki/Mi%C4%99dzynarodowy_numer_rachunku_bankowego', "_blank");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
1
src/app/components/nip/nip.component.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/* No CSS *//*# sourceMappingURL=nip.component.css.map */
|
||||||
9
src/app/components/nip/nip.component.css.map
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"mappings": "",
|
||||||
|
"sources": [
|
||||||
|
"nip.component.scss"
|
||||||
|
],
|
||||||
|
"names": [],
|
||||||
|
"file": "nip.component.css"
|
||||||
|
}
|
||||||
14
src/app/components/nip/nip.component.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<div class="generator">
|
||||||
|
<div class="title">
|
||||||
|
<span>NIP</span>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<input type="text" [formControl]="valueField" />
|
||||||
|
|
||||||
|
<div class="buttons">
|
||||||
|
<img id="nipGenerateButton" src="assets/autorenew_black_24dp.svg" title="Generuj numer NIP" alt="Generuj numer NIP" (click)="generate()"/>
|
||||||
|
<img id="nipCopyButton" src="assets/content_copy_black_24dp.svg" title="Skopiuj numer NIP do schowka" alt="Skopiuj numer NIP do schowka" (click)="copyToClipboard()"/>
|
||||||
|
<img id="nipHelpButton" src="assets/info_black_24dp.svg" title="Szczegóły dotyczące numeru NIP" alt="Definicja numeru NIP na Wikipedii" (click)="navigateToDocs()" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
0
src/app/components/nip/nip.component.scss
Normal file
34
src/app/components/nip/nip.component.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { AbstractControl, FormControl } from '@angular/forms';
|
||||||
|
import { NipService } from 'src/app/service/nip.service';
|
||||||
|
import { ClipboardService } from 'src/app/service/gui/clipboard.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-nip',
|
||||||
|
templateUrl: './nip.component.html',
|
||||||
|
styleUrls: ['./nip.component.scss']
|
||||||
|
})
|
||||||
|
export class NipComponent implements OnInit {
|
||||||
|
public valueField: FormControl;
|
||||||
|
|
||||||
|
constructor(private nipService: NipService, private clipboardService: ClipboardService) {
|
||||||
|
this.valueField = new FormControl('nip');
|
||||||
|
this.valueField.setValidators([(control: AbstractControl) => this.nipService.validateNip(control.value)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
generate(): void {
|
||||||
|
this.valueField.setValue(this.nipService.generateNip());
|
||||||
|
}
|
||||||
|
|
||||||
|
copyToClipboard(): void {
|
||||||
|
this.clipboardService.copyToClipboard(this.valueField.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
navigateToDocs(): void {
|
||||||
|
window.open('https://pl.wikipedia.org/wiki/Numer_identyfikacji_podatkowej', "_blank");
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/app/components/pesel/pesel.component.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/* No CSS *//*# sourceMappingURL=pesel.component.css.map */
|
||||||
9
src/app/components/pesel/pesel.component.css.map
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"mappings": "",
|
||||||
|
"sources": [
|
||||||
|
"pesel.component.scss"
|
||||||
|
],
|
||||||
|
"names": [],
|
||||||
|
"file": "pesel.component.css"
|
||||||
|
}
|
||||||
19
src/app/components/pesel/pesel.component.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<div class="generator">
|
||||||
|
<div class="title">
|
||||||
|
<span>PESEL</span>
|
||||||
|
<div class="titleButtons">
|
||||||
|
<img id="malePeselButton" src="assets/male_black_24dp.svg" title="Płeć męska" alt="Czy generować męskie numery PESEL" (click)="toggleMale()" [style.background] = "generateMale ? 'rgba(0, 0, 0, 0.35)' : ''" />
|
||||||
|
<div style="width: 20px;"></div>
|
||||||
|
<img id="femalePeselButton" src="assets/female_black_24dp.svg" title="Płeć żeńska" alt="Czy generować żeńskie numery PESEL" (click)="toggleFemale()" [style.background] = "generateFemale ? 'rgba(0, 0, 0, 0.35)' : ''" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<input type="text" [formControl]="valueField" />
|
||||||
|
|
||||||
|
<div class="buttons">
|
||||||
|
<img id="peselGenerateButton" src="assets/autorenew_black_24dp.svg" title="Generuj numer PESEL" alt="Generuj numer PESEL" style="margin-left: 1em;" (click)="generate()"/>
|
||||||
|
<img id="peselCopyButton" src="assets/content_copy_black_24dp.svg" title="Skopiuj numer PESEL do schowka" alt="Skopiuj numer PESEL do schowka" style="margin: auto 1em;" (click)="copyToClipboard()"/>
|
||||||
|
<img id="peselHelpButton" src="assets/info_black_24dp.svg" title="Szczegóły dotyczące numeru PESEL" alt="Definicja numeru PESEL na Wikipedii" (click)="navigateToDocs()" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
0
src/app/components/pesel/pesel.component.scss
Normal file
52
src/app/components/pesel/pesel.component.ts
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { AbstractControl, FormControl } from '@angular/forms';
|
||||||
|
import { PeselService } from 'src/app/service/pesel.service';
|
||||||
|
import { ClipboardService } from 'src/app/service/gui/clipboard.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-pesel',
|
||||||
|
templateUrl: './pesel.component.html',
|
||||||
|
styleUrls: ['./pesel.component.scss']
|
||||||
|
})
|
||||||
|
export class PeselComponent implements OnInit {
|
||||||
|
public valueField: FormControl;
|
||||||
|
|
||||||
|
public generateMale: boolean;
|
||||||
|
public generateFemale: boolean;
|
||||||
|
|
||||||
|
constructor(private peselService: PeselService, private clipboardService: ClipboardService) {
|
||||||
|
this.valueField = new FormControl('pesel');
|
||||||
|
this.valueField.setValidators([(control: AbstractControl) => this.peselService.validatePesel(control.value)]);
|
||||||
|
|
||||||
|
this.generateMale = true;
|
||||||
|
this.generateFemale = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
generate(): void {
|
||||||
|
if (this.generateMale === false && this.generateFemale === false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.valueField.setValue(this.peselService.generatePesel(this.generateMale, this.generateFemale));
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleMale(): void {
|
||||||
|
this.generateMale = !this.generateMale;
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleFemale(): void {
|
||||||
|
this.generateFemale = !this.generateFemale;
|
||||||
|
}
|
||||||
|
|
||||||
|
copyToClipboard(): void {
|
||||||
|
this.clipboardService.copyToClipboard(this.valueField.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
navigateToDocs(): void {
|
||||||
|
window.open('https://pl.wikipedia.org/wiki/PESEL', "_blank");
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/app/components/regon/regon.component.css
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/* No CSS *//*# sourceMappingURL=regon.component.css.map */
|
||||||
9
src/app/components/regon/regon.component.css.map
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"mappings": "",
|
||||||
|
"sources": [
|
||||||
|
"regon.component.scss"
|
||||||
|
],
|
||||||
|
"names": [],
|
||||||
|
"file": "regon.component.css"
|
||||||
|
}
|
||||||
14
src/app/components/regon/regon.component.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<div class="generator">
|
||||||
|
<div class="title">
|
||||||
|
<span>REGON</span>
|
||||||
|
</div>
|
||||||
|
<div class="container">
|
||||||
|
<input type="text" [formControl]="valueField" />
|
||||||
|
|
||||||
|
<div class="buttons">
|
||||||
|
<img id="regonGenerateButton" src="assets/autorenew_black_24dp.svg" title="Generuj numer REGON" alt="Generuj numer REGON" (click)="generate()"/>
|
||||||
|
<img id="regonCopyButton" src="assets/content_copy_black_24dp.svg" title="Skopiuj numer REGON do schowka" alt="Skopiuj numer REGON do schowka" (click)="copyToClipboard()"/>
|
||||||
|
<img id="regonHelpButton" src="assets/info_black_24dp.svg" title="Definicja numeru REGON na Wikipedii" alt="Definicja numeru REGON na Wikipedii" (click)="navigateToDocs()" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
0
src/app/components/regon/regon.component.scss
Normal file
34
src/app/components/regon/regon.component.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { AbstractControl, FormControl } from '@angular/forms';
|
||||||
|
import { RegonService } from 'src/app/service/regon.service';
|
||||||
|
import { ClipboardService } from 'src/app/service/gui/clipboard.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-regon',
|
||||||
|
templateUrl: './regon.component.html',
|
||||||
|
styleUrls: ['./regon.component.scss']
|
||||||
|
})
|
||||||
|
export class RegonComponent implements OnInit {
|
||||||
|
public valueField: FormControl;
|
||||||
|
|
||||||
|
constructor(private regonService: RegonService, private clipboardService: ClipboardService) {
|
||||||
|
this.valueField = new FormControl('nip');
|
||||||
|
this.valueField.setValidators([(control: AbstractControl) => this.regonService.validateRegon9(control.value)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.generate();
|
||||||
|
}
|
||||||
|
|
||||||
|
generate(): void {
|
||||||
|
this.valueField.setValue(this.regonService.generateRegon9());
|
||||||
|
}
|
||||||
|
|
||||||
|
copyToClipboard(): void {
|
||||||
|
this.clipboardService.copyToClipboard(this.valueField.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
navigateToDocs(): void {
|
||||||
|
window.open('https://pl.wikipedia.org/wiki/REGON', "_blank");
|
||||||
|
}
|
||||||
|
}
|
||||||
74
src/app/service/common.service.ts
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class CommonService {
|
||||||
|
// numeryczny regexp
|
||||||
|
public static readonly numericRegExp: RegExp = new RegExp("^[0-9]*$");
|
||||||
|
|
||||||
|
constructor() { }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waliduje cyfrę kontrolną dla przekazanej wartości i wag kolejnych cyfr.
|
||||||
|
*
|
||||||
|
* @param value wartość wejściowa do wyliczenia cyfry kontrolnej
|
||||||
|
* @param weights wejściowy zbiór wag
|
||||||
|
* @param lastStepFunction funkcja matematyczna finalizująca wyliczoną sumę
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public validateControlDigit(value: string, weights: number[], lastStepFunction: (weight: number) => number): boolean {
|
||||||
|
const controlDigit: number = this.calculateControlDigit(value, weights, lastStepFunction);
|
||||||
|
const digits: string[] = value.split("");
|
||||||
|
|
||||||
|
return controlDigit == parseInt(digits[digits.length - 1], 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wylicza cyfrę kontrolną dla przekazanej wartości używając przekazanej tablicy wag i końcowej operacji matematycznej
|
||||||
|
*
|
||||||
|
* @param value analizowana wartość
|
||||||
|
* @param weights tablica wag dla kolejnych cyfr
|
||||||
|
* @param lastStepFunction finalizujące działanie matematyczne
|
||||||
|
* @returns wyliczona cyfra kontrolna
|
||||||
|
*/
|
||||||
|
public calculateControlDigit(value: string, weights: number[], lastStepFunction: (weight: number) => number): number {
|
||||||
|
let digits: string[] = value.split("");
|
||||||
|
let calculatedChecksum: number = 0;
|
||||||
|
|
||||||
|
for (let i = 0; i < weights.length; i++) {
|
||||||
|
let digit: number = parseInt(digits[i], 10);
|
||||||
|
calculatedChecksum += digit * weights[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastStepFunction.call(this, calculatedChecksum);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Zwraca liczbę losową z podanego zakresu
|
||||||
|
*
|
||||||
|
* @param min minimalna zwrócona
|
||||||
|
* @param max maksymalna zwrócona wartość
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public getRandomInt(min: number, max: number): number {
|
||||||
|
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Konwertuje przekazaną wartość do tekstu i dopełnia zerami z lewej strony
|
||||||
|
*
|
||||||
|
* @param value przekazana wartość liczbowa
|
||||||
|
* @param length długość tekstu z dopełnionymi zerami
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public pad(value: number, length: number): string {
|
||||||
|
let text: string = value + "";
|
||||||
|
|
||||||
|
while (text.length < length) {
|
||||||
|
text = "0" + text;
|
||||||
|
}
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/app/service/gui/clipboard.service.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { Clipboard } from '@angular/cdk/clipboard';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class ClipboardService {
|
||||||
|
|
||||||
|
constructor(private snackBar: MatSnackBar, private clipboard: Clipboard) { }
|
||||||
|
|
||||||
|
copyToClipboard(value: string): void {
|
||||||
|
if (value == '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.clipboard.copy(value);
|
||||||
|
this.snackBar.open("Skopiowano do schowka.", "", {
|
||||||
|
duration: 1000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
71
src/app/service/iban.service.ts
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ValidationErrors } from '@angular/forms';
|
||||||
|
import { CommonService } from './common.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class IbanService {
|
||||||
|
private readonly bankSortCode: number = 13201784;
|
||||||
|
private readonly magic: number = 252100;
|
||||||
|
|
||||||
|
constructor(private common: CommonService) { }
|
||||||
|
|
||||||
|
public generateIban(): string {
|
||||||
|
const part1: string = this.common.pad(this.common.getRandomInt(1, 9999), 4);
|
||||||
|
const part2: string = this.common.pad(this.common.getRandomInt(1, 9999), 4);
|
||||||
|
const part3: string = this.common.pad(this.common.getRandomInt(1, 9999), 4);
|
||||||
|
const part4: string = this.common.pad(this.common.getRandomInt(1, 9999), 4);
|
||||||
|
|
||||||
|
const ibanWithoutControlDigit = this.bankSortCode + part1 + part2 + part3 + part4;
|
||||||
|
|
||||||
|
const controlDigit: string = this.calculateControlDigit(ibanWithoutControlDigit);
|
||||||
|
|
||||||
|
return controlDigit + ibanWithoutControlDigit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public validateIban(iban: string): ValidationErrors | null {
|
||||||
|
const errors: ValidationErrors = {};
|
||||||
|
|
||||||
|
iban = iban.replace(/ /g, "");
|
||||||
|
|
||||||
|
if (/[a-zA-Z]{2}\d*/g.test(iban)) {
|
||||||
|
iban = iban.substr(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iban.length < 26) {
|
||||||
|
errors.tooShort = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iban.length > 26) {
|
||||||
|
errors.tooLong = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CommonService.numericRegExp.test(iban)) {
|
||||||
|
errors.invalidPattern = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iban.length == 26 && !errors.invalidPattern && !this.validateIbanControlDigit(iban)) {
|
||||||
|
errors.invalidControlDigit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private validateIbanControlDigit(iban: string): boolean {
|
||||||
|
const controlDigit: string = iban.substring(0, 2);
|
||||||
|
const ibanWithoutControlDigit = iban.substring(2, 26);
|
||||||
|
|
||||||
|
const calculatedControlDigit: string = this.calculateControlDigit(ibanWithoutControlDigit);
|
||||||
|
|
||||||
|
return controlDigit == calculatedControlDigit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private calculateControlDigit(value: string): string {
|
||||||
|
const ibanWithoutControlDigit = BigInt(value + this.magic);
|
||||||
|
const rest: bigint = ibanWithoutControlDigit % BigInt(97);
|
||||||
|
const controlDigit: number = 98 - Number(rest);
|
||||||
|
|
||||||
|
return this.common.pad(controlDigit, 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
92
src/app/service/nip.service.ts
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ValidationErrors } from '@angular/forms';
|
||||||
|
import { CommonService } from './common.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class NipService {
|
||||||
|
// wagi kolejnych cyfr numeru NIP
|
||||||
|
private readonly nipWeights: Array<number> = [6, 5, 7, 2, 3, 4, 5, 6, 7];
|
||||||
|
|
||||||
|
private readonly officeCodes: number[] = [
|
||||||
|
107, 108, 109, 111, 112, 113, 114, 115, 116, 117, 118, 119, 121, 122, 123, 124, 125, 154, 156, 157, 158, 337, 338, 339, 341, 342, 355, 356, 375, 376, 377, 378,
|
||||||
|
379, 381, 389, 392, 393, 394, 416, 417, 496, 497, 509, 511, 512, 519, 521, 522, 523, 524, 525, 526, 527, 528, 529, 531, 532, 533, 534, 535, 536, 566, 567, 568,
|
||||||
|
569, 572, 601, 701, 757, 758, 759, 761, 762, 774, 776, 796, 797, 798, 799, 811, 812, 821, 822, 823, 826, 837, 838, 931, 932, 948, 951, 952, 965, 971, 978
|
||||||
|
];
|
||||||
|
|
||||||
|
constructor(private common: CommonService) { }
|
||||||
|
|
||||||
|
public generateNip(): string {
|
||||||
|
let nipWithoutControlDigit: string;
|
||||||
|
let controlDigit: number = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
// losowanie pierwszych 9 cyfr
|
||||||
|
const officeCode: number = this.officeCodes[this.common.getRandomInt(0, this.officeCodes.length - 1)];
|
||||||
|
const rest: number = this.common.getRandomInt(0, 999999);
|
||||||
|
|
||||||
|
// wyliczenie cyfry kontrolnej
|
||||||
|
nipWithoutControlDigit = this.common.pad(officeCode, 3) + this.common.pad(rest, 6);
|
||||||
|
controlDigit = this.common.calculateControlDigit(nipWithoutControlDigit, this.nipWeights, this.lastStepFunction);
|
||||||
|
} while (controlDigit == 10);
|
||||||
|
|
||||||
|
// ostateczna konkatenacja
|
||||||
|
return nipWithoutControlDigit + controlDigit;
|
||||||
|
}
|
||||||
|
|
||||||
|
validateNip(nip: string): ValidationErrors | null {
|
||||||
|
const errors: ValidationErrors = {};
|
||||||
|
|
||||||
|
if (nip.length < 10) {
|
||||||
|
errors.tooShort = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nip.length > 10) {
|
||||||
|
errors.tooLong = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy wszystkie znaki są cyframi
|
||||||
|
if (!this.validateNipRegExp(nip)) {
|
||||||
|
errors.invalidPattern = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy kod placówki jest poprawny
|
||||||
|
if (nip.length >= 3 && !this.validateNipOfficeCode(nip)) {
|
||||||
|
errors.nipInvalidOfficeCode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy cyfra kontrolna jest poprawna
|
||||||
|
if (nip.length == 10 && !errors.invalidPattern && !this.validateNipControlDigit(nip)) {
|
||||||
|
errors.invalidControlDigit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Walidacja numeru PESEL przy użyciu wyrażeń regularnych
|
||||||
|
* @param pesel
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
private validateNipRegExp(pesel: string): boolean {
|
||||||
|
return CommonService.numericRegExp.test(pesel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pelna walidacja numeru PESEL: regexpem i weryfikacja cyfry kontrolnej
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
private validateNipControlDigit(pesel: string): boolean {
|
||||||
|
return this.common.validateControlDigit(pesel, this.nipWeights, this.lastStepFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private validateNipOfficeCode(pesel: string): boolean {
|
||||||
|
const officeCode : number = parseInt(pesel.substring(0, 3), 10);
|
||||||
|
return this.officeCodes.indexOf(officeCode) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private lastStepFunction(sum: number): number {
|
||||||
|
return sum % 11;
|
||||||
|
}
|
||||||
|
}
|
||||||
172
src/app/service/pesel.service.ts
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { CommonService } from './common.service';
|
||||||
|
import { endOfMonth } from 'date-fns'
|
||||||
|
import { ValidationErrors } from '@angular/forms';
|
||||||
|
import { concat } from 'rxjs';
|
||||||
|
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'any'
|
||||||
|
})
|
||||||
|
export class PeselService {
|
||||||
|
// wagi kolejnych cyfr numeru PESEL
|
||||||
|
private readonly peselWeights: number[] = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3];
|
||||||
|
|
||||||
|
private readonly maleDigits: number[] = [1, 3, 5, 7, 9];
|
||||||
|
|
||||||
|
private readonly femaleDigits: number[] = [0, 2, 4, 6, 8];
|
||||||
|
|
||||||
|
constructor(private common: CommonService) { }
|
||||||
|
|
||||||
|
public generatePesel(male: boolean, female: boolean): string {
|
||||||
|
// losowanie pierwszych 10 cyfr
|
||||||
|
const year: number = this.common.getRandomInt(0, 99);
|
||||||
|
const month: number = this.common.getRandomInt(1, 12);
|
||||||
|
const endDayOfMonth: number = endOfMonth(new Date(year, month - 1)).getDate();
|
||||||
|
const day: number = this.common.getRandomInt(1, endDayOfMonth);
|
||||||
|
const rest: number = this.common.getRandomInt(0, 999);
|
||||||
|
|
||||||
|
const sexDigits: number[] = [... male ? this.maleDigits : [], ...female ? this.femaleDigits : []];
|
||||||
|
|
||||||
|
const sexDigitIndex: number = this.common.getRandomInt(0, sexDigits.length - 1);
|
||||||
|
const sexDigit = sexDigits[sexDigitIndex];
|
||||||
|
|
||||||
|
// wyliczenie cyfry kontrolnej
|
||||||
|
const peselWithoutControlDigit: string = this.common.pad(year, 2) + this.common.pad(month, 2) + this.common.pad(day, 2) + this.common.pad(rest, 3) + this.common.pad(sexDigit, 1);
|
||||||
|
const controlDigit: number = this.common.calculateControlDigit(peselWithoutControlDigit, this.peselWeights, this.lastStepFunction);
|
||||||
|
|
||||||
|
// ostateczna konkatenacja
|
||||||
|
return peselWithoutControlDigit + controlDigit;
|
||||||
|
}
|
||||||
|
|
||||||
|
validatePesel(pesel: string): ValidationErrors | null {
|
||||||
|
const errors: ValidationErrors = {};
|
||||||
|
|
||||||
|
if (pesel.length < 11) {
|
||||||
|
errors.tooShort = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pesel.length > 11) {
|
||||||
|
errors.tooLong = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy wszystkie znaki są cyframi
|
||||||
|
if (!this.validatePeselRegExp(pesel)) {
|
||||||
|
errors.invalidPattern = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy miesiac jest poprawny
|
||||||
|
if (pesel.length >= 4 && !this.validatePeselMonth(pesel)) {
|
||||||
|
errors.peselInvalidBirthMonth = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy dzien jest poprawny
|
||||||
|
if (pesel.length >= 6 && !this.validatePeselDay(pesel)) {
|
||||||
|
errors.peselInvalidBirthDay = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy cyfra kontrolna jest poprawna
|
||||||
|
if (pesel.length == 11 && !errors.invalidPattern && !this.validatePeselControlDigit(pesel)) {
|
||||||
|
errors.invalidControlDigit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Walidacja numeru PESEL przy użyciu wyrażeń regularnych
|
||||||
|
* @param pesel
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
private validatePeselRegExp(pesel: string): boolean {
|
||||||
|
return CommonService.numericRegExp.test(pesel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pelna walidacja numeru PESEL: regexpem i weryfikacja cyfry kontrolnej
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
private validatePeselControlDigit(pesel: string): boolean {
|
||||||
|
return this.common.validateControlDigit(pesel, this.peselWeights, this.lastStepFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Waliduje datę w numerze PESEL:
|
||||||
|
* 1800-1899 - miesiąc od 81
|
||||||
|
* 1900-1999 - miesiąc od 01
|
||||||
|
* 2000-2099 - miesiąc od 21
|
||||||
|
* 2100-2199 - miesiąc od 41
|
||||||
|
* 2200-2299 - miesiąc od 61
|
||||||
|
*
|
||||||
|
* @param pesel
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
private validatePeselMonth(pesel: string): boolean {
|
||||||
|
const month: number = parseInt(pesel.substring(2, 4), 10);
|
||||||
|
|
||||||
|
return month > 0 && month < 13 ||
|
||||||
|
month > 20 && month < 33 ||
|
||||||
|
month > 40 && month < 53 ||
|
||||||
|
month > 60 && month < 73 ||
|
||||||
|
month > 80 && month < 93;
|
||||||
|
}
|
||||||
|
|
||||||
|
private validatePeselDay(pesel: string): boolean {
|
||||||
|
// jesli nie mamy miesiaca to sprawdzamy twardy limit na 31
|
||||||
|
if (!this.validatePeselMonth(pesel)) {
|
||||||
|
const day: number = parseInt(pesel.substring(4, 6), 10);
|
||||||
|
|
||||||
|
return day <= 31;
|
||||||
|
}
|
||||||
|
|
||||||
|
const yearDiff: number = parseInt(pesel.substring(0, 2), 10);
|
||||||
|
const month: number = parseInt(pesel.substring(2, 4), 10);
|
||||||
|
const day: number = parseInt(pesel.substring(4, 6), 10);
|
||||||
|
const year: number = this.extractYearBasedOnMonth(month);
|
||||||
|
|
||||||
|
const endDayOfMonth: number = endOfMonth(new Date(year + yearDiff, month - 1)).getDate();
|
||||||
|
|
||||||
|
return day > 0 && day <= endDayOfMonth;
|
||||||
|
}
|
||||||
|
|
||||||
|
private extractDateFromPesel(pesel: string): Date | null {
|
||||||
|
const yearDiff: number = parseInt(pesel.substring(0, 2), 10);
|
||||||
|
const month: number = parseInt(pesel.substring(2, 4), 10);
|
||||||
|
const day: number = parseInt(pesel.substring(4, 6), 10);
|
||||||
|
|
||||||
|
let year: number = this.extractYearBasedOnMonth(month) + yearDiff;
|
||||||
|
|
||||||
|
const date: Date = new Date(year, month - 1, day)
|
||||||
|
|
||||||
|
if (date.getFullYear() == year && date.getMonth() + 1 == month && date.getDate() == day) {
|
||||||
|
return date;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extractYearBasedOnMonth(month: number): number {
|
||||||
|
if (month < 20) {
|
||||||
|
return 1900;
|
||||||
|
} else if (month < 40) {
|
||||||
|
return 2000;
|
||||||
|
} else if (month < 60) {
|
||||||
|
return 2100;
|
||||||
|
} else if (month < 80) {
|
||||||
|
return 2200;
|
||||||
|
} else {
|
||||||
|
return 1800;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lastStepFunction(sum: number): number {
|
||||||
|
sum = sum % 10;
|
||||||
|
|
||||||
|
if (sum == 0) {
|
||||||
|
sum = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
sum = 10 - sum;
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
}
|
||||||
123
src/app/service/regon.service.ts
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { ValidationErrors } from '@angular/forms';
|
||||||
|
import { CommonService } from './common.service';
|
||||||
|
|
||||||
|
@Injectable({
|
||||||
|
providedIn: 'root'
|
||||||
|
})
|
||||||
|
export class RegonService {
|
||||||
|
// wagi kolejnych cyfr numeru Regon/9
|
||||||
|
private static regon9Weights: number[] = [8, 9, 2, 3, 4, 5, 6, 7];
|
||||||
|
|
||||||
|
// wagi kolejnych cyfr numeru Regon/14
|
||||||
|
private static regon14Weights: number[] = [2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8];
|
||||||
|
|
||||||
|
// kody województw
|
||||||
|
private static provinceCodes: number[] = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51,
|
||||||
|
53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97];
|
||||||
|
|
||||||
|
constructor(private common: CommonService) { }
|
||||||
|
|
||||||
|
public generateRegon9(): string {
|
||||||
|
const provinceIndex: number = this.common.getRandomInt(0, RegonService.provinceCodes.length - 1);
|
||||||
|
const province: number = RegonService.provinceCodes[provinceIndex];
|
||||||
|
const rest: number = this.common.getRandomInt(0, 999999);
|
||||||
|
const regonWithoutControlDigit: string = this.common.pad(province, 2) + this.common.pad(rest, 6);
|
||||||
|
|
||||||
|
const controlDigit: number = this.common.calculateControlDigit(regonWithoutControlDigit, RegonService.regon9Weights, this.lastStepFunction);
|
||||||
|
|
||||||
|
return regonWithoutControlDigit + controlDigit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public generateRegon14(): string {
|
||||||
|
const provinceIndex: number = this.common.getRandomInt(0, RegonService.provinceCodes.length - 1);
|
||||||
|
const province: number = RegonService.provinceCodes[provinceIndex];
|
||||||
|
const rest: number = this.common.getRandomInt(0, 999999);
|
||||||
|
const rest2: number = this.common.getRandomInt(0, 99999);
|
||||||
|
const regonWithoutControlDigit: string = this.common.pad(province, 2) + this.common.pad(rest, 6) + this.common.pad(rest2, 5);
|
||||||
|
|
||||||
|
const controlDigit: number = this.common.calculateControlDigit(regonWithoutControlDigit, RegonService.regon14Weights, this.lastStepFunction);
|
||||||
|
|
||||||
|
return regonWithoutControlDigit + controlDigit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public validateRegon9(regon: string): ValidationErrors | null {
|
||||||
|
const errors: ValidationErrors = {};
|
||||||
|
|
||||||
|
if (regon.length < 9) {
|
||||||
|
errors.tooShort = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regon.length > 9) {
|
||||||
|
errors.tooLong = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy wszystkie znaki są cyframi
|
||||||
|
if (!this.validateRegonRegExp(regon)) {
|
||||||
|
errors.invalidPattern = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy kod placówki jest poprawny
|
||||||
|
if (regon.length >= 2 && !this.validateProvinceCode(regon)) {
|
||||||
|
errors.regonInvalidProvinceCode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy cyfra kontrolna jest poprawna
|
||||||
|
if (regon.length == 9 && !errors.invalidPattern && !this.validateRegon9ControlDigit(regon)) {
|
||||||
|
errors.invalidControlDigit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
public validateRegon14(regon: string): ValidationErrors | null {
|
||||||
|
const errors: ValidationErrors = {};
|
||||||
|
|
||||||
|
if (regon.length < 14) {
|
||||||
|
errors.tooShort = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regon.length > 14) {
|
||||||
|
errors.tooLong = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy wszystkie znaki są cyframi
|
||||||
|
if (!this.validateRegonRegExp(regon)) {
|
||||||
|
errors.invalidPattern = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy kod placówki jest poprawny
|
||||||
|
if (regon.length >= 2 && !this.validateProvinceCode(regon)) {
|
||||||
|
errors.regonInvalidProvinceCode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// czy cyfra kontrolna jest poprawna
|
||||||
|
if (regon.length == 14 && !errors.invalidPattern && !this.validateRegon14ControlDigit(regon)) {
|
||||||
|
errors.invalidControlDigit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
private validateRegon9ControlDigit(value: string): boolean {
|
||||||
|
return this.common.validateControlDigit(value, RegonService.regon9Weights, this.lastStepFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private validateRegon14ControlDigit(value: string): boolean {
|
||||||
|
return this.common.validateControlDigit(value, RegonService.regon14Weights, this.lastStepFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private validateProvinceCode(value: string): boolean {
|
||||||
|
const provinceCode: number = parseInt(value.substring(0, 2), 10);
|
||||||
|
return RegonService.provinceCodes.indexOf(provinceCode) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private validateRegonRegExp(regon: string): boolean {
|
||||||
|
return CommonService.numericRegExp.test(regon);
|
||||||
|
}
|
||||||
|
|
||||||
|
private lastStepFunction(sum: number): number {
|
||||||
|
const modulo = sum % 11;
|
||||||
|
return modulo == 10 ? 0 : modulo;
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/app/translate-pipe.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { Pipe, PipeTransform } from '@angular/core';
|
||||||
|
|
||||||
|
@Pipe({ name: 'translate' })
|
||||||
|
export class TranslatePipe implements PipeTransform {
|
||||||
|
private readonly translations: Map<string, string> = new Map([
|
||||||
|
// wspólne
|
||||||
|
["tooLong", "Numer jest zbyt długi."],
|
||||||
|
["tooShort", "Numer jest zbyt krótki."],
|
||||||
|
["invalidPattern", "Wprowadzono znak niebędący cyfrą."],
|
||||||
|
["invalidControlDigit", "Cyfra kontrolna jest niepoprawna."],
|
||||||
|
|
||||||
|
// PESEL
|
||||||
|
["peselInvalidBirthMonth", "Miesiąc w dacie urodzenia jest niepoprawny."],
|
||||||
|
["peselInvalidBirthDay", "Dzień w dacie urodzenia jest niepoprawny."],
|
||||||
|
|
||||||
|
// NIP
|
||||||
|
["nipInvalidOfficeCode", "Kod urzędu skarbowego jest niepoprawny."],
|
||||||
|
|
||||||
|
// REGON
|
||||||
|
["regonInvalidProvinceCode", "Kod województwa jest nieprawidłowy."]
|
||||||
|
]);
|
||||||
|
|
||||||
|
transform(code: string): string {
|
||||||
|
const translated: string | undefined = this.translations.get(code);
|
||||||
|
|
||||||
|
if (translated === undefined) {
|
||||||
|
return 'Translation undefined for code: ' + code;
|
||||||
|
}
|
||||||
|
|
||||||
|
return translated;
|
||||||
|
}
|
||||||
|
}
|
||||||
0
src/assets/.gitkeep
Normal file
BIN
src/assets/Comfortaa-VariableFont_wght.ttf
Normal file
1
src/assets/autorenew_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12 6v1.79c0 .45.54.67.85.35l2.79-2.79c.2-.2.2-.51 0-.71l-2.79-2.79c-.31-.31-.85-.09-.85.36V4c-4.42 0-8 3.58-8 8 0 1.04.2 2.04.57 2.95.27.67 1.13.85 1.64.34.27-.27.38-.68.23-1.04C6.15 13.56 6 12.79 6 12c0-3.31 2.69-6 6-6zm5.79 2.71c-.27.27-.38.69-.23 1.04.28.7.44 1.46.44 2.25 0 3.31-2.69 6-6 6v-1.79c0-.45-.54-.67-.85-.35l-2.79 2.79c-.2.2-.2.51 0 .71l2.79 2.79c.31.31.85.09.85-.35V20c4.42 0 8-3.58 8-8 0-1.04-.2-2.04-.57-2.95-.27-.67-1.13-.85-1.64-.34z"/></svg>
|
||||||
|
After Width: | Height: | Size: 612 B |
1
src/assets/cached_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M18.65 8.35l-2.79 2.79c-.32.32-.1.86.35.86H18c0 3.31-2.69 6-6 6-.79 0-1.56-.15-2.25-.44-.36-.15-.77-.04-1.04.23-.51.51-.33 1.37.34 1.64.91.37 1.91.57 2.95.57 4.42 0 8-3.58 8-8h1.79c.45 0 .67-.54.35-.85l-2.79-2.79c-.19-.2-.51-.2-.7-.01zM6 12c0-3.31 2.69-6 6-6 .79 0 1.56.15 2.25.44.36.15.77.04 1.04-.23.51-.51.33-1.37-.34-1.64C14.04 4.2 13.04 4 12 4c-4.42 0-8 3.58-8 8H2.21c-.45 0-.67.54-.35.85l2.79 2.79c.2.2.51.2.71 0l2.79-2.79c.31-.31.09-.85-.36-.85H6z"/></svg>
|
||||||
|
After Width: | Height: | Size: 613 B |
1
src/assets/contact_support_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M11 23.59v-3.6c-5.01-.26-9-4.42-9-9.49C2 5.26 6.26 1 11.5 1S21 5.26 21 10.5c0 4.95-3.44 9.93-8.57 12.4l-1.43.69zM11.5 3C7.36 3 4 6.36 4 10.5S7.36 18 11.5 18H13v2.3c3.64-2.3 6-6.08 6-9.8C19 6.36 15.64 3 11.5 3zm-1 11.5h2v2h-2zm2-1.5h-2c0-3.25 3-3 3-5 0-1.1-.9-2-2-2s-2 .9-2 2h-2c0-2.21 1.79-4 4-4s4 1.79 4 4c0 2.5-3 2.75-3 5z"/></svg>
|
||||||
|
After Width: | Height: | Size: 483 B |
1
src/assets/content_copy_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><path d="M15,20H5V7c0-0.55-0.45-1-1-1h0C3.45,6,3,6.45,3,7v13c0,1.1,0.9,2,2,2h10c0.55,0,1-0.45,1-1v0C16,20.45,15.55,20,15,20z M20,16V4c0-1.1-0.9-2-2-2H9C7.9,2,7,2.9,7,4v12c0,1.1,0.9,2,2,2h9C19.1,18,20,17.1,20,16z M18,16H9V4h9V16z"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 429 B |
1
src/assets/copy_all_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M18,2H9C7.9,2,7,2.9,7,4v12c0,1.1,0.9,2,2,2h9c1.1,0,2-0.9,2-2V4C20,2.9,19.1,2,18,2z M18,16H9V4h9V16z M3,15v-2h2v2H3z M3,9.5h2v2H3V9.5z M10,20h2v2h-2V20z M3,18.5v-2h2v2H3z M5,22c-1.1,0-2-0.9-2-2h2V22z M8.5,22h-2v-2h2V22z M13.5,22L13.5,22l0-2h2 v0C15.5,21.1,14.6,22,13.5,22z M5,6L5,6l0,2H3v0C3,6.9,3.9,6,5,6z"/></svg>
|
||||||
|
After Width: | Height: | Size: 501 B |
1
src/assets/female_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M17.5,9.5C17.5,6.46,15.04,4,12,4S6.5,6.46,6.5,9.5c0,2.7,1.94,4.93,4.5,5.4V17H9v2h2v2h2v-2h2v-2h-2v-2.1 C15.56,14.43,17.5,12.2,17.5,9.5z M8.5,9.5C8.5,7.57,10.07,6,12,6s3.5,1.57,3.5,3.5S13.93,13,12,13S8.5,11.43,8.5,9.5z"/></svg>
|
||||||
|
After Width: | Height: | Size: 413 B |
1
src/assets/filter_none_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M2 5c-.55 0-1 .45-1 1v15c0 1.1.9 2 2 2h15c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1-.45-1-1V6c0-.55-.45-1-1-1zm19-4H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V3c0-1.1-.9-2-2-2zm-1 16H8c-.55 0-1-.45-1-1V4c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1z"/></svg>
|
||||||
|
After Width: | Height: | Size: 422 B |
1
src/assets/format_color_text_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/></g><g><path d="M2,20h20v4H2V20z M5.49,17h2.42l1.27-3.58h5.65L16.09,17h2.42L13.25,3h-2.5L5.49,17z M9.91,11.39l2.03-5.79h0.12l2.03,5.79 H9.91z"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 335 B |
1
src/assets/help_center_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g><rect fill="none" height="24" width="24"/><path d="M13.25,16.74c0,0.69-0.53,1.26-1.25,1.26c-0.7,0-1.26-0.56-1.26-1.26c0-0.71,0.56-1.25,1.26-1.25 C12.71,15.49,13.25,16.04,13.25,16.74z M11.99,6c-1.77,0-2.98,1.15-3.43,2.49l1.64,0.69c0.22-0.67,0.74-1.48,1.8-1.48 c1.62,0,1.94,1.52,1.37,2.33c-0.54,0.77-1.47,1.29-1.96,2.16c-0.39,0.69-0.31,1.49-0.31,1.98h1.82c0-0.93,0.07-1.12,0.22-1.41 c0.39-0.72,1.11-1.06,1.87-2.17c0.68-1,0.42-2.36-0.02-3.08C14.48,6.67,13.47,6,11.99,6z M19,5H5v14h14V5 M19,3c1.1,0,2,0.9,2,2v14 c0,1.1-0.9,2-2,2H5c-1.1,0-2-0.9-2-2V5c0-1.1,0.9-2,2-2H19L19,3z"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 722 B |
1
src/assets/help_outline_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-4h2v2h-2zm1.61-9.96c-2.06-.3-3.88.97-4.43 2.79-.18.58.26 1.17.87 1.17h.2c.41 0 .74-.29.88-.67.32-.89 1.27-1.5 2.3-1.28.95.2 1.65 1.13 1.57 2.1-.1 1.34-1.62 1.63-2.45 2.88 0 .01-.01.01-.01.02-.01.02-.02.03-.03.05-.09.15-.18.32-.25.5-.01.03-.03.05-.04.08-.01.02-.01.04-.02.07-.12.34-.2.75-.2 1.25h2c0-.42.11-.77.28-1.07.02-.03.03-.06.05-.09.08-.14.18-.27.28-.39.01-.01.02-.03.03-.04.1-.12.21-.23.33-.34.96-.91 2.26-1.65 1.99-3.56-.24-1.74-1.61-3.21-3.35-3.47z"/></svg>
|
||||||
|
After Width: | Height: | Size: 744 B |
1
src/assets/info_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M11 7h2v2h-2zm0 4h2v6h-2zm1-9C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></svg>
|
||||||
|
After Width: | Height: | Size: 307 B |
1
src/assets/input_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g fill="none"><path d="M0 0h24v24H0V0z"/><path d="M0 0h24v24H0V0z" opacity=".87"/></g><path d="M21 3.01H3c-1.1 0-2 .9-2 2V8c0 .55.45 1 1 1s1-.45 1-1V5.99c0-.55.45-1 1-1h16c.55 0 1 .45 1 1v12.03c0 .55-.45 1-1 1H4c-.55 0-1-.45-1-1V16c0-.55-.45-1-1-1s-1 .45-1 1v3.01c0 1.09.89 1.98 1.98 1.98H21c1.1 0 2-.9 2-2V5.01c0-1.1-.9-2-2-2zm-9.15 12.14l2.79-2.79c.2-.2.2-.51 0-.71l-2.79-2.79c-.31-.32-.85-.1-.85.35V11H2c-.55 0-1 .45-1 1s.45 1 1 1h9v1.79c0 .45.54.67.85.36z"/></svg>
|
||||||
|
After Width: | Height: | Size: 571 B |
1
src/assets/male_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="M9.5,11c1.93,0,3.5,1.57,3.5,3.5S11.43,18,9.5,18S6,16.43,6,14.5S7.57,11,9.5,11z M9.5,9C6.46,9,4,11.46,4,14.5 S6.46,20,9.5,20s5.5-2.46,5.5-5.5c0-1.16-0.36-2.23-0.97-3.12L18,7.42V10h2V4h-6v2h2.58l-3.97,3.97C11.73,9.36,10.66,9,9.5,9z"/></svg>
|
||||||
|
After Width: | Height: | Size: 425 B |
1
src/assets/refresh_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M17.65 6.35c-1.63-1.63-3.94-2.57-6.48-2.31-3.67.37-6.69 3.35-7.1 7.02C3.52 15.91 7.27 20 12 20c3.19 0 5.93-1.87 7.21-4.56.32-.67-.16-1.44-.9-1.44-.37 0-.72.2-.88.53-1.13 2.43-3.84 3.97-6.8 3.31-2.22-.49-4.01-2.3-4.48-4.52C5.31 9.44 8.26 6 12 6c1.66 0 3.14.69 4.22 1.78l-1.51 1.51c-.63.63-.19 1.71.7 1.71H19c.55 0 1-.45 1-1V6.41c0-.89-1.08-1.34-1.71-.71l-.64.65z"/></svg>
|
||||||
|
After Width: | Height: | Size: 520 B |
1
src/assets/save_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M17.59 3.59c-.38-.38-.89-.59-1.42-.59H5c-1.11 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V7.83c0-.53-.21-1.04-.59-1.41l-2.82-2.83zM12 19c-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3-1.34 3-3 3zm1-10H7c-1.1 0-2-.9-2-2s.9-2 2-2h6c1.1 0 2 .9 2 2s-.9 2-2 2z"/></svg>
|
||||||
|
After Width: | Height: | Size: 410 B |
1
src/assets/space_bar_black_24dp.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M18 9v4H6V9H4v6h16V9h-2z"/></svg>
|
||||||
|
After Width: | Height: | Size: 183 B |
3
src/environments/environment.prod.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export const environment = {
|
||||||
|
production: true
|
||||||
|
};
|
||||||
16
src/environments/environment.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
// This file can be replaced during build by using the `fileReplacements` array.
|
||||||
|
// `ng build` replaces `environment.ts` with `environment.prod.ts`.
|
||||||
|
// The list of file replacements can be found in `angular.json`.
|
||||||
|
|
||||||
|
export const environment = {
|
||||||
|
production: false
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For easier debugging in development mode, you can import the following file
|
||||||
|
* to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`.
|
||||||
|
*
|
||||||
|
* This import should be commented out in production mode because it will have a negative impact
|
||||||
|
* on performance if an error is thrown.
|
||||||
|
*/
|
||||||
|
// import 'zone.js/plugins/zone-error'; // Included with Angular CLI.
|
||||||
BIN
src/favicon.ico
Normal file
|
After Width: | Height: | Size: 948 B |
16
src/index.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Generator i walidator identyfikatorów</title>
|
||||||
|
<base href="/">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="icon" type="image/x-icon" href="favicon.ico">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<app-root></app-root>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
12
src/main.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { enableProdMode } from '@angular/core';
|
||||||
|
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
|
||||||
|
import { AppModule } from './app/app.module';
|
||||||
|
import { environment } from './environments/environment';
|
||||||
|
|
||||||
|
if (environment.production) {
|
||||||
|
enableProdMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
platformBrowserDynamic().bootstrapModule(AppModule)
|
||||||
|
.catch(err => console.error(err));
|
||||||
69
src/polyfills.ts
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/***************************************************************************************************
|
||||||
|
* Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
|
||||||
|
*/
|
||||||
|
import '@angular/localize/init';
|
||||||
|
/**
|
||||||
|
* This file includes polyfills needed by Angular and is loaded before the app.
|
||||||
|
* You can add your own extra polyfills to this file.
|
||||||
|
*
|
||||||
|
* This file is divided into 2 sections:
|
||||||
|
* 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
|
||||||
|
* 2. Application imports. Files imported after ZoneJS that should be loaded before your main
|
||||||
|
* file.
|
||||||
|
*
|
||||||
|
* The current setup is for so-called "evergreen" browsers; the last versions of browsers that
|
||||||
|
* automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
|
||||||
|
* Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
|
||||||
|
*
|
||||||
|
* Learn more in https://angular.io/guide/browser-support
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* BROWSER POLYFILLS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IE11 requires the following for NgClass support on SVG elements
|
||||||
|
*/
|
||||||
|
// import 'classlist.js'; // Run `npm install --save classlist.js`.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web Animations `@angular/platform-browser/animations`
|
||||||
|
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
|
||||||
|
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
|
||||||
|
*/
|
||||||
|
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, zone.js will patch all possible macroTask and DomEvents
|
||||||
|
* user can disable parts of macroTask/DomEvents patch by setting following flags
|
||||||
|
* because those flags need to be set before `zone.js` being loaded, and webpack
|
||||||
|
* will put import in the top of bundle, so user need to create a separate file
|
||||||
|
* in this directory (for example: zone-flags.ts), and put the following flags
|
||||||
|
* into that file, and then add the following code before importing zone.js.
|
||||||
|
* import './zone-flags';
|
||||||
|
*
|
||||||
|
* The flags allowed in zone-flags.ts are listed here.
|
||||||
|
*
|
||||||
|
* The following flags will work for all browsers.
|
||||||
|
*
|
||||||
|
* (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame
|
||||||
|
* (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick
|
||||||
|
* (window as any).__zone_symbol__UNPATCHED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames
|
||||||
|
*
|
||||||
|
* in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js
|
||||||
|
* with the following flag, it will bypass `zone.js` patch for IE/Edge
|
||||||
|
*
|
||||||
|
* (window as any).__Zone_enable_cross_context_check = true;
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* Zone JS is required by default for Angular itself.
|
||||||
|
*/
|
||||||
|
import 'zone.js'; // Included with Angular CLI.
|
||||||
|
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* APPLICATION IMPORTS
|
||||||
|
*/
|
||||||
194
src/styles.css
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Comfortaa';
|
||||||
|
src: url("assets/Comfortaa-VariableFont_wght.ttf");
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 150%;
|
||||||
|
font-family: 'Comfortaa', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gradient {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: -1;
|
||||||
|
background-image: -webkit-gradient(linear, left top, left bottom, from(#3362bc), color-stop(#3d6cc7), color-stop(#4776d1), color-stop(#5181dc), color-stop(#5a8be7), color-stop(#5a8be7), color-stop(#5b8ae7), color-stop(#5b8ae7), color-stop(#527fdc), color-stop(#4975d1), color-stop(#406ac7), to(#3760bc));
|
||||||
|
background-image: linear-gradient(to bottom, #3362bc, #3d6cc7, #4776d1, #5181dc, #5a8be7, #5a8be7, #5b8ae7, #5b8ae7, #527fdc, #4975d1, #406ac7, #3760bc);
|
||||||
|
}
|
||||||
|
|
||||||
|
.generators {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
-webkit-box-direction: normal;
|
||||||
|
-ms-flex-direction: row;
|
||||||
|
flex-direction: row;
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-ms-flex-positive: 1;
|
||||||
|
flex-grow: 1;
|
||||||
|
-ms-flex-negative: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
-webkit-box-pack: space-evenly;
|
||||||
|
-ms-flex-pack: space-evenly;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
-ms-flex-wrap: wrap;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generator {
|
||||||
|
margin: 1em;
|
||||||
|
background: rgba(255, 255, 255, 0.15);
|
||||||
|
-webkit-box-shadow: 0 8px 32px 0 rgba(0, 38, 135, 0.37);
|
||||||
|
box-shadow: 0 8px 32px 0 rgba(0, 38, 135, 0.37);
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin: 0 1em 1em 1em;
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
place-content: space-between;
|
||||||
|
-ms-flex-wrap: wrap;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .buttons {
|
||||||
|
margin-top: 1em;
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-ms-flex-wrap: nowrap;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
place-content: space-between;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .buttons img {
|
||||||
|
padding: .2em;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .buttons img:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .buttons :nth-child(1) {
|
||||||
|
margin: auto 0 auto 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container .buttons :nth-child(2) {
|
||||||
|
margin: auto 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
-webkit-box-direction: normal;
|
||||||
|
-ms-flex-direction: row;
|
||||||
|
flex-direction: row;
|
||||||
|
-webkit-box-pack: justify;
|
||||||
|
-ms-flex-pack: justify;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.7);
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.title span {
|
||||||
|
margin-left: 1em;
|
||||||
|
padding: 0.4em 0;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title .titleButtons {
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -ms-flexbox;
|
||||||
|
display: flex;
|
||||||
|
-webkit-box-orient: horizontal;
|
||||||
|
-webkit-box-direction: normal;
|
||||||
|
-ms-flex-direction: row;
|
||||||
|
flex-direction: row;
|
||||||
|
-ms-flex-pack: distribute;
|
||||||
|
justify-content: space-around;
|
||||||
|
-ms-flex-line-pack: center;
|
||||||
|
align-content: center;
|
||||||
|
margin: 0 1em;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title .titleButtons img {
|
||||||
|
padding: .1em;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title .titleButtons img:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.title .titleButtons .smaller {
|
||||||
|
padding: 0.2em;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"] {
|
||||||
|
margin-top: 1em;
|
||||||
|
width: 210px;
|
||||||
|
min-width: 0px;
|
||||||
|
-webkit-box-flex: 1;
|
||||||
|
-ms-flex-positive: 1;
|
||||||
|
flex-grow: 1;
|
||||||
|
-ms-flex-negative: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
padding: 0 0.7em;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
font-size: 1em;
|
||||||
|
height: 2em;
|
||||||
|
color: white;
|
||||||
|
background: rgba(255, 255, 255, 0.15);
|
||||||
|
-webkit-box-shadow: 0 8px 32px 0 rgba(0, 38, 135, 0.37);
|
||||||
|
box-shadow: 0 8px 32px 0 rgba(0, 38, 135, 0.37);
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"].ng-valid {
|
||||||
|
border-bottom: 3px solid #87e17a;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"].ng-invalid {
|
||||||
|
border-bottom: 3px solid #fb8686;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-filter: invert(100%);
|
||||||
|
filter: invert(100%);
|
||||||
|
margin: auto 0;
|
||||||
|
background: rgba(0, 0, 0, 0.15);
|
||||||
|
-webkit-box-shadow: 0 8px 32px 0 rgba(255, 217, 120, 0.37);
|
||||||
|
box-shadow: 0 8px 32px 0 rgba(255, 217, 120, 0.37);
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
/*# sourceMappingURL=styles.css.map */
|
||||||
9
src/styles.css.map
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"mappings": "AAAA,UAAU;EACR,WAAW,EAAE,WAAW;EACxB,GAAG,EAAE,6CAA6C;;;AAGpD,AAAA,IAAI,CAAC;EACH,OAAO,EAAE,CAAC;EACV,MAAM,EAAE,CAAC;EACT,eAAe,EAAE,IAAI;EACrB,MAAM,EAAE,IAAI;EACZ,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,4DAA4D;CAC1E;;AAED,AAAA,SAAS,CAAC;EACR,QAAQ,EAAE,KAAK;EACf,GAAG,EAAE,CAAC;EACN,IAAI,EAAE,CAAC;EACP,KAAK,EAAE,CAAC;EACR,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,EAAE;EACX,gBAAgB,EAAE,sIAAsI;CACzJ;;AAED,AAAA,WAAW,CAAC;EACV,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,GAAG;EACnB,SAAS,EAAE,CAAC;EACZ,WAAW,EAAE,CAAC;EACd,eAAe,EAAE,YAAY;EAC7B,SAAS,EAAE,IAAI;CAChB;;AAED,AAAA,UAAU,CAAC;EACT,MAAM,EAAE,GAAG;EACX,UAAU,EAAE,yBAA2B;EACvC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAwB;EACjD,aAAa,EAAE,GAAG;EAClB,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,yBAA2B;CAC9C;;AAED,AAAA,UAAU,CAAC;EACT,MAAM,EAAE,aAAa;EACrB,OAAO,EAAE,IAAI;EACb,aAAa,EAAE,aAAa;EAC5B,SAAS,EAAE,IAAI;CA2BhB;;AA/BD,AAME,UANQ,CAMR,QAAQ,CAAC;EACP,UAAU,EAAE,GAAG;EACf,OAAO,EAAE,IAAI;EACb,SAAS,EAAE,MAAM;EACjB,aAAa,EAAE,aAAa;EAC5B,WAAW,EAAE,IAAI;CAmBlB;;AA9BH,AAaI,UAbM,CAMR,QAAQ,CAON,GAAG,CAAC;EACA,OAAO,EAAE,IAAI;EACb,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;CAKf;;AArBL,AAkBQ,UAlBE,CAMR,QAAQ,CAON,GAAG,AAKE,MAAM,CAAC;EACJ,UAAU,EAAE,kBAAqB;CACpC;;AApBT,AAuBI,UAvBM,CAMR,QAAQ,CAiBN,UAAW,CAAA,CAAC,EAAE;EACZ,MAAM,EAAE,eAAe;CACxB;;AAzBL,AA2BI,UA3BM,CAMR,QAAQ,CAqBN,UAAW,CAAA,CAAC,EAAE;EACZ,MAAM,EAAE,QAAQ;CACjB;;AAIL,AAAA,MAAM,CAAC;EACL,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,GAAG;EACnB,eAAe,EAAE,aAAa;EAE9B,MAAM,EAAE,CAAC;EACT,OAAO,EAAE,CAAC;EAEV,sBAAsB,EAAE,GAAG;EAC3B,uBAAuB,EAAE,GAAG;EAC5B,aAAa,EAAE,GAAG,CAAC,KAAK,CAAC,wBAAwB;EACjD,UAAU,EAAE,wBAAyB;CAoCtC;;AA/CD,AAaE,MAbI,CAaJ,IAAI,CAAC;EACD,WAAW,EAAE,GAAG;EAChB,OAAO,EAAE,OAAO;EAChB,KAAK,EAAE,KAAK;EACZ,UAAU,EAAE,MAAM;EAClB,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,GAAG;CACtB;;AApBH,AAsBE,MAtBI,CAsBJ,aAAa,CAAC;EACV,OAAO,EAAE,IAAI;EACb,cAAc,EAAE,GAAG;EACnB,eAAe,EAAE,YAAY;EAC7B,aAAa,EAAE,MAAM;EAErB,MAAM,EAAE,KAAK;EACb,OAAO,EAAE,CAAC;CAiBb;;AA9CH,AA+BM,MA/BA,CAsBJ,aAAa,CAST,GAAG,CAAC;EACA,OAAO,EAAE,IAAI;EACb,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;CAKf;;AAvCP,AAoCU,MApCJ,CAsBJ,aAAa,CAST,GAAG,AAKE,MAAM,CAAC;EACN,UAAU,EAAE,kBAAqB;CACpC;;AAtCT,AAyCM,MAzCA,CAsBJ,aAAa,CAmBT,QAAQ,CAAC;EACL,OAAO,EAAE,KAAK;EACd,KAAK,EAAE,IAAI;EACX,MAAM,EAAE,IAAI;CACf;;AAIP,AAAA,KAAK,CAAA,AAAA,IAAC,CAAK,MAAM,AAAX,EAAa;EACjB,UAAU,EAAE,GAAG;EACf,KAAK,EAAE,KAAK;EACZ,SAAS,EAAE,GAAG;EACd,SAAS,EAAE,CAAC;EACZ,WAAW,EAAE,CAAC;EACd,OAAO,EAAE,OAAO;EAChB,cAAc,EAAE,GAAG;EACnB,SAAS,EAAE,GAAG;EACd,MAAM,EAAE,GAAG;EACX,KAAK,EAAE,KAAK;EAEZ,UAAU,EAAE,yBAAyB;EACrC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAwB;EACjD,aAAa,EAAE,GAAG;EAClB,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,wBAA2B;CAS9C;;AAxBD,AAiBE,KAjBG,CAAA,AAAA,IAAC,CAAK,MAAM,AAAX,CAiBH,SAAS,CAAC;EACP,aAAa,EAAE,iBACnB;CAAC;;AAnBH,AAqBE,KArBG,CAAA,AAAA,IAAC,CAAK,MAAM,AAAX,CAqBH,WAAW,CAAC;EACT,aAAa,EAAE,iBAAiB;CACnC;;AAGH,AAAA,GAAG,CAAC;EACF,MAAM,EAAE,OAAO;EACf,MAAM,EAAE,YAAY;EACpB,MAAM,EAAE,MAAM;EAEd,UAAU,EAAE,mBAAqB;EACjC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,yBAAyB;EAClD,aAAa,EAAE,GAAG;EAClB,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,kBAAmB;CACtC",
|
||||||
|
"sources": [
|
||||||
|
"styles.scss"
|
||||||
|
],
|
||||||
|
"names": [],
|
||||||
|
"file": "styles.css"
|
||||||
|
}
|
||||||
159
src/styles.scss
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
@font-face {
|
||||||
|
font-family: 'Comfortaa';
|
||||||
|
src: url('assets/Comfortaa-VariableFont_wght.ttf');
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
text-decoration: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 150%;
|
||||||
|
font-family: 'Comfortaa', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gradient {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: -1;
|
||||||
|
background-image: linear-gradient(to bottom, #3362bc, #3d6cc7, #4776d1, #5181dc, #5a8be7, #5a8be7, #5b8ae7, #5b8ae7, #527fdc, #4975d1, #406ac7, #3760bc);
|
||||||
|
}
|
||||||
|
|
||||||
|
.generators {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.generator {
|
||||||
|
margin: 1em;
|
||||||
|
background: rgba( 255, 255, 255, 0.15 );
|
||||||
|
box-shadow: 0 8px 32px 0 rgba( 0, 38, 135, 0.37 );
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba( 255, 255, 255, 0.18 );
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
margin: 0 1em 1em 1em;
|
||||||
|
display: flex;
|
||||||
|
place-content: space-between;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.buttons {
|
||||||
|
margin-top: 1em;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
place-content: space-between;
|
||||||
|
margin-left: auto;
|
||||||
|
|
||||||
|
img {
|
||||||
|
padding: .2em;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba( 0, 0, 0, 0.30 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
:nth-child(1) {
|
||||||
|
margin: auto 0 auto 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:nth-child(2) {
|
||||||
|
margin: auto 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
border-top-left-radius: 3px;
|
||||||
|
border-top-right-radius: 3px;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.7);
|
||||||
|
background: rgba(255, 255, 255, 0.20);
|
||||||
|
|
||||||
|
span {
|
||||||
|
margin-left: 1em;
|
||||||
|
padding: 0.4em 0;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.titleButtons {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-content: center;
|
||||||
|
|
||||||
|
margin: 0 1em;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
img {
|
||||||
|
padding: .1em;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba( 0, 0, 0, 0.30 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.smaller {
|
||||||
|
padding: 0.2em;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type="text"] {
|
||||||
|
margin-top: 1em;
|
||||||
|
width: 210px;
|
||||||
|
min-width: 0px;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
padding: 0 0.7em;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
font-size: 1em;
|
||||||
|
height: 2em;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
background: rgba(255, 255, 255, 0.15);
|
||||||
|
box-shadow: 0 8px 32px 0 rgba( 0, 38, 135, 0.37 );
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba( 255, 255, 255, 0.20 );
|
||||||
|
|
||||||
|
&.ng-valid {
|
||||||
|
border-bottom: 3px solid #87e17a
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ng-invalid {
|
||||||
|
border-bottom: 3px solid #fb8686;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
cursor: pointer;
|
||||||
|
filter: invert(100%);
|
||||||
|
margin: auto 0;
|
||||||
|
|
||||||
|
background: rgba( 0, 0, 0, 0.15 );
|
||||||
|
box-shadow: 0 8px 32px 0 rgba(255, 217, 120, 0.37);
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.10);
|
||||||
|
}
|
||||||
27
src/test.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
|
||||||
|
|
||||||
|
import 'zone.js/testing';
|
||||||
|
import { getTestBed } from '@angular/core/testing';
|
||||||
|
import {
|
||||||
|
BrowserDynamicTestingModule,
|
||||||
|
platformBrowserDynamicTesting
|
||||||
|
} from '@angular/platform-browser-dynamic/testing';
|
||||||
|
|
||||||
|
declare const require: {
|
||||||
|
context(path: string, deep?: boolean, filter?: RegExp): {
|
||||||
|
keys(): string[];
|
||||||
|
<T>(id: string): T;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// First, initialize the Angular testing environment.
|
||||||
|
getTestBed().initTestEnvironment(
|
||||||
|
BrowserDynamicTestingModule,
|
||||||
|
platformBrowserDynamicTesting(),
|
||||||
|
{ teardown: { destroyAfterEach: true }},
|
||||||
|
);
|
||||||
|
|
||||||
|
// Then we find all the tests.
|
||||||
|
const context = require.context('./', true, /\.spec\.ts$/);
|
||||||
|
// And load the modules.
|
||||||
|
context.keys().map(context);
|
||||||
15
tsconfig.app.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./out-tsc/app",
|
||||||
|
"types": []
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/main.ts",
|
||||||
|
"src/polyfills.ts"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"src/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
30
tsconfig.json
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||||
|
{
|
||||||
|
"compileOnSave": false,
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./",
|
||||||
|
"outDir": "./dist/out-tsc",
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"strict": true,
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noFallthroughCasesInSwitch": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"declaration": false,
|
||||||
|
"downlevelIteration": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"importHelpers": true,
|
||||||
|
"target": "es2020",
|
||||||
|
"module": "es2020",
|
||||||
|
"lib": [
|
||||||
|
"es2020",
|
||||||
|
"dom"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"angularCompilerOptions": {
|
||||||
|
"enableI18nLegacyMessageIdFormat": false,
|
||||||
|
"strictInjectionParameters": true,
|
||||||
|
"strictInputAccessModifiers": true,
|
||||||
|
"strictTemplates": true
|
||||||
|
}
|
||||||
|
}
|
||||||
18
tsconfig.spec.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./out-tsc/spec",
|
||||||
|
"types": [
|
||||||
|
"jasmine"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/test.ts",
|
||||||
|
"src/polyfills.ts"
|
||||||
|
],
|
||||||
|
"include": [
|
||||||
|
"src/**/*.spec.ts",
|
||||||
|
"src/**/*.d.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||