Commit e4bc24ac authored by dtati's avatar dtati

first commit

parents
Pipeline #528 failed with stages
# 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
# See http://help.github.com/ignore-files/ for more about ignoring files.
# Compiled output
/dist
/tmp
/out-tsc
/bazel-out
# Node
/node_modules
npm-debug.log
yarn-error.log
# IDEs and editors
.idea/
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace
# Visual Studio Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history/*
# Miscellaneous
/.angular/cache
.sass-cache/
/connect.lock
/coverage
/libpeerconnection.log
testem.log
/typings
# System files
.DS_Store
Thumbs.db
node_modules
\ No newline at end of file
# SkyFaceAngularDemo
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 16.2.3.
## Dependecies
run `npm install`
## Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
## More Informations
Please refere to our platform `https://platform.skyidentification.com/#/`
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"version": 1,
"newProjectRoot": "projects",
"projects": {
"sky_Identification_Angular_Demo": {
"projectType": "application",
"schematics": {},
"root": "",
"sourceRoot": "src",
"prefix": "app",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist/sky-identification-angular-demo",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": [
"zone.js"
],
"tsConfig": "tsconfig.app.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
},
"configurations": {
"production": {
"budgets": [
{
"type": "initial",
"maximumWarning": "500kb",
"maximumError": "1mb"
},
{
"type": "anyComponentStyle",
"maximumWarning": "2kb",
"maximumError": "4kb"
}
],
"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": "sky_Identification_Angular_Demo:build:production"
},
"development": {
"browserTarget": "sky_Identification_Angular_Demo:build:development"
}
},
"defaultConfiguration": "development"
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "sky_Identification_Angular_Demo:build"
}
},
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"polyfills": [
"zone.js",
"zone.js/testing"
],
"tsConfig": "tsconfig.spec.json",
"assets": [
"src/favicon.ico",
"src/assets"
],
"styles": [
"src/styles.css"
],
"scripts": []
}
}
}
}
},
"cli": {
"analytics": false
}
}
This diff is collapsed.
{
"name": "sky-identification-angular-demo",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "^16.2.0",
"@angular/common": "^16.2.0",
"@angular/compiler": "^16.2.0",
"@angular/core": "^16.2.0",
"@angular/forms": "^16.2.0",
"@angular/platform-browser": "^16.2.0",
"@angular/platform-browser-dynamic": "^16.2.0",
"@angular/router": "^16.2.0",
"jquery": "^3.7.1",
"rxjs": "~7.8.0",
"skyid-sdk-web": "^1.1.2",
"tslib": "^2.3.0",
"zone.js": "~0.13.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^16.2.3",
"@angular/cli": "~16.2.3",
"@angular/compiler-cli": "^16.2.0",
"@types/jasmine": "~4.3.0",
"jasmine-core": "~4.6.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.1.3"
}
}
export class ConfigHelper {
// information sent after creation of applicationId by mail
API_url = "***"
LIVENESS_url = "***"
FACE_MATCHING_url = "***"
SKYID_FA_SDK_PARAMS_url = "***"
skyid_fa_sdk_user = "***";
skyid_fa_sdk_password = "***";
skyid_fa_sdk_token = "***";
skyid_fa_sdk_appId = "***";
constructor() {
}
setFileImage(my_selfie_canvas: any) : File {
const canvas_bin = this.skyid_fa_canvas2binary(my_selfie_canvas);
return new File([canvas_bin], "skyid_fa_selected_frame.jpg", { type: "application/octet-stream" })
}
skyid_fa_canvas2binary(req_canvas: any) {
let skyid_fa_canvas_data = req_canvas.toDataURL('image/jpeg', 1.0);
skyid_fa_canvas_data = skyid_fa_canvas_data.replace('data:image/jpeg;base64,', '');
return this.skyid_fa_base64ToArrayBuffer(skyid_fa_canvas_data)
}
skyid_fa_base64ToArrayBuffer(base64: any) {
const binary_string = window.atob(base64);
const len = binary_string.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}
}
\ No newline at end of file
h1 {
text-align: center;
}
h2 {
margin: 0;
}
#multi-step-form-container {
margin-top: 5rem;
}
.text-center {
text-align: center;
}
.mx-auto {
margin-left: auto;
margin-right: auto;
}
.pl-0 {
padding-left: 0;
}
.button {
padding: 0.7rem 1.5rem;
border: 1px solid #4361ee;
background-color: #4361ee;
color: #fff;
border-radius: 5px;
cursor: pointer;
}
.submit-btn {
border: 1px solid #0e9594;
background-color: #0e9594;
}
.mt-3 {
margin-top: 2rem;
}
.d-none {
display: none;
}
.form-step {
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 20px;
padding: 3rem;
}
.font-normal {
font-weight: normal;
}
ul.form-stepper {
counter-reset: section;
margin-bottom: 3rem;
}
ul.form-stepper .form-stepper-circle {
position: relative;
}
ul.form-stepper .form-stepper-circle span {
position: absolute;
top: 50%;
left: 50%;
transform: translateY(-50%) translateX(-50%);
}
.form-stepper-horizontal {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: space-between;
}
ul.form-stepper > li:not(:last-of-type) {
margin-bottom: 0.625rem;
-webkit-transition: margin-bottom 0.4s;
-o-transition: margin-bottom 0.4s;
transition: margin-bottom 0.4s;
}
.form-stepper-horizontal > li:not(:last-of-type) {
margin-bottom: 0 !important;
}
.form-stepper-horizontal li {
position: relative;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
-webkit-box-align: start;
-ms-flex-align: start;
align-items: start;
-webkit-transition: 0.5s;
transition: 0.5s;
}
.form-stepper-horizontal li:not(:last-child):after {
position: relative;
-webkit-box-flex: 1;
-ms-flex: 1;
flex: 1;
height: 1px;
content: "";
top: 32%;
}
.form-stepper-horizontal li:after {
background-color: #dee2e6;
}
.form-stepper-horizontal li.form-stepper-completed:after {
background-color: #4da3ff;
}
.form-stepper-horizontal li:last-child {
flex: unset;
}
ul.form-stepper li a .form-stepper-circle {
display: inline-block;
width: 40px;
height: 40px;
margin-right: 0;
line-height: 1.7rem;
text-align: center;
background: rgba(0, 0, 0, 0.38);
border-radius: 50%;
}
.form-stepper .form-stepper-active .form-stepper-circle {
background-color: #4361ee !important;
color: #fff;
}
.form-stepper .form-stepper-active .label {
color: #4361ee !important;
}
.form-stepper .form-stepper-active .form-stepper-circle:hover {
background-color: #4361ee !important;
color: #fff !important;
}
.form-stepper .form-stepper-unfinished .form-stepper-circle {
background-color: #f8f7ff;
}
.form-stepper .form-stepper-completed .form-stepper-circle {
background-color: #0e9594 !important;
color: #fff;
}
.form-stepper .form-stepper-completed .label {
color: #0e9594 !important;
}
.form-stepper .form-stepper-completed .form-stepper-circle:hover {
background-color: #0e9594 !important;
color: #fff !important;
}
.form-stepper .form-stepper-active span.text-muted {
color: #fff !important;
}
.form-stepper .form-stepper-completed span.text-muted {
color: #fff !important;
}
.form-stepper .label {
font-size: 1rem;
margin-top: 0.5rem;
}
.form-stepper a {
cursor: default;
}
.smart_ocr_get_info{
width: 200px;
background-color: #4361ee;
border-radius: 30pc;
color: white;
/* text-align: center; */
height: 40px;
margin: auto;
cursor: pointer;
/* justify-content: center; */
text-align: center;
display: flex;
justify-content: center;
margin-top: 20px;
align-items: center;
}
input[type="file"] {
position: relative;
}
input[type="file"]::file-selector-button {
width: 136px;
color: transparent;
}
/* Faked label styles and icon */
input[type="file"]::before {
position: absolute;
pointer-events: none;
top: 10px;
left: 16px;
height: 20px;
width: 20px;
content: "";
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%230964B0'%3E%3Cpath d='M18 15v3H6v-3H4v3c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2v-3h-2zM7 9l1.41 1.41L11 7.83V16h2V7.83l2.59 2.58L17 9l-5-5-5 5z'/%3E%3C/svg%3E");
}
input[type="file"]::after {
position: absolute;
pointer-events: none;
top: 11px;
left: 40px;
color: #0964b0;
content: "Upload File";
}
/* ------- From Step 1 ------- */
/* file upload button */
input[type="file"]::file-selector-button {
border-radius: 4px;
padding: 0 16px;
height: 40px;
cursor: pointer;
background-color: white;
border: 1px solid rgba(0, 0, 0, 0.16);
box-shadow: 0px 1px 0px rgba(0, 0, 0, 0.05);
margin-right: 16px;
transition: background-color 200ms;
}
/* file upload button hover state */
input[type="file"]::file-selector-button:hover {
background-color: #f3f4f6;
}
/* file upload button active state */
input[type="file"]::file-selector-button:active {
background-color: #e5e7eb;
}
.main_container{
background-color: #E6E6E6;
}
/* spiner */
.loader {
margin-top: 20px;
margin-bottom: 20px;
width: 48px;
height: 48px;
margin: auto;
border: 5px solid #FFF;
border-bottom-color: #4361ee;
border-radius: 50%;
display: inline-block;
box-sizing: border-box;
animation: rotation 1s linear infinite;
}
@keyframes rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.IndatacoreIdentity{
display: flex;
margin: auto;
background-color: #263269;
width: 70px;
padding: 10px;
border-radius: 20px;
}
/* drag and drop style */
.code-json{
border: 2px dashed #f0f2f5;
padding: 1rem;
height: 100%;
pre{
background-color: #f0f2f5;
padding: 1rem;
}
}
\ No newline at end of file
<div class="main_container">
<div>
<img src="assets/IndatacoreIdentity.png" class="IndatacoreIdentity" alt="">
</div>
<h1>It only takes one more click to discover Sky Face Analysis on the web channel.</h1>
<div id="multi-step-form-container">
<form id="userAccountSetupForm" name="userAccountSetupForm" enctype="multipart/form-data" method="POST">
<section class="form-step" class="form-step" style="background-color: aliceblue;">
<h2 class="font-normal" style="
margin-bottom: 50px;
margin-top: 0px;
text-align: center;
">Download your picture</h2>
<input type="file" (change)="changeImage($event)" name="file" [(ngModel)]="fileImage" accept="image/*">
<div id="imageContainer" style="
justify-content: center;
display: flex;">
<img id="uploadedImageocr" [src]="imageSrc" alt="Uploaded Image" style="
width: auto;
height: auto;
margin-top: 20px;
border-radius: 5px;">
</div>
</section>
<section [style.display]="loadDataFaceDisplay" class="form-step">
<div style="display: flex;justify-content: center;" id="skyid_liveness"></div>
<button *ngIf="!displayButton" class="smart_ocr_get_info" (click)="startScanFace()">Start Face ID</button>
<button *ngIf="displayButton" class="smart_ocr_get_info" (click)="tryagain()">Try again</button>
<div style="text-align: center;">
<span *ngIf="loadSpinnerDisplay" class="loader"></span>
<div class="code-json">
<pre class=" bg-indatacoregray" *ngIf="response_face">
{{response_face | json}}
</pre>
</div>
</div>
</section>
</form>
</div>
<footer>
<p style="text-align: left; color: black;"
>Leader de l'industrie numérique basée sur l'intelligence artificielle et les technologies de Deep Learning. Nous nous efforçons d'innover et d'offrir à nos clients des produits qui répondent à leurs besoins.</p>
</footer>
<br>
</div>
\ No newline at end of file
import { TestBed } from '@angular/core/testing';
import { AppComponent } from './app.component';
describe('AppComponent', () => {
beforeEach(() => TestBed.configureTestingModule({
declarations: [AppComponent]
}));
it('should create the app', () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app).toBeTruthy();
});
it(`should have as title 'sky_Identification_Angular_Demo'`, () => {
const fixture = TestBed.createComponent(AppComponent);
const app = fixture.componentInstance;
expect(app.title).toEqual('sky_Identification_Angular_Demo');
});
it('should render title', () => {
const fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();
const compiled = fixture.nativeElement as HTMLElement;
expect(compiled.querySelector('.content span')?.textContent).toContain('sky_Identification_Angular_Demo app is running!');
});
});
import { Component, OnInit } from '@angular/core';
import { IdentificationService } from './service/identification.service';
//@ts-ignore
import * as skyid from 'skyid-sdk-web';
import { ConfigHelper } from './Helper/ConfigHelper';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = "sky_Identification_Angular_Demo";
imageSrc = "../../assets/CINcrt.jpg";
fileImage : any;
// used to get the token after the login
bearToken!: string;
document_uniqueName!: string;
// used to display data
response_liveness : any;
response_face: any;
my_selfie_canvas :any;
binaryFile: any;
displayButton! : boolean;
loadSpinnerDisplay: boolean = false;
loadDataFaceDisplay: string = 'none';
loadDataDocDisplay: string = 'block';
// Config Object
helperSky = new ConfigHelper();
constructor(private identificatioService: IdentificationService){
skyid.message_variables.skyid_fa_sdk_access_error_message = "Votre token n'est pas valide";
skyid.message_variables.skyid_fa_sdk_loading_error_message = "Error lors de chargement des modules";
skyid.message_variables.skyid_fa_sdk_network_error_message = "Error de connexion au serveur, merci de verifier votre connexion internet";
skyid.message_variables.skyid_fa_sdk_camera_error_message = "Impossible de demmarer votre camera, merci de verifier que votre camera et bien actif";
skyid.message_variables.skyid_fa_face_start_message = "SVP positionner votre visage au centre sans rotation. puis clique sur start.";
skyid.message_variables.skyid_fa_face_loading_message = "Chargement des modules, Patietez SVP.";
skyid.message_variables.skyid_fa_mul_face_warning_msg = "SVP representer un seul visage devant le camera.";
}
ngOnInit(): void {
this.login(this.helperSky.skyid_fa_sdk_user, this.helperSky.skyid_fa_sdk_password);
}
tryagain(){
window.location.reload()
}
// Login method
login(email: string, password: string){
this.identificatioService.login(email, password).subscribe((data:any) =>{
console.log(data);
if(data.status_code == "000"){
this.bearToken = data.response_data.access_token;
this.skiDetecFace(this.bearToken);
}else{
alert('Erreur de connexion');
this.displayButton = true;
}
}, error => {
alert("Try later");
this.displayButton = true;
});
}
// Sky get params method with step
skiDetecFace(bearToken: string){
this.identificatioService.skyid_fa_get_params_request(bearToken).subscribe((data:any) => {
skyid.skyid_fa_init_sdk(data.response_data);
}, error => {
alert("Try later")
});
}
// Next for initializ
next(){
this.init();
this.displayButton = false;
this.loadDataFaceDisplay = 'block';
this.loadDataDocDisplay = 'none';
}
// get file in our input
changeImage(event:any){
var files = event.target.files;
var file = files[0];
console.log(file);
if (files && file) {
var reader = new FileReader();
reader.onload = this.handleReaderLoaded.bind(this);
reader.readAsBinaryString(file);
this.binaryFile = file;
this.next();
}
}
// convert image to base64
handleReaderLoaded(readerEvt:any) {
var binaryString = readerEvt.target.result;
this.imageSrc = 'data:image/png;base64,' + btoa(binaryString);
}
// Camera launcher
init(){
let skyid_liveness = document.getElementById('skyid_liveness');
skyid_liveness!.innerHTML = skyid.skyid_component;
skyid.skyid_fa_setup_sdk();
}
// Method used to start liveliness
startScanFace(){
this.loadSpinnerDisplay = true;
skyid.skyid_fa_start_face_scan(this.skyid_fa_face_scan_end_callback.bind(this), this.process_fa_timeOut);
this.displayButton = true;
}
// Trigger when face analysis does not detect a valid face.
process_fa_timeOut() {
console.log("process_fa_timeOut ");
}
// Trigger when face analysis is done. It returns the result of face analysis .
skyid_fa_face_scan_end_callback(skyid_fa_detected_face_canvas: any) {
this.my_selfie_canvas = skyid_fa_detected_face_canvas
this.skyid_fa_check_liveness(skyid_fa_detected_face_canvas);
}
// Method used to contact the API
skyid_fa_check_liveness(frame : any){
const face_image = this.helperSky.setFileImage(frame);
this.identificatioService.skyid_fa_check_liveness_request(face_image, this.bearToken).subscribe((data: any) => {
if(data.status_code == "000" && data.response_data.face_class == "Real"){
this.response_liveness = data;
skyid.skyid_fa_start_face_scan(this.skyid_fa_face_scan_end_callbackfacematching.bind(this), this.process_fa_timeOut);
}else{
skyid.skyid_fa_stop_webcam();
this.displayButton = true;
this.loadSpinnerDisplay = false;
}
}, error => {
skyid.skyid_fa_stop_webcam();
alert("Try later")
this.displayButton = true;
this.loadSpinnerDisplay = false;
});
}
// callback protocol to re-implement. Trigger when face analysis is done. It returns the result of face analysis :
skyid_fa_face_scan_end_callbackfacematching(skyid_fa_detected_face_canvas:any){
const face_image = this.helperSky.setFileImage(skyid_fa_detected_face_canvas);
this.identificatioService.skyid_fa_face_scan_end_callbackfacematching(this.binaryFile, face_image,
this.bearToken, this.response_liveness.response_data.document_uniqueName).subscribe((data:any) => {
this.response_face = data;
this.loadSpinnerDisplay = false;
skyid.skyid_fa_stop_webcam();
this.displayButton = true;
}, error => {
skyid.skyid_fa_stop_webcam();
alert("Try later")
this.displayButton = true;
});
}
}
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HttpClientModule} from '@angular/common/http';
import { FormsModule } from '@angular/forms';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
import { TestBed } from '@angular/core/testing';
import { IdentificationService } from './identification.service';
describe('IdentificationService', () => {
let service: IdentificationService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(IdentificationService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ConfigHelper } from '../Helper/ConfigHelper';
@Injectable({
providedIn: 'root'
})
export class IdentificationService {
helperSky = new ConfigHelper();
constructor(private httpClient: HttpClient) { }
login(email:string, password:string){
var form = new FormData();
form.append("username", email);
form.append("password", password);
var headers = new HttpHeaders();
headers.set('Content-Type', 'multipart/form-data');
headers.set('Accept', '*/*');
return this.httpClient.post(this.helperSky.API_url, form, {headers: headers});
}
skyid_fa_get_params_request(bearToken:string){
var form = new FormData();
form.append("token", this.helperSky.skyid_fa_sdk_token);
form.append("application_id", this.helperSky.skyid_fa_sdk_appId);
var headers = new HttpHeaders({
Authorization: `Bearer ${bearToken}`,
});
return this.httpClient.post(this.helperSky.SKYID_FA_SDK_PARAMS_url, form, {headers:headers});
}
skyid_fa_check_liveness_request(face_image:any,bearToken : string){
var form = new FormData();
form.append("selfie",face_image);
var headers = new HttpHeaders({
Authorization: `Bearer ${bearToken}`,
});
return this.httpClient.post(this.helperSky.LIVENESS_url, form, {headers:headers});
}
skyid_fa_face_scan_end_callbackfacematching(docImage: File, face_image: File, bearToken:string, guid: string){
var form = new FormData();
form.append("doc_1_1", docImage);
form.append("slf_1", face_image);
form.append('guid', guid);
form.append("token", this.helperSky.skyid_fa_sdk_token);
form.append("application_id", this.helperSky.skyid_fa_sdk_appId);
var headers = new HttpHeaders({
Authorization: `Bearer ${bearToken}`,
});
return this.httpClient.post(this.helperSky.FACE_MATCHING_url, form, {headers:headers});
}
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>SkyIdentificationAngularDemo</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.error(err));
/* You can add global styles to this file, and also import other style files */
/* 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"
],
"include": [
"src/**/*.d.ts"
]
}
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "ES2022",
"module": "ES2022",
"useDefineForClassFields": false,
"lib": [
"ES2022",
"dom"
]
},
"angularCompilerOptions": {
"enableI18nLegacyMessageIdFormat": false,
"strictInjectionParameters": true,
"strictInputAccessModifiers": true,
"strictTemplates": true
}
}
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/spec",
"types": [
"jasmine"
]
},
"include": [
"src/**/*.spec.ts",
"src/**/*.d.ts"
]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment